1

I am trying to get a better understanding of TDD. From a quick google I've found this:

In layman’s terms, Test Driven Development (TDD) is a software development practice that focuses on creating unit test cases before developing the actual code. It is an iterative approach combining programming, unit test creation, and refactoring.

As lately I am trying to focus to make the knowledge gap in my team smaller (small team) I found at least in principle such development flow useful.

Normally in my team we follow scrum development. So we have target for sprints (like features) and we produce tasks and then base on those we have several task stages (like in progress -> review -> done).

However what I often notice is that is that the code is overengineered very often therefore I've been trying to find way to encourage less overengineering and among the benefits of TDD it can be encouraged to write less code.

However my team is a small (like 3 persons) and normally each one of them has very specific skillsets. When I came across TDD my thought was to add an extra stage in our scrum board, say:

unit-test -> development -> review -> done.

Suppose now we have two developers, say A and B (as I said my team is small).

Say then A could write the unit-test/unit-tests first, then B could proceed to the development, knowing that he needs to pass those two tests. In my mind this is also good for A to gain knowledge on the domain of B (without going too much in depth) and viceversa.

However what I am afraid of is that adding an official extra stage of development might make things slower.

What I wonder therefore is what are common pitfalls of TDD development, in relationship to small teams.

4
  • 4
    That is gross misunderstanding of TDD. In TDD, the test is written immediatelly before code is written. The whole TDD cycle (test, code, refactor) should take less than few minutes. The two rules of TDD are : Never write production code without failing test and Never write more test code than is necessary to fail. Batching out failign tests or having someone else write the tests goes straight against TDD principles.
    – Euphoric
    Oct 20, 2023 at 9:16
  • 1
    Writing a small test is supposed to take minutes at max. Same for writing the code to make the test pass. When you want to include multiple devs, let them pair/mob program. They can still follow TDD practices, but without the hassle code handover would cause.
    – Rik D
    Oct 20, 2023 at 9:22
  • 1
    TDD is an implementation technique, a tool which can (and usually should) be used by one person. When dev A is going to write a new function, he/she first writes a test which shapes the new functions parameters, then A implements a little part of the function, and runs the test to try it out. Then A might change the test bit or add a new one, add some new functionality, runs the test again, refactors the function and/or the test. This is a design process where a creator of a function externalizes his/her idea about how a function should behave immediately while writing the function ...
    – Doc Brown
    Oct 20, 2023 at 13:08
  • 1
    ... and bakes these ideas into the test. There have been experiments in pair programming in making this a ping-pong game for two persons (one dev writes a test, another the functionality to fulfill the test, then they switch roles, see openpracticelibrary.com/practice/ping-pong-programming), maybe it works for some people, but AFAIK they haven't become really popular).
    – Doc Brown
    Oct 20, 2023 at 13:14

2 Answers 2

8

That is not the generally recommended way of doing unit tests, and is unlikely to work well.

In terms of planning unit testing should be thought of as simply part of development. The strict TDD cycle is alternating between writing a single test and implementing a single small piece of functionality, switching every few minutes.

Sometimes a developer might decide to work slightly differently and write multiple tests in advance, but even then it would normally just be to test the code that they plan to write immediately, i.e. within their next few minutes or hours of work.

If you try to to write all the tests up front then you either have to do all the tests as very high level integration tests, or you have to plan all the internal design up front, and if you're planning all the design you really might as well implement it.

3
  • How is my thought different from yours? I don't think my question disagrees with your answer Oct 20, 2023 at 8:48
  • 3
    Your question is suggesting there is a stage of writing unit tests that can be separate out from developing production code. I'm saying they should be tightly intermingled. Since scrum teams have the sprint metaphor, think about literal sprinting - you don't plan time for using the left leg and the right leg separately in running. You let the runner use whichever leg will restore their balance at each moment. It's the same way in TDD.
    – bdsl
    Oct 20, 2023 at 10:04
  • 1
    I see. Ok, probably a missunderstanding on my side then. Oct 20, 2023 at 11:02
7

What you describe, where one person is writing the tests and then hands those tests over to someone else to develop the solution that satisfies those tests, is not TDD. In TDD, the tests and the solution are developed by one entity. The entity could be a single developer, a pair, or the mob. The entity creates the necessary (failing) tests, the minimum solution to satisfy those tests and allow them to pass, and then revisiting with additional edge case tests and refactoring, before proceeding with additional failing tests to continue development. If you want to know more about what TDD is, I would recommend Kent Beck's Test-Driven Development: By Example.

Introducing a new hand-off is antithetical to agile and lean methods. Hand-offs and task switching are forms of waste. The changing focus of the individuals on the team slow the work down. Slowing the work down lengthens the feedback loops.

I'm also not convinced that the person writing those unit tests would be effective at doing so without understanding more about the domain. You could easily end up with sub-optimal test cases that need to be reworked (another form of waste, as well) rather than expanded upon.

If the problem is the knowledge gap, then I'd look at paring and mobbing techniques first. Having the team collaborate on the work items can allow the team to share knowledge of how to design and implement a solution within a given domain. The pair (or the mob) can then choose to apply techniques such as ATDD or TDD as appropriate.

1
  • 1
    Testing is a design activity. Writing a test means exploring the problem space and proposing a potential solution that can be validated by making the test pass. And as I write code, I spot new edge cases to test. Through multiple iterations, the overall design is refined and simplified. It doesn't make sense to break up this feedback loop, and it doesn't make sense to write tests that lock in a design early when little about the appropriate solution is understood. However, it would be really cool if new requirements are described via ATDD/BDD style test cases.
    – amon
    Oct 20, 2023 at 15:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.