Utilizando variantes para simplificar testes de Widgets em Flutter

Rodrigo Bastos
4 min readNov 22, 2021

Fala pessoal, tudo bem com vocês? Comigo está tudo bem!

Hoje vou falar sobre um assunto muito legal, porém muito pouco comentado dentro da comunidade do Flutter. Falarei sobre como utilizar variants nos seus testes de widgets. Fazendo isto, você conseguirá ter um teste muito mais conciso, evitando repetição e boilerplate de código de teste.

Para começar faço uma pergunta: você já precisou testar seu aplicativo em múltiples plataformas? Se você já precisou fazer isso e não fez da maneira adequada eu consigo apostar que você acabou criando arquivos de testes gigantes e com uma quantidade absurda de repetição de código. Acertei?

Para resolver isto, o Flutter nos permite criar TestVariants. Estes testes variantes são nada mais nada menos do que uma decrição de uma possível variação para o seu teste. Ao criar esta descrição de variação, o Flutter será responsável por rodar o seu mesmo teste em todas as variações definidas.

Com isso podemos fazer apenas um teste que roda várias vezes, uma para cada definição de variação. Um exemplo prático disso seria rodar um teste de widget para cada plataforma suportada pelo aplicativo, veremos como fazer isto mais a frente.

Todo teste de widget tem uma propriedade variant, onde você pode passar justamente sua variação. TestVariant é uma classe abstrata, então temos que implementar nosso próprio variante para podermos utilizar. Mais uma vez o Flutter facilita nossas vidas e nos dá uma implementação simples porém poderosa do TestVariant. ValueVariant é esta implementação que facilita nossa vida. Basta passarmos nossos valores e tudo vai funcionar no nosso teste.

Chega de conversa, e vamos para o código.

Photo by Lauren Mancke on Unsplash

Digamos que por algum motivo temos um widget que recebe um inteiro, significando o tamanho de uma lista a ser renderizada na tela. Queremos garantir que o widget irá funcionar adequadamente independente do valor passado para o widget. O código do widget ficaria mais ou menos assim:

Nada muito complexo aqui, estou simplesmente mostrando n ListTiles, onde n é o tamanho recebido como parâmetro.

Quero testar que este widget se comporta corretamente quando passado um tamanho de 1, 5 ou 10. A primeira solução que vem a cabeça é criar 3 testes, um para cada caso destes. Para que isso se podemos criar um Variant para isso? :-)

Vamos criar então o nosso Variant de tamanho, que eu vou bondosamente chamar de sizeVariant. O código dele é o seguinte:

Note que criamos um ValueVariant de inteiros, e que para criar um ValueVariant precisamos passar um set para ele. Aqui, faz todo sentido ser um set pois não faria muito sentido termos valores de variações repetidos. Criamos então, passando os valores desejados: 1, 5 e 10.

Feito isto, nosso teste já está quase todo pronto para ser escrito. O mote principal do teste é o seguinte:

Falta porém avisar ao Flutter que queremos utilizar nossa sizeVariant. Fazemos isto passando nossa variant para o parâmetro variant.

Feito isto, precisamos agora apenas capturar o valor do variant dentro da execução do teste. Agora o ValueVariant facilita nossa vida pois ele tem uma propriedade currentValue, que retorna justamente o valor do variant atual.

Podemos então finalizar o código do nosso teste:

Ao rodar este teste, observamos que na verdade 3 testes foram executados, pois o Flutter rodou nosso teste uma vez para cada variante. Ao invés de codificar 3 testes, nos bastou fazer um e criar uma variante para ele :).

O exemplo anterior pode ter parecido um pouco bobo para você, mas o poder dos variants pode ser utilizado para exemplos mais práticos e utéis. Um dos melhores exemplos que podemos citar é como utilizar variantes para testar widgets em diferentes plataformas. Desta maneira podemos efetuar testes simples que testam comportamentos em todas as plataformas suportadas pela aplicação.

Vamos a este exemplo então.

Digamos agora que nosso exemplo é o seguinte. Eu possuo um Widget que tem comportamento adaptativo, ou seja, ele se comporta de maneira diferente de acordo com a plataforma. Precisamos testar isto e o vamos fazer com a ajuda de variantes também.

Veja o exemplo de Widget a seguir:

Ele mostra o widget `AndroidWidget` se a plataforma for Android e `IosWidget` caso contrário. De novo, vamos resistir a tentação de escrever um teste para cada caso e vamos escrever apenas um teste que averigue estes comportamentos.

Comecemos criando o nosso ValueVariant. Ele agora vai ser um Variant de TargetPlatform. No nosso exemplo hipotético queremos testar em duas plataformas: android e ios. Então passamos estas TargetPlatforms para o nosso set.

O teste do nosso widget adaptativo se torna muito simples então. Passamos a plataforma da variante para o ThemeData do nosso MaterialApp. O código é mostrado abaixo:

Observe que precisamos fazer um condicional nos nossos expects, pois eles vão ter que mudar de acordo com a variante que está sendo executada.

E os testes (um para cada plataforma) passam :)

Por hoje é isto pessoal, nos vemos na próxima. Happy Flutter Coding!

--

--