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 Slide

  2. TWITTER
    @Guardiola31337
    BLOG
    pguardiola.com/blog

    View Slide

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

    View Slide

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

    View Slide

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

    View 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 Slide

  7. What do they all
    AGREE on?

    View Slide

  8. PASSES its tests!

    View Slide

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

    View Slide

  10. Testing motivators
    Validate the System

    View Slide

  11. Testing motivators
    Validate the System
    Code Coverage

    View Slide

  12. Testing motivators
    Validate the System
    Code Coverage
    Enable Refactoring

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. Styles of Testing
    STATE
    VERIFICATION

    View Slide

  18. Styles of Testing
    STATE
    VERIFICATION
    BEHAVIOR
    VERIFICATION

    View Slide

  19. HYBRID

    View Slide

  20. Unit Test
    SOLITARY
    1. Never crosses boundaries

    View Slide

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

    View Slide

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

    View Slide

  23. FIRST
    FAST

    View Slide

  24. FIRST
    FAST
    INDEPENDENT

    View Slide

  25. FIRST
    FAST
    INDEPENDENT
    REPEATABLE

    View Slide

  26. FIRST
    FAST
    INDEPENDENT
    REPEATABLE
    SELF-VALIDATING

    View Slide

  27. FIRST
    FAST
    INDEPENDENT
    REPEATABLE
    SELF-VALIDATING
    TIMELY

    View Slide

  28. Test Doubles
    DUMMY

    View Slide

  29. Dummy
    public class DummyAuthorizer implements Authorizer {

    @Override

    public Boolean authorize(String username, String password) {

    return null;

    }

    }

    View Slide

  30. Test Doubles
    DUMMY
    STUB

    View Slide

  31. Stub
    public class AcceptingAuthorizerStub implements Authorizer {

    @Override

    public Boolean authorize(String username, String password) {

    return true;

    }

    }

    View Slide

  32. Test Doubles
    DUMMY
    STUB
    SPY

    View Slide

  33. Spy
    public class AcceptingAuthorizerSpy implements Authorizer {

    public boolean authorizeWasCalled = false;


    public Boolean authorize(String username, String password) {

    authorizeWasCalled = true;

    return true;

    }

    }

    View Slide

  34. Test Doubles
    DUMMY
    STUB
    SPY
    MOCK

    View Slide

  35. 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 Slide

  36. Test Doubles
    DUMMY
    STUB
    SPY
    MOCK
    FAKE

    View Slide

  37. Fake
    public class AcceptingAuthorizerFake implements Authorizer {

    public Boolean authorize(String username, String password) {

    return username.equals("Bob");

    }

    }

    View Slide

  38. AAA
    ARRANGE

    View Slide

  39. AAA
    ARRANGE
    ACT

    View Slide

  40. AAA
    ARRANGE
    ACT
    ASSERT

    View Slide

  41. What about
    ANDROID?

    View Slide

  42. ANDROID Unit Testing
    Java Module

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  50. ANDROID Unit Testing

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

    View Slide

  51. DECOUPLED
    Architecture

    View Slide

  52. Where do I
    START?

    View Slide

  53. public class FooTest {


    @Test

    public void sampleTest() throws Exception {

    assertEquals(expected, actual);

    }

    }
    JUnit

    View Slide

  54. 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 Slide

  55. 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 Slide

  56. How do I IMPROVE
    my tests?
    DAMP

    View Slide

  57. 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 Slide

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

    View Slide

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

    View Slide

  60. 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 Slide

  61. 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 Slide

  62. 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 Slide

  63. READABILITY
    LITERALS will
    REFLECT the examples
    from the BUSINESS

    View Slide

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

    View Slide

  65. 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 Slide

  66. READABILITY
    Avoid CODE DUPLICATION?
    BUILDERS

    View Slide

  67. Questionable Tests
    Testing Language Features or
    Standard Library Classes

    View Slide

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

    View Slide

  69. 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 Slide

  70. 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 Slide

  71. “Practise makes perfect.”

    View Slide

  72. ELEGANT??
    UNIT TESTING
    @Deprecated

    View Slide

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

    View Slide

  74. 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 Slide