How often should we write unit tests?
I am recently introduced to the test-driven approach to development by my mentor at work, and he encourages me to write an unit-test whenenver "it makes sense." I understand some benefits of having a throughout unit-test suite for开发者_Go百科 both regression testing and refractoring, but I do wonder how often and how throughout we should write unit-test.
My mentor/development lead asks me to write a new unit test-case for a newly written control flow in a method that is already being tested by the exsisting test class, and I think it is an overkill. How often do you write your unit tests, and how detailed do you think your unit tests should be? Thanks!
Technically, if you're following strict Test Driven Development...you should be writing your Unit Tests after you have spec'd any portion of your application. You should be going from:
User Requirements -> Function Design -> Unit Tests -> Code
Remembers, Tests come before Code in TDD.
You should write a unit test whenever you write any code. And, as other have pointed out, in TDD you write the tests before you write the code.
If you think it is overkill, ask yourself "if I don't test this code, how do I know it works?"
My mentor/development lead asks me to write a new unit test-case for a newly written control flow
How did that control flow come to be written, unless it was needed to pass a failing test? By the definition of TDD, no production code will come to existence, unless there first exists a failing test which requires that piece of code to be written. So you must have been writing the code using some test-last technique and not TDD.
I recommend you to read the article The Art of Agile Development: Test-Driven Development. You can practice TDD using this tutorial.
I think that your mentor using the phrase "whenever it makes sense" can be harmful, especially to people new to TDD, because it's not possible for one to make a good decision about that until after have many years of experience, after one has reached Ri-level. On one occasion when Kent Beck decided to not write a test, it was appropriately commented by Ron Jeffries: "I trust you, and about three other people, to make good short game decisions."
You should always write a test first. Anything that could possibly break requires a test. Only things that could never break, because of somebody changing the code, don't need tests. For example declarative code rarely breaks: static HTML layout code on a web page is generally not worth testing automatically (you must test it manually to see whether it looks right), but anything dynamic is worth testing.
Unit tests should give you confidence, that the code you write, does what you want. Therefore you should write as many tests as it's needed to give you this confidence.
Writing tests, and more importantly testable code is an independent skill, just like learning to program each new language is an independent skill.
Read Miško Hevery's blog, read some books (I liked Test Driven by Lasse Koskela), use some code coverage tools like Clover, and then write some tests.
As you write tests, your testing skills will improve, and you will come to understand what is involved in writing testable code. Then you will be able to know for your particular project the level of code coverage that is required.
I too have become a recent convert to TDD and I find it extremely helpful. The idea is such that as soon as you have a spec, you start writing unit tests. Once your tests have been written, a large majority of your code can come from those tests. What remains in your tests are the basis of your asserts and you then have a very good repeatable pattern for - write test, implement code, confirm through asserts, continue. Good stuff!
As Justin said, you should be writing your unit test before you write the code.
While this is probably the best thing to do, it is sometime overkill. Depending on the projet I sometimes write a unit-test only for every bug I find (and solve).
Sure, I probably miss some of them, but my unit-testing becomes more and more efficient with the time and I'm pretty sure that I will never miss a corrected bug.
Unit tests will:
- give you the confidence to make refactoring changes while knowing that you're not breaking anything else.
- act as a sort of "living documentation" of your code, allowing others to know exactly how the code will behave in various circumstances.
- when following strict TDD as described by @Justin, passing all the unit tests written before you started writing code will let you know when you are "done" coding. In my experience this also leads to greatly simplified and easier to understand (cleaner) code.
As your mentor mentions, you should only write unit tests that make sense. The rule of thumb I use is that I try to write unit tests for pieces of code that execute business logic. I generally don't write unit tests for bean classes with little more than getters and setters.
Unit tests usually become more valuable with time as they are expanded and enhanced to deal with bug fixes and other code enhancements made after the initial delivery.
There is a fundamental thing about unit tests when doing test driven development, namely that the unit tests describe functionality. If the test does not define e.g. how null inputs behave, then you cannt expect it to work.
You should always write test, if your existing testsuite is insufficient. The best sign, that your tests are not enough are bugs. So a good practice is to write a unit-test for every bug you encounter. With test-driven development you should start with some test, do define the functionality of a class. test-coverage-tools gives you some hints, which parts could need more testing.
The right/thorough answer for this question must be long as this is key question for every testing process, but I'll answer with following simple(?) rules:
If some use case is important write separate test for it so someone else (or you in the future) may spot that case by reading or failing the tests.
If you are wondering longer than 5 seconds if something is important enough to test or not then assume it is :-)
If by any chance testing this case is very hard/expensive complain about this to your manager / tech lead and skip writing the test.
Personaly I use unit tests, when I have massive data, and I dont want to copy/paste a lot of System.out.println, and check them one on one. With Unit tests, you lose 1h to write them, and save a lot of them testing. For trivial stuff, I rather use the println tecnic, or check the debug variables.
精彩评论