Android单元测试:ActivityMonitor waitForActivityWithTimeout返回NULL,getActivity永不返回,INJECT_EVENTS权限错误

Android单元测试:ActivityMonitor waitForActivityWithTimeout返回NULL,getActivity永不返回,INJECT_EVENTS权限错误,第1张

概述我正在使用Google推荐的 Android测试框架:ActivityInstrumentationTestCase2.我在RANDOM测试运行中遇到了以下错误,但持续死亡.这意味着有时所有测试都通过了(快乐!),但很多时候它随机地失败了这三个错误中的任何一个.这令人沮丧,让我对测试结果毫无信心. 为了详细描述这些问题,我提供了我的测试类’简化伪代码和下面的三个问题.两个测试用例都是相互独立的. 我正在使用Google推荐的 Android测试框架:ActivityInstrumentationTestCase2.我在RANDOM测试运行中遇到了以下错误,但持续死亡.这意味着有时所有测试都通过了(快乐!),但很多时候它随机地失败了这三个错误中的任何一个.这令人沮丧,让我对测试结果毫无信心.

为了详细描述这些问题,我提供了我的测试类’简化伪代码和下面的三个问题.两个测试用例都是相互独立的.

public class FirstActivityTest extends ActivityInstrumentationTestCase2<FirstActivity> {    private FirstActivity mActivity;    private ActivityMonitor mActivityMonitor;    public FirstActivityTest () {        super(FirstActivity.class);    }    public voID setUp() throws Exception {        super.setUp();        setActivityInitialtouchMode(false);        mActivity = getActivity();        assertNotNull("Cannot start test since target Activity is NulL!",mActivity);        mActivityMonitor = getInstrumentation().addMonitor(SecondActivity.class.getname(),null,false);    }    public voID tearDown() throws Exception {        super.tearDown();        if(mActivity != null) {            mActivity.finish();            mActivity = null;        }        if(mActivityMonitor != null) {            getInstrumentation().removeMonitor(mActivityMonitor);            mActivityMonitor = null;        }    }    /**     * Open FirstActivity,enter a text and click submit button.      * VerifIEs SecondActivity is open.     */    public voID testA_HappyPath() {        Activity secondActivity = null;        try {            //(Omitted) Get edit text and enter a valID value            //(Omitted) Find submitbutton vIEw            //Click submit button            touchUtils.clickVIEw(this,submitbutton);            //Wait for result and valIDate:            secondActivity = mActivityMonitor.waitForActivityWithTimeout(10000);            assertNotNull("Result SecondActivity should NOT be null!",secondActivity );        } finally {            //Clean up:            if(secondActivity != null) {                secondActivity .finish();                secondActivity = null;            }        }    }    /**     * Open FirstActivity,do NOT enter a text and click submit button.      * VerifIEs error message is returned.     */    public voID testB_Sadpath() {        //(Omitted) Find submitbutton vIEw        //Click submit button        touchUtils.clickVIEw(this,submitbutton);        //(Omitted) ValIDate error message is displayed    }}

现在,我一遍又一遍地运行这两个测试用例(它们将按字母顺序运行),结果如下:

>两个测试用例都通过了,OR
> testA_HappyPath()失败,因为ActivityMonitor.waitForActivityWithTimeout()返回NulL SecondActivity.但是当我查看我的设备时,SecondActivity正确显示.不知何故,测试未能注意到它.为什么?
>当testA_HappyPath()失败时,下一个testB_Sadpath()将在setUp()>期间挂起. getActivity()无限期.我想我关闭了tearDown()中的所有内容.为什么?
> testB_Sadpath()经常在touchUtils.clickVIEw()上失败,并出现以下错误:“注入另一个应用程序需要INJECT_EVENTS权限”(无论testA_HappyPath通过还是失败).为什么?

任何有用的反馈表示赞赏.谢谢!

到目前为止,我已经处理了这三个问题,在互联网上研究了很多建议并做了几次尝试和错误.然而,没有一个人能够立即解决特定的问题 – 通过结合我发现的解决了上述问题(1)和(2)的问题,但仍然有问题(3)未解决.下面详细介绍了我为完成这项工作所做的修复.

ISSUE(1)ActivityMonitor.waitForActivityWithTimeout()返回NulL

1.1.我现在知道我必须在getActivit()之前声明getInstrumentation().addMonitor().请看我如何更改setUp()方法,这以某种方式修复了问题.任何了解这为何要求的人请告诉我们,我们对此表示赞赏.

1.2.在模拟器上,此调用偶尔会返回NulL,导致测试失败.我了解到这是因为等待时间太短了.因此,增加等待时间有助于防止ActivityMonitor过早返回.

问题(2)下一个testB_Sadpath()会在setUp()>期间挂起getActivity()无限期

2.1.如上所述,这发生在前一个测试(testA_HappyPath)失败时.我以为我的tearDown()清理了所有东西并准备好下一个测试.发生的事情是,testA正在等待SecondActivity出现在屏幕上,但由于ActivityMonitor.waitForActivityWithTimeout()返回NulL,testA失败. tearDown()执行得很好.问题是SecondActivity确实出现在屏幕上,但它永远不会在finally块中关闭,因为它的方法实例’secondActivity’仍为null.让SecondActivity活着并且在屏幕上徘徊导致下一个getActivity()挂起.我通过更改finally块来修复此问题,以确保SecondActivity是否存在,它会被关闭.

这些更改总结在下面的代码中(请参阅setUp()和finally块).

public class FirstActivityTest extends ActivityInstrumentationTestCase2<FirstActivity> {    private FirstActivity mActivity;    private ActivityMonitor mActivityMonitor;    public FirstActivityTest () {        super(FirstActivity.class);    }    public voID setUp() throws Exception {        super.setUp();        setActivityInitialtouchMode(false);    }    public voID tearDown() throws Exception {        super.tearDown();        if(mActivity != null) {            mActivity.finish();            mActivity = null;        }        if(mActivityMonitor != null) {            getInstrumentation().removeMonitor(mActivityMonitor);            mActivityMonitor = null;        }    }    /**     * Open FirstActivity,enter a text and click submit button.      * VerifIEs SecondActivity is open.     */    public voID testA_HappyPath() {        mActivityMonitor = getInstrumentation().addMonitor(SecondActivity.class.getname(),false);        mActivity = getActivity();        assertNotNull("Cannot start test since target Activity is NulL!",mActivity);        Activity secondActivity = null;        try {            //(Omitted) Get edit text and enter a valID value            //(Omitted) Find submitbutton vIEw            //Click submit button            touchUtils.clickVIEw(this,submitbutton);            //Wait for result and valIDate:            secondActivity = mActivityMonitor.waitForActivityWithTimeout(20000);            assertNotNull("Result SecondActivity should NOT be null!",secondActivity );        } finally {            //Clean up:            if(secondActivity == null) {                //If empty,wait longer because need to shut down the foreground activity,if any:                 secondActivity = mActivityMonitor.waitForActivityWithTimeout(20000);            }            if(secondActivity != null) {                secondActivity .finish();                secondActivity = null;            }        }    }    /**     * Open FirstActivity,do NOT enter a text and click submit button.      * VerifIEs error message is returned.     */    public voID testB_Sadpath() {        mActivity = getActivity();        assertNotNull("Cannot start test since target Activity is NulL!",mActivity);        //(Omitted) Find submitbutton vIEw        //Click submit button        touchUtils.clickVIEw(this,submitbutton);        //(Omitted) ValIDate error message is displayed    }}

ISSUE(3)testB_Sadpath()经常在touchUtils.clickVIEw()上失败,并出现以下错误:“注入另一个应用程序需要INJECT_EVENTS权限”

我还是无法解决最后一期:-(

解决方法 ISSUE(3)testB_Sadpath()经常在touchUtils.clickVIEw()上失败,并出现以下错误:“注入另一个应用程序需要INJECT_EVENTS权限”

我在AndroID单元测试中找到了另一种避免此问题的方法.我没有使用touchUtils.clickVIEw(),而是通过调用performClick()直接对按钮本身执行单击 *** 作.以下修改过的测试代码解决了我偶尔的INJECT_EVENTS权限错误.特别是,请参阅populateDataAndClicksubmit().

/** * Open FirstActivity,enter a text and click submit button.  * VerifIEs SecondActivity is open. */public voID testA_HappyPath() {    mActivityMonitor = getInstrumentation().addMonitor(SecondActivity.class.getname(),false);    mActivity = getActivity();    assertNotNull("Cannot start test since target Activity is NulL!",mActivity);    Activity secondActivity = null;    try {        String dataValue = "MynameIsNolongerFoonorbar";        populateDataAndClicksubmit(dataValue);        //Wait for result and valIDate:        secondActivity = mActivityMonitor.waitForActivityWithTimeout(20000);        assertNotNull("Result SecondActivity should NOT be null!",secondActivity );    } finally {        //Clean up:        if(secondActivity == null) {            //If empty,if any:             secondActivity = mActivityMonitor.waitForActivityWithTimeout(20000);        }        if(secondActivity != null) {            secondActivity.finish();            secondActivity = null;        }    }}/** * Open FirstActivity,do NOT enter a text and click submit button.  * VerifIEs error message is returned. */public voID testB_Sadpath() {    mActivity = getActivity();    assertNotNull("Cannot start test since target Activity is NulL!",mActivity);    String dataValue = null;    populateDataAndClicksubmit(dataValue);    //(Omitted) ValIDate error message is displayed}private voID populateDataAndClicksubmit(final String dataValueString) {    final EditText editDataVIEw = //(omitted) find it from the activity layout    final button submitbutton = //(Omitted) Find submitbutton vIEw    mActivity.runOnUiThread(            new Runnable() {                public voID run() {                    editDataVIEw.setText(dataValueString);                    submitbutton.performClick();               }            }        );    //Wait and allow app to be IDle while performClick to finish and activity re-drawn:    getInstrumentation().waitForIDleSync();}

笔记:

>此解决方案不能解释为什么touchUtils.clickVIEw()会引发偶尔的注入事件权限错误> VIEw.performClick()要求您的活动让VIEw中的VIEw实现OnClickListener().就我而言,submitbutton已经有了,所以它是一个方便测试代码更改.> getInstrumentation().waitForIDleSync()允许测试代码空闲,直到应用程序完成工作并适当地重新绘制其布局.如果查看其java代码,则在touchUtils.clickVIEw()中执行相同的行.

总结

以上是内存溢出为你收集整理的Android单元测试:ActivityMonitor waitForActivityWithTimeout返回NULL,getActivity永不返回,INJECT_EVENTS权限错误全部内容,希望文章能够帮你解决Android单元测试:ActivityMonitor waitForActivityWithTimeout返回NULL,getActivity永不返回,INJECT_EVENTS权限错误所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1125028.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存