O slideshow foi denunciado.
Seu SlideShare está sendo baixado. ×

Android: testes automatizados e TDD

Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Próximos SlideShares
Testes: Por onde Começar?
Testes: Por onde Começar?
Carregando em…3
×

Confira estes a seguir

1 de 47 Anúncio

Mais Conteúdo rRelacionado

Diapositivos para si (19)

Semelhante a Android: testes automatizados e TDD (20)

Anúncio

Mais de Dextra (20)

Mais recentes (20)

Anúncio

Android: testes automatizados e TDD

  1. 1. Android: Testes Automatizados e TDD Ivan de Aguirre @IvAguirre ivan.aguirre@dextra-sw.com
  2. 2. Agenda • Conceitos e Terminologia. • Overview do Framework de testes. • O que testar? • TDD
  3. 3. Conceitos e Terminologia
  4. 4. Teste Unitário • • • • • • Teste isolado de uma unidade do software. Unidade precisa ser testável. Uso de mocks, stubs e fakes. Execução rápida. Teste Unitário Clássico: unidade = classe. TDD: unidade = comportamento.
  5. 5. Teste Unitário • • • • • • Teste isolado de uma unidade do software. Unidade precisa ser testável. Uso de mocks, stubs e fakes. Execução rápida. Teste Unitário Clássico: unidade = classe. TDD: unidade = comportamento. You can't have unit tests if you don't have units. @CompSciFact
  6. 6. • • • • • • Teste de API Testes de endpoint. Sistema integrado. Asserções são mais difíceis. Testes mais difíceis de manter. Execução mais lenta. Ex.: método de uma classe de serviço, chamada à um webservice.
  7. 7. Teste Funcional • Black Box. • Execução manual. • É o que o tester faz.
  8. 8. • • • Teste de UI Simula uma execução de teste funcional. Difíceis de manter. Execução lenta.
  9. 9. Testes Automatizados • Integrados à build contínua. • Feedback constante. • Todos os testes devem estar passando sempre. Não elimina a necessidade de testes manuais.
  10. 10. Afinal, o que esperamos ao escrever testes?
  11. 11. Afinal, o que esperamos ao escrever testes? Feedback
  12. 12. Afinal, o que esperamos ao escrever testes? Feedback Qualidade
  13. 13. Afinal, o que esperamos ao escrever testes? Feedback Evitar bugs Qualidade
  14. 14. Afinal, o que esperamos ao escrever testes? Feedback Evitar bugs Qualidade Agilidade
  15. 15. Afinal, o que esperamos ao escrever testes? Feedback Qualidade Confiança Evitar bugs Agilidade
  16. 16. Framework
  17. 17. Testes Unitários • Classe base: AndroidTestCase • Especializações: o ApplicationTestCase o LoaderTestCase o ServiceTestCase o ProviderTestCase2
  18. 18. public class AppProviderTestCase extends ProviderTestCase2<DataProvider> { private MockContentResolver mMockResolver; public AppProviderTestCase() { super(DataProvider.class, Question.AUTHORITY); } @Override protected void setUp() throws Exception { super.setUp(); mMockResolver = getMockContentResolver(); }
  19. 19. public void testInsertAndRetrieveQuestions2() { Question q = new Question(1L, "Concorda ?"); q.addRecord(getMockContext()); Cursor c = mMockResolver.query( Question.CONTENT_URI, null, null, null, null); Question retrieved = new Question(c); assertEquals(1, c.getCount()); assertEquals(q.getId(), retrieved.getId()); assertEquals(q.getQuestionText(), retrieved.getQuestionText()); }
  20. 20. Testes com Instrumentação • Classe base: InstrumentationTestCase • Especializações: o ActivityTestCase § ActivityUnitTestCase (onCreate). § ActivityInstrumentationTestCase2 (ciclo completo).
  21. 21. public class QuestionActivityTestCase extends ActivityUnitTestCase<QuestionActivity> { ... public void testIntent() { Intent intent = new Intent(); String question = "Pergunta !!!"; intent.putExtra(Question.Columns.QUESTIONTEXT, question); Activity activity = startActivity(intent, null, null); TextView view = (TextView) activity.findViewById( R.id.question_text); assertEquals(question, view.getText()); } }
  22. 22. public class MainActivityTestCase extends ActivityInstrumentationTestCase2<MainActivity> { public MainActivityTestCase() { super(MainActivity.class); } public void testMainStarts() { assertNotNull("Activity nao foi criada!", getActivity()); } }
  23. 23. Instrumentation in = getInstrumentation(); Ao trabalhar com eventos (click, touch, etc..) cuidado com atrasos da Thread de UI.
  24. 24. • • Testes de UI uiautomatorview (android_sdk/tools): detecta Views acessíveis pelo automator e "NAF" nodes. uiautomator: o http://developer.android.com/tools/help/uiautomator/ index.html android:contentDescriptor: ImageButton, ImageView, CheckBox. o android:hint: EditText. o
  25. 25. Que testes escrever?
  26. 26. O que disse Kent Beck?
  27. 27. I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence (I suspect this level of confidence is high compared to industry standards, but that could just be hubris). If I don't typically make a kind of mistake (like setting the wrong variables in a constructor), I don't test for it. I do tend to make sense of test errors, so I'm extra careful when I have logic with complicated conditionals. When coding on a team, I modify my strategy to carefully test code that we, collectively, tend to get wrong.
  28. 28. Different people will have different testing strategies based on this philosophy, but that seems reasonable to me given the immature state of understanding of how tests can best fit into the inner loop of coding. Ten or twenty years from now we'll likely have a more universal theory of which tests to write, which tests not to write, and how to tell the difference. In the meantime, experimentation seems in order.
  29. 29. Android Facts
  30. 30. Android Facts • • • • • • Receitas de bolo ("boilerplate code"). Emulador é uma beleza. Só que não... Certas classes do framework são difíceis de mockar. Sistema externo pode complicar os testes. Asserções “visuais“ são díficeis de automatizar. Mesmo testes unitários demoram pra executar.
  31. 31. Então: que testes escrever? • • • Você não precisa testar a API do Android. Se necessário crie unidades testáveis fora dos componentes Android e isole o boilerplate code. Difícil de testar de forma automatizada: execução assíncrona, layouts, dependência de sistema remoto, dependência de outras aplicações, boilerplate code, reação à "condições adversas", etc.
  32. 32. Dicas • Classes difíceis de mockar: crie um wrapper. • Content Providers são fáceis de testar. • Testes funcionais automatizados podem ser difíceis de manter. • Testes difíceis de escrever ou de manter podem indicar um problema de design. • Instrumentação no lugar de testes de UI automatizados.
  33. 33. Dicas • Testes de sanidade ajudam a evitar erros. Ex.: apenas iniciar uma Activity. • É possível testar execução "assíncrona" de • forma unitária, por ex.: https:// android.googlesource.com/platform/ frameworks/base/+/master/test-runner/src/ android/test/LoaderTestCase.java Teste de Stress com Monkey:http:// developer.android.com/tools/help/ monkey.html
  34. 34. Exemplo: Sincronização Authenticator.java AuthenticatorService.java SyncAdapter.java SyncService.java authenticator.xml syncadapter.xml
  35. 35. public class SyncAdapter extends AbstractThreadedSyncAdapter{ ... @Override public void onPerformSync(...) { Código que faz a Sincronização } }
  36. 36. public class SyncAdapter extends AbstractThreadedSyncAdapter{ ... @Override public void onPerformSync(...) { Código que faz a Sincronização } } SyncAdapter é difícil de testar com testes unitários!!
  37. 37. public class SyncAdapter extends AbstractThreadedSyncAdapter{ ... @Override public void onPerformSync(...) { } }
  38. 38. public class SyncAdapter extends AbstractThreadedSyncAdapter{ ... @Override public void onPerformSync(...) { new QuestionSync(getContext()) .doSync(); } }
  39. 39. public class SyncAdapter extends AbstractThreadedSyncAdapter{ é uma QuestionSync classe Java comum. É ... mais fácil testá-la!! @Override public void onPerformSync(...) { new QuestionSync(getContext()) .doSync(); } }
  40. 40. public class QuestionSyncTest extends ProviderTestCase2<DataProvider> { ... public void testReceiveOneQuestionWhenDataBaseIsEmpty() { Cursor c = mMockResolver.query(Question.CONTENT_URI, null, null, null, null); assertEquals(0, c.getCount()); String json = "[{"id":1, "question": "nova pergunta"}]"; getSyncForWebServicesReturn(json).doSync(); c = mMockResolver.query(Question.CONTENT_URI, null, null, null, null); assertEquals(1, c.getCount()); } }
  41. 41. private QuestionSync getSyncForWebServicesReturn( final String wsReturn) { final QuestionRemoteRepository mock = new QuestionRemoteRepository() { @Override protected String fetchAll() { return wsReturn; } }; return new QuestionSync(getMockContext()) { @Override public void doSync() { this.questionsRepository = mock; super.doSync(); } };
  42. 42. http://robolectric.org/ http://code.google.com/p/android-test-kit/ http://code.google.com/p/robotium/ http://bitbar.com/
  43. 43. TDD
  44. 44. while (true) { Adicione um novo teste. Faça o teste compilar. Execute o teste: vai falhar !! Implemente da forma mais simples possível para o teste passar. Refatore e mantenha os testes verdes. }
  45. 45. TDD - Sugestão de Workflow • Execução dos testes é muito lenta para TDD de fato. • Crie unidades com TDD (ou algo parecido com isso). • Depois de alguma iterações adicione componentes Android.
  46. 46. Perguntas?
  47. 47. Muito Obrigado! Ivan de Aguirre @IvAguirre ivan.aguirre@dextra-sw.com

×