17

We have a very large Android application with no tests. We're suffering the typical quality/too long manual regression testing cycles problem.

As a server side developer, who is new to Android, I want to introduce developer tests.

I can see how to unit test normal Java code with JUnit.

However, the Activities/Fragments/Adapters are proving more difficult.

I watched the Espresso video from GTAC and was impressed and decided to use that.

Where I'm struggling is how to provide my testcase with mocked data to then confirm the display.

Is this even possible? It seems that Espresso is for black box testing, which limits its use for developers considerably (its target audience) since (usually) black box testing is done by QA.

FinalFive
  • 1,465
  • 2
  • 18
  • 33
  • If i am not wrong, espresso is UI testing framework, my question is why do you need mock values when testing the UI? – user2511882 May 15 '14 at 18:49
  • 6
    What the UI shows is dependent on data it receives from some source such as a database or rest url. I want to provide variations in the data and make sure it displays correctly. – FinalFive May 15 '14 at 20:31
  • Not sure this is Espresso related really. We use Espresso in a rather large project too, with multiple backends and mock data in various ways. E.g. via a substitute server that gives canned responses for known queries, or simply by exchanging the clients side query interface implementation where expected queries are verified and responses defined by the tests are returned. None of those ways are implemented using any Espresso features. – haffax May 15 '14 at 21:13

2 Answers2

15

There is a library called mockwebserver which allows you to mock server responses. Github: https://github.com/square/okhttp/tree/master/mockwebserver

If you are using gradle you can add the following dependency:

 androidTestCompile 'com.squareup.okhttp:mockwebserver:1.3.0'

Some snippets to help:

setup a mock Server

MockWebServer server = new MockWebServer(); 

Add a sample response (will only work the first time the server is called)

server.enqueue(new MockResponse().setBody("Hello World Response"));

Start the server

 server.play();

Get the url of the server to replace the regular url you are using.

  URL baseUrl = server.getUrl("/");

Now, make a request to anything that uses the BaseURL the same way you would call a non mocked web service, the first time you call the service it will return the response from above. The tricky part is that you have the have the exact number of MockResponses queued up as actually requests your app will make. Be careful with debugging/watching your code because the debugger will actually pop one of the responses off if you are stepping through your code.

If you have trouble figuring it out, here is a java web project (works exactly the same in web and not web) I have a few a basic example written in. https://github.com/digitalbuddha/GitPullRank

FriendlyMikhail
  • 2,857
  • 23
  • 39
  • This is using a full stack apk with slight modifications to use controlled end points. The qa team already does this using appium. I'm looking for a developer approach where I can internally control the dependencies but still see things in an emulator or device. – FinalFive May 16 '14 at 05:06
  • +1 this is the way to go IMHO. Make sure to initialise the http client (i.e. `Retrofit` / `okhttp` / whatever) to use the `MockWebServer`s root url as shown in the answer as the endpoint host before starting the `espresso` test case – Dori Jul 24 '14 at 20:32
  • i.e. if using `RetroFit` then `RestAdapter.Builder.setEndpoint(...);` – Dori Jul 25 '14 at 08:16
  • hi, i end up doing this, but the actual webservice gets called and then mock web server how should i avoid actual webservice getting called? Please assist. @Dori – Rat-a-tat-a-tat Ratatouille Mar 25 '16 at 21:03
2

I faced the same problem, and couldn't find any fremowork that fits perfectly what I needed. But Wiremock was the one that got close.

I use it to record the api answers, and/or in reproduction mode, and when on record mode, if the request was already recorded, it wont record again. Although its not fully supported on android (yet), I run it as standalone on my machine, and then run the app or espresso tests. You can also manually edit or add the requests or answers.

You will find a lot of more details here

juhlila
  • 1,114
  • 1
  • 10
  • 16
  • 1
    This is supported on Android now as of January 2016. Check out this other Stack Overflow answer: http://stackoverflow.com/a/34657592/509081 – Sam Edwards Jan 07 '16 at 14:47
  • Hi,please post ur suggestion as answer on this question .. http://stackoverflow.com/questions/38791731/double-tap-in-ios-simulator-not-working?noredirect=1#comment65074170_38791731 – vks Aug 09 '16 at 16:56