2016-09-14 57 views
1

我試圖調試大約3%時間內失敗的Android UI測試。由於Robotium無法找到ImageButton對象,Android UI測試偶爾會失敗

我們的測試類開始時是這樣的:

@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框架升級到最新版本,但這並不能解決問題。

任何人都知道我們做錯了什麼?

回答

1

我相信我找到了原因。從我所知道的情況來看,這個問題是由於tearDown()中的競態條件造成的。根據Robotium源代碼,finishOpenedActivities()通過發送Back按鈕三次。但是,這似乎是在單獨的線程上完成的。因此,即使在新的測試用例開始時,這些命令也可能會繼續發送,從而導致應用程序被測試從視圖中消失,並使Robotium無法讀取UI。

考慮到應用程序已經在每次測試結束時被殺死,finishOpenedActivities()似乎有點多餘。在我評論此行後,問題沒有再出現。

相關問題