14

私は(独立して他のフラグメントとの活動から、すなわち)別に私のフラグメントのUIをテストするための方法を探してきたが、私はそれを行うための方法を見つけることができません。アンドロイド - 独立フラグメントUIテストツール

特にフラグメントA、フラグメントB、フラグメントCがあるとしましょう。フラグメントCに行く唯一の方法は、フラグメントAとフラグメントBをまず通過させることです。私がこれまでに調査し、私は断片AとBを介して

ツールを渡すことなく、(潜在的に任意のが存在する場合、その依存関係をあざけることで)直接フラグメントCをテストするための方法を探しています:

  • monkey:コマンドラインから疑似ランダムイベントを生成するためにのみ使用されます。私が望むものではありません。

  • monkeyrunner:Pythonプログラムを実行してAndroidアプリにイベントストリームを送信できますが、特定のフラグメントをそれらのスクリプトで直接ターゲティングすることはできません。

  • エスプレッソ:ホワイトボックステストツール。これは私が欲しいものに近づきますが、フラグメントCに達する前にフラグメントAとBを通過する必要があります(つまり、アプリケーションを起動してそこからテストを実行する必要があります)。

  • UI Automatorの:ブラックボックステストツール。これも近いですが、もう一度、私が望むもの(フラグメントC)をテストする前に、前のフラグメントを渡す必要があります。

直接テストFragmenトンのUIにする方法はありますか?あなたはRobotium .Thisを使用することができます

答えて

43

私は単独で私のFragmentsのそれぞれをテストするために、カスタムFragmentTestRuleとエスプレッソを使用していています。

は、私は私のアプリでテストした Fragmentsを示し専用 TestActivityを持っています。私の場合、 debugに対して計測テストが実行されるため、 Activitydebugの亜種にのみ存在します。

1.試験Fragmentが追加されるコンテンツビューとsrc/debug/java/your/package/TestActivity.javaTestActivity作成:debug変異体のためのAndroidManifest.xmlを作成しTestActivityを宣言

@VisibleForTesting 
public class TestActivity extends AppCompatActivity { 
    @Override 
    protected void onCreate(@Nullable final Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     FrameLayout frameLayout = new FrameLayout(this); 
     frameLayout.setId(R.id.container); 
     setContentView(frameLayout); 
    } 
} 

2 。これは、テスト時にTestActivityを開始するために必要です。 src/debug/AndroidManifest.xmldebugバリアントに、このマニフェストを追加します。

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> 
    <application>   
     <activity android:name="your.package.TestActivity"/> 
    </application> 
</manifest> 

3. src/androidTest/java/your/test/package/FragmentTestRule.javaandroidTestバリアントでFragmentTestRuleを作成します。

public class FragmentTestRule<F extends Fragment> extends ActivityTestRule<TestActivity> { 

    private final Class<F> mFragmentClass; 
    private F mFragment; 

    public FragmentTestRule(final Class<F> fragmentClass) { 
     super(TestActivity.class, true, false); 
     mFragmentClass = fragmentClass; 
    } 

    @Override 
    protected void afterActivityLaunched() { 
     super.afterActivityLaunched(); 

     getActivity().runOnUiThread(() -> { 
      try { 
       //Instantiate and insert the fragment into the container layout 
       FragmentManager manager = getActivity().getSupportFragmentManager(); 
       FragmentTransaction transaction = manager.beginTransaction(); 
       mFragment = mFragmentClass.newInstance(); 
       transaction.replace(R.id.container, mFragment); 
       transaction.commit(); 
      } catch (InstantiationException | IllegalAccessException e) { 
       Assert.fail(String.format("%s: Could not insert %s into TestActivity: %s", 
         getClass().getSimpleName(), 
         mFragmentClass.getSimpleName(), 
         e.getMessage())); 
      } 
     }); 
    } 
    public F getFragment(){ 
     return mFragment; 
    } 
} 

4。そして、あなたは単独でFragmentsをテストすることができます。

public class MyFragmentTest { 

    @Rule 
    public FragmentTestRule<MyFragment> mFragmentTestRule = new FragmentTestRule<>(MyFragment.class); 

    @Test 
    public void fragment_can_be_instantiated() { 

     // Launch the activity to make the fragment visible 
     mFragmentTestRule.launchActivity(null); 

     // Then use Espresso to test the Fragment 
     onView(withId(R.id.an_id_in_the_fragment)).check(matches(isDisplayed())); 
    } 
} 
+0

唯一の** "少し" **のことは、あなたのテストコードが(少なくともデバッグビルドで)生産的/ランタイムコードと混在していることです。より良い解決策が存在しない場合は、デバッグビルドでのマニフェストエントリを残し、androidTestのクラス(TestActivity、Ruleなど)を保持することです – Ewoks

1

は、AndroidのUIテストのためです。

+1

しかし、RobotiumはUI AutomatorとEspressoと同じ問題があります。フラグメントCをテストするには、まずフラグメントAとBを通過する必要があります。私はフラグメントCを直接テストするためのツールが必要です。 – Tiago

+0

私はrobotiumを使用しているので、あらゆる種類のUIテストの問題を解決します。要件の詳細はわかりませんので、robotium API http://robotium.googlecode.com/svn/doc/com/robotium/soloを確認してください/Solo.html –

+0

@Tiago私はwaitForFragmentByTagのようなAPIを望んでいますが、waitForFragmentByIdは役に立ちます。がんばろう。 –

0

私は@thaussma's ideaを使用してAndoridライブラリをFragmentTestRule開発しました。 Fragmentを単独でテストすることができます。

あなたはこれを追加する必要があります。

@Rule 
public FragmentTestRule<?, FragmentWithoutActivityDependency> fragmentTestRule = 
    FragmentTestRule.create(FragmentWithoutActivityDependency.class); 

More information here

関連する問題