ELEGANT??
UNIT TESTING
by Pablo Guardiola
@Guardiola31337
Slide 2
Slide 2 text
TWITTER
@Guardiola31337
WEBSITE
pguardiola.com
Slide 3
Slide 3 text
4 rules of simple
design
1. Runs all the Tests
2. Reveals all the intention
3. No duplication
4. Fewest number of classes or methods
Slide 4
Slide 4 text
On what are they all
AGREED?
Slide 5
Slide 5 text
PASSES its tests!
Slide 6
Slide 6 text
Have you ever asked
yourself, WHY?
What MOTIVATES
you to write tests?
Slide 7
Slide 7 text
Testing motivators
Validate the System
Code Coverage
Enable Refactoring
Document the Behaviour of the System
Your Manager Told You To
Test Driven Development
Customer Acceptance
Ping-Pong Pair Programming
Slide 8
Slide 8 text
Types of Tests
STATE
VERIFICATION
BEHAVIOR
VERIFICATION
Slide 9
Slide 9 text
HYBRID
Slide 10
Slide 10 text
Unit Test
SOLITARY
SOCIABLE
1. Never cross boundaries
2.The Class Under Test should be the only concrete
class found in a test
Slide 11
Slide 11 text
FIRST
FAST
INDEPENDENT
REPEATABLE
SELF-VALIDATING
TIMELY
Slide 12
Slide 12 text
Test Doubles
DUMMY
STUB
SPY
MOCK
FAKE
Slide 13
Slide 13 text
Dummy
public class DummyAuthorizer implements Authorizer {
@Override
public Boolean authorize(String username, String password) {
return null;
}
}
Slide 14
Slide 14 text
Stub
public class AcceptingAuthorizerStub implements Authorizer {
@Override
public Boolean authorize(String username, String password) {
return true;
}
}
Slide 15
Slide 15 text
Spy
public class AcceptingAuthorizerSpy implements Authorizer {
public boolean authorizeWasCalled = false;
public Boolean authorize(String username, String password) {
authorizeWasCalled = true;
return true;
}
}
Slide 16
Slide 16 text
Mock
public class AcceptingAuthorizerVerificationMock implements Authorizer {
public boolean authorizeWasCalled = false;
public Boolean authorize(String username, String password) {
authorizeWasCalled = true;
return true;
}
public boolean verify() {
return authorizeWasCalled;
}
}
Slide 17
Slide 17 text
Fake
public class AcceptingAuthorizerFake implements Authorizer {
public Boolean authorize(String username, String password) {
return username.equals("Bob");
}
}
Slide 18
Slide 18 text
AAA
ARRANGE
ACT
ASSERT
Slide 19
Slide 19 text
What about
ANDROID?
Slide 20
Slide 20 text
ANDROID Unit Testing
Java Module
MVP
CLEAN Architecture
AS 1.1 + Android Gradle Plugin
MVVM
KOR
Rosie?
Slide 21
Slide 21 text
DECOUPLED
Architecture
Slide 22
Slide 22 text
Where do I
START?
Slide 23
Slide 23 text
public class FooTest {
@Test
public void sampleTest() throws Exception {
assertEquals(expected, actual);
}
}
JUnit
Slide 24
Slide 24 text
Material Movies
@Test
public void obtainFiftyShadesOfGreyMovie() throws Exception {
MediaDataSource inMemoryData = new InMemoryMovieSource();
GetMoviesInMemoryUsecaseController popularMovies = new
GetMoviesInMemoryUsecaseController(GetMoviesUsecase.TV_MOVIES, inMemoryData);
popularMovies.execute();
assertEquals("Fifty Shades of Grey", ((InMemoryMovieSource)
popularMovies.obtainMediaData()).obtainInMemoryMovies().get(3).getTitle());
}
Slide 25
Slide 25 text
Material Movies
@Test
public void checkIfPopularMoviesIsCalled() throws Exception {
GetMoviesUsecase popularMovies = new
GetMoviesUsecaseController(GetMoviesUsecase.TV_MOVIES);
GetMoviesUsecase spy = Mockito.spy(popularMovies);
spy.execute();
verify(spy).getPopularMovies();
}
Slide 26
Slide 26 text
How do I IMPROVE
my tests?
DAMP
Slide 27
Slide 27 text
One Assertion Per Test
(State Verification)
@Test public void shouldCreateVerboseTraceFromStringTrace() throws Exception {
Trace trace = Trace.fromString(VERBOSE_TRACE);
assertEquals(TraceLevel.VERBOSE, trace.getLevel());
assertEquals(ANY_TRACE_DATE + " " + VERBOSE_TRACE_MESSAGE, trace.getMessage());
}
Slide 28
Slide 28 text
ANNOYING to have to look at
the STACKTRACE to know
what’s FAILING
Have NO INFORMATION
about REMAINING TESTS
Slide 29
Slide 29 text
One Assertion Per Test
(Behavior Verification)
@Test public void shouldNotUpdateFilterIfPresenterIsNotInitialized() {
presenter.updateFilter(ANY_FILTER);
verify(lynx, never()).setConfig(any(LynxConfig.class));
verify(lynx, never()).restart();
}
Slide 30
Slide 30 text
1. If your test has an assertion, do not add any mock verifications
2. If your test verifies a mock, do not add any assertions
3. At most, 1 assertion per test
4. At most, 1 mock verification per test
Rule of thumb
Separating The Solitary
From The Sociable
1. Can be slow and nondeterministic
2. Are more susceptible to cascading failures
Sociable Unit Tests
Slide 37
Slide 37 text
Questionable Tests
Testing Language Features or
Standard Library Classes
Testing Framework Features
or Classes
Slide 38
Slide 38 text
Should we even bother
writing Unit Tests?
“The key is to test the areas that you are most
worried about going wrong. That way you get
the most benefit for your testing effort.”
Martin Fowler, Refactoring
Slide 39
Slide 39 text
“Practice makes perfect.”
Slide 40
Slide 40 text
Thank you!
@Guardiola31337
pguardiola.com
Slide 41
Slide 41 text
Extreme Programming Explained: Embrace Change, Kent Beck, AddisonWesley.
Working Effectively with Unit Tests by Jay Fields
Bibliography
Mocks Aren’t Stubs (www.martinfowler.com/articles/mocksArentStubs.html)
The Little Mocker (blog.8thlight.com/uncle-bob/2014/05/14/TheLittleMocker.html)
https://github.com/saulmm/Material-Movies
https://github.com/pedrovgs/Lynx
https://github.com/Sefford/kor
Clean Code: A handbook of Agile Software Craftsmanship, Robert C. Martin
Software Craftsmanship by Sandro Mancuso