Android: 为 Fragments 编写测试用例
Android: Writing test cases for Fragments
在我以前的项目中,我通过活动完成了大部分工作,并根据文档使用了 ActivityInstrumentationTestCase2:
http://developer.android.com/tools/testing/activity_testing.html
我知道如何使用 Activity 个测试用例;但是说到 Fragment ,我没有太多的想法,也没有找到很多相关的文档。
那么当我有几个具有一两个活动的片段时如何编写测试用例呢?
任何示例代码或样本都会更有帮助。
这是使用 ActivityInstrumentationTestCase2
的粗略指南:
步骤 1。创建一个空白 Activity 来保存您的片段
private static class FragmentUtilActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout view = new LinearLayout(this);
view.setId(1);
setContentView(view);
}
}
第 2 步:
在您的测试中,实例化您的片段并将其添加到空白 activity
public class MyFragmentTest extends ActivityInstrumentationTestCase2<FragmentUtilActivity> {
private MyFragment fragment;
@Before
public void setup() {
fragment = new MyFragment();
getActivity().getFragmentManager().beginTransaction().add(1, fragment, null).commit();
}
}
步骤 3 测试您的实例化片段
@Test
public void aTest() {
fragment.getView().findViewById(...);
}
如果您使用 robolectric,使用 FragmentUtilTest class:
非常简单
@Test
public void aTest() {
// instantiate your fragment
MyFragment fragment = new MyFragment();
// Add it to a blank activity
FragmentTestUtil.startVisibleFragment(fragment);
// ... call getView().findViewById() on your fragment
}
使用您的主要 activity 作为发送到 ActivityInstrumentationTestCase2 的测试 activity。然后,您可以通过启动片段的主要 activity 的片段管理器来处理片段。这甚至比测试 activity 更好,因为它使用您在主 activity 中编写的逻辑来测试场景,从而提供更全面和更完整的测试。
示例:
public class YourFragmentTest extends ActivityInstrumentationTestCase2<MainActivity> {
public YourFragmentTest(){
super(MainActivity.class);
}
}
这是我的工作解决方案:
在 androidTest 目录中为此创建一个检测单元测试 class,即:
public class FragmentTest extends
ActivityInstrumentationTestCase2<MainActivity> {
private MainActivity testingActivity;
private TestFragment testFragment;
//...
}
在这个新的 class:
中调用这个构造函数
public FragmentTest() {
super(MainActivity.class);
}
重写 setUp() 方法(确保 R.id.fragmentContainer 在你的 Activity class 中)你将在最后调用 waitForIdleSync():
@Override
protected void setUp() throws Exception {
super.setUp();
// Starts the activity under test using
// the default Intent with:
// action = {@link Intent#ACTION_MAIN}
// flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
// All other fields are null or empty.
testingActivity = getActivity();
testFragment = new TestFragment();
testingActivity.getFragmentManager().beginTransaction().add(R.id.fragmentContainer,testFragment,null).commit();
/**
* Synchronously wait for the application to be idle. Can not be called
* from the main application thread -- use {@link #start} to execute
* instrumentation in its own thread.
*
* Without waitForIdleSync(); our test would have nulls in fragment references.
*/
getInstrumentation().waitForIdleSync();
}
写一个测试方法,例如:
public void testGameFragmentsTextViews() {
String empty = "";
TextView textView = (TextView)testFragment.getView().findViewById(R.id.myTextView);
assertTrue("Empty stuff",(textView.getText().equals(empty)));
}
运行 测试.
现在 ActivityInstrumentationTestCase2 已弃用。现在您可以使用规则在测试中使用活动:http://wiebe-elsinga.com/blog/whats-new-in-android-testing/
为了使这些工作正常,您必须添加依赖项 build.gradle:
testCompile 'com.android.support.test:rules:0.5'
testCompile 'com.android.support.test:runner:0.5'
(见)
AndroidX
提供了一个库,FragmentScenario
,用于创建片段并更改它们的状态。
app/build.gradle
dependencies {
def fragment_version = "1.0.0"
// ...
debugImplementation 'androidx.fragment:fragment-testing:$fragment_version'
}
例子
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" and "factory" arguments are optional.
val fragmentArgs = Bundle().apply {
putInt("selectedListItem", 0)
}
val factory = MyFragmentFactory()
val scenario = launchFragmentInContainer<MyFragment>(
fragmentArgs, factory)
onView(withId(R.id.text)).check(matches(withText("Hello World!")))
}
}
更多信息在 official docs。
在我以前的项目中,我通过活动完成了大部分工作,并根据文档使用了 ActivityInstrumentationTestCase2:
http://developer.android.com/tools/testing/activity_testing.html
我知道如何使用 Activity 个测试用例;但是说到 Fragment ,我没有太多的想法,也没有找到很多相关的文档。
那么当我有几个具有一两个活动的片段时如何编写测试用例呢?
任何示例代码或样本都会更有帮助。
这是使用 ActivityInstrumentationTestCase2
的粗略指南:
步骤 1。创建一个空白 Activity 来保存您的片段
private static class FragmentUtilActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout view = new LinearLayout(this);
view.setId(1);
setContentView(view);
}
}
第 2 步: 在您的测试中,实例化您的片段并将其添加到空白 activity
public class MyFragmentTest extends ActivityInstrumentationTestCase2<FragmentUtilActivity> {
private MyFragment fragment;
@Before
public void setup() {
fragment = new MyFragment();
getActivity().getFragmentManager().beginTransaction().add(1, fragment, null).commit();
}
}
步骤 3 测试您的实例化片段
@Test
public void aTest() {
fragment.getView().findViewById(...);
}
如果您使用 robolectric,使用 FragmentUtilTest class:
非常简单@Test
public void aTest() {
// instantiate your fragment
MyFragment fragment = new MyFragment();
// Add it to a blank activity
FragmentTestUtil.startVisibleFragment(fragment);
// ... call getView().findViewById() on your fragment
}
使用您的主要 activity 作为发送到 ActivityInstrumentationTestCase2 的测试 activity。然后,您可以通过启动片段的主要 activity 的片段管理器来处理片段。这甚至比测试 activity 更好,因为它使用您在主 activity 中编写的逻辑来测试场景,从而提供更全面和更完整的测试。
示例:
public class YourFragmentTest extends ActivityInstrumentationTestCase2<MainActivity> {
public YourFragmentTest(){
super(MainActivity.class);
}
}
这是我的工作解决方案:
在 androidTest 目录中为此创建一个检测单元测试 class,即:
public class FragmentTest extends ActivityInstrumentationTestCase2<MainActivity> { private MainActivity testingActivity; private TestFragment testFragment; //... }
在这个新的 class:
中调用这个构造函数public FragmentTest() { super(MainActivity.class); }
重写 setUp() 方法(确保 R.id.fragmentContainer 在你的 Activity class 中)你将在最后调用 waitForIdleSync():
@Override protected void setUp() throws Exception { super.setUp(); // Starts the activity under test using // the default Intent with: // action = {@link Intent#ACTION_MAIN} // flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK} // All other fields are null or empty. testingActivity = getActivity(); testFragment = new TestFragment(); testingActivity.getFragmentManager().beginTransaction().add(R.id.fragmentContainer,testFragment,null).commit(); /** * Synchronously wait for the application to be idle. Can not be called * from the main application thread -- use {@link #start} to execute * instrumentation in its own thread. * * Without waitForIdleSync(); our test would have nulls in fragment references. */ getInstrumentation().waitForIdleSync(); }
写一个测试方法,例如:
public void testGameFragmentsTextViews() { String empty = ""; TextView textView = (TextView)testFragment.getView().findViewById(R.id.myTextView); assertTrue("Empty stuff",(textView.getText().equals(empty))); }
运行 测试.
现在 ActivityInstrumentationTestCase2 已弃用。现在您可以使用规则在测试中使用活动:http://wiebe-elsinga.com/blog/whats-new-in-android-testing/
为了使这些工作正常,您必须添加依赖项 build.gradle:
testCompile 'com.android.support.test:rules:0.5'
testCompile 'com.android.support.test:runner:0.5'
(见
AndroidX
提供了一个库,FragmentScenario
,用于创建片段并更改它们的状态。
app/build.gradle
dependencies {
def fragment_version = "1.0.0"
// ...
debugImplementation 'androidx.fragment:fragment-testing:$fragment_version'
}
例子
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" and "factory" arguments are optional.
val fragmentArgs = Bundle().apply {
putInt("selectedListItem", 0)
}
val factory = MyFragmentFactory()
val scenario = launchFragmentInContainer<MyFragment>(
fragmentArgs, factory)
onView(withId(R.id.text)).check(matches(withText("Hello World!")))
}
}
更多信息在 official docs。