Testes: Por onde Começar?

Post on 10-Feb-2017

167 views 0 download

Transcript of Testes: Por onde Começar?

Testes: Por onde Começar?

Eduardo Carrara@DuCarrara

Por que criar testesAutomatizados?

Encontre a motivação certa para fazê-lo!Eliminar a parte chata do trabalhoQualidade de Vida do Time \o/Medo de mexer no código?Refatorar nem pensar?

Em momentos diferentes...Projetos Novos (do zero)Projetos Antigos (legados)Adicionando Novas FuncionalidadesDando Manutenção ao Código

Todos estamos

então...

Por onde começar?

Comece PequenoTestes Unitários Rulez!

Seu primeiro Teste UnitárioInclua as dependênciasCrie os testesRode os Testes

Inclua as Dependências

dependencies { testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-integration:1.3'}

Crie o Teste

public class UtilityTest {

private static final String inputDateString = "20150403";

@Test public void testIfGetFormattedMonthDayReturnExpectedFormat() throws Exception { final String expectedDateFormat = "yyyy, MMMM dd"; final String expectedResult = (new SimpleDateFormat(expectedDateFormat)) .format(getExpectedDate()); String result = Utility.getFormattedMonthDay(expectedDateFormat, inputDateString); //Hamcrest assertThat("Date was not correctly formatted.", result, is(expectedResult)); //JUnit Puro assertEquals("Date was not correctly formatted.", expectedResult, result); }}

Local: <caminho para seu projeto>/app/src/test/java

Rode o Teste

Rode o Teste

/build/reports/tests

Dicas para criar seus Testes Unitários#1 Foque em partes pequenas e independentes do código#2 Cuidado com as Dependências#3 Priorize partes críticas do sistema#4 Extraia, Teste e Refatore

#2 Cuidado com as DependênciasOutras unidades de códigoFrameworks e APIs de terceirosExternas como conexão, componentes de hardware etcAndroid

MockingObjetos dublêsControle sobre o Comportamento e EstadoIsolamento da Unidade a ser Testada

MockitoAPI fácil de entenderConfiguração de comportamentos e StubsPermite a verificação de comportamentos

Mockito: Dependência

dependencies { testCompile 'org.mockito:mockito-core:2.+'}

Mockito: Verificação de Comportamento

@RunWith(MockitoJUnitRunner.class)public class ThreadExecutorTest {

private Executor executor;

@Before public void setUp() throws Exception { this.executor = new ThreadExecutor(); }

@Test public void testSuccessfulInteractorExecution() { Interactor interactor = mock(Interactor.class); this.executor.execute(interactor); verify(interactor).operation(); }}

Local: <caminho para seu projeto>/app/src/test/java

Mockito: Stub de Estado@RunWith(RobolectricGradleTestRunner.class)@Config(constants = BuildConfig.class)public class BookBorrowingContentProviderMapperTest {

@Before public void prepareTest() { this.bookBorrowingContentProviderMapper = new BookBorrowingContentProviderMapper(); }

@Test public void testTransformEmptyCursorToBookBorrowing() throws Exception { Cursor cursor = mock(Cursor.class); when(cursor.moveToFirst()).thenReturn(false);

List<BookBorrowing> bookBorrowings = this.bookBorrowingContentProviderMapper.transform(cursor);

assertThat(bookBorrowings, is(empty())); }}

Local: <caminho para seu projeto>/app/src/test/java

RobolectricTestes que dependem do Android na JVMProvê mocks e stubs ao Android SDKExecução mais rápida de testesDemora para disponibilizar versões mais recentes do SDK

Robolectric: Dependência

dependencies { testCompile 'org.robolectric:robolectric:3.0'}

Uso do Robolectric@RunWith(RobolectricGradleTestRunner.class)@Config(constants = BuildConfig.class)public class BookBorrowingContentProviderMapperTest {

@Before public void prepareTest() { this.bookBorrowingContentProviderMapper = new BookBorrowingContentProviderMapper(); }

@Test public void testTransformEmptyCursorToBookBorrowing() throws Exception { Cursor cursor = mock(Cursor.class); when(cursor.moveToFirst()).thenReturn(false);

List<BookBorrowing> bookBorrowings = this.bookBorrowingContentProviderMapper.transform(cursor);

assertThat(bookBorrowings, is(empty())); }}

Local: <caminho para seu projeto>/app/src/test/java

Android Testing Support LibraryFerramentas específicas para testes de componentes AndroidAndroidJUnitRunner + JUnit4 Rules + Espresso + UIAutomatorMuito focado em testes de Interface do UsuárioEm geral compatível com Api Level 8 ou superiorUIAutomator é compatível com Api Level 18 ou superior

ATSL: Dependências

android { defaultConfig{ testInstrumentationRunner ”android.support.test.runner.AndroidJUnitRunner” }}

dependencies { androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support.test:rules:0.5' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'}

ATSL: Espresso@RunWith(AndroidJUnit4.class)public class TestEmptyLoanedBooksList {

private Context context;

@Rule public ActivityTestRule<BookListActivity> activityRule = new ActivityTestRule<>(BookListActivity.class);

@Before public void setUp() { this.context = getTargetContext(); clearTestData(); }

@Test public void simpleTestEmptyStateOfLoanedBooksList() { onView(withId(R.id.loaned_book_list_view)).check(matches(not(isDisplayed()))); onView(withId(R.id.empty_book_list_icon)).check(matches(isDisplayed())); }}

Local: <caminho para seu projeto>/app/src/androidTest/java

AS 2.2 Preview 4: Espresso Recorder

AS 2.2 Preview 4: Espresso Recorder

AS 2.2 P4 Espresso RecorderÉ um pouco lento para capturar os eventosBastante prático para criar asserçõesAinda não lida com transições e loading entre Activities/FragmentsBom para gerar o código inicial do teste de UI

Pensamentos FinaisAutomatizar testes é algo muito complexoTenha paciência e comece pequenoOs testes unitários são a base de uma boa suite de testesPratique!

“… if you are afraid to change something it is

clearly poorly designed.”- Martin Fowler

Eduardo Carrara

@DuCarrara

Obrigado!

github.com/ecarrara-araujo