如何将Android SingleLaunchActivityTestCase转换为ActivityTestRule?(仪器装置测试)
的文档说明该类现在已被弃用,应替换为如何将Android SingleLaunchActivityTestCase转换为ActivityTestRule?(仪器装置测试),android,unit-testing,android-espresso,android-testing,android-instrumentation,Android,Unit Testing,Android Espresso,Android Testing,Android Instrumentation,的文档说明该类现在已被弃用,应替换为ActivityTestRule。但这是如何做到的 SingleLaunchActivityTestCase允许活动启动一次并保持打开状态;然后在此期间可以运行多个测试,然后关闭活动ActivityTestRule似乎没有此功能-它总是为每个@Test方法重新启动活动 那么,是否可以让ActivityTestRule启动一次活动并保持其打开状态,以及如何确保每个@Test函数的上下文(来自ActivityTestRule.getActivity())不为空 示
ActivityTestRule
。但这是如何做到的
SingleLaunchActivityTestCase
允许活动启动一次并保持打开状态;然后在此期间可以运行多个测试,然后关闭活动ActivityTestRule
似乎没有此功能-它总是为每个@Test方法重新启动活动
那么,是否可以让ActivityTestRule
启动一次活动并保持其打开状态,以及如何确保每个@Test
函数的上下文(来自ActivityTestRule.getActivity()
)不为空
示例代码。使用(将launchActivity
参数设置为false
)。然后在设置中使用,但不要在每个测试方法中使用。这样,您将自己启动一次,但每个测试将在同一实例上运行
您可能还希望在测试类结束时显式完成活动,以进行清理
注意:这通常不是测试的最佳实践,因为测试可能相互依赖(这不是一个好主意),或者根据运行顺序提供不正确的结果,等等。因为在这种情况下,活动状态从一个测试持续到下一个测试。我使用Jon Adams answer以一个示例详细说明:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class KeepActivityOpenDuringTests {
@Rule
public ActivityTestRule<MyActivity> activityTestRule =
new ActivityTestRule<>(MyActivity.class, true, false);
/**
* When running the class as a test suite, setUp() is called repeatedly
* for each test method. Use setupDone to prevent multiple setups.
*/
private static boolean setupDone;
// Static to persist across multiple tests
private static Context context;
private static MyActivity activityUnderTest;
@Before
public void setUp() throws Exception {
// Launch the Activity manually, once, to get a real Context object.
if (!setupDone) {
activityUnderTest = activityTestRule.launchActivity(null);
context = (Context) activityUnderTest;
// continue setup of singletons...
setupDone = true;
}
}
@Test
public void test1() {
// Use context ...
}
@Test
public void test2() {
// Use activityUnderTest ...
}
@AfterClass
public static void cleanUp() throws Exception {
if (activityUnderTest != null) {
activityUnderTest.finish();
// Prevent any potential memory leaks
activityUnderTest = null;
context = null;
setupDone = false;
}
}
}
@RunWith(AndroidJUnit4.class)
@最大的
公共类KeepactivityPenduringTests{
@统治
公共活动测试规则活动测试规则=
新的ActivityTestRule(MyActivity.class,true,false);
/**
*将类作为测试套件运行时,会重复调用setUp()
*对于每种测试方法。使用setupDone可防止多次设置。
*/
私有静态布尔设置完成;
//在多个测试中保持静态
私有静态语境;
私有静态MyActivity活动未测试;
@以前
public void setUp()引发异常{
//手动启动活动一次,以获取真实的上下文对象。
如果(!setupDone){
activityUnderTest=activityTestRule.launchActivity(null);
context=(context)activityUnderTest;
//继续设置单例。。。
setupDone=true;
}
}
@试验
公共void test1(){
//使用上下文。。。
}
@试验
公共无效测试2(){
//使用activityUnderTest。。。
}
@下课
public static void cleanUp()引发异常{
如果(activityUnderTest!=null){
activityUnderTest.finish();
//防止任何潜在的内存泄漏
activityUnderTest=null;
上下文=空;
setupDone=false;
}
}
}
当测试作为一个类或单独运行时,它的工作原理与SingleLaunchActivityTestCase类似。请注意,只有当测试同步运行而不是并行运行时,这种测试才会工作,或者您可能会得到双重设置和/或不一致的活动状态。要明确的是,此代码确实完成了op的要求,但如上所述,这通常是一个不好的测试实践。在上课前使用而不是检查非同步静态初始化切换是否更干净?@jondams有用的反馈,谢谢。也许我错了,但这真的被认为是坏习惯吗?它对于测试静态方法很有用,比如数据库访问,它需要在真实的设备/模拟器上使用真实的上下文。以这种方式运行测试更高效、更快,而不是每次启动和停止活动。它只是复制了SingleLaunchActivityTestCase的行为。可能不是讨论这个问题的最佳场所,但是,是的,快速版本是,这不是一个好主意,因为它增加了固定测试顺序和同步运行程序等要求,这会减慢速度并限制速度,并将测试相互联系起来,因为一个测试可能会根据它做什么或不做什么来设置(或中断)未来的测试,等等。这会使测试变得脆弱并相互依赖。再说一次,这没有错,只是一个坏习惯。不过,总体而言,集成测试是有效的。我指的是跨测试共享活动及其状态的做法是不好的做法。奇怪的是,我发现activityUnderTest
在test1()之后仍然强制finish()
。活动在屏幕上不再可见,但上下文仍处于活动状态。有两种方法尝试在每次测试后完成活动:MonitoringInstrumentation.ActivityFinisher.run()
和ActivityTestRule.finishActivity()
。从2020年9月起,有一个名为ActivityScenarioRule
的新类,该类将取代ActivityTestRule
。这可能会使这项技术变得更容易。更多信息: