Esta é uma breve introdução ao mapeamento de testes e uma explicação sobre como começar a configurar testes no Android Open Source Project (AOSP).
Sobre o mapeamento de testes
O mapeamento de testes é uma abordagem baseada em Gerrit que permite aos desenvolvedores criar pré-envio
e as regras de teste pós-envio diretamente na árvore de origem do Android e deixe a
decisões de ramificações e dispositivos a serem testados na infraestrutura de teste.
As definições de mapeamento de teste são arquivos JSON com o nome TEST_MAPPING
que podem ser
colocados em qualquer diretório de origem.
O Atest pode usar os arquivos TEST_MAPPING
para executar testes de pré-envio no
diretórios associados. Com o mapeamento de testes, é possível adicionar o mesmo conjunto de testes às
verificações de pré-envio com uma mudança mínima na árvore de origem do Android.
Confira estes exemplos:
Adicione testes de pré-envio a
TEST_MAPPING
paraservices.core
Adicione testes de pré-envio à
TEST_MAPPING
paratools/dexter
usando importações
O mapeamento de testes depende do arcabouço de testes da Trade Federation (TF) para execução de testes e relatórios de resultados.
Definir grupos de teste
Teste os grupos de mapeamento com um grupo de teste. O nome de um grupo de teste pode ser qualquer string. Por exemplo, presubmit pode ser o nome de um grupo de testes a serem executados ao validar mudanças. E postsubmit podem ser os testes usados para validar os builds depois que as alterações forem mescladas.
Regras de script de compilação do pacote
Para que o Trade Federation test harness
execute módulos de teste para um determinado build, esses módulos precisam ter um
test_suites
definido para Soong ou um LOCAL_COMPATIBILITY_SUITE
definido
para o Make em uma destas duas suítes:
general-tests
é para testes que não dependem de recursos específicos do dispositivo, como hardware específico do fornecedor que a maioria dos dispositivos não tem. A maioria dos testes precisa estar no pacotegeneral-tests
, mesmo que sejam específicos para uma ABI ou para recursos de bit ou hardware, como HWASan (há um destinotest_suites
separado para cada ABI), e mesmo que precisem ser executados em um dispositivo.device-tests
é para testes que dependem de recursos específicos do dispositivo. Normalmente, esses testes são encontrados emvendor/
. Específico do dispositivo se refere apenas a recursos que são exclusivos de um dispositivo. Portanto, isso se aplica aos testes JUnit, bem como aos testes GTest (que normalmente devem ser marcados comogeneral-tests
, mesmo que sejam específicas da ABI).
Exemplos:
Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests
Configurar testes para execução em um conjunto de testes
Para que um teste seja executado dentro de um pacote de testes, o teste:
- Não pode ter nenhum provedor de build.
- precisa limpar após a conclusão, por exemplo, excluindo qualquer elemento temporário arquivos gerados durante o teste.
- Mude as configurações do sistema para o valor padrão ou original.
Não deve presumir que um dispositivo está em um determinado estado, por exemplo, pronto para root. A maioria dos testes não exige privilégios de root para execução. Se um teste precisar de root, ele precisa especificar isso com
RootTargetPreparer
noAndroidTest.xml
, como no exemplo abaixo:<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
Criar arquivos de mapeamento de teste
Para o diretório que exige cobertura de teste, adicione um arquivo JSON TEST_MAPPING
semelhante ao exemplo. Essas regras garantem que os testes sejam executados nas
verificações antes do envio quando qualquer arquivo é tocado nesse diretório ou em qualquer um dos
subdiretórios.
Siga um exemplo
Confira um exemplo de arquivo TEST_MAPPING
(ele está no formato JSON, mas com comentários
suportados):
{
"presubmit": [
// JUnit test with options and file patterns.
{
"name": "CtsWindowManagerDeviceTestCases",
"options": [
{
"include-annotation": "android.platform.test.annotations.RequiresDevice"
}
],
"file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
},
// Device-side GTest with options.
{
"name" : "hello_world_test",
"options": [
{
"native-test-flag": "\"servicename1 servicename2\""
},
{
"native-test-timeout": "6000"
}
]
}
// Host-side GTest.
{
"name" : "net_test_avrcp",
"host" : true
}
],
"postsubmit": [
{
"name": "CtsDeqpTestCases",
"options": [
{
// Use regex in include-filter which is supported in AndroidJUnitTest
"include-filter": "dEQP-EGL.functional.color_clears.*"
}
]
}
],
"imports": [
{
"path": "frameworks/base/services/core/java/com/android/server/am"
}
]
}
Definir atributos
No exemplo, presubmit
e postsubmit
são os nomes de cada
grupo de teste. Consulte Definir grupos de teste para mais informações.
sobre grupos de teste.
Você pode definir o nome do módulo de teste ou do teste de integração da Trade Federation
name (caminho do recurso para o arquivo XML de teste, por exemplo,
uiautomator/uiautomator-demo
).
no valor do atributo name
. O campo name
não pode
usar a classe name
ou o método de teste name
. Para restringir os testes a serem executados,
use opções como include-filter
. Consulte
exemplos de uso de include-filter
.
A configuração host
de um teste indica se ele é sem dispositivo.
em execução no host ou não. O valor padrão é false
, o que significa que o teste
requer um dispositivo para funcionar. Os tipos de teste com suporte são
HostGTest
para
Binários do GTest e HostTest
para JUnit
provas.
O atributo file_patterns
permite definir uma lista de strings de expressões regulares
para corresponder ao caminho relativo de qualquer arquivo de código-fonte (relativo ao
que contém o arquivo TEST_MAPPING
). No exemplo,
O teste CtsWindowManagerDeviceTestCases
é executado no pré-envio somente quando um arquivo Java
começa com Window
ou Activity
, que existe no mesmo diretório do
TEST_MAPPING
ou qualquer um dos subdiretórios dele. As barras invertidas (\) precisam ser
escritas com escape porque estão em um arquivo JSON.
O atributo imports
permite incluir testes em outros arquivos TEST_MAPPING
sem copiar o conteúdo. Os arquivos TEST_MAPPING
nos diretórios
pai do caminho importado também são incluídos. O mapeamento de teste permite
importações aninhadas; isso significa que dois arquivos TEST_MAPPING
podem importar um ao outro, e
o mapeamento de teste
pode mesclar os testes incluídos.
O atributo options
contém opções adicionais de linha de comando do Tradefed.
Para conferir uma lista completa de opções disponíveis para um determinado teste, execute:
tradefed.sh run commandAndExit [test_module] --help
Consulte Processamento de opções no Tradefed para mais detalhes sobre como as opções funcionam.
Executar testes com o Atest
Para executar as regras de teste de pré-envio localmente:
- Acesse o diretório que contém o arquivo
TEST_MAPPING
. Execute o comando:
atest
Todos os testes pré-envio configurados nos arquivos TEST_MAPPING
do diretório
atual e nos diretórios pais são executados. O Atest localiza e executa dois testes
para pré-envio (A e B).
Essa é a maneira mais simples de executar testes de pré-envio em arquivos TEST_MAPPING
no diretório de trabalho atual (CWD, na sigla em inglês) e nos diretórios pai. O Atest
localiza e usa o arquivo TEST_MAPPING
no CWD e em todos os diretórios
pai.
Estruturar o código-fonte
Este exemplo mostra como configurar arquivos TEST_MAPPING
no
árvore de origem:
src
├── project_1
│ └── TEST_MAPPING
├── project_2
│ └── TEST_MAPPING
└── TEST_MAPPING
Conteúdo de src/TEST_MAPPING
:
{
"presubmit": [
{
"name": "A"
}
]
}
Conteúdo de src/project_1/TEST_MAPPING
:
{
"presubmit": [
{
"name": "B"
}
],
"postsubmit": [
{
"name": "C"
}
],
"other_group": [
{
"name": "X"
}
]}
Conteúdo de src/project_2/TEST_MAPPING
:
{
"presubmit": [
{
"name": "D"
}
],
"import": [
{
"path": "src/project_1"
}
]}
Especificar diretórios de destino
É possível especificar um diretório de destino para executar testes em arquivos TEST_MAPPING
nesse
diretório. O comando a seguir executa dois testes (A, B):
atest --test-mapping src/project_1
Executar regras de teste pós-envio
Você também pode usar esse comando para executar as regras de teste pós-envio definidas no
TEST_MAPPING
em src_path
(o padrão é CWD) e os diretórios pais:
atest [--test-mapping] [src_path]:postsubmit
Executar apenas testes que não exigem um dispositivo
Use a opção --host
para que o Atest execute apenas os testes configurados.
no host que não exige dispositivo. Sem essa opção, o Atest executa os dois
testes, aqueles que exigem um dispositivo e aqueles executados em um host que não exigem
um dispositivo. Os testes são executados em dois conjuntos separados:
atest [--test-mapping] --host
Identificar grupos de teste
Você pode especificar grupos de teste no comando "Atest". O comando a seguir executa
todos os testes de postsubmit
relacionados a arquivos no diretório src/project_1
, que
contém apenas um teste (C).
Ou use :all
para executar todos os testes, independentemente do grupo. O comando a seguir
executa quatro testes (A, B, C, X):
atest --test-mapping src/project_1:all
Incluir subdiretórios
Por padrão, a execução de testes em TEST_MAPPING
com o Atest executa apenas testes
de pré-envio configurados no arquivo TEST_MAPPING
no CWD (ou
diretório especificado) e nos diretórios pais. Se você quiser executar testes em todos
os arquivos TEST_MAPPING
nos subdiretórios, use a opção --include-subdir
para
forçar o Atest a incluir esses testes também.
atest --include-subdir
Sem a opção --include-subdir
, o Atest executa apenas o teste A. Com a
opção --include-subdir
, o Atest executa dois testes (A e B).
Compatível com comentário no nível da linha
Você pode adicionar um comentário no formato //
no nível da linha para detalhar o TEST_MAPPING
.
com uma descrição da configuração a seguir.
ATest e a Trade Federation
preprocessam TEST_MAPPING
para um formato JSON válido sem comentários. Para manter
o arquivo JSON limpo, apenas o comentário de formato //
no nível da linha
é aceito.
Exemplo:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}