Android-独立的Fragment UI测试工具 [英] Android - Independent Fragment UI testing tool
问题描述
我一直在寻找一种方法来分别测试我的片段的UI(即独立于其他片段和活动),但是我找不到解决方法.
I've been looking for a way to test the UI of my Fragments separately (ie, independently from other fragments and activities) but I can't find a way to do it.
特别是,假设我有片段A,片段B和片段C.进入片段C的唯一方法(应用方式)是先通过片段A和片段B.我正在寻找一种直接测试片段C的方法(可能会通过模拟其依赖关系(如果存在)来进行测试),而不必通过片段A和片段B.
In particular, let's say I have Fragment A, Fragment B and Fragment C. The only way (app-wise) to go to Fragment C is by passing through Fragment A and Fragment B first. I am looking for a way to test Fragment C directly (potentially by mocking its dependencies, if any exists), without having to pass through Fragment A and B.
到目前为止我研究过的工具:
Tools I investigated so far:
-
monkey:仅用于通过命令行生成伪随机事件.不是我想要的.
monkey: only used to generate pseudo-random events through command line. Not what I want.
monkeyrunner:它可以运行Python程序以将事件流发送到我的Android应用程序,但不能直接使用这些脚本将特定的Fragment作为目标.
monkeyrunner: it can run Python programs to send event streams to my Android app, but it cannot target a particular Fragment directly with those scripts.
Espresso:白盒测试工具.这接近我想要的,但是它仍然需要在到达片段C之前通过片段A和B(即,您需要启动您的应用程序,然后测试将从此处运行).
Espresso: white-box testing tool. This comes close to what I want, but it still requires passing through Fragment A and B before reaching Fragment C (ie, you need to start your app and then the tests will run from there).
UI Automator:黑盒测试工具.这也很接近,但是同样,它要求在测试我想要的片段(片段C)之前,先通过之前的片段.
UI Automator: black-box testing tool. This also comes close, but again, it requires passing through the previous Fragments before testing the one I want (Fragment C).
有什么方法可以直接测试Fragmen的用户界面吗?
Is there any way to test the UI of a Fragment directly?
推荐答案
我正在使用自定义FragmentTestRule
和Espresso来分别测试我的每个Fragments
.
I'm am using a custom FragmentTestRule
and Espresso to test each of my Fragments
in isolation.
我有一个专用的TestActivity
,它在我的应用程序中显示了经过测试的Fragments
.在我的情况下,Activity
仅存在于debug
变体中,因为我的检测测试是针对debug
运行的.
I have a dedicated TestActivity
that shows the tested Fragments
in my app. In my case the Activity
only exists in the debug
variant because my instrumentation tests run against debug
.
TL; DR使用@brais-gabin .
1.在src/debug/java/your/package/TestActivity.java
中创建一个TestActivity
,其内容视图会将经过测试的Fragment
添加到以下内容:
1. Create a TestActivity
in src/debug/java/your/package/TestActivity.java
with a content view where the tested Fragment
will be added to:
@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
变体中:
2. Create a AndroidManifest.xml for the debug
variant and declare the TestActivity
. This is required to start the TestActivity
when testing. Add this Manifest to the debug
variant in 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.在src/androidTest/java/your/test/package/FragmentTestRule.java
的androidTest
变体中创建FragmentTestRule
:
3. Create the FragmentTestRule
in the androidTest
variant at 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;
}
}
4.然后,您可以单独测试Fragments
:
4. Then you can test Fragments
in isolation:
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()));
}
}
这篇关于Android-独立的Fragment UI测试工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!