Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Android testing

206 Aufrufe

Veröffentlicht am

Slides of Android testing course

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Android testing

  1. 1. ANDROID TESTING
  2. 2. ANTONIO LÓPEZ MARÍN @tonilopezmr tonilopezmr@gmail.com tonilopezmr.github.io github.com/tonilopezmr ANDROID TESTING
  3. 3. ¿DE QUÉ @tonilopezmr VA ESTE CURSO?
  4. 4. . TEST BASICS . . UNIT TEST . . . EL CAMINO A LA TESTABILIDAD . . . . INTEGRATION TEST . . . . . UI TEST @tonilopezmr
  5. 5. UN TEST ES EL PROCESO DE EJECUTAR UN PROGRAMA CON EL OBJETIVO DE BUSCAR ERRORES @tonilopezmr@tonilopezmr
  6. 6. ¿POR QUÉ @tonilopezmr ESCRIBIR TEST ?
  7. 7. TIEMPO @tonilopezmr GANA
  8. 8. DINERO @tonilopezmr AHORRA
  9. 9. RESPONSABILIDAD @tonilopezmr ES TU
  10. 10. 0 1 2 3 4 CAMINO HACIA EL ÉXITO @tonilopezmr
  11. 11. ¿QUÉ @tonilopezmr ES UN TEST ?
  12. 12. DISEÑO @tonilopezmr UNA HERRAMIENTA DE
  13. 13. REFACTORIZAR @tonilopezmr LA ÚNICA MANERA DE
  14. 14. DOCUMENTACIÓN @tonilopezmr TU
  15. 15. AMIGO @tonilopezmr TU MEJOR
  16. 16. UN TEST ES QUIEN TE DICE QUE TU CÓDIGO FUNCIONA @tonilopezmr@tonilopezmr@tonilopezmr
  17. 17. ¿CÓMO ES @tonilopezmr UN TEST?
  18. 18. CLIENTE @tonilopezmr CERCANO AL
  19. 19. LENGUAJE NATURAL PARECIDO AL @tonilopezmr
  20. 20. TIPOS @tonilopezmr DE TEST
  21. 21. SUT @tonilopezmr FUNCIONES CAJA NEGRA CAJA BLANCA SYSTEM UNDER TEST
  22. 22. UI Integration Test Unit Test @tonilopezmr by Mike Cohn
  23. 23. @tonilopezmr JVM UNIDAD INDEPENDIENTE TEST DOUBLES REALLY FAST TEST F.I.R.S.T
  24. 24. @tonilopezmr JVM UNIDAD INDEPENDIENTE TEST DOUBLES REALLY FAST TEST F.I.R.S.T
  25. 25. @tonilopezmr JVM UNIDAD INDEPENDIENTE TEST DOUBLES REALLY FAST TEST F.I.R.S.T
  26. 26. @tonilopezmr JVM UNIDAD INDEPENDIENTE TEST DOUBLES REALLY FAST TEST F.I.R.S.T
  27. 27. @tonilopezmr JVM UNIDAD INDEPENDIENTE TEST DOUBLES REALLY FAST TEST F.I.R.S.T
  28. 28. UNIT TEST @tonilopezmr TESTEA UNA UNIDAD UNIT TEST
  29. 29. UNIT TEST FAST ISOLATED REPEATABLE SELF-VALIDATION TIMELY @tonilopezmr@tonilopezmr
  30. 30. PEQUEÑO @tonilopezmr SCOPE UNIT TEST
  31. 31. @tonilopezmr GIVEN WHEN THEN ARRANGE ACT ASSERT UNIT TEST
  32. 32. TEST DOUBLES @tonilopezmr UNIT TEST
  33. 33. class Book {
 
 private int pages;
 private double price; 
 public Book(int pages, double price) {
 this.pages = pages; this.price = price;
 } 
 public int getPages() {
 return pages;
 }
 public double getPrice() {
 return price;
 }
 
 } @tonilopezmr TEST DOUBLE
  34. 34. TEST DOUBLE DUMMY NO HACE NADA @tonilopezmr BookShop bookShop = new BookShop(); 
 bookShop.add(new BookDummy()); 
 bookShop.add(new BookDummy()); //debería devolver 2 bookShop.booksCount(); class BookDummy extends Book { 
 @Override public int getPages() {
 return 0;
 }
 } @tonilopezmr
  35. 35. TEST DOUBLE DUMMY NO HACE NADA @tonilopezmr BookShop bookShop = new BookShop(); 
 bookShop.add(new BookDummy()); 
 bookShop.add(new BookDummy()); //debería devolver 2 bookShop.booksCount(); class BookDummy extends Book { 
 @Override public int getPages() {
 return 0;
 }
 } @tonilopezmr
  36. 36. TEST DOUBLE DUMMY NO HACE NADA @tonilopezmr BookShop bookShop = new BookShop(); //Given 
 bookShop.add(new BookDummy());
 bookShop.add(new BookDummy()); //debería devolver 2 bookShop.booksCount(); class BookDummy extends Book { 
 @Override public int getPages() {
 return 0;
 }
 } @tonilopezmr
  37. 37. TEST DOUBLE DUMMY NO HACE NADA @tonilopezmr BookShop bookShop = new BookShop(); //Given 
 bookShop.add(new BookDummy()); //When
 bookShop.add(new BookDummy()); //debería devolver 2 bookShop.booksCount(); class BookDummy extends Book { 
 @Override public int getPages() {
 return 0;
 }
 } @tonilopezmr
  38. 38. TEST DOUBLE DUMMY NO HACE NADA @tonilopezmr BookShop bookShop = new BookShop(); //Given 
 bookShop.add(new BookDummy()); //When
 bookShop.add(new BookDummy()); //debería devolver 2 //Then bookShop.booksCount(); class BookDummy extends Book { 
 @Override public int getPages() {
 return 0;
 }
 } @tonilopezmr
  39. 39. TEST DOUBLE FAKES CERCANO A LO REAL @tonilopezmr class InMemoryBookRepository extends BookRepository {
 
 List<Book> books = new LinkedList<>();
 
 @Override public List<Book> getAll() {
 return books;
 }
 } inMemoryBookRepository = new InMemoryBookRepository();
 bookShop = new BookShop(inMemoryBookRepository); 
 bookShop.store(new BookDummy());
 bookShop.store(new BookDummy()); 
 inMemoryBookRepository.getAll(); //debería devolver 2
  40. 40. TEST DOUBLE FAKES CERCANO A LO REAL @tonilopezmr class InMemoryBookRepository extends BookRepository {
 
 List<Book> books = new LinkedList<>();
 
 @Override public List<Book> getAll() {
 return books;
 }
 } inMemoryBookRepository = new InMemoryBookRepository();
 bookShop = new BookShop(inMemoryBookRepository); 
 bookShop.store(new BookDummy());
 bookShop.store(new BookDummy()); 
 inMemoryBookRepository.getAll(); //debería devolver 2
  41. 41. TEST DOUBLE FAKES CERCANO A LO REAL @tonilopezmr class InMemoryBookRepository extends BookRepository {
 
 List<Book> books = new LinkedList<>();
 
 @Override public List<Book> getAll() {
 return books;
 }
 } inMemoryBookRepository = new InMemoryBookRepository();
 bookShop = new BookShop(inMemoryBookRepository); 
 bookShop.store(new BookDummy());
 bookShop.store(new BookDummy()); 
 inMemoryBookRepository.getAll(); //debería devolver 2
  42. 42. TEST DOUBLE FAKES CERCANO A LO REAL @tonilopezmr class InMemoryBookRepository extends BookRepository {
 
 List<Book> books = new LinkedList<>();
 
 @Override public List<Book> getAll() {
 return books;
 }
 } inMemoryBookRepository = new InMemoryBookRepository();
 bookShop = new BookShop(inMemoryBookRepository); 
 bookShop.store(new BookDummy());
 bookShop.store(new BookDummy()); 
 inMemoryBookRepository.getAll(); //debería devolver 2
  43. 43. TEST DOUBLE STUBS RESPUESTA PREPARADA @tonilopezmr class BookStub extends Book { @Override
 public double getPrice() {
 return 2.5;
 }
 } BookShop bookShop= new BookShop(); bookShop.add(new BookStub());
 bookShop.add(new BookStub());
 
 bookShop.totalAmount(); //debería de volver 5
  44. 44. TEST DOUBLE STUBS RESPUESTA PREPARADA @tonilopezmr class BookStub extends Book { @Override
 public double getPrice() {
 return 2.5;
 }
 } BookShop bookShop= new BookShop(); bookShop.add(new BookStub());
 bookShop.add(new BookStub());
 
 bookShop.totalAmount(); //debería de volver 5
  45. 45. TEST DOUBLE STUBS RESPUESTA PREPARADA @tonilopezmr class BookStub extends Book { @Override
 public double getPrice() {
 return 2.5;
 }
 } BookShop bookShop= new BookShop(); bookShop.add(new BookStub());
 bookShop.add(new BookStub());
 
 bookShop.totalAmount(); //debería de volver 5
  46. 46. TEST DOUBLE SPIES GUARDAN INFORMACIÓN @tonilopezmr class SpyBookApi extends BookRepository {
 
 public int getCallCount;
 
 public Response<Page> get(int page) {
 getCallCount++;
 return new ResponseDummy<Page>();
 }
 } 
 SpyBookApi spyBookApi = new SpyBookApi();
 
 BookReader bookReader = new BookReader(spyBookApi);
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 spyBookApi.getCallCount; //debería devolver 100
  47. 47. TEST DOUBLE SPIES GUARDAN INFORMACIÓN @tonilopezmr class SpyBookApi extends BookRepository {
 
 public int getCallCount;
 
 public Response<Page> get(int page) {
 getCallCount++;
 return new ResponseDummy<Page>();
 }
 } 
 SpyBookApi spyBookApi = new SpyBookApi();
 
 BookReader bookReader = new BookReader(spyBookApi);
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 spyBookApi.getCallCount; //debería devolver 100
  48. 48. TEST DOUBLE SPIES GUARDAN INFORMACIÓN @tonilopezmr class SpyBookApi extends BookRepository {
 
 public int getCallCount;
 
 public Response<Page> get(int page) {
 getCallCount++;
 return new ResponseDummy<Page>();
 }
 } 
 SpyBookApi spyBookApi = new SpyBookApi();
 
 BookReader bookReader = new BookReader(spyBookApi);
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 spyBookApi.getCallCount; //debería devolver 100
  49. 49. TEST DOUBLE SPIES GUARDAN INFORMACIÓN @tonilopezmr class SpyBookApi extends BookRepository {
 
 public int getCallCount;
 
 public Response<Page> get(int page) {
 getCallCount++;
 return new ResponseDummy<Page>();
 }
 } 
 SpyBookApi spyBookApi = new SpyBookApi();
 
 BookReader bookReader = new BookReader(spyBookApi);
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 spyBookApi.getCallCount; //debería devolver 100
  50. 50. TEST DOUBLE MOCKS PREVISIVOS @tonilopezmr class BookApiMock extends BookRepository {
 
 public boolean createWasCalled; 
 public void create(Book book) {
 createWasCalled = true;
 }
 } 
 SpyBookMock bookApiMock = new SpyBookMock();
 BookReader bookReader = new BookReader(bookApiMock); 
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 bookApiMock.callCount; //debería devolver 100 bookApiMock.createWasCalled; //debería devolver false
  51. 51. TEST DOUBLE MOCKS PREVISIVOS @tonilopezmr class BookApiMock extends BookRepository {
 
 public boolean createWasCalled; 
 public void create(Book book) {
 createWasCalled = true;
 }
 } 
 SpyBookMock bookApiMock = new SpyBookMock();
 BookReader bookReader = new BookReader(bookApiMock); 
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 bookApiMock.callCount; //debería devolver 100 bookApiMock.createWasCalled; //debería devolver false
  52. 52. TEST DOUBLE MOCKS PREVISIVOS @tonilopezmr class BookApiMock extends BookRepository {
 
 public boolean createWasCalled; 
 public void create(Book book) {
 createWasCalled = true;
 }
 } 
 SpyBookMock bookApiMock = new SpyBookMock();
 BookReader bookReader = new BookReader(bookApiMock); 
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 bookApiMock.callCount; //debería devolver 100 bookApiMock.createWasCalled; //debería devolver false
  53. 53. TEST DOUBLE MOCKS PREVISIVOS @tonilopezmr class BookApiMock extends BookRepository {
 
 public boolean createWasCalled; 
 public void create(Book book) {
 createWasCalled = true;
 }
 } 
 SpyBookMock bookApiMock = new SpyBookMock();
 BookReader bookReader = new BookReader(bookApiMock); 
 bookReader.load(new Book(100, 5d));
 bookReader.getAllPages();
 
 bookApiMock.callCount; //debería devolver 100 bookApiMock.createWasCalled; //debería devolver false
  54. 54. TEST DOUBLE DUMMY NO HACE NADA FAKES CERCANO A LO REAL STUBS RESPUESTA PREPARADA SPIES GUARDAN INFORMACIÓN MOCKS PREVISIVOS @tonilopezmr@tonilopezmr
  55. 55. HERRAMIENTAS @tonilopezmr UNIT TEST @tonilopezmr UNIT TEST
  56. 56. JUNIT 4 HAMCREST MOCKITO @tonilopezmr@tonilopezmr UNIT TEST
  57. 57. assertEquals() 
 assertTrue() 
 assertNull() 
 assertSame()
 
 assertArrayEquals() 
 assertThat() @tonilopezmr@tonilopezmr JUNIT 4 
 assertFalse() 
 assertNotNull() 
 assertNotSame() assertEquals("patata", patataString) http://junit.org/junit4/
  58. 58. assertEquals() 
 assertTrue() 
 assertNull() 
 assertSame()
 
 assertArrayEquals() 
 assertThat() @tonilopezmr@tonilopezmr JUNIT 4 
 assertFalse() 
 assertNotNull() 
 assertNotSame() assertEquals("patata", patataString) http://junit.org/junit4/
  59. 59. @tonilopezmr@tonilopezmr HAMCREST assertThat(patataString, is("patata")) http://hamcrest.org/
  60. 60. @tonilopezmr@tonilopezmr HAMCREST assertThat(patataString, is("patata")) http://hamcrest.org/
  61. 61. @tonilopezmr@tonilopezmr HAMCREST is()
 nullValue()
 sameInstance()
 any()
 contains() not()
 notNullValue() 
 sameInstance() assertThat(patataString, is(not(“patata”))) assertThat(patataList, contains(“patata”,“boniato”))) assertThat(patataList, not(contains(“patata”)))) http://hamcrest.org/
  62. 62. @tonilopezmr@tonilopezmr HAMCRESTis()
 nullValue()
 sameInstance()
 any()
 contains() not()
 notNullValue() 
 sameInstance() assertThat(patataString, is(not(“patata”))) assertThat(patataList, contains(“patata”,“boniato”))) assertThat(patataList, not(contains(“patata”)))) http://hamcrest.org/
  63. 63. @tonilopezmr@tonilopezmr HAMCRESTis()
 nullValue()
 sameInstance()
 any()
 contains() not()
 notNullValue() 
 sameInstance() assertThat(patataString, is(not(“patata”))) assertThat(patataList, contains(“patata”,“boniato”))) assertThat(patataList, not(contains(“patata”)))) http://hamcrest.org/
  64. 64. @tonilopezmr@tonilopezmr HAMCRESTis()
 nullValue()
 sameInstance()
 any()
 contains() not()
 notNullValue() 
 sameInstance() assertThat(patataString, is(not(“patata”))) assertThat(patataList, contains(“patata”,“boniato”))) assertThat(patataList, not(contains(“patata”)))) http://hamcrest.org/
  65. 65. @tonilopezmr@tonilopezmr MOCKITO Book book = mock(Book.class) when(book.getPrice()).thenReturn(4.5) verify(bookApi).getPages(); given(book.getPrice()).willReturn(4.5) http://mockito.org/
  66. 66. @tonilopezmr@tonilopezmr MOCKITO Book book = mock(Book.class) when(book.getPrice()).thenReturn(4.5) verify(bookApi).getPages(); given(book.getPrice()).willReturn(4.5) http://mockito.org/
  67. 67. @tonilopezmr@tonilopezmr MOCKITO Book book = mock(Book.class) when(book.getPrice()).thenReturn(4.5) verify(bookApi).getPages(); given(book.getPrice()).willReturn(4.5) http://mockito.org/
  68. 68. @tonilopezmr@tonilopezmr MOCKITO Book book = mock(Book.class) when(book.getPrice()).thenReturn(4.5) verify(bookApi).getPages(); given(book.getPrice()).willReturn(4.5) http://mockito.org/
  69. 69. VALE, VALE, SI YO QUIERO HACER TESTS, PERO… ¿CÓMO LO HAGO? ¯_( )_/¯ @tonilopezmr
  70. 70. GO TO PRACTICE @tonilopezmr
  71. 71. ANDROID TESTING
  72. 72. VALE, VALE, SI YO SE HACER TESTS, PERO… ¿QUÉ PASA SI MI CÓDIGO NO ES TESTEABLE? ¯_( )_/¯ @tonilopezmr
  73. 73. HAZLOTESTEABLE @tonilopezmr
  74. 74. LA ARQUITECTURA DEL SOFTWARE TIENE QUE OCULTAR LOS DETALLES DE IMPLEMENTACIÓN @tonilopezmr@tonilopezmr@tonilopezmr
  75. 75. SINGLE RESPONSIBILITY OPEN/CLOSE LISKOV SUBSTITUTION INTERFACE SEGREGATION DEPENDENCY INVERSION @tonilopezmr@tonilopezmr
  76. 76. SOLID @tonilopezmr SINGLE RESPONSIBILITY UN OBJETO HACE UNA ÚNICA COSA UNA CLASE MANEJA VARIAS CAPAS NÚMERO DE MÉTODOS PUBLICOS NOS CUESTA TESTEAR LA CLASE
  77. 77. SOLID @tonilopezmr SINGLE RESPONSIBILITY UNA CLASE MANEJA VARIAS CAPAS NÚMERO DE MÉTODOS PUBLICOS NOS CUESTA TESTEAR LA CLASE UN OBJETO HACE UNA ÚNICA COSA
  78. 78. SOLID @tonilopezmr SINGLE RESPONSIBILITY UNA CLASE MANEJA VARIAS CAPAS NÚMERO DE MÉTODOS PUBLICOS NOS CUESTA TESTEAR LA CLASE UN OBJETO HACE UNA ÚNICA COSA
  79. 79. SOLID @tonilopezmr SINGLE RESPONSIBILITY UNA CLASE MANEJA VARIAS CAPAS NÚMERO DE MÉTODOS PUBLICOS NOS CUESTA TESTEAR LA CLASE UN OBJETO HACE UNA ÚNICA COSA
  80. 80. SOLID @tonilopezmr OPEN/CLOSE ABIERTAA EXTENSIÓN CERRADAA MODIFICACIÓN ESCRIBIR NUEVAS FUNCIONALIDADES NO DEBE AFECTAR A NUESTRO CÓDIGO YA ESCRITO
  81. 81. SOLID @tonilopezmr LISKOV SUBSTITUTION EXTENDER UNA CLASE SIN ALTERAR SU COMPORTAMIENTO TODO MÉTODO SOBRESCRITO DEBE TENER IMPLEMENTACIÓN NO VALE DEJAR MÉTODOS VACÍOS NOS AYUDA A USAR HERENCIA CORRECTAMENTE
  82. 82. SOLID @tonilopezmr LISKOV SUBSTITUTION EXTENDER UNA CLASE SIN ALTERAR SU COMPORTAMIENTO TODO MÉTODO SOBRESCRITO DEBE TENER IMPLEMENTACIÓN NO VALE DEJAR MÉTODOS VACÍOS NOS AYUDA A USAR HERENCIA CORRECTAMENTE
  83. 83. SOLID @tonilopezmr LISKOV SUBSTITUTION EXTENDER UNA CLASE SIN ALTERAR SU COMPORTAMIENTO TODO MÉTODO SOBRESCRITO DEBE TENER IMPLEMENTACIÓN NO VALE DEJAR MÉTODOS VACÍOS NOS AYUDA A USAR HERENCIA CORRECTAMENTE
  84. 84. SOLID @tonilopezmr LISKOV SUBSTITUTION TODO MÉTODO SOBRESCRITO DEBE TENER IMPLEMENTACIÓN NO VALE DEJAR MÉTODOS VACÍOS NOS AYUDA A USAR HERENCIA CORRECTAMENTE EXTENDER UNA CLASE SIN ALTERAR SU COMPORTAMIENTO
  85. 85. SOLID @tonilopezmr INTERFACE SEGREGATION NINGUNACLASE DEPENDE DE MÉTODOS QUE NO USA INTERFACES MÁS PEQUEÑAS “SEGREGACIÓN”
  86. 86. SOLID @tonilopezmr DEPENDENCY INVERSION OCULTARDETALLES DE IMPLEMENTACIÓN LÓGICA DE NEGOCIO QUE DEPENDE DE DETALLES DE IMPLEMENTACIÓN ¿CUALES SON LAS DEPENDENCIAS? MUY DIFÍCIL HACER TEST Depender de abstracciones nunca de concreciones
  87. 87. SOLID @tonilopezmr DEPENDENCY INVERSION OCULTARDETALLES DE IMPLEMENTACIÓN LÓGICA DE NEGOCIO QUE DEPENDE DE DETALLES DE IMPLEMENTACIÓN ¿CUALES SON LAS DEPENDENCIAS? MUY DIFÍCIL HACER TEST Depender de abstracciones nunca de concreciones
  88. 88. SOLID @tonilopezmr DEPENDENCY INVERSION OCULTARDETALLES DE IMPLEMENTACIÓN LÓGICA DE NEGOCIO QUE DEPENDE DE DETALLES DE IMPLEMENTACIÓN ¿CUALES SON LAS DEPENDENCIAS? MUY DIFÍCIL HACER TEST Depender de abstracciones nunca de concreciones
  89. 89. SOLID @tonilopezmr DEPENDENCY INVERSION LÓGICA DE NEGOCIO QUE DEPENDE DE DETALLES DE IMPLEMENTACIÓN ¿CUALES SON LAS DEPENDENCIAS? MUY DIFÍCIL HACER TEST OCULTARDETALLES DE IMPLEMENTACIÓNDepender de abstracciones nunca de concreciones
  90. 90. DEPENDENCY INVERSION @tonilopezmr
  91. 91. NOS PERMITE REMPLAZAR NUESTRO CÓDIGO DE PRODUCCIÓN POR NUESTRO TEST DOUBLE QUE NECESITEMOS @tonilopezmr@tonilopezmr@tonilopezmr
  92. 92. SCOPE @tonilopezmr ELEGIR EL
  93. 93. INTERFACES @tonilopezmr USO DE
  94. 94. INTERFACES @tonilopezmr USO DE NO SIEMPRE
  95. 95. MUY BAJO @tonilopezmr NIVEL DE ACOPLAMIENTO
  96. 96. CONSTRUCTOR @tonilopezmr DEPENDENCIAS POR
  97. 97. SQLiteManager sqliteManager = new SQLiteManager();
 CharacterCache characterCache = new CharacterCache(sqliteManager); CharacterValidator characterValidator = new CharacterValidator(); 
 CharacterApi characterApi = new CharacterApi(); 
 CharacterRepository characterRepository = new CharacterRepository(characterValidator, characterApi, characterCache); 
 CharacterListPresenter characterListPresenter = new CharacterListPresenter(characterRepository); @tonilopezmr
  98. 98. SQLiteManager sqliteManager = new SQLiteManager();
 CharacterCache characterCache = new CharacterCache(sqliteManager); CharacterValidator characterValidator = new CharacterValidator(); 
 CharacterApi characterApi = new CharacterApi(); 
 CharacterRepository characterRepository = new CharacterRepository(characterValidator, characterApi, characterCache); 
 CharacterListPresenter characterListPresenter = new CharacterListPresenter(characterRepository); @tonilopezmr
  99. 99. SQLiteManager sqliteManager = new SQLiteManager();
 CharacterCache characterCache = new CharacterCache(sqliteManager); CharacterValidator characterValidator = new CharacterValidator(); 
 CharacterApi characterApi = new CharacterApi(); 
 CharacterRepository characterRepository = new CharacterRepository(characterValidator, characterApi, characterCache); 
 CharacterListPresenter characterListPresenter = new CharacterListPresenter(characterRepository); @tonilopezmr
  100. 100. SQLiteManager sqliteManager = new SQLiteManager();
 CharacterCache characterCache = new CharacterCache(sqliteManager); CharacterValidator characterValidator = new CharacterValidator(); 
 CharacterApi characterApi = new CharacterApi(); 
 CharacterRepository characterRepository = new CharacterRepository(characterValidator, characterApi, characterCache); 
 CharacterListPresenter characterListPresenter = new CharacterListPresenter(characterRepository); @tonilopezmr
  101. 101. FACTORIAS @tonilopezmr SE PUEDE RESOLVER MEDIANTE
  102. 102. DEPENDENCY INJECTION @tonilopezmr
  103. 103. DEPENDENCIAS @tonilopezmr CONFIGURACIÓN DE
  104. 104. ABSTRACCIONES @tonilopezmr EXTRAER DONDE SE DEPENDE DE
  105. 105. MODEL VIEW PRESENTER @tonilopezmr ARCHITECTURE PATTERN
  106. 106. @tonilopezmr VIEW PRESENTER MODEL presenter.cargaPersonajes modelo.damePersonajestoma personajes vista.dejaDeMostrarUnLoader vista.mostrarXBotones vista.mostrarPersonajes
  107. 107. @tonilopezmr VIEW 
 public interface CharacterListView {
 void initUI();
 void show(List<GoTCharacter> characterList);
 void showEmptyCase();
 void hideEmptyCase();
 void showProgressBar();
 void hideProgressBar(); void showCharacterListError(); void showNetworkError(); 
 }
  108. 108. @tonilopezmr PRESENTER public class CharacterListPresenter {
 
 private Domain domain;
 
 public CharacterListPresenter(Domain domain) {
 this.domain = domain;
 }
 
 public void init() {
 view.initUi();
 view.hideProgressBar();
 view.show(domain.getAll());
 }
 
 public void setView(CharacterListView view) {
 this.view = view;
 } }
  109. 109. @tonilopezmr MODEL BUSINESS LOGIC
  110. 110. EJEMPLO @tonilopezmr
  111. 111. GAME OF THRONES @tonilopezmr
  112. 112. LISTAR PERSONAJES LISTAR ORDENADOS POR NOMBRE PERSONAJES POR CASA AÑADIR PERSONAJES
  113. 113. VALE, VALE, SI EL MVP LO ENTIENDO, PERO… ¿CÓMO AÑADO COSAS A EL INJECTOR? ¯_( )_/¯ @tonilopezmr
  114. 114. GO TO PRACTICE @tonilopezmr
  115. 115. @tonilopezmr INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA NO TAN RÁPIDOS
  116. 116. @tonilopezmr INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA NO TAN RÁPIDOS
  117. 117. @tonilopezmr INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA NO TAN RÁPIDOS
  118. 118. @tonilopezmr INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA NO TAN RÁPIDOS
  119. 119. MÁS GRANDE @tonilopezmr SCOPE
  120. 120. API CLIENT @tonilopezmr
  121. 121. REQUEST/RESPONSE @tonilopezmr HTTP
  122. 122. JSON @tonilopezmr PARSING
  123. 123. HEADER @tonilopezmr ASSERTING
  124. 124. API @tonilopezmr FAKE
  125. 125. SERVIDOR @tonilopezmr RUNTIME TEST
  126. 126. MOCKWEBSERVER @tonilopezmr https://github.com/square/okhttp/tree/master/mockwebserver
  127. 127. public class MockWebServerTest {
 
 private MockWebServer server;
 
 @Before
 public void setUp() throws Exception {
 this.server = new MockWebServer();
 this.server.start();
 }
 
 @After
 public void tearDown() throws Exception {
 this.server.shutdown();
 }
 
 protected String getBaseEndpoint() {
 return server.url("/").toString();
 } } https://github.com/square/okhttp/tree/master/mockwebserver
  128. 128. public class IntegrationApiTest extends MockWebServerTest {
 protected void enqueueMockResponse(String body) {
 MockResponse mockResponse = new MockResponse();
 mockResponse.setResponseCode(200);
 mockResponse.setBody(body);
 server.enqueue(mockResponse);
 } } https://github.com/square/okhttp/tree/master/mockwebserver
  129. 129. GO TO PRACTICE @tonilopezmr
  130. 130. @tonilopezmr FRAMEWORKS FRAGILES END - TO -END LENTA
  131. 131. @tonilopezmr FRAMEWORKS FRAGILES END - TO -END LENTA
  132. 132. @tonilopezmr FRAMEWORKS FRAGILES END - TO -END LENTA
  133. 133. @tonilopezmr FRAMEWORKS FRAGILES END - TO -END LENTA
  134. 134. @tonilopezmr FRAMEWORKS FRAGILES END - TO -END LENTA
  135. 135. AUTOMATIC UI TESTING @tonilopezmr@tonilopezmr@tonilopezmr
  136. 136. ESPRESSO @tonilopezmr
  137. 137. onView(ViewMatcher)
 .perform(ViewAction)
 .check(ViewAssertion) @tonilopezmr
  138. 138. onView(ViewMatcher)
 .perform(ViewAction)
 .check(ViewAssertion) ViewMatcher implement Matcher<? super View> @tonilopezmr
  139. 139. onView(ViewMatcher)
 .perform(ViewAction)
 .check(ViewAssertion) ViewAction click() @tonilopezmr
  140. 140. onView(ViewMatcher)
 .perform(ViewAction)
 .check(ViewAssertion) ViewAssertion assert views @tonilopezmr
  141. 141. onView(withId(R.id.button))
 .perform(click())
 .check(isDisplayed()) @tonilopezmr
  142. 142. onView(ViewMatcher)
 .perform(ViewAction)
 .check(ViewAssertion) onData(ObjectMatcher) .DataOptions
 .perform(ViewAction)
 .check(ViewAssertion) @tonilopezmr
  143. 143. onData(ObjectMatcher) .DataOptions
 .perform(ViewAction)
 .check(ViewAssertion) ObjectMatcher implement Matcher<? super Object> @tonilopezmr
  144. 144. onData(ObjectMatcher) .DataOptions
 .perform(ViewAction)
 .check(ViewAssertion) DataOptions AdapterView, GridView @tonilopezmr
  145. 145. @tonilopezmr
  146. 146. @tonilopezmr
  147. 147. @tonilopezmr
  148. 148. GO TO PRACTICE @tonilopezmr

×