How to write an Android UI test where the contents of views are determined at runtime?

浪尽此生 提交于 2019-12-24 05:59:45

问题


The Situation

I'm writing a timetable-viewing application and the first feature to be implemented is choosing the course for which to view the timetable.

The user chooses the name of their course from a list and is taken to another screen to further specify which year, group etc. of the course they're currently in. The screens to choose your course and edit your course details are as follows:


The Goal

Inspired by the Google I/O 17 talk on Test-Driven Development on Android, what I wish to write is a UI test case to test this feature. Specifically, I want my test to confirm that if the user clicks on one of the course names they will be taken to the 'edit course details' screen and that the course title at the top e.g. 'Accounting and Finance' matches the one that was clicked in the list.


The Problem

The test, using Espresso, for the specific case of choosing the course titled 'Accounting and Finance' and seeing if the correct title shows up on the next screen, would look (roughly) like this:

@Test
public void chooseCourse() {
    onView(withId(R.id.rv_course_list))
            .perform(RecyclerViewActions.actionOnItemAtPosition(
                    /*Somehow find position of Accounting and Finance*/,
                    click())
            );


    onView(withId(R.id.course_title))
            .check(matches(withText("Accounting and Finance")))
            .check(matches(isDisplayed()));
}

My problem is that the RecyclerView course list will be populated using results from a HTTP request or a SQLite database at runtime and there is no way of knowing beforehand whether the list will contain 'Accounting and Finance' or something else (I don't want the test to fail just because a specific course isn't in the list when the application runs).

Taking this into consideration I cannot hard-code the course name into the test. Please note that I'm not trying to write a unit test where I would just mock the dependency of obtaining the course list to ensure that 'Accounting and Finance' is in the list (and would probably just isolate the ChooseCourseActivity class, capturing its Intents).

In the video I linked to above, the presenter talks us through a UI test of the add-note feature of a notes application where the test is as follows:

  1. Click on the 'add note' button
  2. Enter title and description of the note
  3. Click on the 'save note' button
  4. Verify that a new note with the details from step 2 is contained in the list

In that scenario hard-coding the text (title and description) used to find the views works great because the code in the test determines the contents of the view i.e. the note in the notes list. In my case, the contents of the view will be determined by a HTTP response or db query


The Question

  • How do I write an adequate UI test for the choose-course feature before implementing it?
  • Is the method used in the video to test the notes app simply not applicable to my feature (because I cannot hard-code the course title that is to be chosen from the list)?
  • Am I just misunderstanding UI testing and should be mocking dependencies (even though the speaker in the video did not)?

Edit: The best solution to this problem seems to be what is called 'hermetic testing' and this blog describes how to apply it to android UI.


回答1:


You can test this in a few different ways and I've used a combination of all of them within my apps.

1) You can mock your network/database layer as you suggested.

2) You can make a call to your API in your test to get your 'expected' data set and then verify that it appears correctly in your UI.

3) You can Stub your networking layer to allow you to inject known data and not rely on your networking endpoint. Retrofit in particular makes it very easy to do this.

4) You can test against live endpoints using a known test dataset that won't change frequently.

I tend to use Espresso both for UI level tests and full blown regression tests. In the UI level tests, I stub out the networking/on device persistence layer and just test the client side with datasets that I inject during the test. For regression tests, I care about testing the integration with my API and for those I use a testing account that has known unchanging data.



来源:https://stackoverflow.com/questions/44806049/how-to-write-an-android-ui-test-where-the-contents-of-views-are-determined-at-ru

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!