refactoring junit tests - nordic testing days · refactoring junit tests franziska sauerwein...
TRANSCRIPT
Refactoring JUnit TestsFranziska Sauerwein @Singsalad
1
2
Setup (find a pair!)
install IDE (USB)import/download projectrun ConferenceTest
https://github.com/franziskas/RefactoringJUnitTests
3
The problem: Tests that are
complex to readhard to maintaintake a long time to run
-> Tests lose their value4
Some reasons for this:
complex object modelsbad code designuse of external resources
5
What we can do (short term)
simplify setup & assertionsclean test codeseparate dependencies
6
Builder
hides irrelevant dataallows easy changes to testdefaults (e.g. new validation)simplifies creation & enablereuse
7
Matcher
increases test readabilityimproves test failure messageis combinable & reusable
8
Combining Matchers
allOf(..)
anyOf(..)
not(..)9
Object Matchers
equalTo(..) / sameInstance(..)
instanceOf(..) / isCompatibleType(..)
notNullValue(..) / nullValue(..)
10
Collection Matchers
array(..) / hasItemInArray(..)
hasEntry(..) / hasKey(..) / hasValue(..)
hasItem(..), hasItems(..)
11
Number Matchers
closeTo(..)
greaterThan(..) / greaterThanOrEqualTo(..)
lessThan(..) / lessThanOrEqualTo(..)
12
String Matchers
equalToIgnoringCase(..)
equalToIgnoringWhiteSpace(..)
containsString(..)
endsWith(..) / startsWith(..)13
Custom Matchersprivate Matcher<User> hasEmail() { return new TypeSafeDiagnosingMatcher<Foo>() {
@Override public void describeTo(final Description description) { description.appendText("expected user to have an email"); } @Override protected boolean matchesSafely(final User user, final Description mismatchDescription) { mismatchDescription .appendText(" was ") .appendValue(user.getEmail();
return user.getEmail()!= null && user.getEmail().length() > 3;} };}
14
Custom Matchersprivate Matcher<User> hasEmail() { return new TypeSafeDiagnosingMatcher<Foo>() {
@Override public void describeTo(final Description description) { description.appendText("expected user to have an email"); } @Override protected boolean matchesSafely(final User user, final Description mismatchDescription) { mismatchDescription .appendText(" was ") .appendValue(user.getEmail();
return user.getEmail()!= null && user.getEmail().length() > 3;} };}
15
Custom Matchersprivate Matcher<User> hasEmail() { return new TypeSafeDiagnosingMatcher<Foo>() {
@Override public void describeTo(final Description description) { description.appendText("expected user to have an email"); } @Override protected boolean matchesSafely(final User user, final Description mismatchDescription) { mismatchDescription .appendText(" was ") .appendValue(user.getEmail();
return user.getEmail()!= null && user.getEmail().length() > 3;} };}
16
Custom Matchersprivate Matcher<User> hasEmail() { return new TypeSafeDiagnosingMatcher<Foo>() {
@Override public void describeTo(final Description description) { description.appendText("expected user to have an email"); } @Override protected boolean matchesSafely(final User user, final Description mismatchDescription) { mismatchDescription .appendText(" was ") .appendValue(user.getEmail();
return user.getEmail()!= null && user.getEmail().length() > 3;} };}
17
www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/
18
Modularisation
one test - one concernunit tests for functionalitylarger tests for journey
19
Summary
fix the code designin the meantime, ease the paintreat test code at least as well asproduction code
20
Try it yourself!
21