TDD with unclear requirements

I know that TDD helps a lot, and I like this development method when you first create a test and then implement it. This is very clear and correct.

But because of the taste of my projects, it often happens that when I start developing a module, I know very little about what I want and how it will look in the end. Requirements appear as I develop, maybe 2 or 3 iterations, when I delete all or part of the old code and write new one.

I see two problems: 1. I want to see the result as soon as possible in order to understand that my ideas are right or wrong. Unit tests slow down this process. Therefore, it often happens that I write unit tests after completing the code, which, as you know, is a bad template. 2. If I am writing tests for the first time, I need to rewrite not only the code two or more times, but also the tests. It takes a lot of time.

Can someone tell me how TDD can be applied in this situation?

Thanks in advance!

+6
unit-testing tdd
source share
11 answers

I want to see the result as soon as possible in order to understand that my ideas are right or wrong. Unit tests slow down this process.

I do not agree. Unit tests and TDDs often speed up getting results because they force you to focus on the results, rather than inject tons of code that you'll never need. It also allows you to run various parts of your code as you write them so that you can constantly see what results you get, rather than waiting for your entire program to complete.

+12
source share

I believe TDD works especially well in this situation; in fact, I would say that having unclear and / or changing requirements is actually very common.

I believe that the best use of TDD is that your code does what you expect from it. When you write any code, you should know what you want, whether it is clear requirements or not. The power of TDD is that if there is a change in requirements, you can simply modify one or more of your unit tests to reflect the changed requirements, and then update your code, making sure that you are not violating the others (no change).

I think that one thing that causes a lot of people with TDD is the assumption that all tests should be written in advance. I think it’s more efficient to use the rule of thumb that you never write implementation code until all your tests pass; it just ensures that all the code is covered, and also make sure that you check that all the code does what you want, so you don’t worry about writing all your tests.

+7
source share

IMHO, your main problem is when you need to delete some code. This is waste , and this is what should be considered first.

Perhaps you could prototype or use “spike solutions” to test requirements and your ideas, and then apply TDD to real code as soon as the requirements are stable.

The risk is to apply this and send a prototype.

Also, you can first test the "solar path" and implement only the rest, such as error handling ... after the requirements are fixed. However, the second phase of implementation will be less motivating.

What development process are you using? This sounds flexible since you have iterations, but not in an environment that fully supports it.

+5
source share

TDD helps you express the intent of your code. This means that by writing a test, you have to say what you expect from your code. How your expectations are fulfilled is secondary (this is an implementation). Ask yourself: “What is more important, implementation or what is the provided functionality?” If this is an implementation, you do not need to write tests. If this is provided functionality, then testing of the tests will begin first, which will help you with this.

Another valuable thing: TDD, you will not implement functionality that is not needed. You write only code that should satisfy the intention. This is also called YAGNI (you won’t need it).

+2
source share

You won’t get away from this - if you measure how long it takes to code, how much time you need to write classes, etc., it will take longer with TDD. If you are experienced, it will add about 15%; if you are a beginner, it will take at least 60% longer, if not more.

BUT, in general, you will be faster. Why?

  • By writing the test first, you indicate what you want and provide exactly that, and nothing more - therefore, saving time by writing down unused code.
  • Without tests, you might think that the results are so obvious that what you did right is when it is not. Tests show that you did the right thing.
  • You will get faster feedback from automated tests than with manual testing.
  • With manual testing, the time taken to test everything as your application grows grows rapidly - this means that you will stop performing it.
  • with the help of manual tests it is easy to make mistakes and “see” something passing when it is not, this is especially true if you run them again and again and again.
  • (good) unit tests give you a second client for your code, which often highlights design problems that you might otherwise miss

Add all this, and if you measure from the moment of creation to delivery, and TDD is much faster - you get fewer defects, you take fewer risks, you progress at a constant speed (which simplifies the assessment) and the list goes on.

TDD will make you faster, not a question, but it’s not easy, and you should allow yourself a little room to study, and not be disappointed if it initially looks slower.

Finally, you should look at some BDD methods to improve what you do with TDD. Start with the function you want to implement and go down to the code from there, pulling out the stories and then the scripts. Focus on the implementation of the scenario decision scenario in thin vertical slices. This will help clarify the requirements.

+2
source share

TDD will slow down development for almost anyone. So, if the initial development speed is 10 on a scale of 1-10, with TDD you can get around 8 if you own it.

This development after this moment becomes interesting. As projects increase, development effectiveness usually decreases — often to 3 on the same scale. With TDD, it is very possible to stay in the range of 7-8.

See "technical duty" for a good read. As far as I know, any code without unit tests is actually a technical duty.

+2
source share

Using TDD can make you write code faster - failure to write a test for a specific scenario may mean that there is a problem in the requirements.
When you are TDD, you should find these problem areas faster, and not after writing 80% of the code.

There are several things you can do to make your tests more resilient to change:

  • You should try to reuse the code inside your tests in the form of factory methods that create your test objects along with validation methods that validate the test result. This is if some important change in behavior occurs in your code, you have less code to change in your test.

  • Use an IoC container instead of passing arguments to your main classes - again, if the signature is a change method that you do not need to change all your tests.

  • Make your unit tests short and isolated - each test should check only one aspect of your code and use the Mocking / Isolation environment to make the test independent of external objects.

  • Test and write the code for the required function only (YAGNI). Try to ask yourself what value my client will get from the code I'm writing. Do not create complex architecture, instead create the necessary functionality in parts, reorganizing your code along the way.

+1
source share

Here's a blog post that I found useful in explaining the use of TDD on a very iterative scale of the design process: http://blog.extracheese.org/2009/11/how_i_started_tdd.html .

0
source share

Joshua Block commented on something similar in Coders at Work. His advice was to write examples of how the API will be used (about page length). Then think about examples and APIs, and refactoring APIs. Then write a specification and unit tests. Be prepared, however, to reorganize the API and rewrite the specification when implementing the API.

0
source share

When I deal with vague requirements, I know that my code will need to be changed. Having solid tests helps me feel more comfortable changing my code. Practicing TDD helps me write solid tests, and so I do it.

Despite the fact that TDD is, first of all, design technology, it has one big advantage in your situation: it encourages the programmer to consider details and specific scenarios. When I do this, I notice that I quickly find gaps or misunderstandings or a lack of clarity in the requirements. The act of trying to write tests makes me deal with a lack of clarity in the requirements, and not try to sweep these difficulties under the carpet.

Therefore, when I have unclear requirements, I practice TDD both because it helps me identify specific requirements that I need to solve, but also because it encourages me to write code that is easier for me to change, since I am more understand what I need to build.

0
source share

In this early phase of the prototype, I believe that this is enough to write testable code. That is, when you write your code, think about how to make testing possible, but for now focus on the code itself, and not on the tests.

You should have tests when you do something.

-one
source share

All Articles