Android 如果一个 activity 在调用 finish() 开始另一个 activity 后结束/完成,Kotlin 会检测测试
Android Kotlin instrumented test testing if an activity is ended/ finished after calling finish() starting another activity
我正在使用 Kotlin 开发 Android 应用程序。我正在我的项目中添加仪器测试。现在,我正在努力测试在启动另一个 activity 后是否未打开 activity。这是我的场景。
我有启动 LoginActivity 的 MainActivity。
这是MainActivity的代码
class MainActivity : AppCompatActivity() {
companion object {
val LAUNCH_DELAY: Long = 2000
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Handler().postDelayed({
this.startLoginActivity()
finish() //please, pay attention here
}, LAUNCH_DELAY)
}
protected fun startLoginActivity()
{
startActivity(Intent(this, LoginActivity::class.java))
}
}
正如您在上面的代码中看到的,我在启动 LoginActivity 后调用 finish() 方法来终止 activity。我想测试是否在主 activity 启动的登录 activity 中按下后退按钮,应用程序关闭并且它不会返回到主 activity.
这是我的测试class
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@Rule @JvmField
val mainActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule<MainActivity>(MainActivity::class.java)
@Rule @JvmField
val loginActivityRule: ActivityTestRule<LoginActivity> = ActivityTestRule<LoginActivity>(LoginActivity::class.java)
@Before
fun setUp() {
}
@Test
fun mainActivityHistoryIsForgottenAfterStartingLoginActivity()
{
Intents.init()
Thread.sleep(MainActivity.LAUNCH_DELAY);
Intents.release()
pressBack()
//here how can I assert if the main activity is not open.
}
}
请注意代码中的注释。我想断言主 activity 是否未打开,或者当在登录 activity 中按下后退按钮时它不会返回到主 activity。我该如何测试?
由于您想测试与您的应用的高级交互,您应该使用 UI Automator test framework。
先把库添加到build.gradle
:
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}
然后像这样写一个测试:
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val mainActivityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun mainActivityHistoryIsForgottenAfterStartingLoginActivity()
{
// mainActivityRule makes sure MainActivity is launched, so we just need to wait
// for MainActivity to launch LoginActivity
Thread.sleep(MainActivity.LAUNCH_DELAY)
// Wait some more since the system is not instantaneous
Thread.sleep(1000)
// Now LoginActivity should be showing. Press the back button
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
uiDevice.pressBack()
// Wait some more still since the system is not instantaneous
Thread.sleep(1000)
// Make sure that we have left our app, i.e. pressing back have closed our app
// BuildConfig.APPLICATION_ID is the package name of our app
// So if the currently active package (app) is NOT our own app, it means
// our own app was closed, which is what we want to test.
assertNotEquals(uiDevice.currentPackageName, BuildConfig.APPLICATION_ID)
}
}
注意你不应该有这个:
@Rule @JvmField
val loginActivityRule: ActivityTestRule<LoginActivity> = ActivityTestRule<LoginActivity>(LoginActivity::class.java)
因为这将在测试开始时启动 LoginActivity
。你不想要那个。您希望 MainActivity
启动 LoginActivity
。另请注意,您可以简化
@Rule @JvmField
val mainActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule<MainActivity>(MainActivity::class.java)
到
@get:Rule
val mainActivityRule = ActivityTestRule(MainActivity::class.java)
而且你不需要任何
@Before
fun setUp() {
}
因为它是空的,什么也不做。
我正在使用 Kotlin 开发 Android 应用程序。我正在我的项目中添加仪器测试。现在,我正在努力测试在启动另一个 activity 后是否未打开 activity。这是我的场景。
我有启动 LoginActivity 的 MainActivity。
这是MainActivity的代码
class MainActivity : AppCompatActivity() {
companion object {
val LAUNCH_DELAY: Long = 2000
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Handler().postDelayed({
this.startLoginActivity()
finish() //please, pay attention here
}, LAUNCH_DELAY)
}
protected fun startLoginActivity()
{
startActivity(Intent(this, LoginActivity::class.java))
}
}
正如您在上面的代码中看到的,我在启动 LoginActivity 后调用 finish() 方法来终止 activity。我想测试是否在主 activity 启动的登录 activity 中按下后退按钮,应用程序关闭并且它不会返回到主 activity.
这是我的测试class
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@Rule @JvmField
val mainActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule<MainActivity>(MainActivity::class.java)
@Rule @JvmField
val loginActivityRule: ActivityTestRule<LoginActivity> = ActivityTestRule<LoginActivity>(LoginActivity::class.java)
@Before
fun setUp() {
}
@Test
fun mainActivityHistoryIsForgottenAfterStartingLoginActivity()
{
Intents.init()
Thread.sleep(MainActivity.LAUNCH_DELAY);
Intents.release()
pressBack()
//here how can I assert if the main activity is not open.
}
}
请注意代码中的注释。我想断言主 activity 是否未打开,或者当在登录 activity 中按下后退按钮时它不会返回到主 activity。我该如何测试?
由于您想测试与您的应用的高级交互,您应该使用 UI Automator test framework。
先把库添加到build.gradle
:
dependencies {
...
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}
然后像这样写一个测试:
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val mainActivityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun mainActivityHistoryIsForgottenAfterStartingLoginActivity()
{
// mainActivityRule makes sure MainActivity is launched, so we just need to wait
// for MainActivity to launch LoginActivity
Thread.sleep(MainActivity.LAUNCH_DELAY)
// Wait some more since the system is not instantaneous
Thread.sleep(1000)
// Now LoginActivity should be showing. Press the back button
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
uiDevice.pressBack()
// Wait some more still since the system is not instantaneous
Thread.sleep(1000)
// Make sure that we have left our app, i.e. pressing back have closed our app
// BuildConfig.APPLICATION_ID is the package name of our app
// So if the currently active package (app) is NOT our own app, it means
// our own app was closed, which is what we want to test.
assertNotEquals(uiDevice.currentPackageName, BuildConfig.APPLICATION_ID)
}
}
注意你不应该有这个:
@Rule @JvmField
val loginActivityRule: ActivityTestRule<LoginActivity> = ActivityTestRule<LoginActivity>(LoginActivity::class.java)
因为这将在测试开始时启动 LoginActivity
。你不想要那个。您希望 MainActivity
启动 LoginActivity
。另请注意,您可以简化
@Rule @JvmField
val mainActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule<MainActivity>(MainActivity::class.java)
到
@get:Rule
val mainActivityRule = ActivityTestRule(MainActivity::class.java)
而且你不需要任何
@Before
fun setUp() {
}
因为它是空的,什么也不做。