2015-11-10 2 views
6

मैं वर्तमान में एस्प्रेसो परीक्षण में एक प्रोजेक्ट को दबाकर काम कर रहा हूं। मैंने दस्तावेजों का एक समूह पढ़ा है और शुरू करने के लिए दिए गए अभ्यासों का पालन किया है।एंड्रॉइड एस्प्रेसो इंटेंट्स परीक्षण '`init() के साथ यादृच्छिक रूप से विफल होने के लिए इस विधि का उपयोग करने से पहले कहा जाना चाहिए'

सबकुछ ठीक काम करता है, हालांकि, जब यह इरादे से संबंधित परीक्षण की बात आती है, तो परिणाम अजीब होता है।

अधिकांश समय, मेरे मैक में पारित परीक्षण, लेकिन असफल संदेश java.lang.IllegalStateException: init() must be called prior to using this method के साथ मेरे सहयोगी के विंडोज़ (सभी परीक्षण विफल नहीं) में विफल हो गए।

काफी अजीब बात है, अगर हम एंड्रॉइड स्टूडियो में डीबग परीक्षण चलाते हैं तो चरण-दर-चरण कोड प्रवाह होता है, यह गुजरता है।

@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()) 
    )); 
    } 
} 

परीक्षण पुस्तकालय संस्करण (लगभग सभी निर्भरता तारीख तक कर रहे हैं और हम परीक्षण करने के लिए दोनों भौतिक विज्ञान उपकरणों और एमुलेटर का उपयोग करें):

  • नियम: 0.4

    यहाँ परीक्षण कोड है .1

  • धावक: 0.4.1
  • espresso- *: 2.2.1
  • समर्थन *: 23.1.0

कोई भी विचार प्रशंसा के योग्य है। धन्यवाद!

उत्तर

14

दो समाधान:

  1. उपयोग बजाय IntentsTestRule की और फिर अपने @Before में और @After मैन्युअल Intents.init() और Intents.release() क्रमशः फोन ActivityTestRule।
  2. एक कस्टम IntentTestRule लिखें और अपने खाता प्रबंधक लॉग इन को शामिल करने के लिए सक्रियता लॉन्च() से पहले ओवरराइड करें। अपने वर्तमान @After तर्क के लिए सक्रियता के बाद उपयोग करें। यह आपको डिफ़ॉल्ट IntentTestRule कन्स्ट्रक्टर का उपयोग करने की अनुमति भी देगा। (पसंदीदा समाधान)

के रूप में यह क्यों हो रहा है:।

"एक असंबंधित नोट पर अंत में, सावधान जब नए IntentsTestRule का उपयोग किया यह प्रारंभ नहीं होता है, Intents.init(), जब तक गतिविधि शुरू होने के बाद (एक्टिविटी लांच() के बाद)। " - Shameless plug to my own post (halfway down helpful visual)

मुझे लगता है कि आप, नहीं बुलाया जाता है एक रेस स्थिति है जहाँ आपके @Before विधि में आप launchActivity (क्रियान्वित कर रहे हैं) तो एस्प्रेसो intending(not(isInternal())).respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, null)); पर अमल करने से पहले अपनी गतिविधि बनाने से कोशिश करता है, जो afterActivityLaunched() का मतलब है में चल रहे हैं जो का मतलब है न तो Intents.init(), दुर्घटना!

उम्मीद है कि इससे मदद मिलती है।

0

IntentsTestRuleActivityTestRule से लिया गया है और Intents.init() और Intents.release() आपके लिए प्रबंधित करना चाहिए।

हालांकि, मेरे मामले में IntentsTestRule ठीक से काम नहीं किया।इसलिए मैं ActivityTestRule पर वापस स्विच करता हूं और इरादे को भेजे गए परीक्षण के बाद और Intents.release() पर कॉल करता हूं।

अधिक जानकारी के लिए कृपया यह reference देखें।

संबंधित मुद्दे

 संबंधित मुद्दे