Um teste local é executado diretamente na sua própria estação de trabalho, em vez de um teste do Android dispositivo ou emulador. Assim, ele usa a máquina virtual Java (JVM) local, em vez de um dispositivo Android para executar testes. Os testes locais permitem avaliar a lógica do seu app mais rapidamente. No entanto, não poder interagir com o O framework do Android cria uma limitação nos tipos de testes que podem ser executados.
Um teste de unidade verifica o comportamento de uma pequena seção de código, a unidade teste. Isso é feito executando esse código e verificando o resultado.
Os testes de unidade geralmente são simples, mas sua configuração pode ser problemática quando a unidade em teste não foi projetado pensando na capacidade de teste:
- O código que você quer verificar precisa estar acessível em um teste. Para exemplo, não é possível testar um método particular diretamente. Em vez disso, você testa a classe usando as APIs públicas dele.
- Para executar testes de unidade em isolamento, as dependências da unidade em testes precisam ser substituídos por componentes que você controla, como falsos ou outros duplos de teste. Isso é especialmente problemático se seu código depende framework do Android.
Para saber mais sobre estratégias comuns de teste de unidade no Android, leia O que fazer teste.
Local dos testes locais
Por padrão, os arquivos de origem para testes de unidade locais são colocados em
module-name/src/test/
: Esse diretório já existe quando você cria um novo diretório
projeto usando o Android Studio.
Adicionar dependências de teste
Você também precisa configurar as dependências de teste para que o projeto use o APIs padrão fornecidas pelo framework de testes JUnit (em inglês).
Para fazer isso, abra o arquivo build.gradle
do módulo do app e especifique o seguinte:
bibliotecas como dependências. Use a função testImplementation
para indicar
que elas se aplicam ao conjunto de origem do teste local, e não ao aplicativo:
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
Criar uma classe de teste de unidade local
Crie a classe de teste de unidade local como uma classe de teste JUnit 4.
Para isso, crie uma classe que contenha um ou mais métodos de teste, normalmente em
module-name/src/test/
: Um método de teste começa com a anotação @Test
e
contém o código para exercitar e verificar um único aspecto do componente que
que você quer testar.
O exemplo a seguir demonstra como implementar uma classe de teste de unidade local. A
o método de teste emailValidator_correctEmailSimple_returnsTrue()
tenta verificar
isValidEmail()
,que é um método no app. A função de teste vai retornar
true se isValidEmail()
também retornar verdadeiro.
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
Java
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
Crie testes legíveis que avaliem se os componentes do
app retornem os resultados esperados. Recomendamos que você use uma biblioteca de declarações como
junit.Assert, Hamcrest ou
Verdade. O snippet acima é um exemplo de como usar
junit.Assert
:
Biblioteca Mockable do Android
Quando você executa testes de unidade locais, o plug-in do Android para Gradle inclui uma que contém todas as APIs do framework do Android, de acordo com a versão usada no seu projeto. A biblioteca contém todos os métodos públicos e dessas APIs, mas o código dentro dos métodos foi removido. Se houver dos métodos forem acessados, o teste vai gerar uma exceção.
Isso permite que testes locais sejam criados ao referenciar classes no ambiente
framework, como Context
. Mais importante ainda, permite que você use uma simulação
com classes do Android.
Simular dependências do Android
Um problema típico é descobrir se uma classe está usando um recurso de string. Você pode
acesse recursos de string chamando o método getString()
no Context
. No entanto, um teste local não pode usar Context
ou qualquer um dos métodos porque
que pertencem ao framework do Android. O ideal é chamar getString()
saíram da aula, mas isso nem sempre é prático. A solução é
criar uma simulação ou um stub de Context
que sempre retorne o mesmo valor quando a
O método getString()
é invocado.
Com a biblioteca Mockable do Android e estruturas simuladas, como Mockito ou MockK, você pode programar os comportamento das simulações das classes do Android nos seus testes de unidade.
Para adicionar um objeto simulado ao teste de unidade local usando o Mockito, siga este modelo de programação:
- Inclua a dependência da biblioteca Mockito no seu arquivo
build.gradle
, da seguinte maneira: descrito em Configurar seu ambiente de teste. - No início da definição da classe de teste de unidade, adicione o
@RunWith(MockitoJUnitRunner.class)
. Essa anotação diz ao Executor de testes Mockito para validar se o uso do framework está correto e simplifica a inicialização dos objetos simulados. - Para criar um objeto simulado para uma dependência do Android, adicione a anotação
@Mock
. antes da declaração do campo. - Para fragmentar o comportamento da dependência, especifique uma condição e
o valor retornado quando a condição é atendida usando
when()
ethenReturn()
. métodos.
O exemplo a seguir mostra como criar um teste de unidade que usa uma simulação
Objeto Context
em Kotlin criado com o Mockito-Kotlin.
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
Para saber mais sobre o uso do framework Mockito, consulte a API Mockito.
reference e a classe SharedPreferencesHelperTest
na
exemplo de código. Teste também o Codelab de testes do Android.
Erro: "Method ... not mocked"
A biblioteca Mockable Android gera uma exceção quando você tenta acessar qualquer um dos
métodos com a mensagem Error: "Method ... not mocked
.
Se as exceções geradas causarem problemas para seus testes, será possível alterar
comportamento de modo que os métodos retornem nulo ou zero, dependendo do
tipo de retorno. Para isso, adicione a seguinte configuração ao arquivo
arquivo build.gradle
de nível superior no Groovy:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}