Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

PROBLEMA COM SERVIDOR LOCAL

Estou com um problema uma tanto quanto curioso, já fiz várias pesquisas e modificações e não consegui solucionar. O problema é o seguinte:

Tenho um recycler view que retorna 3 itens ao consultar uma api, criei um método para fazer um assert se pelo menos um item foi retornado do servidor., o curioso está quando uso um servidor externo (homologação) com https, funciona normalmente, quando uso o servidor local com http, retorna erro. O servidor local possui exatamente os mesmos dados que o servidor de homologação. Segue o método implementado:

@Test
    public void shouldDisplayAtLeastOneCategory() {
        onView(withId(R.id.recyclerView))
                .perform(actionOnItem(hasDescendant(withText("CATEGORIA 1")), click()));
    }

Segue umn trecho do erro quando apontado para a API do servidor local:

android.support.test.espresso.PerformException: Error performing 'performing ViewAction: single click on item matching: holder with view: has descendant: with text: is "CATEGORIA 1"' on view 'with id: br.com.rosadasorte:id/recyclerView'.
at android.support.test.espresso.PerformException$Builder.build(PerformException.java:82)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:79)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:51)
at android.support.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:312)
at android.support.test.espresso.ViewInteraction.desugaredPerform(ViewInteraction.java:173)
at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:114)
at br.com.rosadasorte.ScreenMainTest.shouldDisplayLeastOneCategory(ScreenMainTest.java:56)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(is assignable from class: class android.support.v7.widget.RecyclerView and is displayed on the screen to the user)
Target view: "RecyclerView{id=2131296501, res-name=recyclerView, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=true, is-selected=false, layout-params=android.widget.RelativeLayout$LayoutParams@5f99062, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=0}"
5 respostas

Hum, acho que o problema está aqui

Target view: "RecyclerView{id=2131296501, res-name=recyclerView, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=true, is-selected=false, layout-params=android.widget.RelativeLayout$LayoutParams@5f99062, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=0}"

O que mais me chamou atenção é porque a view não tem altura e nem largura?

Oi Cesar, tudo bem?

Considerando que com o servidor de homologação esteja funcionando, realmente não parece ser um problema com o espresso, sendo assim, faça uns testes e me diga os seguintes pontos:

  • O que é devolvido com a requisição HTTP? Tá usando o Retrofit? Se sim adicione o logging interceptor para que ele mapeie toda a request.

  • O teste quebra o App?

  • Tentou colocar um delay com Thread.sleep()? Se sim, apareceu alguma coisa na tela?

  • Tá usando um dispotivo com Android 9? Sem sim, permitiu o uso do domínio via HTTP?

Dê uma olhada nesses pontos, me manda, se possível, com mais detalhes para que eu consiga entender os pontos problemáticos.

Realmente esse é o momento problemático que envolve os testes que possuem mais integrações.

[]s

solução!

Fala Alex, tudo certo e você?

Respondendo as perguntas:

O que é devolvido com a requisição HTTP? Tá usando o Retrofit? Se sim adicione o logging interceptor para que ele mapeie toda a request.

Resposta: Estou usando retrofit e já uso o logging interceptor, conteúdo devolvido da API abaixo:

2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: <-- 200 OK http://10.0.2.2/painel_adm/services/listCategory (441ms)
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Date: Mon, 26 Nov 2018 23:20:26 GMT
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Server: Apache/2.4.35 (Win32) OpenSSL/1.0.2p PHP/7.1.23
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: X-Powered-By: PHP/7.1.23
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Content-Length: 1007
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Keep-Alive: timeout=5, max=100
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Connection: Keep-Alive
2018-11-26 21:20:26.101 31243-31289/? D/OkHttp: Content-Type: application/json
2018-11-26 21:20:26.102 31243-31289/? D/OkHttp: {"status":"success","categories":[{"id":9,"name":"CATEGORIA 1","category_type_id":1,"imagecategoria2.png","image_last_update":0,"available":1,"brief":"CATEGORIA 1","description":"CATEGORIA 1","color":"#00923f","priority":1,"created_at":1514503945740,"last_update":1514503945740},{"id":10,"name":"CATEGORIA 2","category_type_id":2,"image":"categoria2.png","image_last_update":0,"available":1,"brief":"BREVE RESUMO AQUI","description":"CATEGORIA 2","color":"#292878","priority":2,"created_at":1514503995660,"last_update":1514503995660},{"id":3,"name":"CATEGORIA 3","category_type_id":9,"image":"categoria3.png","image_last_update":1526745461309,"available":1,"brief":"BREVE RESUMO AQUI","description":"CATEGORIA 3","color":"#A548A3","priority":3,"created_at":1485609656784,"last_update":1514459290482}]}
2018-11-26 21:20:26.102 31243-31289/? D/OkHttp: <-- END HTTP (1007-byte body)

O teste quebra o App?

Resposta: Não

Tentou colocar um delay com Thread.sleep()? Se sim, apareceu alguma coisa na tela?

Resposta: Coloquei um delay de 500 milissegundos aparentemente resolveu, mais fiquei curioso. Esse problema deveria ser ao contrário, , porque presumo que a chamada da API para o ambiente externo deveria ter o tempo de resposta maior comparado com o servidor local., no qual ocorre o inverso.

Tá usando um dispositivo com Android 9? Sem sim, permitiu o uso do domínio via HTTP?

Resposta: Não.

Opa Cesar, tranquilo também :)

Bom, parece que o problema não está na request e pelo menos não quebra o App. Realmente é muito estranho funcionar com um ambiente e com o outro não funcionar. O que aconteceu bastante comigo foi em dispositivos físicos ser mais rápido aí precisava do delay e em virtuais não precisar.

Infelizmente a API do Espresso não muito boa para lidar com essas questões assíncronas... Nesse exercício eu comento sobre esse possível problema.

Estranho usar o aparelho Android 9 e não permitir a request HTTP e funcionar, por padrão, o Android 9 não permite mais esse tipo de requisição.

Bom, de qualquer maneira, você conseguiu fazer o teste, certo?

Opa, resolveu sim, cheguei nessa aula hoje.

Obrigado pela dica.

Obs: Não estou usando Android 9