2. Why?
It’s such a pain.
there is never enough time!
@jhooks | 2010 | joelhooks.com
3. Sanity.
Developers want a productive environment where
things work as expected.
Unit test can help create this environment at the code level.
@jhooks | 2010 | joelhooks.com
4. Protect your work.
We work hard on the functionality that we add to the
application.
Unit tests serve as a guard against accidental “harm” of code.
@jhooks | 2010 | joelhooks.com
5. Developer documentation.
Well written unit test provide excellent documentation
for other developers.
Unit tests describe how a piece of logical code should work in a way that English
language docs often can’t.
@jhooks | 2010 | joelhooks.com
6. Collective ownership.
Code that is protected can be worked on by anybody
with greater assurance that nothing will be accidentally
broken.
@jhooks | 2010 | joelhooks.com
7. Fearless refactoring.
Code can be constantly improved upon with less fear
of accidental breakage.
Unit tests verify that changes don’t break the existing logic.
@jhooks | 2010 | joelhooks.com
8. What should be tested?
Models
Service classes
Commands
Utility classes
any other logical code
@jhooks | 2010 | joelhooks.com
9. When to write tests...
Before you write the code?
After you write the code?
@jhooks | 2010 | joelhooks.com
10. Test Driven Development
10 Ways to Improve Your Code - Neal Ford
@jhooks | 2010 | joelhooks.com
11. Less fear.
Writing unit tests firsts lets you focus on the
functionality you are adding.
Write the test. Write the code. Tests pass. Done.
@jhooks | 2010 | joelhooks.com
12. Ensure test coverage.
Tests written before production code ensures that the
production code is tested.
Tests are not an afterthought.
@jhooks | 2010 | joelhooks.com
13. Reduces tedium of testing.
Wait... What?!
Writing tests before the production code eliminates the need for a massive testing
effort after the code is written.
@jhooks | 2010 | joelhooks.com
14. Guarantees testable code.
Testing first ensures that the production code can be
tested.
Testing after often results in the discovery that the code isn’t testable without
refactoring. Refactoring that isn’t protected by tests.
@jhooks | 2010 | joelhooks.com
15. TDD is not a guarantee.
Like most practices, TDD is no guarantee of quality or
success in development.
It is a tool.
@jhooks | 2010 | joelhooks.com
16. So when should I test?
Test driven development is not required.
Try it out. It can be painful to start, but once you get a rhythm going the benefits
are very real.
@jhooks | 2010 | joelhooks.com
17. What is a good unit test?
automated
repeatable
run by anybody
future use
fast
single push
easy
@jhooks | 2010 | joelhooks.com
18. Unit tests are by developers for developers.
Quality over quantity please.
@jhooks | 2010 | joelhooks.com
19. Trustworthy
Developers will run and use tests they trust.
A trustworthy test is free of bugs and does what it says it does.
@jhooks | 2010 | joelhooks.com
20. Tests are written to last.
Most tests are not meant to be temporary. They
change for very specific reasons
Bugs in production code
Bugs in the test
API updates in the production code
Test is no longer valid or is not needed
To eliminate duplication
@jhooks | 2010 | joelhooks.com
21. There is no logic in the test.
Logic in a unit tests makes the test harder to read and
understand. There is more likely to be bugs in the test.
It can also make the test harder to name.
There should be no switch, if, or else statements.
There should be no for each, for, or while statements.
The test is a series of method calls with no control flow.
@jhooks | 2010 | joelhooks.com
22. Only one thing is tested.
A unit test is testing a single behavior. Testing multiple
things makes a test hard to understand.
Assert only one thing.
Should be easy to name (you don’t need an and in the name).
When it fails, it is clear what actually failed.
@jhooks | 2010 | joelhooks.com
23. Maintainable
Unmaintainable tests are ignored and are often
simply removed from the suite.
Unmaintainable tests cannot be trusted.
@jhooks | 2010 | joelhooks.com
24. Test the API
Unit tests are written against the public contract of the
unit being tested. We shouldn’t be trying to test
private methods.
Private and protected methods can affect the outcome of public methods.
Does it make sense to make a private method public?
Test the results of the public API that uses private methods
Is the private method pure utility? Would it makes sense as a static method of a
utility class?
@jhooks | 2010 | joelhooks.com
25. Avoid duplication (DRY)
Avoiding the duplication of code in unit tests is as, if
not more, important than it is with production code.
Create helper methods like factories to assist in setup of common items
Use setup methods for setup of items common to all test methods in the case
Setup should be as short, simple, and as easy to read as possible
@jhooks | 2010 | joelhooks.com
26. Tests should be isolated.
Don’t try to use Parsley, configure and access remote
services, or otherwise try to simulate the broader
application in a unit test.
Are test methods constrained to a linear order of execution?
Is the test calling other test methods?
Do tests share global state?
Test behaviors, not workflows.
If shared state can’t be avoid, be sure to reset it in the teardown.
@jhooks | 2010 | joelhooks.com
27. Avoid multiple asserts.
Unit tests are testing specific single behaviors. It seems
like more work because results might be related, but
the results should be verified independently.
Give each assertion its own test
Give each test a meaningful name
This makes failures easy to understand and fix
@jhooks | 2010 | joelhooks.com
28. Avoid over-specification.
Tests shouldn’t make assumptions about the
implementation of behavior, instead they should focus
on the results of the behavior.
Does the test specify purely internal behavior of the unit?
Is the test using complicated mock objects when simple stubs would be enough?
Does the test assume specific results when it isn’t required?
@jhooks | 2010 | joelhooks.com
29. Readable
Code in tests is easy to understand quickly. What is
being tested is recognizable instantly without
deciphering or translation.
Readable tests are more trustworthy and maintainable.
@jhooks | 2010 | joelhooks.com
30. Standard test names.
If all tests are named in the same pattern they will be
easy to read..
methodUnderTest_descriptionOfState_expectedBehavior()
@jhooks | 2010 | joelhooks.com
31. Good variable names.
As with all code, good variable names can help
greatly in making the code readable.
Avoid abbreviations
Use static constants instead of hardcoded values
@jhooks | 2010 | joelhooks.com
32. Consistent test structure.
Setup -> Action -> Assert
[Test]
public function doSomeWork_workWasDone_isTrue()
{
//setup
var aDependency:ISomeDependency = new SomeDependency();
//execute behavior
aDependency.doSomeWork();
//verify expected state is valid
assertThat(allTestsNeedThis.workWasDone, isTrue());
}
@jhooks | 2010 | joelhooks.com