4 ms·
Can anyone explain the advantages of writing unit tests before vs after certain sections of code has been finished? I use unit tests, but only after the code's
by wting 14y ago
Can anyone explain the advantages of writing unit tests before vs after certain sections of code has been finished?
I use unit tests, but only after the code's finished or there's a good stopping point. Otherwise I have to do too much refactoring every time I change a function's name or signature.
Maybe TDD is forcing you to architect the program in the beginning, but I find it cumbersome because stuff changes so much throughout the course of finishing a project.
- Kaivo 14y agoWhen given a list of prototypes to code, writing the tests before starting helps me figure out specific edge cases and think about all the details the functions have to do before starting to code. Then, once I start coding the functions, it easily flows out and doesn't need as much refactoring afterward. However, it's true that when refactoring and changing a lot of details here and there, I prefer to return type those tests afterward instead since a small change in a function can require a lot of change in the tests.
- joshuacc 14y agoSome points from a recent presentation I gave on the subject. Writing tests first: * Leads to better code design by encouraging smaller units of code which you can combine to achieve your larger goals. * Having tests/specs lets you refactor with confidence. * Writing the specs first means that they are going to be more complete, so you can have more confidence in them. * Since you saw the specs fail, you know that they can fail. If you only test afterwards, you don't know if it's passing because your code is good or because the test is bad. * The more confidence you have in your tests/specs, the faster you can improve your existing code.
- eeperson 14y agoI feel like a lot of these points are more about just having tests rather than writing tests first. Also, I think some of these points only make sense if you already have a pretty good idea of what you are going to write. More specifically: 1. This may be the case but I don't think this requires that you write your tests up front just that you don't leave all of your testing until the very end 2. This is just about having tests 3. I don't really see why writing your tests up front would make them more complete unless you already know exactly what you want to build. I find that I often come up with most of my edge cases while I am writing the code. 4. In many cases, if you tests before you still don't know if your tests pass because of your code is good or because the test is bad. Many tests, up front, fail for very obvious reasons (such as the function you are testing simply doesn't exist yet). Just because they fail in the beginning doesn't mean they are good tests. What you actually want is mutation testing [1]. Testing up front is just a really crude version of this. I usually do mutation testing manually by removing the code I am trying to test, at the end, to ensure that my test fails if it is not there. 5. Again, just about having tests Ultimately I think you want interactive testing development. Write some code, write some tests, repeat. The actual ordering of the first 2 steps needs to be decided on a case by case basis. Writing all of your tests up front can be awkward. Writing all of your tests at the end is sometimes nearly impossible. [1] http://dev.theladders.com/2013/02/mutation-testing-with-pit-a-step-beyond-normal-code-coverage/ http://dev.theladders.com/2013/02/mutation-testing-with-pit-...
- joshuacc 14y agoI agree that many of these points are about having tests. But my observation has been that if tests aren't written first, they either aren't written at all, or they are written half-heartedly.
- strommen 14y agoThe advantage to writing test first is that it allows/forces you to test the test. If you write the test before you've written the code, then you'll be expecting the test to fail (in a very specific way) the first time it is run. By observing this you ensure that the test actually exercises the application code that you intended. If you write the test after you've written the code, then you'll be expecting the test to pass the first time it is run. However if there is a bug in the test, it may pass for the wrong reason - e.g. if you forget some part of the test setup that causes the relevant application code to get skipped entirely.
- stevebot 14y agoBiggest advantage: they actually get written. I've seen so many lines of software ship without coverage just because the test were not written beforehand.
- thomasmeeks 14y agoThere are advantages to TDD. It forces you to use your code as you write it, which is a very good way to ensure you have a reasonable API. For example, if you hate writing your tests, then there may be something wrong with your code. It also ensures that you have /some/ tests, and bad tests are better than no tests. But TDD is really about reaching a good design, not about creating useful tests along the way. One of the reasons is exactly what you state. The unit tests that are created in the course of TDD are extremely tied to the particulars of your implementation, and end up being a maintenance pain point in a large application. It is important for your tests to survive a refactor without needing to be changed. So, it is not uncommon for tests created in the course of TDD to be thrown away after you write some good integration tests / feature specs / whatever you'd like to call them for your code. TDD is not, however, the only way to get to good design. You can also use behavior driven development (BDD) -- which is similar. Or you can just get in front of a whiteboard. Whatever works for you. At the end of the day what matters is getting to good design and good tests in a way that's efficient and enjoyable for you.
- jasonlotito 14y ago> Otherwise I have to do too much refactoring every time I change a function's name or signature. It's 2013. Your editor of choice can do this for you.
- lmm 14y agoThe best design tends to be emergent; http://c2.com/cgi/wiki?WhatIsAnAdvancer http://c2.com/cgi/wiki?WhatIsAnAdvancer Writing the tests first forces you to think about how a given interface will actually be used, which tends to lead to better code, because you're writing an interface that makes sense for the client rather than for the called code. In turn that means better encapsulation. It's probably possible to do this in the abstract, but if you're writing the test code anyway it doesn't cost you anything.