2015-11-10 9 views
6

Şu an bir espresso testine girmeye çalışıyorum. Bir sürü belge okudum ve başlamak için verilen uygulamaları takip ediyorum.Android Espresso Intens testi ile tesadüfen başarısız '`init() bu yöntemi kullanmadan önce çağrılmalıdır' '

Her şey iyi çalışıyor, Ancak, Intents ilgili test söz konusu olduğunda, sonuç garip.

Çoğu zaman, Mac'lerimden geçti, ancak iş arkadaşımın Windows'unda (tüm testler başarısız değil) hata mesajı java.lang.IllegalStateException: init() must be called prior to using this method ile başarısız.

Garip bir şekilde, Android Studio'da Hata Ayıklama testini çalıştırırsak, kod adım adım akarsa, geçer.

@RunWith(AndroidJUnit4.class) 
@LargeTest 
public class MainActivityTest { 

    @Rule public IntentsTestRule<MainActivity> mRule = new IntentsTestRule<>(MainActivity.class, true, false); 

    AccountManager accountManager; 
    MainActivity activity; 


    private void buildLoginStatus() throws AuthenticatorException { 
    DanteApp app = (DanteApp) InstrumentationRegistry.getTargetContext().getApplicationContext(); 
    accountManager = app.getDanteAppComponent().accountManager(); 

    DoctorModel doctorModel = AccountMocker.mockDoctorModel(); 
    accountManager.save(doctorModel.doctor); 
    accountManager.setAccessToken(doctorModel.access_token, false); 
    } 

    @Before public void before() throws Exception { 
    buildLoginStatus(); 

    // must login 
    assertThat(accountManager.hasAuthenticated(), is(true)); 

    activity = mRule.launchActivity(null); 
    // block all of the outer intents 
    intending(not(isInternal())).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, null)); 
    } 

    @After public void tearDown() throws Exception { 
    accountManager.delete(); 
    } 

    // failed 
    @Test public void testViewDisplay() throws Exception { 

    // check tabhost is displayed 
    onView(withClassName(equalTo(TabHost.class.getName()))).check(matches(isDisplayed())); 

    // check toolbar is displayed 
    onView(withClassName(equalTo(ToolBar.class.getName()))).check(matches(isDisplayed())); 
    } 

    // passed 
    @Test public void testCallServiceHotline() throws Exception { 
    // switch to the account tab layout 
    onView(withChild(withText(R.string.account))).perform(click()); 
    // click account menu to make a service call 
    onView(withId(R.id.contact)).perform(click()); 

    // check call start expectly 
    intended(allOf(
     not(isInternal()), 
     hasAction(Intent.ACTION_DIAL), 
     hasData(Uri.parse("tel:" + activity.getString(R.string.call_service))) 
    )); 
    } 


    // failed 
    @Test public void testOpenSettingsUI() throws Exception { 
    // stub all internal intents 
    Intents.intending(isInternal()) 
     .respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, null)); 

    onView(withChild(withText(R.string.account))).perform(click()); 
    onView(withId(R.id.setting)).perform(click()); 

    // check open settings activity successfully 
    intended(anyOf(
     hasComponent(SettingActivity.class.getName()) 
    )); 
    } 
} 

test kütüphanesi sürümü (neredeyse tüm bağımlılıkları güncel ve biz test etmek hem fizik cihazları ve emülatör kullanın):

  • kural: 0.4 Burada

    Test kodudur 0,1
  • koşucu: 0.4.1
  • espresso- *: 2.2.1
  • support- *: 23.1.0

Herhangi bir fikir takdire layıktır. Teşekkürler!

cevap

14

İki Çözümleri:

  1. Kullanım ActivityTestRule yerine IntentsTestRule ve ardından @Before ve @After elle sırasıyla() Intents.init() ve Intents.release diyoruz.
  2. AccountManager mantığınızı eklemek için özel bir IntentTestRule yazın ve önce AccticLaunched() işlevini geçersiz kılın. Geçerli @After mantığınız için AfterActivityFinished kullanın. Bu ayrıca varsayılan IntentTestRule yapıcısını kullanmanıza da izin verecektir.

olarak bunun neden olduğunu için (Tercih Çözüm):.

"Yeni IntentsTestRule kullanırken Nihayet alakasız bir not, dikkatli ol O Intents.init (başlatmak değil) kadar aktivite başlatıldıktan sonra (AfterActivityLaunched()). " - Shameless plug to my own post (halfway down helpful visual)

Sana, çağrılmaz afterActivityLaunched() demektir ki @Before yönteminde sonra espresso etkinlik gerçekten oluşturulmadan önce intending(not(isInternal())).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, null)); yürütmeye çalışırsa) launchActivity (yürütme bir yarış durumu, içine çalışan düşündüğümüz Intents.init() ne demektir, çarpışma!

Bu yardımcı olur umarım.

0

IntentsTestRule, ActivityTestRule'dan türetilmiştir ve sizin için Intents.init() ve Intents.release()'u yönetmelidir. Bununla birlikte, benim durumumda IntentsTestRule düzgün çalışmadı.Bu nedenle, ActivityTestRule'a dönüp önce Intent'i gönderen testten sonra Intents.init() ve Intents.release() numaralı telefonu arayın.

Daha fazla bilgi için lütfen bkz. reference.

İlgili konular