Android UI测试偶尔会因为Robotium无法找到ImageButton对象而失败



我正在尝试调试一个Android UI测试,失败的时间约为3%。

我们的测试类像这样开始:

@RunWith(AndroidJUnit4.class)
public class ActionWidgetAdapterTest {
    private Solo solo;
    @Rule
    public ActivityTestRule<SampleContainer> mActivityRule = new ActivityTestRule<>(SampleContainer.class);
    // SampleContainer is used exclusively for the test case and extends AppCompatActivity
    @Before
    public void setUp() throws Exception {
        solo = new Solo(InstrumentationRegistry.getInstrumentation(), mActivityRule.getActivity());
    }
    @After
    public void tearDown() throws Exception {
        solo.finishOpenedActivities();
    }
    // rest of class
    // [...]
}

有问题的测试用例如下:

@Test
@LargeTest
@FlakyTest
public void testAddActions() throws Exception {
    final ArrayList<Action> actions = new ArrayList<>();
    // Action is our in-house version of the Action class from the Leanback library
    final Action a1 = new Action(0, "text1", R.drawable.action_button_focused);
    final Action a2 = new Action(1, "text2", R.drawable.action_button_focused);
    final Action a3 = new Action(0, "text3", R.drawable.action_button_focused);
    final Action a4 = new Action(1, "text4", R.drawable.action_button_focused);
    actions.add(a1);
    actions.add(a2);
    actions.add(a3);
    actions.add(a4);
    // handler for posting to the main thread
    Handler mainHandler = new Handler(mActivityRule.getActivity().getBaseContext()
                                                                 .getMainLooper());
    Runnable myRunnable = () -> {
        // add actions to adapter
        mActivityRule.getActivity().mActionWidgetAdapter.addActions(actions);
    };
    mainHandler.post(myRunnable);
    solo.sleep(1000); // pause to resolve any timing issues
    assertTrue(mActivityRule.getActivity().mActionWidgetAdapter.getItemCount() == 4);
    // test edge case - navigate all the way to the left
    solo.sendKey(Solo.LEFT);
    pressUpDownEnter();
    solo.sendKey(Solo.LEFT);
    pressUpDownEnter();
    solo.sendKey(Solo.LEFT);
    pressUpDownEnter();
    solo.sendKey(Solo.LEFT);
    pressUpDownEnter();
    solo.sendKey(Solo.LEFT);
    assertTrue(solo.getImageButton(0).isFocused());
    assertFalse(solo.getImageButton(2).isFocused());
}

测试用例通过了绝大多数时间。但是,在执行assertTrue(solo.getImageButton(0).isFocused());时,失败的可能性很小;当这种情况发生时,Robotium抱怨"没有找到3个ImageButtons"。这似乎没有什么规律可循。我将Robotium框架升级到最新版本,但这并不能解决问题。

有人知道我们做错了什么吗?

我相信我已经找到原因了。据我所知,这个问题是由于tearDown()中的竞争条件。根据Robotium源代码,finishOpenedActivities()通过发送后退按钮三次工作。然而,这似乎是在一个单独的线程上完成的。因此,即使在新的测试用例开始时,命令也可能继续发送,导致正在测试的应用程序从视图中消失,并使Robotium无法读取UI。

考虑到应用程序已经在每个测试结束时被杀死,finishOpenedActivities()似乎有点多余。在我注释掉那行之后,这个问题没有再出现。

相关内容

  • 没有找到相关文章

最新更新