I use the Android testing platform in accordance with the recommendations of Google: ActivityInstrumentationTestCase2. I experienced the following errors during test runs of RANDOM , but with constant fatality. This means that sometimes all tests passed (happy!), But many times it happened by accident with any of these three errors. This upsets and makes me distrust the test results.
To describe the problems in detail, I provided a simplified pseudocode and three problems below. Both test cases are independent of each other.
public class FirstActivityTest extends ActivityInstrumentationTestCase2<FirstActivity> { private FirstActivity mActivity; private ActivityMonitor mActivityMonitor; public FirstActivityTest () { super(FirstActivity.class); } public void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(false); mActivity = getActivity(); assertNotNull("Cannot start test since target Activity is NULL!", mActivity); mActivityMonitor = getInstrumentation().addMonitor(SecondActivity.class.getName(), null, false); } public void tearDown() throws Exception { super.tearDown(); if(mActivity != null) { mActivity.finish(); mActivity = null; } if(mActivityMonitor != null) { getInstrumentation().removeMonitor(mActivityMonitor); mActivityMonitor = null; } } public void testA_HappyPath() { Activity secondActivity = null; try {
Now I have run these two test cases again and again (they will be executed in alphabetical order), the following results:
- Both test cases passed, OR
- testA_HappyPath () failed because ActivityMonitor.waitForActivityWithTimeout () returned NULL SecondActivity. But when I looked at my device, SecondActivity is displayed correctly. Somehow, the test did not notice this. Why?
- If testA_HappyPath () fails, the next test B_SadPath () will hang during setUp ()> getActivity () for an unlimited time. I think I closed everything in tearDown (). Why?
- testB_SadPath () often did not work when using TouchUtils.clickView () with the following error: " INJECT_EVENTS permission is required to enter another application" (regardless of whether the test passes or does not pass testA_HappyPath). Why?
Any helpful feedback is appreciated. Thanks!
I reviewed these 3 questions over the course of a few days, studied many suggestions all over the Internet, and made several attempts and mistakes. However, not a single problem solved a specific problem, however, combining what I found, I solved problem (1) and (2) above, but still have problem (3) that is not resolved. Below is a detailed description of what I did to make this work.
ISSUE (1) ActivityMonitor.waitForActivityWithTimeout () returns NULL
1.1. Now I found out that I have to declare getInstrumentation (). AddMonitor () BEFORE getActivit (). See how I changed the setUp () method, and that somehow fixed the problem. Anyone who understands why this is a requirement, please let us know, we appreciate it.
1,2. In the emulator, this call could sometimes return NULL, which caused an error. I found out that this is because the wait times were too low. Thus, increasing the latency helps prevent the ActivityMonitor from returning too quickly.
ISSUE (2) Next testB_SadPath () will hang during setUp ()> getActivity () indefinitely
2.1. As I described above, this happened when the previous test (testA_HappyPath) failed. I thought my tearDown () cleared everything and checked the next test. It so happened that testA was expecting SecondActivity to appear on the screen, but since ActivityMonitor.waitForActivityWithTimeout () returned NULL, testA failed. TearDown () was executed just fine. The problem is that SecondActivity actually appeared on the screen, but it never stops in the finally block, because its instance of the "secondActivity" method was still null. The presence of SecondActivity live and lingers on the screen, causing the next getActivity () to hang. I fixed this by modifying the finally block to make sure that SecondActivity ever exists, it is disabled.
These changes are summarized in the code below (see setUp () and finally block).
public class FirstActivityTest extends ActivityInstrumentationTestCase2<FirstActivity> { private FirstActivity mActivity; private ActivityMonitor mActivityMonitor; public FirstActivityTest () { super(FirstActivity.class); } public void setUp() throws Exception { super.setUp(); setActivityInitialTouchMode(false); } public void tearDown() throws Exception { super.tearDown(); if(mActivity != null) { mActivity.finish(); mActivity = null; } if(mActivityMonitor != null) { getInstrumentation().removeMonitor(mActivityMonitor); mActivityMonitor = null; } } public void testA_HappyPath() { mActivityMonitor = getInstrumentation().addMonitor(SecondActivity.class.getName(), null, false); mActivity = getActivity(); assertNotNull("Cannot start test since target Activity is NULL!", mActivity); Activity secondActivity = null; try {
RESEARCH (3) testB_SadPath () often fails when using TouchUtils.clickView () with the following error: "INJECT_EVENTS permission is required for injection into another application"
I still can not solve this last problem: - (