goodtests
TRANSCRIPT
Good TestsA few things on how to write good tests
Page 1 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Summary
Page 2
• Motivation for testing
• Good tests
• Some advice to write better tests
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Manual vs automated testing
Page 3 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
CalculatorApp
Enter first value: 5
Enter second value: 10
What operation: add
Result is: 15
testThatAdditionWorks() {
firstValue = 5
secondValue = 10
result = calculator.add(firstValue, secondValue)
verify(result, equals(15))
}
Why do we write tests at all?
Page 4
Confidence
- We write tests to have confidence in our software. - To hand the software to our customers and KNOW that it works.- To be able to make changes and know that it still works.
Everybody knows that:„I‘m not sure, if I change this, will something break?“
If the tests are good, you can change your code with confidence.Because the tests will tell you, if you changed the behaviour!
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
https://www.flickr.com/photos/nicolopaternoster/3933549608
When do I have enough (unit)tests?
Experiment: Delete the contents of a class and recreate the code only from the tests.
Page 5
How many tests should I write?How many assertions?How much coverage is enough?When can I stop writing tests? When am I done?
Write tests first.Only write code, when tests are red.
And automatically you have enough tests, assertions and coverage.
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
What makes a test a good one?
It‘s not easy to write good tests.There are a lot of requirements to our tests:
• Should be easy to read and understand.• Should communicate intent well.• Should be easy to maintain.• Should provide a clear message, when they fail.• Should test only one feature• Should execute fast• Should be complete
And very important:• We write a lot of tests. There is more test code than production code.
Page 6 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
https://www.flickr.com/photos/83633410@N07/7658298768
And what happens instead?
• Tests are hard to maintain• Tests are hard to understand• Tests break often
Page 7
All the above are signs of bad tests.
-> The tests become a burden
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Page 8
Solution is simple: Write good tests!
But:What makes a test a good test?How to write good tests?
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
https://www.flickr.com/photos/spackletoe/90811910/sizes/l
Requirements describe an event / action and the expected result:• When request A is send, module X shall respond with B.• A click on the x-button shall close the window.• Input values of 2 and 4 shall result in a return value of 6.
Page 9
Tests as requirements
Don‘t:test()testMethodName()
Do:test_that_click_on_x-button_closes_window()test_that_2_and_4_return_6()should_throw_exception_on_empty_username()
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
→ communicates intent very well
Tests as documentation
Page 10
• Good tests help to understand the application
• Documents the behaviour of the application
• Not outdated like requirements or documentation
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Refactor tests
Remove noise and duplication at test setup / „given phase“.Many tests have the same setup, only subtle differences in the test data.
Page 11 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Object Mother
• Factory for test data• Has (static) methods to create test objects• Creates standard fixtures (certain state/baseline) for tests
Examples:• Address address = TestAddress.newAddressInGermany(); • Customer customer = TestCustomer.newCustomer();
Page 13
Problems: • With variability in test data many methods are created• Tend to become “God-classes”, messy and hard to maintain
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Test Data Builders
• Based on builder pattern• Comes with defaults for all fields• Tests that don‘t care about certain values, use defaults• Tests that need certain values, override only those• Thus the relevant parts are outlined
Example: • Address address = new AddressBuilder().withStreet(“Andreasstr.”).build();• Customer customer = new CustomerBuilder().build();
Page 14 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
Or use
Page 16 | Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014
For Java: make-it-easy
Makes it easier to create test data buildershttps://code.google.com/p/make-it-easy/
Conclusion
Page 19
• Try to write good tests, a lot of bad tests are really painful
• Specify the behaviour of your software with tests
• Write tests as requirements to communicate intent
• Write tests before the implementation code for best coverage
• Refactor tests, especially extract methods
• Improve your tests with Object Mothers or Test Data Builders
| Good Tests | Felix Sperling | Twitter: @felixsperling | 09.10.2014