Unit Testing Android Apps

7fd4ba468da56bb5330a6352c1b54f52?s=47 felipecsl
August 23, 2014

Unit Testing Android Apps

7fd4ba468da56bb5330a6352c1b54f52?s=128

felipecsl

August 23, 2014
Tweet

Transcript

  1. Unit Testing Android Apps

  2. @felipecsl Unit Testing Android Apps

  3. None
  4. 8MM+ downloads 210k reviews 4.5 ★ average rating

  5. Android app 2 developers

  6. Android não foi desenhado com testabilidade em mente.

  7. None
  8. 2. Técnicas 3. Ferramentas 1. Motivação

  9. 1. Motivação

  10. Você ainda não está convencido do valor de escrever testes

    automatizados. Premissa
  11. Tranquilidade: Consigo dormir à noite?

  12. Maintainability: Consigo alterar o código facilmente?

  13. O que causa Débito Técnico? The three sins of software

    development: http://blog.ionelmc.ro/2014/08/14/the-three-sins-of-software-development/
  14. Medo “Melhor não mexer nesse código…"

  15. Arrogância “Eu sei o que estou fazendo!”

  16. Estimativas irreais “Isso é barbada.”

  17. Não se trata de encontrar bugs

  18. TDD é um processo de design

  19. Código bem desenhado é facilmente testável

  20. S.O.L.I.D.

  21. http://www.agileapps.co.uk/methodology/continuous.html Red, Green, Refactor

  22. #isTDDdead http://martinfowler.com/articles/is-tdd-dead/ http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html http://blog.8thlight.com/uncle-bob/2014/04/25/MonogamousTDD.html

  23. 2. Técnicas

  24. http://martinfowler.com/bliki/TestPyramid.html

  25. http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/

  26. 3. Ferramentas

  27. Testes Unitários

  28. None
  29. build.gradle http://gradleplease.appspot.com/ Gradle, please

  30. build.gradle buildscript { repositories { mavenCentral() } dependencies { classpath

    'org.robolectric:robolectric-gradle-plugin:0.12.0' } } apply plugin: 'robolectric'
  31. build.gradle android { defaultConfig { // optional testInstrumentationRunner "com.example.MyAppTestRunner" }

    robolectric { include '**/*Test.class' } // optional sourceSets { androidTest { setRoot('src/test') } } }
  32. build.gradle dependencies { compile 'com.android.support:appcompat-v7:20.0.0' // other dev dependencies... androidTestCompile

    'junit:junit:4.10' androidTestCompile 'org.robolectric:robolectric:2.4-SNAPSHOT' androidTestCompile 'org.mockito:mockito-core:1.9.5' androidTestCompile 'org.hamcrest:hamcrest-library:1.3' }
  33. JUnit + Hamcrest @Config(emulateSdk = 18) @RunWith(MyTestRunner.class) public class UserTest

    { private User user; @Before public void setUp() { user = new User(); user.setId(3); } @Test public void userShouldPersistFields() { assertFalse(user.isPublicAccount()); assertThat(user.getId(), equalTo(3)); } }
  34. Robolectric Shadow Objects

  35. Robolectric @RunWith(RobolectricTestRunner.class) @Test public 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)); }
  36. Mockito @Before public void setUp() { HttpClient httpClient = mock(httpClient.class);

    ApiEndpoint endpoint = new ApiEndpoint(httpClient); } @Test public void userShouldPersistFields() { when(httpClient.get("/users/2")).thenReturn(new User()); endpoint.getUser(2); verify(httpClient).get("/users/2"); }
  37. http://www.confreaks.com/videos/659-rubyconf2011-why-you-don-t-get-mock-objects Assert on messages, not state. Mocks

  38. Rodando testes ./gradlew test

  39. Rodando uma classe de teste apenas ./gradlew test --tests \

    com.example.test.SomeClassTests
  40. Bonus points: AssertJ Android assertThat(view).isGone(); assertThat(layout).isVisible() .isVertical() .hasChildCount(4) .hasShowDividers(SHOW_DIVIDERS_MIDDLE); https://github.com/square/assertj-android

  41. Testes Funcionais

  42. Ferramentas

  43. Feature: Rating a stand Scenario: Find and rate a stand

    from the list Given I am on the foodstand list Then I should see a "rating" button Then I should not see "Dixie Burger & Gumbo Soup" When I touch the "rating" button Then I should see "Dixie Burger & Gumbo Soup" When I touch "Dixie Burger & Gumbo Soup" Then I should see details for "Dixie Burger & Gumbo Soup" When I touch the "rate_it" button Then I should see the rating panel When I touch "star5" And I touch "rate" Then "Dixie Burger & Gumbo Soup" should be rated 5 stars
  44. Espresso Ferramentas

  45. Integração Contínua

  46. None
  47. None
  48. Test Cloud

  49. Obrigado! @felipecsl http://felipecsl.com