This document discusses best practices for test-driven development (TDD). It begins by describing the different types of tests - unit, integration, and acceptance. It then discusses the debate around having more unit tests vs acceptance tests. The document argues that less acceptance tests and more unit tests leads to faster, higher quality code. The rest of the document outlines five rules for writing effective tests: 1) Write tests before coding, 2) Don't test everything, 3) Test only public APIs, 4) Don't create extra getters for testing, and 5) Listen to what your tests are telling you about your code quality and design.
1. "TDD — Are you sure you
properly test code?"
Dmitriy Nesteryuk
06 October, 2012
Contacts:
Email: nesterukd@gmail.com
Skype: nest_d
2. Which kind of tests do we know?
● acceptance
● integration
● unit
3. TDD Cycle
The schema was taken from http://speakerdeck.com/u/froots/p/testing-your-
backbone-from-the-outside-in
4. What is the best way to choose?
less acceptance tests, more unit tests
OR
more acceptance tests, less unit tests
5. Less acceptance tests, more unit tests
Advantages:
● faster tests
● better quality of code
● better architecture of an application
● more flexible code
Disadvantages:
● more time for refactoring
● more time for implementing new features
6. More acceptance tests, less unit tests
Advantages:
● less time for refactoring
● less time for implementing new features
Disadvantages:
● slow tests
● worse quality of code
● worse architecture of an application
8. Rule #1: Write tests before coding
If you don't follow this rule, you lose:
● requirements to your code
● powerful tool for improving your code
● ~100% code coverage
● correct tests
9. Rule #2: Don't test everything
A lot of people tell they stopped writing tests,
because it consumes a lot of time. But, they
don't investigate why it happens to them.
In some cases it happens because they write
needless tests.
13. Rule #2: Don't test everything
Questions to such tests:
● Why do we have to test DOM methods? Did we write them?
● What will we have to do if the tag name is changed?
● What will we have to do if the css class is changed?
14. Rule #2: Don't test everything
Conclusion:
Test only your own code, it is needless to test libraries/tools which you cannot
control. If something goes wrong with your units in this case,
acceptance/integration tests will catch it. Using this way, you will reduce
amount of tests which you have to support.
Test only logic of your application, is the name of the css class the logic of your
application? Even if it isn't here, your application will continue to work, maybe it
will be displayed a bit ugly, but it will still be working. The same thing we can
say about the tag name.
15. Rule #3: Test only public API
Some people test code in the way which won't be used in a
real app. Eventually, they run into a problem with
supporting such code.
18. Rule #3: Test only public API
You should not test protected/public methods,
because:
● You violate encapsulation
● Private/Protected methods are created to reduce code duplication within
an object
● Sometimes private/protected methods are internal helpers
● You don't call private/protected methods in a real app, therefore, you will
test your unit in way which won't be used. Is it helpful? You must test your
units in the same way how it is used in your app.
20. Rule #3: Test only public API
Conclusion:
To check the same behavior within a few methods, the shared tests can be used.
But... If you have a lot of them, it looks like code smell and you have to think more
about design of your code, may be your class has more than one responsibility
and you have to refactore your class.
21. Rule #4: Don't create extra getters
Some people add extra methods/properties for testing
purposes only.
25. Rule #4: Don't create extra getters
We take a look at our code and start thinking:
"Hmm... It looks like I have to tests the fact that 'collection'
and 'layout' properties contain objects"
30. Rule #4: Don't create extra getters
Conclusion:
Don't create extra methods/properties only to be able to tests your unit.
Eventually, you will have to support them. It will be wasting of your time.
Properties (instance variables) somehow are used within your object, therefore, if
some property (instance variable) won't contain correct value, tests for other
methods (units) will be broken and you will be notified about mistakes in your
code.
31. Rule #5: Listen to the tests
Some application has a lot of tests, but they have very low
quality of code, inflexible code, incorrect architecture.
35. Rule #5: Listen to the tests
Question occurred in mind:
● Why did we have to write almost the same tests?
● What will happen if we will need to add a new route with similar behavior?
36. Rule #5: Listen to the tests
Tests told us about code duplication. They made us be
lazy.
Good developer is a lazy developer. You should be
interested in solving only unique challenges.
39. Rule #5: Listen to the tests
Great!!! But... It only a half of what tests tell us. We have
not listened to tests where they told us about a few
responsibilities in our class (prototype since it is
JavaScript).