21
Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1

Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

  • Upload
    others

  • View
    27

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Refactoring JUnit TestsFranziska Sauerwein @Singsalad

1

Page 2: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

2

Page 3: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Setup (find a pair!)

install IDE (USB)import/download projectrun ConferenceTest

https://github.com/franziskas/RefactoringJUnitTests

3

Page 4: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

The problem: Tests that are

complex to readhard to maintaintake a long time to run

-> Tests lose their value4

Page 5: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Some reasons for this:

complex object modelsbad code designuse of external resources

5

Page 6: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

What we can do (short term)

simplify setup & assertionsclean test codeseparate dependencies

6

Page 7: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Builder

hides irrelevant dataallows easy changes to testdefaults (e.g. new validation)simplifies creation & enablereuse

7

Page 8: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Matcher

increases test readabilityimproves test failure messageis combinable & reusable

8

Page 9: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Combining Matchers

allOf(..)

anyOf(..)

not(..)9

Page 10: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Object Matchers

equalTo(..) / sameInstance(..)

instanceOf(..) / isCompatibleType(..)

notNullValue(..) / nullValue(..)

10

Page 11: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Collection Matchers

array(..) / hasItemInArray(..)

hasEntry(..) / hasKey(..) / hasValue(..)

hasItem(..), hasItems(..)

11

Page 12: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Number Matchers

closeTo(..)

greaterThan(..) / greaterThanOrEqualTo(..)

lessThan(..) / lessThanOrEqualTo(..)

12

Page 13: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

String Matchers

equalToIgnoringCase(..)

equalToIgnoringWhiteSpace(..)

containsString(..)

endsWith(..) / startsWith(..)13

Page 14: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

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

Page 15: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

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

Page 16: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

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

Page 17: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

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

Page 18: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/

18

Page 19: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Modularisation

one test - one concernunit tests for functionalitylarger tests for journey

19

Page 20: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Summary

fix the code designin the meantime, ease the paintreat test code at least as well asproduction code

20

Page 21: Refactoring JUnit Tests - Nordic Testing Days · Refactoring JUnit Tests Franziska Sauerwein @Singsalad 1. 2. Setup (find a pair!) ... -> Tests lose their value 4. Some reasons for

Try it yourself!

21