Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
独立于Android的片段UI测试工具_Android_Android Testing_Android Espresso_Android Uiautomator - Fatal编程技术网

独立于Android的片段UI测试工具

独立于Android的片段UI测试工具,android,android-testing,android-espresso,android-uiautomator,Android,Android Testing,Android Espresso,Android Uiautomator,我一直在寻找一种方法来分别测试我的片段的UI(即,独立于其他片段和活动),但我找不到一种方法 特别是,假设我有片段A、片段B和片段C。进入片段C的唯一方法(应用程序方面)是首先通过片段A和片段B。我正在寻找一种直接测试片段C的方法(可能通过模拟其依赖关系,如果存在的话),而不必通过片段a和B 到目前为止,我调查的工具包括: monkey:仅用于通过命令行生成伪随机事件。不是我想要的 monkeyrunner:它可以运行Python程序将事件流发送到我的Android应用程序,但它不能直接用这些

我一直在寻找一种方法来分别测试我的片段的UI(即,独立于其他片段和活动),但我找不到一种方法

特别是,假设我有片段A、片段B和片段C。进入片段C的唯一方法(应用程序方面)是首先通过片段A和片段B。我正在寻找一种直接测试片段C的方法(可能通过模拟其依赖关系,如果存在的话),而不必通过片段a和B

到目前为止,我调查的工具包括:

  • monkey:仅用于通过命令行生成伪随机事件。不是我想要的

  • monkeyrunner:它可以运行Python程序将事件流发送到我的Android应用程序,但它不能直接用这些脚本将特定片段作为目标

  • 浓缩咖啡:白盒测试工具。这接近于我想要的,但它仍然需要在到达片段C之前通过片段A和B(即,您需要启动应用程序,然后从那里运行测试)

  • UI自动机:黑盒测试工具。这也很接近,但同样,它需要在测试我想要的片段(片段C)之前通过前面的片段


有什么方法可以直接测试Fragmen的UI吗?

您可以使用。这是用于android UI测试的。

我正在使用自定义的
FragmentTestRule
和浓缩咖啡来单独测试我的
片段

我有一个专用的
测试活动
,显示我的应用程序中测试的
片段。在我的情况下,
活动
只存在于
调试
变量中,因为我的检测测试是针对
调试
运行的

TL;博士使用令人敬畏的图书馆

1。在
src/debug/java/your/package/TestActivity.java
中创建一个
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。为
debug
变量创建一个AndroidManifest.xml
,并声明
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>
4。然后您可以单独测试
片段

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()));
    }
}
公共类MyFragmentTest{
@统治
公共FragmentTestRule MFFragmentTestRule=新的FragmentTestRule(MyFragment.class);
@试验
公共无效片段\u可以\u实例化(){
//启动活动以使片段可见
MFFragmentTestRule.launchActivity(null);
//然后用浓缩咖啡测试碎片
onView(使用id(R.id.an_id_在_片段中)).check(匹配项(isDisplayed());
}
}
我使用开发了一个android库。它允许您单独测试
片段

您只需添加以下内容:

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

public FragmentTestRule如果您正在使用导航架构组件,并且在应用程序中使用单个活动架构,则可以在测试开始时通过深入链接到目标片段(带有适当参数)来快速测试每个片段。

例如:

@Rule
@JvmField
var activityRule = ActivityTestRule(MainActivity::class.java)

protected fun launchFragment(destinationId: Int,
                             argBundle: Bundle? = null) {
    val launchFragmentIntent = buildLaunchFragmentIntent(destinationId, argBundle)
    activityRule.launchActivity(launchFragmentIntent)
}

private fun buildLaunchFragmentIntent(destinationId: Int, argBundle: Bundle?): Intent =
        NavDeepLinkBuilder(InstrumentationRegistry.getInstrumentation().targetContext)
                .setGraph(R.navigation.navigation)
                .setComponentName(MainActivity::class.java)
                .setDestination(destinationId)
                .setArguments(argBundle)
                .createTaskStackBuilder().intents[0]
destinationId是导航图中的片段目标id。下面是一个调用示例,一旦您准备好启动片段,就会执行该调用:

launchFragment(R.id.target_fragment, targetBundle())

private fun targetBundle(): Bundle? {
    val bundle = Bundle()
    bundle.putString(ARGUMENT_ID, "Argument needed by fragment")
    return bundle
}

这样做将直接启动碎片。如果你的测试有效,那么这证明了当碎片深度链接到你的应用程序时,你的应用程序不会崩溃。它还可以确保应用程序在进程被系统终止时保持稳定,并尝试重建堆栈和重新启动片段。

但是Robotium与UI Automator和Espresso存在相同的问题。为了测试片段C,我需要先通过片段A和B。我想要一个可以让我直接测试片段C的工具。因为我一直在使用robotium,它可以解决任何类型的UI测试问题。我不知道您需求的详细信息,所以请检查robotium API@Tiago。我希望waitForFragmentByTag、waitForFragmentById等API可以帮助您。祝你好运。唯一的“小”问题是,你的测试代码与生产性/运行时代码混合在一起(至少在调试版本中),当你向套件中添加更多测试时,这些代码很容易很快就会变得混乱:(如果没有更好的解决方案,可能的解决办法是在调试版本中只保留清单条目,并保留类(测试活动性、规则等)在里面androidTest@thaussma谢谢,这个解决方案也解决了我的问题。我只是想知道,在项目中添加
测试活动
只是为了测试目的,这是一个好的做法吗?@Kavita\p:通常,您希望避免在生产代码中有任何仅测试的依赖项。将
测试活动
添加到生产代码中会破坏这一点规则。我认为在这种情况下,好处大于(小)风险。它简单明了。我认为@Ewoks的评论夸大了一项活动的影响,然后暗示这可能会导致在生产中添加许多其他测试依赖项。这总是一个坏主意。。。
launchFragment(R.id.target_fragment, targetBundle())

private fun targetBundle(): Bundle? {
    val bundle = Bundle()
    bundle.putString(ARGUMENT_ID, "Argument needed by fragment")
    return bundle
}