2
respostas

[Bug] Testes feitos em aula passam mesmo quando o valor esperado está completamente errado

O teste realizado no minuto 17:33 passa com sucesso independentemente do valor que é passado para expect. Por exemplo, neste teste abaixo, onde era esperado que o contador exibisse o valor "00:01" após o botão de pausar ter sido pressionado, o mesmo não falha apesar de todos os outros valores errados esperados. No último expect é possível observar que mesmo um valor absurdo (56:03dfsdfsd) não fez o teste falhar.
Captura de tela do VS Code contendo o trecho de código do teste realizado em aula no minuto 17:33
Este não foi o único teste que apresentou esse comportamento inesperado. O teste realizado em 20:25 também passou com sucesso, quando eu esperava que falhasse. No teste, era esperado que houvesse apenas 1 chamada à função stopTimer, porém passar qualquer valor em called() faz com que o teste passe com sucesso. Veja que no teste abaixo eu verifiquei se a função foi chamada mais de 20 vezes, e mesmo assim o teste não falhou.
Captura de tela do VS Code contendo o trecho de código do teste realizado em aula no minuto 20:25

Um outro rapaz aqui no fórum compartilhou que fez uso do await nas chamadas ao widgetTester.runAsync(), mas para mim isso fez dar erro antes mesmo da verificação. Note no print abaixo que o botão de Pausar sequer foi encontrado dentre os widgets.
Captura de tela de código demonstrado no minuto 20:25 com algumas modificações

Com isso, resolvi fazer um último teste, que foi o de remover o await que eu acrescentei acima e buscar um texto qualquer em vez de "Pausar", e mesmo assim o teste passou com sucesso.
Captura de tela demonstrando erro em teste realizado em aula
Já tentei entender com IA o que está acontecendo, mas ela não conseguiu solucionar o problema. Ela me indicou a colocar o await, conforme já havia sido indicado por um colega e que, como demonstrei no print mais acima, não funcionou comigo. Ao relatar para a IA que o await não resolveu o problema, ela me indicou a "não colocar interações de UI dentro do runAsync". Não sei mais o que fazer para fazer o teste funcionar como esperado (falhar com os textos obviamente errados, e ter sucesso somente com os valores verdadeiros).

Versões que estou utilizando:
Flutter 3.38.9
Mocktail ^1.0.4
Provider ^6.1.5+1

2 respostas

Continuando com a verificação do que pode estar causando os problemas nos testes acima, descobri que nada muda na tela, mesmo após garantir a execução da função startTimer. O botão de Pausar não é encontrado após o timer ser iniciado.
Insira aqui a descrição dessa imagem para ajudar na acessibilidade
Mas se em vez disso eu tentar novamente procurar pelo botão Iniciar, o resultado é que ele ainda permanece na tela. Veja que apenas mudar o texto passado para find.next() já resolve a falha no teste anterior. Nem mesmo passar o Duration para pumpAndSettle parece ter qualquer efeito.
Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Olá, estudante, como vai?

O comportamento acontece devido à forma como o ambiente de testes do Flutter lida com operações assíncronas e objetos simulados. Como o TimerViewModel está sendo simulado, ele não possui comportamento próprio: ele apenas retorna aquilo que configuramos. Portanto, se o widget depende de um estado específico para exibir determinado elemento (por exemplo, isPlaying == true para mostrar o botão Pausar), esse estado precisa estar configurado no mock.

Uma forma de testar esse cenário é iniciar o widget já no estado de execução, configurando o mock antes do pumpWidget. Assim, você valida a renderização da interface quando o cronômetro já está rodando no momento da construção do widget.

testWidgets('pausa a contagem ao clicar em Pausar', (tester) async {
      when(() => mockTimerViewModel.isPlaying).thenReturn(true);
      when(
        () => mockTimerViewModel.duration,
      ).thenReturn(const Duration(seconds: 1));

  await tester.pumpWidget(createWidget());

  final pauseButton = find.text('Pausar');
  expect(pauseButton, findsOneWidget);

  await tester.tap(pauseButton);

  await tester.pump();

  expect(find.text('Continuar'), findsOneWidget);

  expect(find.text("00:01"), findsOneWidget);
});

Espero ter ajudado.

Siga firme nos seus estudos e conte com o fórum sempre que precisar.

Abraços :)

Caso este post tenha lhe ajudado, por favor, marcar como solucionado