data driven parameterized testing with spock framework
Explore as maneiras de escrever testes controlados por dados ou parametrizados com a estrutura do Spock:
Nisso Série de tutoriais de treinamento Spock grátis , nós exploramos tudo sobre Teste de Unidade em Spock e acessórios de teste, afirmações e relatórios em nosso tutorial anterior.
Neste tutorial, tentaremos entender o que são testes parametrizados e como você pode aproveitar os recursos integrados do Spock para obter testes orientados por dados.
Vamos começar!!
Assista ao tutorial em vídeo
O que você aprenderá:
- O que são testes parametrizados?
- Escrevendo testes parametrizados com Spock
- Ciclo de vida do bloco “onde”
- dicas e truques
- Conclusão
- Leitura recomendada
O que são testes parametrizados?
Para qualquer pessoa que já trabalhou com automação / testes de unidade, teste baseado em dados não é um termo novo.
Os testes parametrizados não são nada, mas são qualquer tipo de teste que compartilha a mesma lógica de execução e diferem apenas nos dados de entrada e no resultado em alguns casos.
Exemplo: Suponha que você tenha um aplicativo Calculadora, para testar a funcionalidade completamente, você pode querer executar seus testes em diferentes conjuntos de entrada.
Exemplo: Valores negativos, números fracionários, inteiros normais, inteiros próximos ao intervalo máximo permitido, etc. Não importa quais valores de entrada você tenha, você deseja executar a mesma lógica de execução.
Outro bom motivo para escrever testes parametrizados é que ele não testa apenas um caminho feliz, mas também testa o caminho de erro ou cenários negativos.
Exemplo: Suponha que haja um aplicativo que retorna se uma determinada extensão de arquivo é válida ou não. Os testes baseados em dados podem permitir que o desenvolvedor execute rapidamente testes para extensões de arquivo com suporte e quaisquer cenários de erro ou testes de entrada negativa.
Agora, tradicionalmente, você pode pensar em escrever ou copiar os testes para vários valores de entrada, mas essa não é a maneira correta ou inteligente de obter esse tipo de execução de teste. Além disso, conforme o número de testes começa a aumentar em seu aplicativo, esses testes se tornam difíceis de manter.
Escrevendo testes parametrizados com Spock
O bloco where:
O bloco where em um teste de Spock é o bloco que contém os dados para o teste parametrizado. Pode conter opcionalmente valores de entrada e saída esperados. Um ponto importante a se notar sobre este bloco é que este deve ser o último bloco em um teste de Spock.
Dito isso, ele pode ser combinado com todos os outros blocos como dado, quando e então, mas deve ser o último bloco.
Vejamos um exemplo para entender melhor
Estaremos usando um aplicativo de calculadora que usa 2 parâmetros de entrada e retorna a soma das entradas fornecidas. Estaremos escrevendo um teste parametrizado fornecendo várias entradas e valores esperados de saída.
def 'sample parameterized test'() input2
No exemplo de código acima, você pode ver o seguinte:
- Bloco “where” que contém os dados para a execução do teste.
- “Where” block é o último bloco do teste.
- 'Onde' é combinado com os outros blocos, ou seja, dado, quando e então.
- A representação de dados é um formato especial denominado tabelas de dados, que examinaremos em detalhes nas próximas seções deste tutorial.
- A linha de cabeçalho de dados é essencialmente as propriedades / variáveis de entrada que podem ser usadas diretamente no teste. Por exemplo. Consulte a declaração no bloco 'quando', onde usamos diretamente input1 e input2 como parâmetros de entrada sem defini-los explicitamente.
Usando Datatables
Vamos tentar entender as tabelas de dados em detalhes agora. Cada linha da tabela de dados representa dados para um cenário individual (execução de teste).
Por convenção, ou seja, os valores de entrada são precedidos por um único tubo (‘|’), enquanto os valores de saída são precedidos por um tubo duplo (‘||’). Isso não tem nenhum significado lógico, mas é uma convenção e melhora a legibilidade. Portanto, ambos os exemplos abaixo são verdadeiros.
input1 |input2 |expectedResult 10 |15 |25 -4 |6 |2 input1 |input2 || expectedResult 10 |15 || 25 -4 |6 || 2
A linha do cabeçalho, conforme mostrado acima, tem um nome para cada um dos parâmetros fornecidos como dados a serem testados. É importante notar aqui que esses nomes de parâmetro não devem colidir com nenhuma variável local / global existente no teste, caso contrário, haverá erros em tempo de compilação para resolver nomes de variáveis.
Um ponto importante a se observar ao usar tabelas de dados é que um mínimo de 2 colunas é necessário. Se você só precisa de uma coluna, uma coluna em branco com valores como caractere de sublinhado é uma solução alternativa como a seguir.
input1 ||_ 10 ||_ -4 ||_
A vantagem desse formato é simplicidade, legibilidade e extensibilidade. Adicionar uma nova entrada de dados é tão simples quanto adicionar uma nova linha com valores de dados.
Outro ponto a ser observado aqui é que as tabelas de dados podem ser usadas para conter qualquer tipo de variáveis, classes, objetos, enums, etc., o que o torna ainda mais poderoso. Como groovy é uma linguagem tipificada opcionalmente, se um tipo explícito não for especificado, as variáveis na tabela de dados implicam em dependendo do tipo de dados fornecidos.
Vamos ver outro Exemplo usando tabelas de dados com uma lista de strings como entrada e saída como uma contagem de elementos na string.
def 'sample parameterized test with list data type'() when: def actualCount = input1.size() then: actualCount == expectedCount where: input1
No exemplo acima, você pode notar que fornecemos a entrada como uma lista de array de Strings e a saída é o tamanho desta lista de array. Portanto, é muito flexível ter dados de entrada de diferentes tipos.
Você também pode simplesmente mencionar quaisquer expressões que retornem dados do respectivo tipo de entrada e usar em tabelas de dados diretamente.
Ciclo de vida do bloco “onde”
Para testes contendo bloco where e amostras de dados na forma de tabelas de dados, cada linha de dados representa uma execução do método de teste.
Por exemplo, se houver 5 linhas de dados e o teste contiver blocos “dados” e “quando”, então para essa linha de dados os blocos de teste serão executados uma vez. Portanto, no geral, haverá um total de 5 execuções do método de teste.
dicas e truques
Vamos ver algumas dicas e truques para testes parametrizados enquanto trabalhamos com essas tabelas de dados.
# 1) Exibir os resultados da execução de cada linha separadamente. Como vimos na seção de ciclo de vida, para cada linha de dados há uma execução do código de teste. Para obter essas linhas ou resultados exibidos separadamente para cada uma dessas linhas, a anotação “@Unroll” pode ser usada para tais testes.
Vamos tentar entender isso com um exemplo:
Estaremos usando o mesmo aplicativo de calculadora com 3 conjuntos de dados de entrada fornecidos ao método em teste.
bloqueador de pop-up gratuito para cromo
def 'sample parameterized test'() -20
Sem a anotação “@Unroll”, vamos ver como fica o resultado no terminal (bem como nos relatórios baseados em html). Com esse tipo de saída, torna-se difícil descobrir qual conjunto de entrada causou a falha do teste.
Agora vamos ver como a saída do teste é relatada separadamente para cada linha depois de adicionar a anotação '@Unroll' ao método de teste (que tem tabelas de dados como entrada de dados).
#dois) Agora, vamos entender como adicionar informações significativas a esses testes orientados a dados (em vez de alguns índices anexados automaticamente como na imagem acima).
Podemos usar marcadores de posição para as propriedades de entrada e saída (conforme tabela de dados) e então podemos ver os valores preenchidos em nomes de testes com dados de tabelas de dados.
Vamos usar o mesmo exemplo e atualizar o nome do teste para obter dados da entrada e saída esperada, conforme mencionado nas tabelas de dados:
@Unroll def 'result of adding #input1 & #input2 should be #expectedResult'() given: def app = new CalculatorApp() when: def resultSum = app.add(input1, input1) then: resultSum == 2 * input1 where: input1
Agora vamos ver como fica a saída no terminal e nos relatórios baseados em HTML:
Portanto, como você pode ver aqui, os dados de entrada e saída agora são exibidos junto com os nomes dos testes quando eles estão sendo executados. Dessa forma, ele torna a solução de problemas e depuração muito mais fácil, pois indica claramente qual entrada causou a falha ou o mau comportamento do teste.
Conclusão
Neste tutorial, aprendemos a escrever testes parametrizados com a estrutura Spock. Também discutimos vários recursos das tabelas de dados e como elas podem ser usadas.
Confira nosso próximo tutorial para saber como usar Mocks e Stubs com Spock !!
PREV Tutorial | PRÓXIMO Tutorial
Leitura recomendada
- Escrevendo testes de unidade com Spock Framework
- Perguntas da entrevista de Spock com respostas (mais populares)
- Spock para integração e teste funcional com selênio
- Spock Mocking e Stubbing (exemplos com tutoriais em vídeo)
- Tutorial do Spock: Testando com Spock e Groovy
- Data Driven Framework no Selenium WebDriver usando Apache POI
- Como realizar testes orientados a dados usando a ferramenta TestComplete
- Como funcionam os testes orientados a dados (exemplos de QTP e Selenium)