Robotium. In the suite of tests each next test is

2019-06-15 07:05发布

I have multiple UI tests. When I run a single test, everything is OK. But if I run a batch of them (as a part of CI build) test fail, because tests that go first change the state of the application, and the next tests are affected by those changes. (Since the app is not getting killed).

I tried getActivity().finish() in tearDown().
Tried solo.finalize() which does the same actually.

Is there a way to have a fresh app at the beginning of each test run? (Using Robotium).
And is there a way to programmatically kill the app at the end of a test?
I'm using ActivityInstrumentationTestCase2 with Robotium

7条回答
ゆ 、 Hurt°
2楼-- · 2019-06-15 07:33

Not exactly sure of the nature of your test suite but I had problems running multiple "fresh start" tests and hanging on second test. My problem related to spawned activities and was resovled by launching the activity with FLAG_ACTIVITY_CLEAR_TOP - of course this clears the stack but I think that's what you want?

    Intent i = new Intent();
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    setActivityIntent(i);
    solo = new Solo(getInstrumentation(), getActivity());
查看更多
Explosion°爆炸
3楼-- · 2019-06-15 07:34

Or just add solo.finishOpenedActivities();

查看更多
beautiful°
4楼-- · 2019-06-15 07:35

You can try to delete super.tearDown();

查看更多
疯言疯语
5楼-- · 2019-06-15 07:39

Why not adding an adhoc way of "killing" the app, depending on the specific app you're testing? For example, depending on your application activity depth, "press back 3 times" or something similar could be good enough.

You could add that in the tearDown method of your tests superclass, so that it's ran after each of your tests.

You should think about your Robotium tests not as normal unit-tests (they're not!), but as user-cases, acceptance-tests. So if you want to close the app, do in these tests exactly what you would expect the user to do to close the app.

查看更多
smile是对你的礼貌
6楼-- · 2019-06-15 07:39

The causes of the problem are:

  1. There is no Android API to get a list of all the activities in a stack.
  2. A workaround for (1) is to use an ActivityMonitor to keep track of each Activity that starts.
  3. Robotium uses the workaround, but it sets up its ActivityMonitor AFTER your ActivityInstrumentationTestCase2 test case starts its activity, i.e.:

    Activity activity = getActivity();
    Solo solo = new Solo(getInstrumentation(), activity);
    

If your activity-under-test is a forwarding activity, then it is likely starting the destination activity before Solo registers its ActivityMonitor. Solo.finishOPenedActivities() relies on the list that it collected from its ActivityMonitor.

As per the @Guillaume answer, I call this method from the test case or from tearDown():

private void backOutToHome() {
    boolean more = true;
    while(more) {
        try {
            getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
        } catch (SecurityException e) { // Done, at Home.
            more = false;
        }
    }
}
查看更多
叛逆
7楼-- · 2019-06-15 07:44

If you run your build with maven or ant (Robotium is a convenience wrapper for JUnit-Tests), there is an option to fork a new process for every test class or even test case. This provides clean environment, but slows down test execution.

I personally prefer to stick with vanilla Junit / TestNG and utilize mocking (with jMockit) to assure proper interaction beween my code and android. See sample here:

https://github.com/ko5tik/andject/blob/master/src/test/java/de/pribluda/android/andject/ViewInjectionTest.java

查看更多
登录 后发表回答