Mat*_*lfe 21 android android-wake-lock android-testing android-espresso
我一直在用androids新的espresso框架编写测试,并发现它运行良好.一个烦人的事情(特别是浓缩咖啡)是我必须确保我的屏幕醒来并解锁以便运行测试.我找到了一种解决方法(通过各种来源),但我不确定整合它的最佳方法.
所以这就是我所做的,在我的"Home"活动中,我有以下代码:
Home.class:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/************ Put this in a conditional for a test version ***********/
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Run Code Online (Sandbox Code Playgroud)
您还需要添加以下权限:
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Run Code Online (Sandbox Code Playgroud)
所以在这样做之后,我的测试现在唤醒我的手机运行所以我没有必须站岗并确保屏幕在测试开始之前没有关闭.
我宁愿不在我的应用程序中包含这些权限.我知道使用gradle可以制作具有自己的android清单的不同"风味",它将合并到主清单中.我正在考虑使用它,但我不想仅仅因为这个已经使用测试构建类型来运行而添加了一种风味.从android gradle文档看起来,您无法为instrumentTest目录创建AndroidManifest,因为它将自动生成.
但是,我想知道是否有另一种方法可以在不创建变量的情况下执行此操作,然后指定测试应该运行该变体.此外,我不确定所有这些的确切语法,并认为只是为了其他人在网站上有这些信息会很好,因为它似乎分散了.
最后,如果有人知道更好的方法来解决唤醒手机测试的问题,我很乐意听到它,因为我不是这种方式的忠实粉丝,我正在尝试.
Mat*_*lfe 15
我实际上想出了一个非常简单的方法来处理这个问题.从主清单中删除keyguard和wakelock权限,并将它们放在src/debug/AndroidManifest.xml中,如下所示:
SRC /调试/ AndroidManifest.xml中
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
</manifest>
Run Code Online (Sandbox Code Playgroud)
当应用程序构建用于调试时,上述权限将合并到主清单中.默认情况下,构建系统使用调试版本进行仪器测试,因此这很好.
然后在我的onCreate中我把问题中提到的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (BuildConfig.DEBUG) {
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
...
}
Run Code Online (Sandbox Code Playgroud)
现在我的手机可以运行测试,而不是我先用手唤醒它们,我没有必要将上述权限添加到我的应用程序的发布版本.
如果从CI环境运行测试,最简单的方法是使用如下所示的adb命令:
adb -s $DEVICE_ID shell input keyevent 82
Run Code Online (Sandbox Code Playgroud)
这将解锁您的设备屏幕.
现在不推荐使用KeyguardLock,您只需使用:
if (BuildConfig.DEBUG) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
Run Code Online (Sandbox Code Playgroud)
我已经按照 Matt 的建议创建了 src/debug/AndroidManifest.xml 文件,并将以下代码添加到 testCase 中:
@Override
public void setUp() throws Exception {
super.setUp();
// Espresso will not launch our activity for us, we must launch it via getActivity().
Activity activity = getActivity();
KeyguardManager km = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
KeyguardManager.KeyguardLock keyguardLock = km.newKeyguardLock("TAG");
keyguardLock.disableKeyguard();
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Run Code Online (Sandbox Code Playgroud)
这是一种不使用任何已弃用的 API、没有明显权限的方法,即使设备设置了锁针也能正常工作。
@RunWith(AndroidJUnit4::class)
class MyActivityTest {
// Replace with your own Activity test rule.
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@Before
fun setUp() {
UiDevice.getInstance(getInstrumentation()).wakeUp()
composeTestRule.activity.setShowWhenLocked(true)
}
}
Run Code Online (Sandbox Code Playgroud)
@RunWith(AndroidJUnit4::class)
class MyActivityTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<MyActivity>()
@get:Rule
val screenLockRule = RunWhenScreenOffOrLockedRule()
}
Run Code Online (Sandbox Code Playgroud)
/**
* This rule will allow the tests to run even if the device's screen is off or locked.
* Allows a developer to fire and forget running the UI Test across different devices or on the CI
* emulator.
*/
class RunWhenScreenOffOrLockedRule : TestRule {
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
override fun evaluate() {
// Turn screen on
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).wakeUp()
// Allow any activity to run when locked
ActivityLifecycleMonitorRegistry
.getInstance()
.addLifecycleCallback { activity, stage ->
if (stage === Stage.PRE_ON_CREATE) {
activity.setShowWhenLocked(true)
}
}
// Continue with other statements
base.evaluate()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7962 次 |
最近记录: |