Android testing

149
ANDROID TESTING

Transcript of Android testing

Page 1: Android testing

ANDROID TESTING

Page 2: Android testing

ANTONIO LÓPEZ MARÍN

@tonilopezmr

[email protected]

tonilopezmr.github.io

github.com/tonilopezmr

ANDROID TESTING

Page 3: Android testing

¿DE QUÉ

@tonilopezmr

VA ESTE CURSO ?

Page 4: Android testing

. TEST BASICS

. . UNIT TEST

. . . EL CAMINO A LA TESTABILIDAD

. . . . INTEGRATION TEST

. . . . . UI TEST

@tonilopezmr

Page 5: Android testing

UN TEST ES EL PROCESO DE EJECUTAR UN PROGRAMA CON EL OBJETIVO DE BUSCAR ERRORES

@tonilopezmr@tonilopezmr

Page 6: Android testing

¿POR QUÉ

@tonilopezmr

ESCRIBIR TEST ?

Page 7: Android testing

TIEMPO

@tonilopezmr

GANA

Page 8: Android testing

DINERO

@tonilopezmr

AHORRA

Page 9: Android testing

RESPONSABILIDAD

@tonilopezmr

ES TU

Page 10: Android testing

0

1

2

3

4

CAMINO HACIA ELÉXITO

@tonilopezmr

Page 11: Android testing

¿QUÉ

@tonilopezmr

ES UN TEST ?

Page 12: Android testing

DISEÑO

@tonilopezmr

UNA HERRAMIENTA DE

Page 13: Android testing

REFACTORIZAR

@tonilopezmr

LA ÚNICA MANERA DE

Page 14: Android testing

DOCUMENTACIÓN

@tonilopezmr

TU

Page 15: Android testing

AMIGO

@tonilopezmr

TU MEJOR

Page 16: Android testing

UN TEST ES QUIEN TE DICE QUE TU CÓDIGO FUNCIONA

@tonilopezmr@tonilopezmr@tonilopezmr

Page 17: Android testing

¿CÓMO ES

@tonilopezmr

UN TEST?

Page 18: Android testing

CLIENTE

@tonilopezmr

CERCANO AL

Page 19: Android testing

LENGUAJE NATURALPARECIDO AL

@tonilopezmr

Page 20: Android testing

TIPOS

@tonilopezmr

DE TEST

Page 21: Android testing

SUT

@tonilopezmr

FUNCIONES

CAJA NEGRA CAJA BLANCA

SYSTEM UNDER TEST

Page 22: Android testing

UI

Integration Test

Unit Test

@tonilopezmr

by Mike Cohn

Page 23: Android testing

@tonilopezmr

JVM UNIDAD INDEPENDIENTE

TEST DOUBLES REALLY FAST TEST

F.I.R.S.T

Page 24: Android testing

@tonilopezmr

JVM UNIDAD INDEPENDIENTE

TEST DOUBLES REALLY FAST TEST

F.I.R.S.T

Page 25: Android testing

@tonilopezmr

JVM UNIDAD INDEPENDIENTE

TEST DOUBLES REALLY FAST TEST

F.I.R.S.T

Page 26: Android testing

@tonilopezmr

JVM UNIDAD INDEPENDIENTE

TEST DOUBLES REALLY FAST TEST

F.I.R.S.T

Page 27: Android testing

@tonilopezmr

JVM UNIDAD INDEPENDIENTE

TEST DOUBLES REALLY FAST TEST

F.I.R.S.T

Page 28: Android testing

UNIT TEST

@tonilopezmr

TESTEA UNA UNIDAD

UNIT TEST

Page 29: Android testing

UNIT TEST

FAST ISOLATED REPEATABLE SELF-VALIDATION TIMELY

@tonilopezmr@tonilopezmr

Page 30: Android testing

PEQUEÑO

@tonilopezmr

SCOPE

UNIT TEST

Page 31: Android testing

@tonilopezmr

GIVEN WHEN THEN

ARRANGE ACT ASSERT

UNIT TEST

Page 32: Android testing

TEST DOUBLES

@tonilopezmrUNIT TEST

Page 33: Android testing

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; } }

@tonilopezmrTEST DOUBLE

Page 34: Android testing

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

Page 35: Android testing

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

Page 36: Android testing

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

Page 37: Android testing

TEST DOUBLE

DUMMY NO HACE NADA

@tonilopezmr

BookShop bookShop = new BookShop(); //Given bookShop.add(new BookDummy()); //WhenbookShop.add(new BookDummy());

//debería devolver 2 bookShop.booksCount();

class BookDummy extends Book { @Override public int getPages() { return 0; } }

@tonilopezmr

Page 38: Android testing

TEST DOUBLE

DUMMY NO HACE NADA

@tonilopezmr

BookShop bookShop = new BookShop(); //Given bookShop.add(new BookDummy()); //WhenbookShop.add(new BookDummy());

//debería devolver 2 //Then bookShop.booksCount();

class BookDummy extends Book { @Override public int getPages() { return 0; } }

@tonilopezmr

Page 39: Android testing

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

Page 40: Android testing

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

Page 41: Android testing

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

Page 42: Android testing

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

Page 43: Android testing

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

Page 44: Android testing

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

Page 45: Android testing

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

Page 46: Android testing

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

Page 47: Android testing

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

Page 48: Android testing

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

Page 49: Android testing

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

Page 50: Android testing

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

Page 51: Android testing

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

Page 52: Android testing

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

Page 53: Android testing

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

Page 54: Android testing

TEST DOUBLE

DUMMY NO HACE NADA FAKES CERCANO A LO REAL STUBS RESPUESTA PREPARADA SPIES GUARDAN INFORMACIÓN MOCKS PREVISIVOS

@tonilopezmr@tonilopezmr

Page 55: Android testing

HERRAMIENTAS

@tonilopezmr

UNIT TEST

@tonilopezmrUNIT TEST

Page 56: Android testing

JUNIT 4 HAMCREST MOCKITO

@tonilopezmr@tonilopezmrUNIT TEST

Page 57: Android testing

assertEquals() assertTrue() assertNull() assertSame()assertArrayEquals() assertThat()

@tonilopezmr@tonilopezmr

JUNIT 4assertFalse() assertNotNull() assertNotSame()

assertEquals("patata", patataString)

http://junit.org/junit4/

Page 58: Android testing

assertEquals() assertTrue() assertNull() assertSame()assertArrayEquals() assertThat()

@tonilopezmr@tonilopezmr

JUNIT 4assertFalse() assertNotNull() assertNotSame()

assertEquals("patata", patataString)

http://junit.org/junit4/

Page 59: Android testing

@tonilopezmr@tonilopezmr

HAMCRESTassertThat(patataString, is("patata"))

http://hamcrest.org/

Page 60: Android testing

@tonilopezmr@tonilopezmr

HAMCRESTassertThat(patataString, is("patata"))

http://hamcrest.org/

Page 61: Android testing

@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/

Page 62: Android testing

@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/

Page 63: Android testing

@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/

Page 64: Android testing

@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/

Page 65: Android testing

@tonilopezmr@tonilopezmr

MOCKITOBook book = mock(Book.class)

when(book.getPrice()).thenReturn(4.5)

verify(bookApi).getPages();

given(book.getPrice()).willReturn(4.5)

http://mockito.org/

Page 66: Android testing

@tonilopezmr@tonilopezmr

MOCKITOBook book = mock(Book.class)

when(book.getPrice()).thenReturn(4.5)

verify(bookApi).getPages();

given(book.getPrice()).willReturn(4.5)

http://mockito.org/

Page 67: Android testing

@tonilopezmr@tonilopezmr

MOCKITOBook book = mock(Book.class)

when(book.getPrice()).thenReturn(4.5)

verify(bookApi).getPages();

given(book.getPrice()).willReturn(4.5)

http://mockito.org/

Page 68: Android testing

@tonilopezmr@tonilopezmr

MOCKITOBook book = mock(Book.class)

when(book.getPrice()).thenReturn(4.5)

verify(bookApi).getPages();

given(book.getPrice()).willReturn(4.5)

http://mockito.org/

Page 69: Android testing

VALE, VALE, SI YO QUIERO HACER TESTS, PERO…

¿CÓMO LO HAGO?

¯\_( )_/¯

@tonilopezmr

Page 70: Android testing

GO TO PRACTICE

@tonilopezmr

Page 71: Android testing

ANDROID TESTING

Page 72: Android testing

VALE, VALE, SI YO SE HACER TESTS, PERO…

¿QUÉ PASA SI MI CÓDIGO NO ES TESTEABLE?

¯\_( )_/¯

@tonilopezmr

Page 73: Android testing

HAZLOTESTEABLE

@tonilopezmr

Page 74: Android testing

LA ARQUITECTURA DEL SOFTWARE TIENE QUE OCULTAR LOS DETALLES DE IMPLEMENTACIÓN

@tonilopezmr@tonilopezmr@tonilopezmr

Page 75: Android testing

SINGLE RESPONSIBILITY OPEN/CLOSE LISKOV SUBSTITUTION INTERFACE SEGREGATION DEPENDENCY INVERSION

@tonilopezmr@tonilopezmr

Page 76: Android testing

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

Page 77: Android testing

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

Page 78: Android testing

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

Page 79: Android testing

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

Page 80: Android testing

SOLID @tonilopezmr

OPEN/CLOSE

ABIERTA A EXTENSIÓN CERRADA A MODIFICACIÓN

ESCRIBIR NUEVAS FUNCIONALIDADES NO DEBE AFECTAR A NUESTRO CÓDIGO YA ESCRITO

Page 81: Android testing

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

Page 82: Android testing

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

Page 83: Android testing

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

Page 84: Android testing

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

Page 85: Android testing

SOLID @tonilopezmr

INTERFACE SEGREGATION

NINGUNA CLASE DEPENDE DE MÉTODOS QUE NO USA

INTERFACES MÁS PEQUEÑAS “SEGREGACIÓN”

Page 86: Android testing

SOLID @tonilopezmr

DEPENDENCY INVERSION

OCULTAR DETALLES 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

Page 87: Android testing

SOLID @tonilopezmr

DEPENDENCY INVERSION

OCULTAR DETALLES 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

Page 88: Android testing

SOLID @tonilopezmr

DEPENDENCY INVERSION

OCULTAR DETALLES 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

Page 89: Android testing

SOLID @tonilopezmr

DEPENDENCY INVERSION

LÓGICA DE NEGOCIO QUE DEPENDE DE DETALLES DE IMPLEMENTACIÓN ¿CUALES SON LAS DEPENDENCIAS?

MUY DIFÍCIL HACER TEST

OCULTAR DETALLES DE IMPLEMENTACIÓNDepender de abstracciones nunca de concreciones

Page 90: Android testing

DEPENDENCY INVERSION

@tonilopezmr

Page 91: Android testing

NOS PERMITE REMPLAZAR NUESTRO CÓDIGO DE PRODUCCIÓN POR NUESTRO TEST DOUBLE QUE NECESITEMOS

@tonilopezmr@tonilopezmr@tonilopezmr

Page 92: Android testing

SCOPE

@tonilopezmr

ELEGIR EL

Page 93: Android testing

INTERFACES

@tonilopezmr

USO DE

Page 94: Android testing

INTERFACES

@tonilopezmr

USO DE

NO SIEMPRE

Page 95: Android testing

MUY BAJO

@tonilopezmr

NIVEL DE ACOPLAMIENTO

Page 96: Android testing

CONSTRUCTOR

@tonilopezmr

DEPENDENCIAS POR

Page 97: Android testing

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

Page 98: Android testing

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

Page 99: Android testing

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

Page 100: Android testing

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

Page 101: Android testing

FACTORIAS

@tonilopezmr

SE PUEDE RESOLVER MEDIANTE

Page 102: Android testing

DEPENDENCY INJECTION

@tonilopezmr

Page 103: Android testing

DEPENDENCIAS

@tonilopezmr

CONFIGURACIÓN DE

Page 104: Android testing

ABSTRACCIONES

@tonilopezmr

EXTRAER DONDE SE DEPENDE DE

Page 105: Android testing

MODEL VIEW PRESENTER

@tonilopezmr

ARCHITECTURE PATTERN

Page 106: Android testing

@tonilopezmr

VIEW

PRESENTER

MODEL

presenter.cargaPersonajes

modelo.damePersonajestoma personajes

vista.dejaDeMostrarUnLoader

vista.mostrarXBotones

vista.mostrarPersonajes

Page 107: Android testing

@tonilopezmrVIEW

public interface CharacterListView {

void initUI(); void show(List<GoTCharacter> characterList); void showEmptyCase(); void hideEmptyCase(); void showProgressBar(); void hideProgressBar(); void showCharacterListError(); void showNetworkError(); }

Page 108: Android testing

@tonilopezmrPRESENTER

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; }

}

Page 109: Android testing

@tonilopezmrMODEL

BUSINESS LOGIC

Page 110: Android testing

EJEMPLO

@tonilopezmr

Page 111: Android testing

GAME OF THRONES

@tonilopezmr

Page 112: Android testing
Page 113: Android testing

LISTAR PERSONAJES LISTAR ORDENADOS POR NOMBRE PERSONAJES POR CASA AÑADIR PERSONAJES

Page 114: Android testing

VALE, VALE, SI EL MVP LO ENTIENDO, PERO…

¿CÓMO AÑADO COSAS A EL INJECTOR?

¯\_( )_/¯

@tonilopezmr

Page 115: Android testing

GO TO PRACTICE

@tonilopezmr

Page 116: Android testing

@tonilopezmr

INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA

NO TAN RÁPIDOS

Page 117: Android testing

@tonilopezmr

INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA

NO TAN RÁPIDOS

Page 118: Android testing

@tonilopezmr

INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA

NO TAN RÁPIDOS

Page 119: Android testing

@tonilopezmr

INTEGRACIÓN DE MÓDULOS MI INTEGRACIÓN CON MI API FUNCIONA

NO TAN RÁPIDOS

Page 120: Android testing

MÁS GRANDE

@tonilopezmr

SCOPE

Page 121: Android testing

API CLIENT

@tonilopezmr

Page 122: Android testing

REQUEST/RESPONSE

@tonilopezmr

HTTP

Page 123: Android testing

JSON

@tonilopezmr

PARSING

Page 124: Android testing

HEADER

@tonilopezmr

ASSERTING

Page 125: Android testing

API

@tonilopezmr

FAKE

Page 126: Android testing

SERVIDOR

@tonilopezmr

RUNTIME TEST

Page 127: Android testing

MOCKWEBSERVER

@tonilopezmr

https://github.com/square/okhttp/tree/master/mockwebserver

Page 128: Android testing

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

Page 129: Android testing

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

Page 130: Android testing

GO TO PRACTICE

@tonilopezmr

Page 131: Android testing

@tonilopezmr

FRAMEWORKS FRAGILES

END - TO -END LENTA

Page 132: Android testing

@tonilopezmr

FRAMEWORKS FRAGILES

END - TO -END LENTA

Page 133: Android testing

@tonilopezmr

FRAMEWORKS FRAGILES

END - TO -END LENTA

Page 134: Android testing

@tonilopezmr

FRAMEWORKS FRAGILES

END - TO -END LENTA

Page 135: Android testing

@tonilopezmr

FRAMEWORKS FRAGILES

END - TO -END LENTA

Page 136: Android testing

AUTOMATIC UI TESTING

@tonilopezmr@tonilopezmr@tonilopezmr

Page 137: Android testing

ESPRESSO

@tonilopezmr

Page 138: Android testing

onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion)

@tonilopezmr

Page 139: Android testing

onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion)

ViewMatcher

implement Matcher<? super View>

@tonilopezmr

Page 140: Android testing

onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion)

ViewAction

click()

@tonilopezmr

Page 141: Android testing

onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion)

ViewAssertion

assert views

@tonilopezmr

Page 142: Android testing

onView(withId(R.id.button)) .perform(click()) .check(isDisplayed())

@tonilopezmr

Page 143: Android testing

onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion)

onData(ObjectMatcher) .DataOptions .perform(ViewAction) .check(ViewAssertion)

@tonilopezmr

Page 144: Android testing

onData(ObjectMatcher) .DataOptions .perform(ViewAction) .check(ViewAssertion)

ObjectMatcher

implement Matcher<? super Object>

@tonilopezmr

Page 145: Android testing

onData(ObjectMatcher) .DataOptions .perform(ViewAction) .check(ViewAssertion)

DataOptions

AdapterView, GridView

@tonilopezmr

Page 146: Android testing

@tonilopezmr

Page 147: Android testing

@tonilopezmr

Page 148: Android testing

@tonilopezmr

Page 149: Android testing

GO TO PRACTICE

@tonilopezmr