提问人:Sergi Poza Paterna 提问时间:11/17/2023 更新时间:11/17/2023 访问量:6
多模块android应用中的测试结构
Testing structure in multi-module android application
问:
我对在 Android 中的测试有点困惑。我对 e2e 和集成测试感到困惑,我不知道我应该将它们放在哪个模块(数据、域或演示文稿)中。
据我了解,e2e 测试整个系统的行为是否符合其部署方式。例如,验证当我将有效凭据放在登录屏幕上时,它是否登录并重定向到另一个屏幕。而且,集成测试的重点是测试不同组件的集成,例如存储库与数据源(如数据库或其他)的交互。
因此,我对何时应该进行 e2e 或集成测试有疑问。假设我有一个登录屏幕,其中包含一个 View an VM 类。 我应该为 View(e2e 期望登录行为)和 VM(集成期望状态正确更新并且存储库按预期响应)创建不同的测试,还是只是检查整个登录系统是否正常工作的 e2e 测试?
此外,我一直在思考我应该如何在不同的模块中组织所有这些测试,以
一个集成测试,用于验证用例是否与模拟存储库正确交互
private lateinit var authRepository: AuthRepository
private lateinit var loginUsecase: LoginUsecase
@ExperimentalCoroutinesApi
@get:Rule
var mainCoroutineRole = MainCoroutineRole()
@BeforeEach
fun setup() {
mockkClass(AuthRepository::class)
authRepository = mockk()
loginUsecase = LoginUsecase(authRepository)
}
@Test
fun `login with valid credentials returns user`() = runBlocking {
val expected = User(username = "spozap", password = "P@ssw0rd!")
coEvery { authRepository.login(expected.username, expected.password) } returns flow { Resource.Success(expected) }
loginUsecase("spozap", "P@ssw0rd!")
coVerify { authRepository.login("spozap", "P@ssw0rd!") }
}
验证用例的一些单元:
private lateinit var validatePasswordUsecase: ValidatePasswordUsecase
@BeforeEach
fun init() {
validatePasswordUsecase = ValidatePasswordUsecase()
}
@Test
fun `it returns validation error with NOT_NULL_FILLED code when empty password`() {
val result = validatePasswordUsecase("")
val expected = ValidationResult( successful = false, errorMessage = ValidationError.NOT_NULL_FIELD )
assertThat(result).isEqualTo(expected)
}
@Test
fun `it returns successful validation result with no errorMessage when password is valid`() {
val result = validatePasswordUsecase("P@ssw0rd!")
val expected = ValidationResult(successful = true, errorMessage = null)
assertThat(result).isEqualTo(expected)
}
还有一个 UI 测试
private lateinit var navController: NavHostController
@get:Rule(order = 0)
val hiltRule = HiltAndroidRule(this)
@get:Rule(order = 1)
val composeRule = createAndroidComposeRule<MainActivity>()
@Before
fun setup() {
hiltRule.inject()
composeRule.activity.setContent {
navController = rememberNavController()
AppTheme {
NavHost(navController = navController, startDestination = AppScreens.Login.route ) {
composable(route = AppScreens.Login.route) {
LoginScreen(navController = navController)
}
composable(route = AppScreens.Home.route) {
HomeScreen()
}
}
}
}
}
@Test
fun loginWithValidCredentialsRedirectsToHomeScreen() {
composeRule.onNodeWithTag(TestTags.USERNAME_INPUT).performTextInput("user1")
composeRule.onNodeWithTag(TestTags.PASSWORD_INPUT).performTextInput("P@ssw0rd")
composeRule.onNodeWithText("Entrar").performClick()
assertThat(navController.currentBackStackEntry?.destination?.route)
.isEqualTo(AppScreens.Home.route)
}
答: 暂无答案
评论