2012-08-02 11 views
6

Activityの2つの異なるクラスをテストしようとしています。 SharedPreferencesからユーザートークンが非nullの場合IntroActivityTestユニットテスト中にgetActivity()メソッドが無期限にブロックされます

public class RootActivityTest extends ActivityInstrumentationTestCase2<RootActivity> { 

    RootActivity activity; 

    public RootActivityTest() { 

     super(RootActivity.class); 
    } 

    @Override 
    protected void setUp() throws Exception { 

     super.setUp(); 
     activity = getActivity(); 
    } 

    public void testInitialTab() { 

     assertTrue(activity.getSupportActionBar().getSelectedTab().getText().toString().equalsIgnoreCase("Library")); 
    } 
} 

、それはすぐに開始:ここに私のコードは、その後、私はこの問題を説明します:RootActivityTest

IntroActivityTest

public class IntroActivityTest extends ActivityInstrumentationTestCase2<IntroActivity> { 

    IntroActivity activity; 

    public IntroActivityTest() { 

     super(IntroActivity.class); 
    } 

    @Override 
    protected void setUp() throws Exception { 

     super.setUp(); 
     activity = getActivity(); 
    } 

    public void testIntroBypass() { 

     if (new SharedPreferencesHelper(getInstrumentation().getTargetContext()).retrieveUserToken() == null) { 
      assertTrue(!activity.isFinishing()); 
     } 
     else { 
      assertTrue(activity.isFinishing()); 
     } 
    } 
} 

RootActivity。 nullの場合は、IntroActivityのままです。問題は、それがnullでない場合、1番目のテスト(IntroActivityTest)が成功し、RootActivityTestgetActivity()メソッド呼び出しでハングし、テストでは例外が発生せず、その行にハングするだけです。ユーザートークンがNULLの場合、両方のテストが完全に正常に実行されます。

この原因は何ですか?観測からは、RootActivityTestIntroActivityから開始されたRootActivityを使用しようとしていますが、RootActivityのインスタンスを開始してはいけませんか? ActivityInstrumentationTestCase2 APIによれば

答えて

7

このクラスは、単一の活性の機能テストを提供します。テスト中のアクティビティは、(InstrumentationTestCase.launchActivity()を呼び出すことによって)システムインフラストラクチャを使用して作成され、アクティビティを直接操作することができます。

各ActivityInstrumentationTestCase2実装は完全に分離されており、他のActivityInstrumentationTestCase2実装に依存しない独自のライフサイクルを持ちます。テスト可能なアクティビティは、テスト対象のアプリケーション自体からではなく、計測インフラストラクチャを通じて常に作成する必要があります。あなたのケースでは、RootActivityTestはアプリケーションからのIntroActivityによって開始されたRootActivityと、RootActivityに対する継続的な実行テストを選択しません。 RootActivityがどこから来て(InstrumentationTestRunnerではなく)、RootActivityTestを実行している場合、InstrumentationTestRunnerはテスト可能なRootActivityを作成しようとすると混乱し、この見知らぬ人が殺されるのを単に止めて待機します。

SharedPreferencesのユーザートークンがnullでない場合は、をテストするには、すぐにRootActivityを開始します。 nullの場合、それはIntroActivityのままです。IntroActivityTestにすべてを書き込んで、Instrumentation.ActivityMonitorを使用してIntroActivityから開始したRootActivityを検出できます。コードサンプルはhereをご覧ください。 RootActivityTestでgetActivity()を呼び出すときにRootActivityが適切に起動できるように、IntroActivityTestでテストを行った後でRootActivityを完了する必要があることに注意してください。

RootActivityを起動して前面に持ってきた後、RootActivityに関連するすべてのものをテストするためにRootActivityTestを使用します。たとえば、TextViewはよくレンダリングされ、ボタンは正しいことを行います。RootActivityTestでは、 RootActivityの起動方法は、getActivity()を呼び出し、計測可能なRootActivityをインストゥルメンテーションに問い合わせるだけです。

+0

すばらしい答え!私の場合、私の新しいActivityは 'onCreate()'で始まっていたので、私は 'getActivity()'と呼ばれる前にモニタを設定する必要がありました。 –

0

前回のテストでアクティビティが終了せず、新しいテストが同じ意図で開始されたとき、私は同じ問題に直面しました。しかしOS Androidは既にその活動が始まっていて何もしなかったので、InstrumentationTestCaseはすでに起動している活動を待つことを開始しました

関連する問題