我一直在寻找一种方法来分别测试我的碎片的UI(即独立于其他碎片和活动),但我找不到办法。
特别是,假设我有片段A,片段B和片段C.进入片段C的唯一方法(应用方式)是首先通过片段A和片段B.我正在寻找一种直接测试Fragment C的方法(可能通过模拟它的依赖关系,如果存在的话),而不必通过Fragment A和B.
到目前为止我调查的工具:
有没有办法直接测试片段的UI?
我正在使用定制的FragmentTestRule
和Espresso来隔离测试我的每个Fragments
。
我有一个专门的TestActivity
,在我的应用程序中显示测试的Fragments
。在我的情况下,Activity
仅存在于debug
变体中,因为我的仪器测试针对debug
。
TL; DR使用FragmentTestRule的真棒@brais-gabin库。
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
所必需的。将此清单添加到debug
中的src/debug/AndroidManifest.xml
变体中:
<?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.在FragmentTestRule
的androidTest
变体中创建src/androidTest/java/your/test/package/FragmentTestRule.java
:
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;
}
}
然后你可以孤立地测试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()));
}
}
我使用qazxsw poi开发了qazxsw poi一个Android库。它允许您孤立地测试您的FragmentTestRules。
你只需要添加这个:
@thaussma's idea
Fragment
。
你可以使用@Rule
public FragmentTestRule<?, FragmentWithoutActivityDependency> fragmentTestRule =
FragmentTestRule.create(FragmentWithoutActivityDependency.class);
。这是用于Android UI测试。
如果您正在使用导航架构组件并且在应用程序中使用单个活动体系结构,则可以在测试开始时通过深度链接到目标片段(使用适当的参数)快速测试每个片段。
例如:
More information here
destinationId是导航图中的片段目标ID。以下是一旦您准备好启动片段就会执行的调用示例:
Robotium
这样做会直接启动片段。如果你的测试有效,那么证明你的应用程序在片段深层链接时不会崩溃。如果进程被系统杀死并且它尝试重建堆栈并重新启动片段,它还可以确保应用程序稳定。