sexta-feira, 5 de junho de 2020

Main looper has queued unexecuted runnables

"Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call."

Pensa em uma mensagem de erro que me deu problema!

Essa mensagem pode dar em testes automatizados no Android. Estou usando Android Studio, JUnit, e auxílio do Robolectric para os testes. Especificamente no meu caso, isso era um problema que acontecia nos meus testes em que abro um DatePicker (aquele negócio de selecionar uma data), coloco uma data e dou Ok. Depois que faço iss, na minha aplicação, acontece uma requisição para um site. Essa requisição, como resposta, coloca itens em uma lista.

E aí vinha o problema: ao verificar a lista, às vezes os itens estavam lá, às vezes não!

Quando eles não estavam lá, eu ganhava um erro e ele tinha essa mensagem acima. Tentei e desisti várias vezes de consertar isso. Já fiz testes rodarem de novo até passar, e ignorei o erro por algum tempo.

Então a última vez eu comecei a olhar mais a fundo. Segui a sugestão da mensagem, adicionar esse tal shadowOf(getMainLooper()).idle(). Mas ela não diz exatamente onde. E o pior do erro intermitente: tem que rodar várias vezes, porque às vezes o teste funciona, mas o problema está lá ainda. Determinei que rodaria 20 vezes, se desse certo... E falhou. Acho que na 3ª tentativa.

Fui colocando o shadowOf(getMainLooper()).idle() mais para baixo no teste. Teve vez que deu erro até na 7ª, 10ª vez! Então me deu um estralo e fui ver qual era a explicação da função idle (shadowOf(getMainLooper()).idle()): "Executes all posted tasks scheduled before or at the current time". Traduzindo: "Executa todas as tarefas agendadas antes e no momento atual".

Testes intermitentes podem acontecer porque algo que foi chamado não terminou de executar. Essa função faz com que seu teste espere certas coisas terminarem. Por isso o android sugere que você use ela.

No meu caso, o lugar certo de executar ela foi logo antes de verificar se os dados da lista que eu estava preenchendo.

O código no momento que escrevo está em uma branch no github. O primeiro link é da branch:
https://github.com/darakeon/dfm/blob/4.1.4.5/android/DFM/src/test/kotlin/com/darakeon/dfm/summary/SummaryActivityTest.kt#L234

Caso ele não funcione mais, quer dizer que já coloquei em produção, tente ver no segundo link. Procure por um teste chamado dateDialog:
https://github.com/darakeon/dfm/blob/master/android/DFM/src/test/kotlin/com/darakeon/dfm/summary/SummaryActivityTest.kt

Nenhum comentário:

Postar um comentário