2016-02-10 21 views
7

Korzystanie stare testy JUnit3 stylu na Androida, mogę wykonać następujące czynności destory i wznowić działalność:Destroy i ponownie aktywny z testowaniem Wsparcia Biblioteki

Instrumentation inst = getInstrumentation(); 
Activity activity = inst.getActivity(); 
// do something 
activity.finish(); 
Assert.assertTrue(this.activity.isFinishing()); 
activity = inst.getActivity(); 
// assert that activity's state is restored 

Jak mogę osiągnąć to samo przy użyciu nowego Testowanie biblioteki pomocy technicznej? Nie mam problemu z używaniem Espresso i/lub UI Automator lub jakiegokolwiek innego mechanizmu dostarczonego przez nową bibliotekę.

Aktualizacja:

Próbowałem następujące:

Activity activity = activityTestRule.getActivity(); 
// do something 
activity.finish(); 
Assert.assertTrue(this.activity.isFinishing()); 
activity = activityTestRule.getActivity(); 
// assert that activity's state is restored 

Jednak wydaje się, że ActivityTestRule.getActivity() nie uruchamia aktywność,.

+0

Założę się, że część 'finish()' nie powinna różnić się od poprzedniej. Nie wiem, czy 'getActivity()', wywołany na twoim 'ActivityTestRule', ponownie utworzy zniszczone działanie, czy nie. – CommonsWare

+0

@CommonsWare Próbowałem tego i nie wydaje się, aby ponownie uruchomić działanie. –

+0

Teraz, gdy o tym myślę, nie jestem do końca pewien, jaki stan spodziewasz się przywrócić po 'finish()'. Możesz spróbować wywołać 'launchActivity()' po 'finish()' i zobaczyć co się stanie, chociaż to stworzy nową instancję. Lub, prawdopodobnie, możesz dodać to samemu.[Widżet 'ActivityTestRule'] (https://android.googlesource.com/platform/frameworks/testing/+/android-support-test/rules/src/main/java/android/support/test/rule/ActivityTestRule.java) i siekać! – CommonsWare

Odpowiedz

6

Jak wspomniano o @CommonsWare, niestandardowa reguła jest całkiem przydatna. Oto mój proste rozwiązanie (wiele ulepszeń są możliwe, ale to jest po prostu szybki ramy, które mogą być budowane na):

public class ControlledActivityTestRule<T extends Activity> extends ActivityTestRule<T> { 
    public ControlledActivityTestRule(Class<T> activityClass) { 
     super(activityClass, false); 
    } 

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode) { 
     super(activityClass, initialTouchMode, true); 
    } 

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) { 
     super(activityClass, initialTouchMode, launchActivity); 
    } 

    public void finish() { 
     finishActivity(); 
    } 

    public void relaunchActivity() { 
     finishActivity(); 
     launchActivity(); 
    } 

    public void launchActivity() { 
     launchActivity(getActivityIntent()); 
    } 
} 

Uwaga, jeśli zrobisz to tak, klasa ta musi być w pakiecie android.support.test.rule do dostęp do prywatnej metody pakietowej ActivityTestRule#finishActivity. Następnie w przypadku testowego, wdrożyć tę zasadę:

@Rule 
public ControlledActivityTestRule<TestFountainPreferenceActivity> actRule = new ControlledActivityTestRule<>(TestFountainPreferenceActivity.class); 

następnie w swoim indywidualnym przypadku testowego, zadzwonić actRule.finish() i actRule.launchActivity() zabić i uruchom go ponownie. Możesz też zadzwonić pod numer actRule.relaunchActivity(), jeśli nie musisz nic robić między zabiciem a ponownym uruchomieniem. Zauważ, że możesz przekazać trzeci parametr false, aby opóźnić rozpoczęcie działania, jeśli masz pierwsze uruchomienie, a następnie zadzwonić pod numer actRule.launchActivity(), aby go uruchomić, ale utracisz dostęp do niektórych wbudowanych uchwytów, takich jak #afterActivityLaunched i #afterActivityFinished().

+0

A gdzie jest finishActivity() wygląda tak, jak pakiet local. ??? – Campino

+0

Zgadza się, #finishActivity jest chroniony pakietowo, więc wystawiam go za pomocą dostarczonej metody #finish. – JCricket

+0

Czy istnieje sposób na jego rozszerzenie, aby odtworzona aktywność otrzymywała pakiet z onSaveInstanceState? – MateuszL

0

odpowiedź JCricket pracował dla mnie raz Dodałem tam spać ...

package android.support.test.rule; 

public class ControlledActivityTestRule<T extends Activity> extends ActivityTestRule<T> { 
    public ControlledActivityTestRule(Class<T> activityClass) { 
     super(activityClass, false); 
    } 

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode) { 
     super(activityClass, initialTouchMode, true); 
    } 

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) { 
     super(activityClass, initialTouchMode, launchActivity); 
    } 

    public void finish() { 
     finishActivity(); 
    } 

    public void relaunchActivity(int seconds) { 
     finishActivity(); 
     sleep(seconds); 
     launchActivity(); 
     sleep(seconds); 
    } 

    public void launchActivity() { 
     launchActivity(getActivityIntent()); 
    } 

    public void sleep(int seconds) { 
     if (seconds > 0) { 
      try { 
       Thread.sleep(seconds * 1000); 
      } catch (Exception ex) { 
      } 
     } 
    } 
} 

byłem wtedy w stanie zrobić test z iteracji:

@Rule 
public ControlledActivityTestRule<MainActivity> mActivityRule = new ControlledActivityTestRule<>(MainActivity.class); 

@Test 
public void testOAA310() { 
    int count = 1000; 
    for (int i = 0; i < count; i++) { 
     testCaseOAA310(); 
     mActivityRule.relaunchActivity(5); 
    } 
} 

void testCaseOAA310() { /* ... blah blah blah... */ } 
+0

Dlaczego 'testOAA310()' wywołuje samo siebie? To wydaje się być nieskończoną rekurencją. –

+0

testOAA310 wywołuje testCaseOAA310 ... nie sam. – djunod

+0

Jaka jest różnica w nazwach tych metod? –

2

Jak JCricket i djunod mówi sposobem na to jest stworzenie niestandardowej reguły. Problem, z którym musiałem się zmierzyć, polega na tym, że metoda finishActivity jest chroniona pakietowo i można jej użyć w niestandardowej regule testowej.

To jest moje rozwiązanie:

public class RelaunchActivityRule<T extends Activity> extends ActivityTestRule<T> { 

    public RelaunchActivityRule(Class<T> activityClass) { 
    super(activityClass,false); 
    } 

    public RelaunchActivityRule(Class<T> activityClass, boolean initialTouchMode) { 
    super(activityClass, initialTouchMode,true); 
    } 

    public RelaunchActivityRule(Class<T> activityClass, boolean initialTouchMode, 
     boolean launchActivity) { 
    super(activityClass, initialTouchMode, launchActivity); 
    } 

    @Override protected void afterActivityFinished() { 
    super.afterActivityFinished(); 
    launchActivity(getActivityIntent()); 
    } 
} 
0

Spróbuj utworzyć regułę niestandardową. Wywołanie launchActivity(getActivityIntent()) w metodzie afterActivityFinished spowoduje ponowne uruchomienie działania po zakończeniu.

public class RestartActivityRule<T extends Activity> extends ActivityTestRule<T> { 

    public RestartActivityRule(Class<T> activityClass) { 
     super(activityClass,false); 
    } 

    public RestartActivityRule(Class<T> activityClass, boolean initialTouchMode) { 
     super(activityClass, initialTouchMode,true); 
    } 

    public RestartActivityRule(Class<T> activityClass, boolean initialTouchMode, 
     boolean launchActivity) { 
     super(activityClass, initialTouchMode, launchActivity); 
    } 

    @Override protected void afterActivityFinished() { 
     super.afterActivityFinished(); 
     launchActivity(getActivityIntent()); 
    } 
} 
Powiązane problemy