Testeas o k ase??

46
@Guardiola31337 - pguardiola.com Pablo Guardiola Testeas o k ase??

description

Slides usadas en la charla Testeas o k ase?? del Codemotion Spain 2013. En la sesión se pretende explicar la importancia del testing en dispositivos móviles, así como animar a los desarrolladores a que implementen tests unitarios en sus aplicaciones, concretamente usando el framework Robolectric para Android. Se explicará el funcionamiento de la herramienta, mostrando por qué es tan potente junto con las posibilidades que nos ofrece y, finalmente, se enseñará un ejemplo práctico detallando lo fácil que es tanto configurarlo como empezar a escribir tests.

Transcript of Testeas o k ase??

Page 1: Testeas o k ase??

@Guardiola31337 - pguardiola.com

Pablo GuardiolaTesteas o k ase??

Page 2: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaAgenda

‣ Importancia del testing sobre dispositivos móviles

‣ Robolectric

‣ Demo

Page 3: Testeas o k ase??

‣ Número de apps Android en el market: 866033‣ Porcentaje de apps de baja calidad: 23 %

@Guardiola31337 - pguardiola.comPablo GuardiolaNumerosas apps en los markets = Competencia brutal

Page 4: Testeas o k ase??

‣ Porcentaje de apps con menos de 3 ratings: 43.9 %‣ Porcentaje de apps entre 0 y 4 estrellas: 65.22 %

@Guardiola31337 - pguardiola.comPablo GuardiolaNumerosas apps en los markets = Competencia brutal

Page 5: Testeas o k ase??

‣ No cabrees a tus usuarios

@Guardiola31337 - pguardiola.comPablo Guardiola¿El código hace exactamente lo que quieres?

Page 6: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿El código hace exactamente lo que quieres?

Page 7: Testeas o k ase??

‣ Testing manual = mucho tiempo

@Guardiola31337 -pguardiola.comPablo Guardiola¿Podemos reducir el tiempo dedicado a testing usando tests automáticos?

Page 8: Testeas o k ase??

‣ Testing automático

@Guardiola31337 - pguardiola.comPablo Guardiola¿Podemos reducir el tiempo dedicado a testing usando tests automáticos?

Page 9: Testeas o k ase??

‣ ¡Cuidado con las actualizaciones!

@Guardiola31337 -pguardiola.comPablo GuardiolaVivimos en un mundo ágil

Page 10: Testeas o k ase??

@Guardiola31337 -pguardiola.comPablo GuardiolaTesteas o k ase??

Page 11: Testeas o k ase??

‣ Incrementa el nivel de confianza que se tiene del código

‣ Hacer testing “obliga” a escribir código modular

‣ Se desarrolla un producto de calidad

@Guardiola31337 - pguardiola.comPablo GuardiolaVentajas de hacer testing

Page 12: Testeas o k ase??

‣ Go, go, go!

@Guardiola31337 - pguardiola.comPablo GuardiolaAndroid testing

Page 13: Testeas o k ase??

‣ JUnit

@Guardiola31337 - pguardiola.comPablo GuardiolaAndroid testing

‣ Los métodos de android.jar devuelven Stub!

Page 14: Testeas o k ase??

‣ Android testing framework

@Guardiola31337 - pguardiola.comPablo GuardiolaOtras opciones

‣ Tests deben ejecutarse en un terminal o emulador

Page 15: Testeas o k ase??

‣ Separar código Java y Android

‣ POJO’s

‣ Tests instrumentales

‣ Mocking framework

‣ ¡¡¡NO HACER!!!

@Guardiola31337 - pguardiola.comPablo GuardiolaOtras opciones

Page 16: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaOtras opciones

‣ Entonces, ¿qué?

Page 17: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Por qué usar Robolectric?

‣ Es rápido

‣ Interacción con las clases de Android

‣ Incluye HTTP/API testing

‣ Permite invocar métodos privados

‣ Muy fácil de integrar con otros frameworks

Page 18: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaAdemás, Robolectric te permite...

‣ Usar JUnit 4

‣ Iteraciones rápidas

‣ Permite aplicar TDD en el desarrollo

‣ Verificar la lógica y el comportamiento frente a la implementación

Page 19: Testeas o k ase??

‣ Shadows

@Guardiola31337 - pguardiola.comPablo Guardiola¿Cómo funciona?

Page 20: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Cómo funciona?

Page 21: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Cómo funciona?

Page 22: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Cómo funciona?

‣Robolectric actúa como un proxy

Page 23: Testeas o k ase??

‣ Se debe indicar con una anotación qué clase es la encargada de realizar el test

@Guardiola31337 - pguardiola.comPablo GuardiolaShow me the code!

@RunWith(RobolectricTestRunner.class) // <== REQUIRED for Robolectric!public class HomeActivityTest { @Test public void shouldHaveAButtonThatSaysPressMe() throws Exception { // test code here }}

Page 24: Testeas o k ase??

‣ En ocasiones Robolectric está oculto...

@Guardiola31337 - pguardiola.comPablo GuardiolaShow me the code!

@RunWith(RobolectricTestRunner.class)public class HomeActivityTest { @Test public void shouldHaveHappySmiles() throws Exception { String appName = new MyActivity() .getResources().getString(R.string.app_name); assertThat(appName, equalTo("SampleRobolectric")); }}

‣ ¡Escondido! Pero haciendo su trabajo \o/

Page 25: Testeas o k ase??

‣ Métodos para acceder al estado de los objetos Android

@Guardiola31337 - pguardiola.comPablo GuardiolaShadows

<ImageView android:id="@+id/pivotal_logo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:src="@drawable/pivotallabs_logo" android:layout_marginBottom="10dip" > @Testpublic void shouldHaveALogo() throws Exception { ImageView pivotalLogo = (ImageView)activity.findViewById(R.id.pivotal_logo); ShadowImageView shadowPivotalLogo = Robolectric.shadowOf(pivotalLogo); assertThat(shadowPivotalLogo.resourceId, equalTo(R.drawable.pivotallabs_logo));}

‣Acceso a estado y variables, de otro modo sería imposible

Page 26: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaHTTP testing

@RunWith(RobolectricTestRunner.class)public class HttpTest { @Test public void testGet_FormsCorrectRequest_noBasicAuth() throws Exception { Robolectric.addPendingHttpResponse(200, "OK"); new Http().get("www.codemotion.es",            Maps.<String, String>newHashMap(),            null,            null); assertThat(((HttpUriRequest) Robolectric.getSentHttpRequest(0)).getURI(),            equalTo(URI.create("www.codemotion.es"))); }}

Page 27: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaHTTP testing

‣ Robolectric hace de mock server, necesita saber cómo responder a la llamada para evitar RuntimeException

‣ Respuesta por defecto compartida

Robolectric.addPendingHttpResponse(200, "OK");

@RunWith(RobolectricTestRunner.class)public class HttpTest { @Before public void setup() { Robolectric.addPendingHttpResponse(200, "OK"); } ...}

Page 28: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaHTTP testing

‣ Otros ejemplos

@Test public void shouldReturnCorrectResponse() throws Exception { Robolectric .addPendingHttpResponse(666, "it's all cool"); Http.Response response = http.get("www.example.com", new HashMap<String, String>(), null, null);    assertThat(fromStream(response.getResponseBody()), equalTo("it's all cool"));    assertThat(response.getStatusCode(), equalTo(666)); }}

‣ Métodos correctos, cabeceras...

Page 29: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaExtendiendo Robolectric

‣ Robolectric no tiene funcionalidad para todo‣ Robolectric permite extender las clases Shadow

@[email protected]()__constructo__@RealObject

Page 30: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaInconvenientes

‣ No hay clases Shadow para todo‣ No todo se comporta del mismo modo que en la DVM‣ Android no es Java

Page 31: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Por qué no usar directamente el código Android?

‣ Difícil conseguir los .jar reales‣ Difícil trabajar con código nativo‣ Difícil dejar de usar las clases Shadow

Page 32: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

2.0

Page 33: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ Uso del SDK de Android

‣ No más excepciones Stub!

‣ Objetivo eliminar el 99% de las clases Shadow

Page 34: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ El paquete de soporte no usa clases Shadow

‣ Fragments, action bar, loaders usan su implementación real

‣ Tests tendrán mismo comportamiento que en los dispositivos

Page 35: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ Se pueden testear estilos y temas

‣ Acceso a los recursos del sistema

‣ Soporte ActionBarSherlock

‣ Mejoras de rendimiento y corrección de bugs

Page 36: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ Testing bajo diferentes configuraciones del dispositivo

@Test @Config("en")public void shouldGiveEnglishResponses() throws Exception { assertThat(activity.findViewById(R.id.message)) .hasText("Hello!"); }}

@Test @Config("fr")public void shouldGiveFrenchResponses throws Exception { assertThat(activity.findViewById(R.id.message)) .hasText("Bonjour!"); }}

Page 37: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ ActivityController mayor control sobre el ciclo de vida

FooActivity foo = Robolectric.buildActivity(FooActivity.class)        .create().start().resume().get();

ActivityController<FooActivity> fooController = Robolectric.buildActivity(FooActivity.class).create();FooActivity foo = fooController.get();// Ensure the user was injected.assertThat(foo.user).isNotNull();// Log the user out.foo.user.expireSession();fooController.start().resume();// Ensure the activity is now finishing.assertThat(foo).isFinishing();

Page 38: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaRobolectric 2.0

‣ El uso del SDK de Android está aumentando considerablemente

‣ Todo el mundo puede contribuir:

‣ https://github.com/robolectric/robolectric‣ http://robolectric.org/‣ http://robolectric.blogspot.com.es/

Page 39: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

Project name: SampleRobolectricPackage name: com.pguardiola.samplerobolectric

Activity name: MyActivityAdd Framework Support -> Maven

Page 40: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

<groupId>com.pguardiola.samplerobolectric</groupId> <artifactId>SampleRobolectric</artifactId> <version>1.0-SNAPSHOT</version> <packaging>apk</packaging> <name>My Sample App</name>

<dependencies> <dependency> <groupId>com.google.android</groupId> <artifactId>android</artifactId> <version>4.1.1.4</version> <scope>provided</scope> </dependency>

<!-- Make sure this is below the android dependencies --> <dependency> <groupId>org.robolectric</groupId> <artifactId>robolectric</artifactId> <version>2.1.1</version> <scope>test</scope> </dependency>

Page 41: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies>

<build> <finalName>${project.artifactId}</finalName>

<plugins> <plugin> <groupId>com.jayway.maven.plugins.android.generation2</groupId> <artifactId>android-maven-plugin</artifactId> <version>3.6.1</version> <configuration> <sdk> <!-- platform or api level (api level 16 = platform 4.1)--> <platform>18</platform> </sdk> <undeployBeforeDeploy>true</undeployBeforeDeploy> </configuration> <extensions>true</extensions> </plugin> </plugins> </build>

Page 42: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

‣ Alt+Enter -> Create Test -> JUnit4

@RunWith(RobolectricTestRunner.class)public class MyActivityTest { @Test public void shouldHaveHappySmiles() throws Exception { String appName = new MyActivity().getResources() .getString(R.string.app_name); assertThat(appName, equalTo("SampleRobolectric")); }}

Page 43: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

‣ Imports

import org.junit.Test;import org.junit.runner.RunWith;import org.robolectric.RobolectricTestRunner;import static org.hamcrest.CoreMatchers.equalTo;

import static org.junit.Assert.assertThat;

Page 44: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaDemo

Run -> MyActivityTest

MyActivityTest fails

SampleRobolectric pass

Page 45: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo Guardiola¿Preguntas?

Page 46: Testeas o k ase??

@Guardiola31337 - pguardiola.comPablo GuardiolaGracias

Happy testing!!Pablo Guardiola

@Guardiola31337