为了详细描述这些问题,我提供了我的测试类’简化伪代码和下面的三个问题.两个测试用例都是相互独立的.
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权限错误所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)