A Dozen Reasons Why Test-First Is Better Than Test-Later (Pt. 1)

An editor of Dr. Dobbs magazine once wrote to me—replying to my response to an article—“All the benefits [of Test-Driven Development] could be attained equally by writing tests after the code, rather than before.”[1]

Tests exercise software to be sure it’s doing what was intended. So, whether you use Test-Driven Development (TDD) or write unit-tests after coding, you’re presumably getting the same benefit. The safety-net gets built, either way. Right?[2]

So, all else being equal (resulting quality, maintainability, lines of test code, lines of implementation code, time spent writing code), what advantage is there to writing the test first?

The difference between TDD and test-after unit-testing is subtle, but important. TDD is much more than writing the unit test first.

Chew on each of these separately. They frequently overlap, and I’ve even resorted to a bit of intentional repetition. These are all just words, alas: You won’t really feel it in your bones until you do TDD for a while. Think of each of the following sections as a finger pointing at the Moon: You won’t actually see the Moon until you give up on looking at the finger.



1. You cannot write untestable code.

If you do TDD well—playing the game that you cannot add any code that hasn’t been earned through a failing test—you literally cannot write untestable code.

This may seem obvious, at first, but what may not be so obvious is how easy it is to make unit-testing a bit of code harder by not writing the test first. If writing tests after were that simple, people would do it. And, they don’t, mostly.

Are you passing a non-virtual (sealed, or final) third-party dependency? How will you test all the permutations of interactions and responses with that object?

Did you create a method without a reasonable return value? (Note: Not all methods need a return value. Sometimes the most reasonable return value is none at all, aka void.)

Or (worse!) did you return an error code that the caller has to look up, or some object that the calling code now has to test against a null pointer?

Did you have a path that will throw an exception that the calling code has to deal with? Or (worse!) a Java “checked” exception that the client either has to wrap, declare as thrown, re-throw, or ignore?

Did you create a “helper” or “utility” method and, since it has no state, did you make it static? Yes, these are very easy to test. But their callers (typically someone on your team will be writing the calling code) are no longer easy to test.

Most (not all) developers tend to write perfectly reasonable procedural code when they don’t write the test first. The problem with perfectly reasonable procedural code is that it tends to be “scripty,” walking through a scenario and using branching to differentiate scenarios. Good procedural code makes for smelly object code, and bloated functional code.

TDD actually encourages us to write script code, but in the tests themselves. Each test is a representation of a possible calling sequence for client code. And it frees us up to design the implementation however we want, using the features of our programming language to its full potential: Objects, stateless functions, lambdas, abstractions, mix-ins, contracts, you-name-it.

2. You are recording your thoughts.

Objects and classes never live independent of each other. Instead, they combine and interact to create all the required behaviors. A “unit test” is a test of one tiny “unit” of that larger “business model” behavior.

The thought-process for TDD is not “Oh, let me write a test for my code…well how can I do that if I haven’t written the code?” Here’s a more common internal dialog: “I need this particular object to provide this next new bit of behavior. When I give the object this particular state, then ask it to act on that state, here are results I expect.”

Note that this internal dialog naturally occurs from a viewpoint external to the object. You’re recording a mini-specification for that new behavior in a simple, developer-readable, re-runnable automated test.

3. We design the interface from the viewpoint of calling code.

With TDD, often the required object class, or its methods, don’t even exist yet; so we’re effectively designing the naming and the interface (public method signatures) to that object through the tests. The unit tests are the first “clients” of that behavior. In this way, our interfaces (i.e., what objects are designed to do for other objects) are designed from the correct perspective: Each from the caller’s perspective.

4. You have to know the answer.

Perfectly rational, professional developers, when faced with making a decision with insufficient information, will often choose something that “feels right,” and plan to ask for clarification later—presumably during their copious free time, at a very relaxed meeting full of open dialog, during some testing and “hardening” phase that never seems to happen.

Computer programming does not do well with vagaries. Computers will do what you tell ‘em to do; nothing more, nothing less, and nothing different.

So if you don’t know for which day to journal a transaction that happens exactly at midnight, you’d better go find out! Ask the product advocate, business analyst, tester, or your pair-programming partner. If no one seems to know, then we need to ask an actual customer.



So we can’t write the test unless we know the answer we’d expect. You have to get out the calculator, slide-rule, or Google; or preferably the product advocate has told you what to expect (preferably through a Cucumber scenario).

What do we tend to do if we simply write out the whole 10240-bit quantum-encryption algorithm first, them write a unit test for it? We may assume the answer (which would look like random static anyway) our own code gives us is correct! And that, folks, is a huge disaster waiting to happen.

We’re more likely to look for the right answer before ever writing the solution to that request, than we are to ask questions after we’ve already written the code.

While we wait…

That’s the first 4 of 12. The next batch will be out in a month. Comments so far? Thanks for reading! “See” you next month!

Footnotes

[1] http://www.drdobbs.com/architecture-and-design/addressing-the-corruption-of-agile/240166890

[2] Lauri Williams did a study comparing test-first with test-after. The test-after team was finished before the test-first team. Alas, their code had more defects, because they didn’t sufficiently unit-test the code. In other words, they cheated. Not because they were cheaters, but because unit-testing code after the fact is harder…and boring. And you’re far more likely to miss an important case. https://collaboration.csc.ncsu.edu/laurie/Papers/TDDpaperv8.pdf


Related Articles

Responses

https://bezaleelsolutions.com/privacypolicy/ https://okalyfleurs.com/ https://protogelvictory.it.com https://latotovictory.it.com https://tabichill.com/mancingduit/ https://snowsofthenile.com/contact-us/ https://aimlautism.com/FATCAI99/ NANASTOTO LATOTO TVTOTO WDBOS DEPOBOS PROTOGEL HOKIJITU FATCAI99 LUNATOGEL MANCINGDUIT https://archidiocesisgranada.es/santo-del-dia/santa-sofia-2/ https://archidiocesisgranada.es/noticias/contacto/ PROTOGEL TVTOTO TVTOTO JUTAWANBET WDBOS FATCAI99 FATCAI99 LUNATOGEL NANASTOTO LUNATOGEL PROTOGEL WDBOS JUTAWANBET DEPOBOS MANCINGDUIT WDBOS LUNATOGEL MANCINGDUIT DEPOBOS NANASTOTO LUNATOGEL JUTAWANBET NANASTOTO LATOTO TVTOTO JUTAWANBET NANASTOTO LATOTO TVTOTO MANCINGDUIT FATCAI99 BANDAR80 LAPAK99 JUTAWANBET NANASTOTO LATOTO TVTOTO WDBOS DEPOBOS PROTOGEL HOKIJITU LUNATOGEL MANCINGDUIT FATCAI99 BANDAR80 LAPAK99 BANDAR80 LUNATOGEL MANCINGDUIT JUTAWANBET LATOTO HOKIJITU TVTOTO PROTOGEL LATOTO TVTOTO WDBOS PROTOGEL HOKIJITU LUNATOGEL MANCINGDUIT BANDAR80 LAPAK99 TOGELON LIGABANDOT SITUSTOTO JUTAWANBET NANASTOTO LATOTO TVTOTO WDBOS DEPOBOS PROTOGEL HOKIJITU LUNATOGEL MANCINGDUIT FATCAI99 BANDAR80 MANCINGDUIT FATCAI99 SITUSTOTO LAPAK99 LIGABANDOT TOGELON SITUSTOTO LUNATOGEL https://www.maleributiken.se/integritetspolicy/ https://www.maleributiken.se/allmanna-villkor/ https://www.maleributiken.se/integritetspolicy/ LATOTO TOGELON SITUSTOTO JUTAWANBET NANASTOTO LATOTO TVTOTO WDBOS DEPOBOS PROTOGEL HOKIJITU LUNATOGEL MANCINGDUIT FATCAI99 BANDAR80 LAPAK99 DEPOBOS SITUSTOTO LIGABANDOT TOGELON NANASTOTO WDBOS DEPOBOS LUNATOGEL NANASTOTO HOKIJITU MANCINGDUIT FATCAI99 LAPAK99 LIGABANDOT SITUSTOTO JUTAWANBET NANASTOTO WDBOS DEPOBOS DEPOBOS DEPOBOS LAPAK99 PROTOGEL NANASTOTO DEPOBOS DEPOBOS NANASTOTO TVTOTO LATOTO PROTOGEL DEPOBOS NANASTOTO LUNATOGEL MANCINGDUIT DEPOBOS NANASTOTO LUNATOGEL MANCINGDUIT TVTOTO TOGELON SITUSTOTO LAPAK99 JUTAWANBET NANASTOTO TOGELON SITUSTOTO JUTAWANBET NANASTOTO TOGELON SITUSTOTO LUNATOGEL DEPOBOS NANASTOTO TOGELON SITUSTOTO JUTAWANBET LUNATOGEL TOGELON NANASTOTO JUTAWANBET TOGELON JUTAWANBET JUTAWANBET LATOTO NANASTOTO DEPOBOS LUNATOGEL NANASTOTO DEPOBOS TOGELON LUNATOGEL JUTAWANBET LATOTO SITUSTOTO JUTAWANBET LATOTO SITUSTOTO TVTOTO MANCINGDUIT NANASTOTO DEPOBOS TOGELON LUNATOGEL PROTOGEL TVTOTO MANCINGDUIT NANASTOTO TVTOTO MANCINGDUIT LAPAK99 HOKIJITU LATOTO FATCAI99 BANDAR80 PROTOGEL DEPOBOS JUTAWANBET TVTOTO https://barryvilleny.com/donation/ https://barryvilleny.com/scholarship/ https://barryvilleny.com/sitemap/ https://barryvilleny.com/privacy-policy/ MANCINGDUIT NANASTOTO TOGELON TVTOTO DEPOBOS LATOTO TOGELON NANASTOTO MANCINGDUIT FATCAI99 TVTOTO PROTOGEL NANASTOTO TOGELON LUNATOGEL PROTOGEL DEPOBOS WDBOS LATOTO TVTOTO MANCINGDUIT LAPAK99 FATCAI99 HOKIJITU LIGABANDOT BANDAR80 JUTAWANBET NANASTOTO TOGELON LUNATOGEL PROTOGEL DEPOBOS WDBOS LATOTO TVTOTO MANCINGDUIT LAPAK99 FATCAI99 HOKIJITU LIGABANDOT BANDAR80 JUTAWANBET NANASTOTO TOGELON LUNATOGEL PROTOGEL DEPOBOS DEPOBOS NANASTOTO TOGELON SITUSTOTO LUNATOGEL PROTOGEL DEPOBOS NANASTOTO TOGELON SITUSTOTO NANASTOTO TOGELON SITUSTOTO LUNATOGEL PROTOGEL DEPOBOS DEPOBOS NANASTOTO TOGELON NANASTOTO TOGELON SITUSTOTO SITUSTOTO PROTOGEL LUNATOGEL DEPOBOS LUNATOGEL https://desertbar.com/fee-arbitration/ MANCINGDUIT TVTOTO JUTAWANBET FATCAI99 LAPAK99 HOKIJITU TVTOTO LATOTO NANASTOTO NANASTOTO TVTOTO LATOTO DEPOBOS TOGELON WDBOS TVTOTO LATOTO NANASTOTO NANASTOTO DEPOBOS SLOT GACOR SLOT GACOR SLOT GACOR SLOT GACOR MANCINGDUIT TVTOTO WDBOS DEPOBOS LATOTO LIGABANDOT HOKIJITU NANASTOTO LUNATOGEL TOGELON MANCINGDUIT TVTOTO WDBOS DEPOBOS LATOTO HOKIJITU LIGABANDOT SITUSTOTO NANASTOTO TVTOTO MANCINGDUIT PROTOGEL NANASTOTO TOGELON LUNATOGEL SITUSTOTO DEPOBOS WDBOS JUTAWANBET TVTOTO MANCINGDUIT https://ebcconnects.com/resources/faq/ https://ebcconnects.com/resources/church-resources/ PROTOGEL JUTAWANBET TVTOTO MANCINGDUIT FATCAI99 HOKIJITU BANDAR80 JUTAWANBET TVTOTO MANCINGDUIT TVTOTO MANCINGDUIT NANASTOTO NANASTOTO TVTOTO TOGELON MANCINGDUIT WDBOS DEPOBOS LATOTO NANASTOTO LUNATOGEL SITUSTOTO TOGELON WDBOS DEPOBOS LATOTO JUTAWANBET HOKIJITU FATCAI99 NANASTOTO LUNATOGEL SITUSTOTO TOGELON LATOTO WDBOS DEPOBOS JUTAWANBET HOKIJITU FATCAI99 LIGABANDOT DEPOBOS LATOTO WDBOS NANASTOTO LATOTO TVTOTO LIGABANDOT BANDAR80 JUTAWANBET SITUSTOTO FATCAI99 DEPOBOS WDBOS DEPOBOS JUTAWANBET HOKIJITU FATCAI99