O Espresso afirma que não há necessidade Thread.sleep();
, mas meu código não funciona a menos que eu o inclua. Estou me conectando a um IP. Durante a conexão, uma caixa de diálogo de progresso é exibida. Preciso sleep
aguardar o encerramento do diálogo. Este é o meu snippet de teste onde o utilizo:
IP.enterIP(); // fills out an IP dialog (this is done with espresso)
//progress dialog is now shown
Thread.sleep(1500);
onView(withId(R.id.button).perform(click());
Eu tentei este código com e sem o, Thread.sleep();
mas ele diz R.id.Button
que não existe. A única maneira de fazer funcionar é dormindo.
Além disso, tentei substituir Thread.sleep();
por coisas como getInstrumentation().waitForIdleSync();
e ainda sem sorte.
Esta é a única maneira de fazer isso? Ou eu estou esquecendo de alguma coisa?
Desde já, obrigado.
android
testing
android-espresso
Chad Bingham
fonte
fonte
Respostas:
Em minha opinião, a abordagem correta será:
E então o padrão de uso será:
fonte
Obrigado a AlexK por sua resposta incrível. Há casos em que você precisa fazer algum atraso no código. Não está necessariamente esperando pela resposta do servidor, mas pode estar esperando que a animação seja concluída. Pessoalmente, tenho problemas com o Espresso idolingResources (acho que estamos escrevendo muitas linhas de código para uma coisa simples), então mudei a maneira como AlexK estava fazendo para o seguinte código:
Então você pode criar uma
Delay
classe e colocar este método nela para acessá-la facilmente. Você pode usá-lo em sua classe de teste da mesma maneira:onView(isRoot()).perform(waitFor(5000));
fonte
Thread.sleep()
Tropecei neste tópico ao procurar uma resposta para um problema semelhante em que estava esperando uma resposta do servidor e alterando a visibilidade dos elementos com base na resposta.
Embora a solução acima tenha definitivamente ajudado, acabei encontrando este excelente exemplo de chiuki e agora uso essa abordagem como minha opção sempre que estou esperando que as ações ocorram durante os períodos de inatividade do aplicativo.
Eu adicionei ElapsedTimeIdlingResource () à minha própria classe de utilitários, agora posso usar isso efetivamente como uma alternativa adequada ao Espresso e agora o uso é bom e limpo:
fonte
I/TestRunner: java.lang.NoClassDefFoundError: fr.x.app.y.testtools.ElapsedTimeIdlingResource
erro. Qualquer ideia. Eu uso o Proguard, mas com a ofuscação desabilitada.-keep
instrução para classes que não estão sendo encontradas para ter certeza de que o ProGuard não as está removendo como desnecessárias. Mais informações aqui: developer.android.com/tools/help/proguard.html#keep-codeAcho que é mais fácil adicionar esta linha:
Espera um determinado número de milissegundos (de uptimeMillis) antes de retornar. Semelhante a sleep (long), mas não lança InterruptedException; Os eventos interrupt () são adiados até a próxima operação interruptível. Não retorna até que pelo menos o número especificado de milissegundos tenha decorrido.
fonte
Você pode apenas usar os métodos do Barista:
BaristaSleepActions.sleep(2000);
BaristaSleepActions.sleep(2, SECONDS);
Barista é uma biblioteca que envolve o Espresso para evitar adicionar todo o código necessário para a resposta aceita. E aqui está um link! https://github.com/SchibstedSpain/Barista
fonte
Thread.sleep()
. Desculpe! Estava em alguns dos primeiros vídeos que o Google fez sobre o Espresso, mas não me lembro qual ... foi há alguns anos. Desculpe! : ·) Oh! Editar! Coloquei o link do vídeo no PR que abri há três anos. Confira! github.com/AdevintaSpain/Barista/pull/19Isso é semelhante a esta resposta, mas usa um tempo limite em vez de tentativas e pode ser encadeado com outras ViewInteractions:
Uso:
fonte
Eu sou novo em programação e Espresso, então, embora eu saiba que a solução boa e razoável é usar ociosidade, ainda não sou inteligente o suficiente para fazer isso.
Até que eu me torne mais experiente, ainda preciso que meus testes sejam executados de alguma forma, então, por enquanto, estou usando esta solução suja que faz uma série de tentativas de encontrar um elemento, pára se o encontrar e se não, dorme brevemente e inicia novamente até atingir o número máximo de tentativas (o maior número de tentativas até agora foi em torno de 150).
Estou usando isso em todos os métodos que encontram elementos por ID, texto, pai etc:
fonte
findById(int itemId)
método retornará um elemento (que pode ser NULL) se owaitForElementUntilDisplayed(element);
retorna verdadeiro ou falso .... então, isso não está okIdlingResource
s não são suficientes para mim devido à granularidade da taxa de pesquisa de 5 segundos (muito grande para o meu caso de uso). A resposta aceita também não funciona para mim (a explicação do motivo já está incluída no feed de comentários longos dessa resposta). Obrigado por isso! Peguei sua ideia e fiz minha própria solução e funcionou perfeitamente.O Espresso foi desenvolvido para evitar chamadas sleep () nos testes. Seu teste não deve abrir uma caixa de diálogo para inserir um IP, que deve ser de responsabilidade da atividade testada.
Por outro lado, seu teste de IU deve:
O teste deve ser semelhante a este:
O Espresso espera que tudo o que está acontecendo no thread de IU e no pool AsyncTask termine antes de executar seus testes.
Lembre-se de que seus testes não devem fazer nada que seja de responsabilidade do seu aplicativo. Deve se comportar como um "usuário bem informado": um usuário que clica, verifica se algo está mostrado na tela, mas, na verdade, conhece os IDs dos componentes
fonte
Você deve usar o Espresso Idling Resource, é sugerido neste CodeLab
Exemplo de uma chamada assíncrona do apresentador
Dependências
Para androidx
Repo oficial: https://github.com/googlecodelabs/android-testing
Exemplo de IdlingResource: https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IdlingResourceSample
fonte
Embora eu ache que é melhor usar recursos de inatividade para isso ( https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/ ), você provavelmente poderia usar isso como um substituto:
e chame-o em seu código como, por exemplo:
ao invés de
Isso também permite que você adicione tempos limite para ver ações e ver asserções.
fonte
return new TimedViewInteraction(Espresso.onView(viewMatcher));
comreturn new TimedViewInteraction(Espresso.onView(viewMatcher).check(matches(isDisplayed())));
Meu utilitário repete a execução executável ou chamável até que passe sem erros ou lance lançável após um tempo limite. Funciona perfeitamente para testes do Espresso!
Suponha que a última interação de visualização (clique de botão) ative alguns threads de fundo (rede, banco de dados etc.). Como resultado, uma nova tela deve aparecer e queremos verificá-la em nossa próxima etapa, mas não sabemos quando a nova tela estará pronta para ser testada.
A abordagem recomendada é forçar seu aplicativo a enviar mensagens sobre estados de threads para o seu teste. Às vezes, podemos usar mecanismos integrados como OkHttp3IdlingResource. Em outros casos, você deve inserir partes de código em locais diferentes das fontes do seu aplicativo (você deve conhecer a lógica do aplicativo!) Apenas para suporte de teste. Além disso, devemos desligar todas as suas animações (embora seja parte da IU).
A outra abordagem é esperar, por exemplo, SystemClock.sleep (10000). Mas não sabemos quanto tempo esperar e mesmo longos atrasos não podem garantir o sucesso. Por outro lado, seu teste vai durar muito.
Minha abordagem é adicionar condição de tempo para visualizar a interação. Por exemplo, testamos que a nova tela deve aparecer durante 10000 mc (tempo limite). Mas não esperamos e verificamos tão rapidamente quanto queremos (por exemplo, a cada 100 ms). Claro, bloqueamos o thread de teste dessa forma, mas geralmente é exatamente o que precisamos em tais casos.
Esta é a fonte da minha turma:
https://gist.github.com/alexshr/ca90212e49e74eb201fbc976255b47e0
fonte
Este é um auxiliar que estou usando no Kotlin para testes do Android. No meu caso, estou usando longOperation para simular a resposta do servidor, mas você pode ajustá-la para seu propósito.
fonte
Vou adicionar minha maneira de fazer isso à mistura:
Chamado assim:
Você pode adicionar parâmetros como iterações máximas, comprimento da iteração etc. à função suspendUntilSuccess.
Ainda prefiro usar recursos inativos, mas quando os testes estão dando errado devido a animações lentas do dispositivo por exemplo, eu uso esta função e funciona bem. É claro que ele pode travar por até 5 segundos como está antes de falhar, portanto, pode aumentar o tempo de execução de seus testes se a ação nunca for bem-sucedida.
fonte