我正在使用自定义的 FragmentTestRule
和 Espresso 来测试每个独立的 Fragment
。
我有一个专门的 TestActivity
,用于展示我应用中被测试的 Fragments
。在我的情况下,Activity
只存在于 debug
变体中,因为我的 instrumentation 测试运行在 debug
上。
TL;DR 使用由 @brais-gabin 制作的很棒的 FragmentTestRule 库。
1. 创建一个 TestActivity
文件位于 src/debug/java/your/package/TestActivity.java
中,并设置一个内容视图,在该视图中添加要测试的 Fragment
:
@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. 为 debug
变体创建 AndroidManifest.xml 文件,并声明 TestActivity
。这是在测试时启动 TestActivity
所必需的。将此清单添加到 src/debug/AndroidManifest.xml
中的 debug
变体中:
<?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. 在 androidTest
变体中的路径为 src/androidTest/java/your/test/package/FragmentTestRule.java
创建 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 {
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() {
mFragmentTestRule.launchActivity(null);
onView(withId(R.id.an_id_in_the_fragment)).check(matches(isDisplayed()));
}
}
TestActivity
是否是一个好的做法? - Kavita Patil