Tag Archives: TDD

The TDD Tetrahedron

Posted on by

Are you looking for some concrete expression for Test Driven Development? Let me give you a glimpse of what I am working currently on – the TDD Tetrahedron.

The idea originates from when a colleague at Crisp, David Barnholdt, wrote about not focusing on one step at the time. So I thought for a while and came up with this idea, a tetrahedron where each side displayed “failing test”, “implementation” and “refactor”, respectively.

You turn it and look at the first side where you read “failing test”. You write a failing test and turn it again, reading “implementation”. Write the implementation and run the test to get the green bar. Once again you turn the tetrahedron and read “refactor”. You look for something to refactor, confident that if you do, you will be supported by unit tests all the way.

Or the thing just sit on your table to tell everyone how cool you are as being a TDD programmer. At least wish to be. 🙂

Anyways, here are some sneak preview pictures of the greatest thing that ever happened to the world of programming, ta da – the TDD Tetrahedron!

TDD TetrahedronTDD TetrahedronTDD Tetrahedron

Beyond Basic TDD

Posted on by

This coming spring we will host a course with Robert C Martin on advanced TDD. I would really appreciate the input from my experienced TDD readers on what they consider to be the largest obstacles when it comes to TDD. This is your chance to shape the event so that it is customized to meet your needs.

A few months ago we hosted a very popular course with Michael Feathers. He talked about refactoring legacy systems and of course, unit tests which are an essential part of that. But the crowd cried out for more.

I have been practicing TDD for two years. I program in Java and frequently use Mockito and Wicket. The latter has support for unit testing web interfaces and it is great although it has its quirks.

But what is everyone else doing?

In my experience the GUI is the hardest part to develop using TDD, at the same time there is a lot to gain by using TDD. You really, really want automated tests instead of manually clicking through your interface.

A GUI can be built many ways and on different platforms. I mentioned web, where there are different technical issues with different frameworks. There are also Swing-based Java applications and mobile platforms.

How can you test the GUI? There are several different options. You can send events, but there are issues ensuring that the event reaches the correct control, timing issues and performance problems.

You can go slightly under the surface by programatically calling the functions that should be invoked by the events. But you may run into issues with correctness. For example, the button you try to test a click on may not be visible.

You can argue that a GUI is not considered done until a human has looked at it. Yes, but that is no excuse for not writing tests.

There are of course other complicated scenarios. Take multi-threading, how do you handle that?

Besides the technical problems, there are also social problems.

The first that springs to mind is that there is a feeling that it takes too long to write the tests. As a TDD addict, you know that this is an illusion. You reach "done" on the Scrum board faster when you write tests. The feeling stems from the fact that time feels shorter if you sit staring at the code thinking instead of expressing yourself in code. Also, if you don’t write tests, time gets split up between implementing and fixing bugs. So the latter does not included in the former, as it should. "Oh, I’m done, there are just some bugs to fix".

There is also a fear that maintaining the tests takes too long. That may be quite true. If you write code that is hard to maintain, it will apply to your test code as well. If the code you test has poorly designed interfaces that change frequently, that will adversely impact your test code AND other clients. Maintenance will always be necessary. As the requirements change, the tests need to change.

It’s important to point out that TDD is not about testing, it is about specification. That is why some people prefer to say BDD instead. It is a common misunderstanding that TDD means testing. That manifests itself in comments like "even though you wrote unit tests, there are bugs".

Real testing is a different animal altogether which can make use of the same tools.

It gets fuzzy. When should you stop and say that there are enough unit tests to specify the behaviour of the unit and when do you do real testing with bounds checking etc? And does it matter when?

Another social problem: How do approach co-workers who refuse to write unit tests?

The problem is not just that they are slower and missing their own potential. The larger problem is that they are not writing specification.

We are agile now, so we don’t write requirements in Word documents that are printed and read and transformed into test documents and design documents that are printed and reviewed and changed and printed again when they are finally approved for use in coding which uncovers contradictions, fuzziness and other problems which render the design document obsolete and now the requirements are also obsolete so the requirements document changes and gets printed …

We talk directly to the product owner. We have little notes that are topics for discussion. We jot down a few remarks on the notes. Then we code and when we are done, we can throw the notes away.

So where is the specification? Anyone who has tried to make changes to a legacy system knows that there is none but the code. Not even when there are huge systems of documents that are supposed to describe the system.

If you don’t write documents that specify the system and you don’t write unit tests that express what the system should do, the only thing left is the system itself and that is not enough. The system mixes the purpose with the solution on every line of code. And you are in legacy land from day 1.

But now I’d like to hear from you! Comment here or mail me (per.lundholm at crisp.se). What have I missed? What do you think should go into an advanced class on TDD?

What to refactor?

Posted on by

 

1. Team vote on this weeks refactoring
candidate

Simple yet effective, team members will "know" which areas that are troublesome and use the last developed stories as judgment of "pains".

2. Refactor where changes are frequent

When encountering bad code, write a simple comment:

//Refactor me pleeaase
private String generateXml(Session session, int depth, string prefix)

Second time a developer in the team encounters this code, he needs to refactor it..

What? No! Gaaaah...

This approach will keep code frequently changed clean, but with a heavier start up cost 🙂

The Last on Code Review

Posted on by

Code quality. It has been haunting me for so long I forgot when I started to think about it. Do other people think about it? For sure. Do everyone? Certainly not.

I was doing RUP and before that some waterfall process from DoD. Before that I was programming Fortran. Now, what has been my single most important recommendation for reaching code quality?

Peer code review.

But enough. It just struck me how much I do not miss code reviews.

I’ll tell you why and I’ll tell you what is the replacement, because there should be one.

I had completely forgotten about code reviews until I ran into a colleague from the past and suddenly remembered a code review in particular.

It was humiliating. First of all, it was boring to print the code on paper and then spend hours reading it. Secondly, I had to face the fact that a lot of the code was copied but not used. I put a big X across the whole page of dead code. Humiliation became a fact when everyone saw it on the meeting.

It was so boring that despite we were caring about code quality and believed in code review, it was hard to make it happen.

Code review is dead – long live the new code review: pair programming!

There are today two very important practices for code and design quality, one of them is pair programming and the other one is test driven design.

Pair programming is code review because there is somebody looking at the code as you type. If you write code that is either hard to understand or breaks some design rule, it is spotted before you have put down hours into it.

It easier to change something before you get emotionally attached to it.

The old code review also had another downside, the reviewers became attached to the flaws they found. Imagine building up arguments for a position on the design of the code that you think needs to be fixed. You come to the review meeting and the design is already changed. Would you not be tempted to tell everyone what you had found, despite being useless information? I would.

Pair programming is also a setting where two people help each other to solve a problem. A code review is a meeting were a group of people discuss a single persons efforts, the one that was the last to touch the code. I hated it when it was me.

Bye, bye peer code review. Will you rest in peace and not be awaken ever again.

Mock the Clock

Posted on by

Say you have a test case “Given a departure more than 90 days from now, when a passenger logs on, should present a premature login page”.

You first thought is of course to set up a mock for departures so that when we simulate the log on, system logic will discover that there are more than 90 days. So you take the current time and adds 90 days to set the time for the mocked departure. Easy. But it fails twice a year when we go to and from daylight saving. You could fix that too, of course. But then we discover a  bug when it is exactly 90 days from now and you need to write a test that shows that. Again, you pick the current time and start calculating.

Later on, you discover that some of the manual tests are taking very long time. It turns out that the testers are constantly changing their test data to match the current date. Lets say that we have a test that involves the birthday of somebody. So the testers have to manipulate the test data to change birthdays for people in their test data.

That has to be waste.

“Now” is a concept that is readily available to your code so it will no specific point in the code where you can change the notion of “now” for the system. Also, how fast shall time pass? If there are test cases that requires time to pass, it might be useful if you could throttle the speed of the clock.

My advice is to consider which of your tests that are affected by current date and time passing. Create a utility that will return the current time as is or some fake time depending on configuration.

E.g. a system property in Java could be a date-time string which is read if the system is not in production mode. A more advanced variant would include a user interface for easy access to the meaning of “now”.

There are of course other solutions, but I am surprised that the problems with time are overlooked so often.

The Wicket framework is not TDD-friendly

Posted on by

The Wicket framework is somewhat deceptive when it comes to testing, especially TDD. The wicket tester is pretty good for integration tests. However, when trying to test individual components in a TDD manner, you’ll get bitten by the “final” keyword that appears quite frequently among the Wicket components. Mockito won’t help you, my favorite subclass-and-override technique cannot be applied. So, you’re on your own, implementing extra methods in order to get the component under test, which leads to frustration and lack of focus.

Essensen och kruxet med testdriven utveckling

Posted on by

När du förstått poängen med testdriven utveckling kommer givetvis krånglet. Så hur tar man sig vidare?

Vi börjar med poängen så att vi är överens om vad vi menar.

Testdriven utveckling (TDD) säger att man först skriver ett test som fallerar (viktigt), sedan implementerar man så att det inte längre fallerer.

I det läget tar man sig en funderare om man tycker att designen och kodstrukturen är enklast möjliga. Om inte så fixar man till den, utan att ändra vad koden gör, refactor på engelska. Eftersom de tester man har, går igenom så är det tryggt att ändra implementationen.

Vi fortsätter sedan med ett nytt varv, test – implementation – refactor.

Enkelt så långt, men vad är poängen? Det finns flera poänger.

För det första så beskriver ett test vad som skall göras medan implementationen beskriver hur det ska göras. Testerna blir därmed specifikationer skrivna i ett formellt språk, Java (eller vad som gäller för projektet).

För det andra, eftersom testet skrivs innan implementationen så blir designen av gränssnittet gjort utifrån en brukare (testet) vilket blir bättre än om det görs med utgångspunkt i hur implementationen är utformad.

För det tredje så blir det av att skriva tester vilket inte är fallet om man skriver dem efteråt. Täckningsgraden för tester skrivna efteråt blir dessutom betydligt lägre eftersom det oftast blir svårt att komma åt delar av implementationen.

Motivationen att skriva tester för kod som uppfattas som fungerande är extremt låg.

Att det finns automatiskt exekverande tester är en kritisk framgångsfaktor. All kod behöver förändras, men kan säga att underhåll av en kodrad egentligen börjar så fort den är skriven.

Med automatiserade tester kan jag ändra i befintlig kod med större trygghet. Testerna specificerar ju vad som är korrekt så om jag ändrar något som går utanför det, så märker jag det direkt.

Det var essensen, så vad är då kruxet?

Det absolut vanligaste problemet med införandet av TDD är att det finns väldigt mycket kod som inte har automatiska tester. När man vill införa TDD så står denna kodmängd framför en som ett oöverstigligt berg.

Tanken är att nästa ändring som jag inför ska jag göra testdrivet, d v s skriva ett test som visar vad som ska hända, konstatera att det inte händer och sedan ändra så att det händer. Men koden jag ska ändra i, den har inga tester och är inte förberedd för det!

Så antingen struntar jag i TDD och ändrar ändå, som förut. Tar det försiktigt och rör ingenting som verkar krångligt. Kör lite informella tester och hoppas att testarna ska upptäcka eventuella fel. Förmodligen gör de det och så får jag tillbaka problemet någon tid senare när jag hunnit glömma alldeles för mycket. Eller så biter jag ihop för jag vill inte gå den vägen en gång till.

Det får kosta om det vill, bara jag slipper idissla varje ändring flera gånger.

Nu infinner sig problemet att arkitekturen är inte utformad så att jag lätt kan införa tester. Den komponent jag ska ändra i är beroende av flera andra komponenter som jag inte tänkt mig skulle behöva blandas in. I synnerhet som dessa i sin tur är beroende av ytterligare andra komponenter.

Här krävs att jag tar till något som isolererar komponenten från omgivande komponenter. Det finns flera knep, bl a olika ramverk som simulerar komponenter (mocking) och bara skickar tillbaka fördefinierade resultat. Min favorit för Java är Mockito.

Ibland räcker det dock med att ärva eller implementera gränssnitt och definera metoder som skickar givna svar.

Tyvärr behöver vi något mer. Även om vi lyckas begränsa komponenten så att den inte anropar kringliggande komponenter så vet vi inte om vi har haft sönder den eftersom vi inte har någon formell definition på "trasig" respektive "fungerande".

Vad vi kan göra då är att ta ett fingeravtryck. Innan vi ändrar något så skriver vi ett eller flera tester som är bara till för att generera utdata. Vi försöker skapa ett avtryck av hur komponenten beter sig. När vi sedan ändrar i komponenten så kan vi se om utdata förändrats på något oväntat sätt. I så fall kan vi gå in och analysera vad det berodde på och om det ska anses vara fel eller rätt.

Några böcker:
"Test Driven", av Lasse Koskela.
"Working effectively with Legacy Code", av Michael Feathers

Wicket + Mockito = Love

Posted on by

I’ve survived my first Rocket Day. RD are our seminars at Crisp where we talk for half a day on a subject of choice. Mine was Test Driven Development with Wicket and Mockito.

I chosed to do a live coding performance as I liked to do a very down-to-earth, practical seminar.

The slides are currently in swedish but I will translat them to english. Later. 😉

However, most of you read swedish so I have published them here.

Ivar Jacobson gör en pudel!

Posted on by

Ivar Jacobson, Pan-Wei Ng, och Ian Spence har just publicerat en ganska lång artikel i DDJ med namnet Enough of Processes: Let’s Do Practices, Part I. Det är, förvånande nog, ett ganska ärligt erkännande att dagens processer för mjukvaruutveckling inte fungerar.

In the first installment of this two-part article, we examine the issues facing the current generation of processes and show why we have all had enough of them.

Ett ganska häpnadsväckande uttalande från skaparen av RUP! Artikeln räknar upp många anledningar till varför processer i dagens mening har problem, och presenterar sedan en teaser till något de kallar Practices, men väntar med att förklara vad de menar till den ännu opublicerade Part II av artikeln.

I någon mening är det kanske intressant vad de har i kikaren, men det verkar trots allt som om de egentligen inte vet vad de talar om.

The industry is not really getting any better at developing software

Really? Jag tycker Scrum, XP och TDD är väldigt tydliga och rejäla steg i rätt riktning.