Как начать и не начинать занятия в разных тестах в одном классе? - PullRequest
0 голосов
/ 28 апреля 2019

Мое приложение сначала загружает список элементов по http-запросу (Retrofit), а затем показывает его в RecyclerView.

Хорошо.

Теперь я пишу множество тестов Эспрессо для проверки экрана (активность = TradersActivity), которые показывают результат загруженного списка.

Так что я высмеиваю элементы загрузки с помощью okhttp3.mockwebserver.MockResponse и помещаю их в метод @Before.В результате сначала загрузите данные, а затем запустите эспрессо-тест (например, itemList_isDisplayed()). Вот фрагмент теста Эспрессо:

i

mport okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer

@RunWith(AndroidJUnit4::class)
class TradersActivityTest {

    @Rule
    @JvmField
    var tradersIntentTestRule = IntentsTestRule(TradersActivity::class.java, false, false)

    @Before
    fun setup() {
        mockServer = MockWebServer()
        mockServer.start(8081)

        mockServer.enqueue(MockResponse()
                .setResponseCode(200)
                .setBody(FileUtil.getStringFromFile(context, DEFAULT_TRADERS_LIST)));
        tradersIntentTestRule.launchActivity(Intent())
    }

   @Test
    fun toolBar_height() {
        onView(withId(R.id.toolBar))
                .check(matches(withHeightResId(R.dimen.tool_bar_height)))
    }

    @Test
    fun itemList_isDisplayed() {
        onView(withId(R.id.tradersRecyclerView))
                .perform(RecyclerViewActions.scrollToPosition<RecyclerView.ViewHolder>(checkItemCount));
        onView(withRecyclerView(R.id.tradersRecyclerView).atPosition(checkItemCount))
                .check(matches(isDisplayed()))
    }

    @Test
    fun itemList_BaseisDisplayed() {
        onView(withId(R.id.tradersRecyclerView))
                .perform(scrollToPosition<RecyclerView.ViewHolder>(checkItemCount));
        onView(withRecyclerView(R.id.tradersRecyclerView).atPositionOnView(checkItemCount, R.id.baseTextView))
                .check(matches(isDisplayed()))
    }

}

Nice.все работает нормально.

Но теперь я хочу написать тест, который проверяет show toast, когда имеет ошибку возврата HTTP-ответа (например, http status = 400 ).И я добавляю этот тест:

 @Test
    fun network_clientError_showToast() {
        mockServer.enqueue(MockResponse()
                .setResponseCode(400))
        tradersIntentTestRule.launchActivity(Intent())
        onView(withText(R.string.client_error)).inRoot(ToastMatcher()).check(matches(isDisplayed()))
}

Как вы видите, этот тест "network_clientError_showToast" сначала заглушает ответ об ошибке, а затем запускает действие.В результате, когда я запускаю тест, я получаю ошибку:

java.lang.RuntimeException: Could not launch intent Intent { flg=0x10000000 cmp=com.myproject.debug/com.myproject.ui.activity.TradersActivity } within 45 seconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1556450658437 and now the last time the queue went idle was: 1556450667375. If these numbers are the same your activity might be hogging the event queue.
at androidx.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:459)
at androidx.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:358)
at 

Так что мне нужны две вещи:

  1. Запуск TradersActivity по @Before методу.В результате мне не нужно начинать действия с КАЖДОГО теста, который проверяет пользовательский интерфейс.

  2. Запуск TradersActivity на тестах, которые проверяют сетевые ошибки (например, http status = 400 )

Как я могу это сделать в one class TradersActivityTest?Спасибо.

...