DEV Community

Rasmus Schultz
Rasmus Schultz

Posted on

Test-driven vs test-first

I've tried test-first many times over my career, and I will happily admit that it does not work for me.

If it works for you, that's great. But personally, I need to think about the code and the design first, before I know what I need to test.

How I Write Code

My workflow is very much driven by tests.

I typically write one function, or maybe just part of a function, with testing in mind - and then I add the test. I would agree that test-last is not a good strategy, but what works best for me, personally, is to alternate between writing code and tests.

For one, I find that writing the test first is just too clumsy in type-safe languages. I don't want to have the IDE screaming at me the whole way - if I write the test first, there is no auto-completion, or sometimes the wrong auto-completion.

But more than that, I simply haven't discovered the right shape or form of the code yet - and that is something I want to tease out, discover and adjust, before committing to a public interface, which I'm going to be testing against.

In other words, my code is definitely driven by tests - but it's not exclusively driven by tests. Plenty of other factors inform the design of my code - for example, the existing code, and the language itself, both inform and constrain a design.

I design for testability, but perhaps more than that, I design for readability - which isn't something that I, personally, can just intuit, ahead of actually writing code.

More Roads to Rome

We both strive for the same values, and arrive at code with the same qualities: it works, it's modular, it's cohesive, it's decoupled, it has good separation of concerns and meaningful abstractions. We both want readable tests that test the right things, aren't too dependent on implementation details, and so on.

In my experience, the difference between the test-first approach and my approach is largely personality - rather than outcomes.

My code is just as informed and driven by tests, at every step of the process, as your test-first code. My approach is every bit as test-driven as yours.

I just don't have the exact same process and mental model that happens to work for you.

Since you've been insisting on test-first for much of my career, of course I've tried it, and more than once. And frankly, if I were forced to write my tests first, my code and tests would not be as good as they are.

It's simply not how my mind works, and I'm definitely not alone in feeling this way either - I know plenty of capable, experienced developers who feel the same way.

Finding Balance

I wish you would not conflate test-first with test-driven.

And please don't give me your song about the original definition or meaning of the word "test-driven" - I understand the origins of these words, but they are just words. Nobody owns them.

My approach is neither test-first or test-after - I'd like to refer to it as test-along, and I wish you would acknowledge the fact that it is every bit as test-driven as your test-first approach.

If you belong to this group of test-first enforcers, I hope that you would reconsider your position on this. There is an approach between test-first and test-after, which, to me and many others, is just as efficient, practical and meaningful as your test-first approach.

In fact, I would urge you to try it.

In my experience, a balanced approach, in software development — as it is everywhere in life — is usually better than polar extremes.

Top comments (3)

Collapse
 
melezhik profile image
Alexey Melezhik

I need to think about the code and the design first, before I know what I need to test.

That's right. However many devs finish here and don't write tests at all.😄 This is why I developed Sparrow - a dead efficient tool to write tests ( see Tomty indeed ).

Collapse
 
arnauddenoyelle profile image
Arnaud Denoyelle

"I simply haven't discovered the right shape or form of the code yet" => totally agree with that. IMHO, TDD helps to find the shape. Writing expected results for test cases gives a part of the public interface.

Collapse
 
mindplay profile image
Rasmus Schultz

In my experience, designing from the perspective of client code in general (of which the test is only one, and arguably the least important) is what leads to the best possible public interface.

Again, if writing the test first works best for you, personally, you should absolutely do that.

The larger point here is that not everyone has the same experience - so definitely try it, but don't force it. 🙂