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???

3c2bdd16c0ea8511dc254b8497a06f78?s=128

Pablo Guardiola

October 23, 2016
Tweet

Transcript

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

  2. TWITTER @Guardiola31337 BLOG pguardiola.com/blog

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

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

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

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

    2. Reveals all the intention 3. No duplication 4. Fewest classes or methods
  7. What do they all AGREE on?

  8. PASSES its tests!

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

    write tests?
  10. Testing motivators Validate the System

  11. Testing motivators Validate the System Code Coverage

  12. Testing motivators Validate the System Code Coverage Enable Refactoring

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

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

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

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

    the Behaviour of the System Test Driven Development Customer Acceptance …
  17. Styles of Testing STATE VERIFICATION

  18. Styles of Testing STATE VERIFICATION BEHAVIOR VERIFICATION

  19. HYBRID

  20. Unit Test SOLITARY 1. Never crosses boundaries

  21. Unit Test SOLITARY 1. Never crosses boundaries 2.The Class Under

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

    Under Test should be the only concrete class found in a test
  23. FIRST FAST

  24. FIRST FAST INDEPENDENT

  25. FIRST FAST INDEPENDENT REPEATABLE

  26. FIRST FAST INDEPENDENT REPEATABLE SELF-VALIDATING

  27. FIRST FAST INDEPENDENT REPEATABLE SELF-VALIDATING TIMELY

  28. Test Doubles DUMMY

  29. Dummy public class DummyAuthorizer implements Authorizer {
 @Override
 public Boolean

    authorize(String username, String password) {
 return null;
 }
 }
  30. Test Doubles DUMMY STUB

  31. Stub public class AcceptingAuthorizerStub implements Authorizer {
 @Override
 public Boolean

    authorize(String username, String password) {
 return true;
 }
 }
  32. Test Doubles DUMMY STUB SPY

  33. Spy public class AcceptingAuthorizerSpy implements Authorizer {
 public boolean authorizeWasCalled

    = false;
 
 public Boolean authorize(String username, String password) {
 authorizeWasCalled = true;
 return true;
 }
 }
  34. Test Doubles DUMMY STUB SPY MOCK

  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;
 }
 }
  36. Test Doubles DUMMY STUB SPY MOCK FAKE

  37. Fake public class AcceptingAuthorizerFake implements Authorizer {
 public Boolean authorize(String

    username, String password) {
 return username.equals("Bob");
 }
 }
  38. AAA ARRANGE

  39. AAA ARRANGE ACT

  40. AAA ARRANGE ACT ASSERT

  41. What about ANDROID?

  42. ANDROID Unit Testing Java Module

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

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

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

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

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

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

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

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

    Architecture AS 1.1 + Android Gradle Plugin MVVM Catan Architecture
  51. DECOUPLED Architecture

  52. Where do I START?

  53. public class FooTest {
 
 @Test
 public void sampleTest() throws

    Exception {
 assertEquals(expected, actual);
 }
 } JUnit
  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());
 }
  55. Clean Contacts @Test public void contactsInteractorExecutedWhenResumed() throws Exception {
 InteractorInvoker

    interactorInvoker = mock(InteractorInvoker.class);
 GetContactsInteractor getContactsInteractor = mock(GetContactsInteractor.class);
 final ListMapper<Contact, PresentationContact> 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));
 }
  56. How do I IMPROVE my tests? DAMP

  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());
 }
  58. It’s ANNOYING to have to look at the STACKTRACE to

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

    know what’s FAILING Have NO INFORMATION about REMAINING TESTS
  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();
 }
  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());
 }
  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());
 }
  63. READABILITY LITERALS will REFLECT the examples from the BUSINESS

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

    LITERAL
  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);
 }
  66. READABILITY Avoid CODE DUPLICATION? BUILDERS

  67. Questionable Tests Testing Language Features or Standard Library Classes

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

    Framework Features or Classes
  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());
 }
  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
  71. “Practise makes perfect.”

  72. ELEGANT?? UNIT TESTING @Deprecated

  73. Thank you! @Guardiola31337 pguardiola.com guardiola31337@gmail.com

  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