Code duplication in tests is not bad.

Change my mind.

· · Web · 2 · 4 · 1
@musicmatze I think it makes sense to try to deduplicate code in tests when doing test driven development, since if goals change it's less likely you will have to update many tests.
@musicmatze I suppose the same is true without TDD, but I feel like it's more important when doing TDD.

@robby so, in your opinion, I should try to implement a framework for filling my special datastructures with testing-data before testing algorithms that work on them?

What if the framework for filling them is buggy? Do I need tests for my testing code?

> Do I need tests for my testing code?

No, when you are doing "the right way" (meaning "red-green-refactor") you don't need it.

See this post (and thread). @vertigo explains it beautifully:


@janriemer @musicmatze @vertigo so ideally with TDD things go like:

1. Create idea
2. Write tests to check that code matches idea
3. All tests fail because code hasn't been written
4. Write code until all tests pass
5. Fin

What if the idea from 1 changes between 2 and 4? Maybe customer requirements change, maybe adjacent processes change, etc. In this case, we will have to make some changes to the tests probably. Deduplication can make changes to the tests faster to do, and less error prone.

@robby @janriemer @musicmatze Step 5 would be refactor your code so that it meets coding guidelines for your organization or project, and step 6 would be to re-test to make sure you didn't break anything in the mean time. Step 7 would be fin. For projects that need it, step 7 would also be to write documentation covering what you've just coded; but, that's a subjective judgement call.

That said, all 7 steps occur several times per hour (yes, per hour), not per week or sprint. If your customer is changing requirements at a rate of several times per day, in a way that impacts what you're doing, it's time to sit down with the customer and re-evaluate their terms of their development contract.

The granularity for your tests are minute; individual features of individual functions on a single user-story. Hence why they're called unit tests.

The whole idea is literally to introduce at most one bug at a time, so you know exactly where and how to fix it. (Missing features are treated as bugs in this case.) OK, sometimes you introduce more than one bug during a session; it happens. But, it's quite rare to introduce so many that it's unmanageable. And, your proficiency with the idea improves with practice, like anything else.

@robby @janriemer @musicmatze Oh, and if you need to research how to make something in the first place, you are free to use whatever approach you're comfortable with to hack up a prototype. This is called a "spike", and many projects have several spikes associated with them.

The purpose of the spike is to get a handle on the scope of a solution to a problem. They're not intended to become production-ready code. Just quick hacks. Thus, these don't (and, many would argue, should not) need TDD to develop.

Spikes are throw-away code. Once you have the experience of a solution that a spike provides, you can use that to guide your TDD work to produce a "production-ready" (such as it may be) version of the code. It sounds like you're duplicating work, and to some extent you are. However, the pay-off is not having to do a ground-up rewrite later on, something I've ended up having to do on many commercial projects in the past because the original authors decided to jump to another job rather than rework their earlier code for better maintainability.

@vertigo @robby @musicmatze THIS! 👏

Thank you so much for explaining the essence of TDD!❤️ You speak right from my soul.🤗

@vertigo @robby @janriemer thank you all for your contribution to the discussion.

I remember we had TDD at University and I actually developed a codebase with TDD (IIRC it was my kairos crate) and the results were amazing (as in productivity and code cleanness; to me, the crate is more or less meh).

@musicmatze Oh, that's really cool you had TDD at Uni.
We didn't (not even unit testing).😢

kairos crate looks really interesting. Thank you.🙂

Well, I only had in a masters course... Not sure what you're studying for...

@robby @vertigo @musicmatze Yes, maintainability can be harder when there is duplicate test code, but here is the thing:

1. Tests must be understood easily - if you are hiding away the inputs and the "acting" of the SUT (system under test) behind some abstraction to reduce duplication, you make it maybe easier to maintain, but much harder to understand what the test should verify.


@robby @vertigo @musicmatze

2. If you have a lot of "acting" to do on your SUT and, as a consequence, a lot of duplication of method call sequences between your tests, this is actually an indication that you should build an abstraction for it _in your production code_.

is not only - it is also .


@musicmatze always "it depends".
For code that is in the "Arrange-Act"-section of your test: Yes, code duplication is NOT bad.

For code that is in the "Assert"-section, I'd say, it makes sense to have a single function, especially, if you must assert *multiple* things on an object: `assert_complex(expected_value, actual_value);`

For Arrange-Act-Assert pattern see here:


Sign in to participate in the conversation
Mastodon for Tech Folks

This Mastodon instance is for people interested in technology. Discussions aren't limited to technology, because tech folks shouldn't be limited to technology either!