2017-03-06 173 views
1

我的活動「MainActivity」需要在某些情況下啓動自己的另一活動ontop。啓動活動超時,因爲活動啓動另一個活動

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ... 
    if (condition) { 
     startActivity(new Intent(this, AnotherActivity.class)) 
    } 
} 

我想在MainActivity上運行測試,聲明AnotherActivity在啓動時使用這些條件。

我的Espresso測試無法啓動MainActivity,因爲它似乎等待MainActivity出現在屏幕上。自從我開始其他活動之後,這不會發生。該活動通過ActivityTestRule啓動。

我跑我的咖啡測試時,得到了以下異常:

java.lang.RuntimeException: Could not launch intent Intent { act=android.intent.action.MAIN flg=0x14000000 cmp=com.djoglobal.corebelt.debug/com.djo.compex.corebelt.ui.MainActivity } 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 1488804986217 and now the last time the queue went idle was: 1488804986217. If these numbers are the same your activity might be hogging the event queue. 
at android.support.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:360) 
at android.support.test.rule.ActivityTestRule.launchActivity(ActivityTestRule.java:219) 
at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:268) 
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at tools.fastlane.screengrab.locale.LocaleTestRule$1.evaluate(LocaleTestRule.java:32) 
at org.junit.rules.RunRules.evaluate(RunRules.java:20) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runners.Suite.runChild(Suite.java:128) 
at org.junit.runners.Suite.runChild(Suite.java:27) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at org.junit.runner.JUnitCore.run(JUnitCore.java:115) 
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59) 
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262) 
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932) 

我也有同樣的行爲,如果我在開始的onResume「AnotherActivity」。

我正在使用Espresso 2.2.1

任何想法來測試這種情況?

+0

您是否找到了解決此問題的解決方案? – makovkastar

回答

0

您可以張貼在啓動活動Handler

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ... 

    if (condition) { 
     final int millisUntilLaunch = 500; 

     final Handler handler = new Handler(); 

     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       startActivity(new Intent(this, AnotherActivity.class)); 
      } 
     }, millisUntilLaunch); 
    } 
} 
+0

這是工作謝謝你。但我寧願:1)不要修改應用程序的功能/生產代碼以使測試工作。 2)不讓用戶在兩者之間看到MainActivity的小幽靈 – Kain

0

我已經利用Espresso Intents存根的啓動活動的意圖,以防止它被顯示出來。

在我的情況LoginActivity在MainActivity中的onCreate()開始,如果用戶沒有登錄:

Account account = AccountUtils.getAccount(this); 
if (account == null) { 
    startActivity(this, LoginActivity.class); 
    finish(); 
    return; 
} 

的特濃咖啡的測試,驗證了LoginActivity啓動:

@Test 
public void startsLoginActivityImmediately() { 
    Intents.init(); 

    // Stub the login intent to prevent LoginActivity from being displayed. 
    // This helps to fix the Espresso timeout exception. 
    Matcher<Intent> loginIntent = hasComponent(LoginActivity.class.getName()); 
    intending(loginIntent).respondWith(new Instrumentation.ActivityResult(0, null)); 

    mActivityRule.launchActivity(null); 
    intended(hasComponent(LoginActivity.class.getName())); 

    Intents.release(); 
} 

我希望這種方法可以解決您的問題。

0

我認爲你有問題就在這裏的某個地方: mActivityTestRule.launchActivity(null); 當我通過null,我有同樣的錯誤你。

這是我的代碼示例,它在每一個場景(見註釋部分)工作原理:

@RunWith(AndroidJUnit4.class) 
public class MyTest { 

    @Rule 
    public ActivityTestRule<TestActivity1> mActivityTestRule = new ActivityTestRule<>(TestActivity1.class); 

    @Before 
    public void setup() { 
     Intents.init(); 
    } 

    @After 
    public void tearDown() { 
     Intents.release(); 
    } 

    @Test 
    public void test() { 
     Intent intent = new Intent(); 
     mActivityTestRule.launchActivity(intent); 
     intended(hasComponent(TestActivity2.class.getName())); 
    } 
} 

....

public class TestActivity1 extends Activity{ 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_home); 
     setTitle("first"); 

     if (isConditionMatch()) { 
      startActivity(new Intent(this, TestActivity2.class)); 
     } 
    } 
} 

您也可以通過更換試試這裏執行單元測試startActivity(new Intent(this, TestActivity2.class));與方法調用並將其放入演示者或類似的東西。