Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elegant?? Unit Testing (Mobilization 2016)

Elegant?? Unit Testing (Mobilization 2016)

In this session we will learn the basics of Unit Testing and its importance. We will define what a Unit Test is, what type of Unit Tests there are and then talk about Test Doubles. Finally, we will focus on how to write new tests and improve existing ones by reviewing some Android Github projects.

Can you sleep soundly without writing tests? Really???

Pablo Guardiola

October 23, 2016
Tweet

More Decks by Pablo Guardiola

Other Decks in Programming

Transcript

  1. ELEGANT??
    UNIT TESTING
    by Pablo Guardiola
    @Guardiola31337

    View full-size slide

  2. TWITTER
    @Guardiola31337
    BLOG
    pguardiola.com/blog

    View full-size slide

  3. 4 rules of simple
    design
    1. Runs all the Tests

    View full-size slide

  4. 4 rules of simple
    design
    1. Runs all the Tests
    2. Reveals all the intention

    View full-size slide

  5. 4 rules of simple
    design
    1. Runs all the Tests
    2. Reveals all the intention
    3. No duplication

    View full-size slide

  6. 4 rules of simple
    design
    1. Runs all the Tests
    2. Reveals all the intention
    3. No duplication
    4. Fewest classes or methods

    View full-size slide

  7. What do they all
    AGREE on?

    View full-size slide

  8. PASSES its tests!

    View full-size slide

  9. Have you ever asked
    yourself, WHY?
    What MOTIVATES
    you to write tests?

    View full-size slide

  10. Testing motivators
    Validate the System

    View full-size slide

  11. Testing motivators
    Validate the System
    Code Coverage

    View full-size slide

  12. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring

    View full-size slide

  13. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring
    Document the Behaviour of the System

    View full-size slide

  14. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring
    Document the Behaviour of the System
    Test Driven Development

    View full-size slide

  15. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring
    Document the Behaviour of the System
    Test Driven Development
    Customer Acceptance

    View full-size slide

  16. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring
    Document the Behaviour of the System
    Test Driven Development
    Customer Acceptance

    View full-size slide

  17. Styles of Testing
    STATE
    VERIFICATION

    View full-size slide

  18. Styles of Testing
    STATE
    VERIFICATION
    BEHAVIOR
    VERIFICATION

    View full-size slide

  19. Unit Test
    SOLITARY
    1. Never crosses boundaries

    View full-size slide

  20. Unit Test
    SOLITARY
    1. Never crosses boundaries
    2.The Class Under Test should be the only concrete
    class found in a test

    View full-size slide

  21. Unit Test
    SOLITARY
    SOCIABLE
    1. Never crosses boundaries
    2.The Class Under Test should be the only concrete
    class found in a test

    View full-size slide

  22. FIRST
    FAST
    INDEPENDENT

    View full-size slide

  23. FIRST
    FAST
    INDEPENDENT
    REPEATABLE

    View full-size slide

  24. FIRST
    FAST
    INDEPENDENT
    REPEATABLE
    SELF-VALIDATING

    View full-size slide

  25. FIRST
    FAST
    INDEPENDENT
    REPEATABLE
    SELF-VALIDATING
    TIMELY

    View full-size slide

  26. Test Doubles
    DUMMY

    View full-size slide

  27. Dummy
    public class DummyAuthorizer implements Authorizer {

    @Override

    public Boolean authorize(String username, String password) {

    return null;

    }

    }

    View full-size slide

  28. Test Doubles
    DUMMY
    STUB

    View full-size slide

  29. Stub
    public class AcceptingAuthorizerStub implements Authorizer {

    @Override

    public Boolean authorize(String username, String password) {

    return true;

    }

    }

    View full-size slide

  30. Test Doubles
    DUMMY
    STUB
    SPY

    View full-size slide

  31. Spy
    public class AcceptingAuthorizerSpy implements Authorizer {

    public boolean authorizeWasCalled = false;


    public Boolean authorize(String username, String password) {

    authorizeWasCalled = true;

    return true;

    }

    }

    View full-size slide

  32. Test Doubles
    DUMMY
    STUB
    SPY
    MOCK

    View full-size slide

  33. 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;

    }

    }

    View full-size slide

  34. Test Doubles
    DUMMY
    STUB
    SPY
    MOCK
    FAKE

    View full-size slide

  35. Fake
    public class AcceptingAuthorizerFake implements Authorizer {

    public Boolean authorize(String username, String password) {

    return username.equals("Bob");

    }

    }

    View full-size slide

  36. AAA
    ARRANGE
    ACT

    View full-size slide

  37. AAA
    ARRANGE
    ACT
    ASSERT

    View full-size slide

  38. What about
    ANDROID?

    View full-size slide

  39. ANDROID Unit Testing
    Java Module

    View full-size slide

  40. ANDROID Unit Testing
    Java Module
    AS 1.1 + Android Gradle Plugin

    View full-size slide

  41. ANDROID Unit Testing
    Java Module
    MVP
    AS 1.1 + Android Gradle Plugin

    View full-size slide

  42. ANDROID Unit Testing
    Java Module
    MVP
    AS 1.1 + Android Gradle Plugin
    MVVM

    View full-size slide

  43. ANDROID Unit Testing
    Java Module
    MVP
    CLEAN Architecture
    AS 1.1 + Android Gradle Plugin
    MVVM

    View full-size slide

  44. ANDROID Unit Testing
    Java Module
    MVP
    CLEAN Architecture
    AS 1.1 + Android Gradle Plugin
    MVVM
    Catan Architecture

    View full-size slide

  45. ANDROID Unit Testing
    Java Module
    Mosby
    MVP
    CLEAN Architecture
    AS 1.1 + Android Gradle Plugin
    MVVM
    Catan Architecture

    View full-size slide

  46. ANDROID Unit Testing
    Java Module
    Rosie
    Mosby
    MVP
    CLEAN Architecture
    AS 1.1 + Android Gradle Plugin
    MVVM
    Catan Architecture

    View full-size slide

  47. ANDROID Unit Testing

    Java Module
    Rosie
    Mosby
    MVP
    CLEAN Architecture
    AS 1.1 + Android Gradle Plugin
    MVVM
    Catan Architecture

    View full-size slide

  48. DECOUPLED
    Architecture

    View full-size slide

  49. Where do I
    START?

    View full-size slide

  50. public class FooTest {


    @Test

    public void sampleTest() throws Exception {

    assertEquals(expected, actual);

    }

    }
    JUnit

    View full-size slide

  51. Clean Contacts
    @Test public void obtainContactFirstNameFromRepo() throws Exception {

    ContactsBddDataSource mockContactsBddDataSource =
    mock(ContactsBddDataSource.class);

    ContactsNetworkDataSource mockContactsNetworkDataSource =
    mock(ContactsNetworkDataSource.class);

    ContactsRepositoryImp contactsRepository =

    new ContactsRepositoryImp(mockContactsNetworkDataSource,
    mockContactsBddDataSource);

    Contact mobilization = new Contact();

    Name name = new Name();

    name.setFirst(“Mobilization 2016");

    mobilization.setName(name);

    when(mockContactsBddDataSource.obtain(“MobilizationMD5")).thenReturn(droidCon);


    Contact contact = contactsRepository.obtain("MobilizationMD5");


    assertEquals("Mobilization 2016", contact.getName().getFirst());

    }

    View full-size slide

  52. Clean Contacts
    @Test public void contactsInteractorExecutedWhenResumed() throws Exception {

    InteractorInvoker interactorInvoker = mock(InteractorInvoker.class);

    GetContactsInteractor getContactsInteractor = mock(GetContactsInteractor.class);

    final ListMapper listMapper = mock(ListMapper.class);

    ThreadSpec mainThreadSpec = mock(ThreadSpec.class);

    MainPresenter mainPresenter =

    new MainPresenter(interactorInvoker, getContactsInteractor, listMapper,
    mainThreadSpec);


    mainPresenter.onResume();


    verify(interactorInvoker).execute(Mockito.eq(getContactsInteractor),
    Mockito.any(InteractorOutputImp.class));

    }

    View full-size slide

  53. How do I IMPROVE
    my tests?
    DAMP

    View full-size slide

  54. 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());

    }

    View full-size slide

  55. It’s ANNOYING to have to look
    at the STACKTRACE to know
    what’s FAILING

    View full-size slide

  56. It’s ANNOYING to have to look
    at the STACKTRACE to know
    what’s FAILING
    Have NO INFORMATION
    about REMAINING TESTS

    View full-size slide

  57. 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();

    }

    View full-size slide

  58. Expect Literals
    @Test

    public void testSaveAllNextLevel() throws Exception {

    doReturn(Boolean.TRUE).when(repository).hasNextLevel();


    assertEquals(elements.size(), repository.saveAll(elements).size());

    verify(nextLevel, times(1)).saveAll(anyCollection());

    }

    View full-size slide

  59. Expect Literals
    @Test

    public void testSaveAllNextLevel() throws Exception {

    doReturn(Boolean.TRUE).when(repository).hasNextLevel();


    assertEquals(3, repository.saveAll(elements).size());

    verify(nextLevel, times(1)).saveAll(anyCollection());

    }

    View full-size slide

  60. READABILITY
    LITERALS will
    REFLECT the examples
    from the BUSINESS

    View full-size slide

  61. Value Objects vs Expect Literals
    CONVERT
    VALUE OBJECT into
    a LITERAL

    View full-size slide

  62. Avoid Inline Setup
    @Before

    public void setUp() throws Exception {

    initMocks(this);


    elements.add(mockedElement1);

    elements.add(mockedElement2);

    elements.add(mockedElement3);


    ids.add(EXPECTED_FIRST_ID);

    ids.add(EXPECTED_SECOND_ID);

    ids.add(EXPECTED_THIRD_ID);


    repository = new BaseFastRepositoryImpl(currentLevel, null);

    }

    View full-size slide

  63. READABILITY
    Avoid CODE DUPLICATION?
    BUILDERS

    View full-size slide

  64. Questionable Tests
    Testing Language Features or
    Standard Library Classes

    View full-size slide

  65. Questionable Tests
    Testing Language Features or
    Standard Library Classes
    Testing Framework Features
    or Classes

    View full-size slide

  66. Don’t test your stubs
    @Test

    public void doNotTestYourStubs() throws Exception {

    Name name = mock(Name.class);

    // blah blah blah...

    when(name.getFullName()).thenReturn("Don't test your stubs, please!");

    // 27 lines of stuff...

    assertEquals("Don't test your stubs, please!", name.getFullName());

    }

    View full-size slide

  67. 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

    View full-size slide

  68. “Practise makes perfect.”

    View full-size slide

  69. ELEGANT??
    UNIT TESTING
    @Deprecated

    View full-size slide

  70. Thank you!
    @Guardiola31337
    pguardiola.com
    [email protected]

    View full-size slide

  71. 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/PaNaVTEC/Clean-Contacts
    https://github.com/pedrovgs/Lynx
    https://github.com/Guardiola31337/CatanArchitecture
    Ted Mosby - Software Architect (http://hannesdorfmann.com/android/mosby)
    Responsible Design for Android by J. B. Rainsberger
    Clean Code: A handbook of Agile Software Craftsmanship, Robert C. Martin
    Software Craftsmanship by Sandro Mancuso

    View full-size slide