我目前正在构建一个Android应用程序,我正在进行最好的测试设置,以使我的应用程序防弹:)如果有任何小/大缺失请随时推荐!:)
所以我的测试有点像这样:(请记住我的应用程序有一个后端服务器)
所有这些测试都将在TeamCity CI服务器上运行.我们试图在尽可能多的测试中使用roboletric,因为它比在设备上加载测试更快.
我的问题是,我的设置中是否有任何大/小的缺失,或者是否有任何框架可以使我们更容易运行除了使用robolectric/android maven插件/ teamcity之外的所有这些测试?
我正在尝试为现有应用程序编写一些测试.我想为测试提供一个测试应用程序类,我按照这里的例子,因为我也使用Dagger进行DI.
但是,如果测试中的活动是ActionBarActivity,我会收到以下异常:
java.lang.IllegalArgumentException: android.content.pm.PackageManager$NameNotFoundException: ComponentInfo{mypackage.view.activity/mypackage.view.activity.MyActivity}
at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:282)
at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:116)
at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:57)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98)
at mypackage.view.activity.MyActivity.onCreate(MyActivity.java:68)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.test.ActivityUnitTestCase.startActivity(ActivityUnitTestCase.java:158)
at mypackage.MyActivityTest.test(MyActivityTest.java:89)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
Caused by: android.content.pm.PackageManager$NameNotFoundException: ComponentInfo{mypackage.view.activity/mypackage.view.activity.MyActivity}
at android.app.ApplicationPackageManager.getActivityInfo(ApplicationPackageManager.java:242)
at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:298)
at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:279)
... 21 more
Run Code Online (Sandbox Code Playgroud)
我的测试类如下所示:
public class MyActivityTest extends ActivityUnitTestCase<MyActivity> {
...
public MyActivityTest() {
super(MyActivity.class);
}
private Context context;
private TestBaseApplication application;
@Override
protected void setUp() throws Exception {
super.setUp(); …Run Code Online (Sandbox Code Playgroud) android unit-testing android-testing android-actionbaractivity
我在我的Android(4.0+)应用程序片段(在Activity中)使用Tab栏.
我想创建Espresso测试但是如果我创建主要Activity并打开片段.我得到这个例外:
java.lang.IllegalStateException: ViewPager does not have adapter instance.
at com.astuetz.PagerSlidingTabStrip.setViewPager(PagerSlidingTabStrip.java:177)
at cz.villamemories.detoxme.staticcontent.StaticContentFragment.onCreateView(StaticContentFragment.java:197)
Run Code Online (Sandbox Code Playgroud)
片段中的代码:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewPagerAdapter = new StaticContentPagerAdapter(
this.getChildFragmentManager(), mItemsList, categories);
mPager.setAdapter(mViewPagerAdapter);
mTabs.setViewPager(mPager); //line 197
Run Code Online (Sandbox Code Playgroud)
你有什么提示可能有问题吗?怎么了?
我正在尝试使用MVP来增强单元测试并更快地运行测试(因为我测试的逻辑不是android代码所以我避免使用像RobotElectric这样的东西).
但I'm使用RXAndroid,它需要尺蠖得到Schedulers.io()和AndroidSchedulers.mainThread(),当我尝试运行某个像
class Phone {
public Observable<> sendSms(String number){
//...
}
}
Phone.getInstance().sendSms(phoneNumber)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(phone -> {
mView.dismissProgress();
mView.startCodeView(phone);
}, error -> {
mView.dismissProgress();
mView.showError(error);
});
Run Code Online (Sandbox Code Playgroud)
我明白了:
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.getMainLooper(Looper.java)
at rx.android.schedulers.AndroidSchedulers.<clinit>(AndroidSchedulers.java:27)
... 28 more
Run Code Online (Sandbox Code Playgroud)
我试过了:
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为我想运行完整的JUnit测试,而不是Roboelectric或Espresso的东西.
我怎么能完成它?是否有任何调度程序不会因此而崩溃?
我编写了一些片段场景测试,这些测试将截取屏幕截图和一些点击事件。由于未显示图像视图,很少有测试失败。
测试库( https://developer.android.com/training/basics/fragments/testing )中的测试活动似乎使用 FragmentActivity,它不是 AppCompatActivity 的子类。结果,这些图像视图不可见。我可以添加属性android:src以使其在测试中可见,但这将是一个丑陋的修复。还有其他解决办法吗?
感谢对此的任何评论或建议。
view_item.xml
<ImageView
android:id="@+id/ivRemove"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="@dimen/spacing_16dp"
android:layout_marginTop="@dimen/spacing_16dp"
android:layout_marginBottom="@dimen/spacing_16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_remove" />
Run Code Online (Sandbox Code Playgroud)
构建.gradle.kts
defaultConfig {
this.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
this.vectorDrawables.useSupportLibrary = true
}
Run Code Online (Sandbox Code Playgroud) android android-testing android-vectordrawable android-fragmentscenario
我添加coreLibraryDesugaringEnabled到我们的应用程序中,它对于正常的应用程序运行来说工作得很好。
compileOptions {
coreLibraryDesugaringEnabled true
}
Run Code Online (Sandbox Code Playgroud)
和
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
Run Code Online (Sandbox Code Playgroud)
但是,当我运行连接测试时,它会崩溃,并且类上没有此类方法错误Stream:
16:03:56.426 11998 12041 E AndroidRuntime: FATAL EXCEPTION: com....
16:03:56.426 11998 12041 E AndroidRuntime: Process: ...
16:03:56.426 11998 12041 E AndroidRuntime: java.lang.NoSuchMethodError: No static method e([Ljava/lang/Object;)Lj$/util/stream/Stream; in class Lj$/util/n; or its super classes (declaration of 'j$.util.n' appears in /data/app/com....-qU6nwXthxze4O_9rcf1hGg==/base.apk!classes2.dex)
16:03:56.426 11998 12041 E AndroidRuntime: at j$.util.stream.Stream$-CC.of(:1000)
16:03:56.426 11998 12041 E AndroidRuntime: at ...
Run Code Online (Sandbox Code Playgroud)
我发现一些模糊的参考,这可能是因为在调用Multidex.install?之前引用了该类。我首先将该类引用为静态初始化程序,因此可以很早就访问它。不确定这是否是转移注意力,但我想我会提一下。
如果有帮助,则使用AndroidJUnit4ClassRunner.
编辑:我发现了一个模糊的参考,只有一篇文章指出仪器测试不支持这一点:
请注意,在 Android Studio 4.0 中,不支持在仪器测试中使用这些库脱糖类型。
https://medium.com/androiddevelopers/support-for-newer-java-language-apis-bca79fc8ef65
但即使是谷歌关于该功能的嵌入式视频也没有提及这一点。也不确定 …
我有一个设置背景颜色的可组合项,我想测试一下。
@Composable
fun MyComposableButton(
enabledColor: Color,
disableColor: Color,
isEnabled: Boolean = true,
) {
val buttonBackgroundColor = if (enabled) enabledColor else disableColor
Button(
...
enabled = enabled,
colors = ButtonDefaults.textButtonColors(
backgroundColor = buttonBackgroundColor
)
) { ... }
}
Run Code Online (Sandbox Code Playgroud)
我期待编写如下测试:verifyEnabledBackgroundColor和verifyDisabledBakcgroundColor。
我在组合测试中找不到直接可用的任何断言,当尝试创建自己的断言时,我发现使用SemanticMatcther了 a SemanticNode,但构造函数是最新的内部断言,因此无法进行。
我尝试过mock,Color但我做不到,根据这个答案,需要高 API 级别,这对我的项目来说是不行的。
如何测试设置可组合项的背景颜色?
我正在使用 jetpack compose 并使用此代码来显示我的 Snackbar:
LaunchedEffect(true) {
viewModel.snackBar.collectLatest { message ->
scaffoldState.snackbarHostState.currentSnackbarData?.dismiss()
scaffoldState.snackbarHostState.showSnackbar(message = message)
}
}
Run Code Online (Sandbox Code Playgroud)
通常,当我想访问 compose 元素时,我使用testTagin modifier。但 Snackbar 没有。那么我如何测试我的 Snackbar 是否显示特定文本?
我尝试使用:
composeRule.onNodeWithText(SNACKBAR_MESSAGE).assertIsDisplayed()
Run Code Online (Sandbox Code Playgroud)
但它找不到任何节点。
testing android android-testing android-snackbar android-jetpack-compose
我正在尝试使用 Kotlin(1.6.21) Coroutines(1.6.4) 和 Kotlin Flow 进行 ViewModel 测试。
遵循官方Kotlin 协程测试文档,但ViewModel 在测试完成之前不会等待/返回挂起函数的结果。已经浏览了 StackOverflow 的热门答案,并尝试了所有建议的解决方案,例如注入相同的内容CoroutineDispatcher,并传递相同的内容CoroutineScope,但到目前为止没有一个有效。所以在这里我发布当前的简单测试实现。必须发布测试用例中涉及的所有类代码以获得更好的想法。
ReferEarnDetailViewModel.kt:
注入 Usecase 和 CoroutineContextProvider 并使用 viewModelScope 和提供的调度程序调用 API。但是从测试用例调用callReferEarnDetails()后,它不会收集模拟用例方法发出的任何数据。已尝试使用直接 repo 方法调用,也没有 Kotlin 流程,但同样失败。
@HiltViewModel class
ReferEarnDetailViewModel @Inject constructor(
val appDatabase: AppDatabase?,
private val referEarnDetailsUseCase: ReferEarnDetailsUseCase,
private val coroutineContextProvider: CoroutineContextProvider) : BaseViewModel() {
fun callReferEarnDetails() {
setProgress(true)
viewModelScope.launch(coroutineContextProvider.default + handler) {
referEarnDetailsUseCase.execute(UrlUtils.getUrl(R.string.url_referral_detail))
.collect { referEarnDetail ->
parseReferEarnDetail(referEarnDetail)
}
}
}
private fun parseReferEarnDetail(referEarnDetail:
ResultState<CommonEntity.CommonResponse<ReferEarnDetailDomain>>) {
when (referEarnDetail) …Run Code Online (Sandbox Code Playgroud) android kotlin android-testing android-viewmodel kotlin-coroutines
编辑:发现 MockK 导致了这个问题。我猜当我模拟 API 请求时,它会复制这些文件。当我删除 MockK 和/或 Mockito 时。我没有收到这些错误。有任何想法吗?
收到此错误,表明存在这些重复的元数据文件。我尝试在 build.gradle 文件中添加打包选项块以排除这些文件,但随后我的测试根本无法运行。有没有办法手动删除重复项?这些文件将位于哪里?任何帮助是极大的赞赏。我迷路了哈哈。
测试:
@RunWith(AndroidJUnit4::class)
class ViewModelTests {
@get:Rule(order = 1)
val testRule = ActivityScenarioRule(MainActivity::class.java)
private lateinit var viewModel: NewsViewModel
private lateinit var repositoryImpl: RepositoryImpl
private val context = InstrumentationRegistry.getInstrumentation().targetContext
@Before
fun setUp() {
val newsDao = NewsDatabase.getDatabase(context).myDao()
val newsApi = mockk<NewsApi>()
viewModel = mockk()
repositoryImpl = RepositoryImpl(newsApi, newsDao)
}
@Test
fun test_empty_database() = runBlocking {
assertEquals(0, repositoryImpl.getNewsFromDatabase.value?.size)
}
}
Run Code Online (Sandbox Code Playgroud)
错误:任务“:app:mergeDebugAndroidTestJavaResource”执行失败。
执行 com.android.build.gradle.internal.tasks.MergeJavaResWorkAction 时发生故障 从输入中找到路径“META-INF/LICENSE.md”的 6 个文件: - /Users/sammorton/.gradle/caches/modules-2/文件-2.1/org.junit.jupiter/junit-jupiter-params/5.8.2/ddeaf92fc263f895bfb73ffeca7fd56e23c2cce/junit-jupiter-params-5.8.2.jar - …
android-testing ×10
android ×9
kotlin ×2
unit-testing ×2
build.gradle ×1
gradle ×1
java ×1
robolectric ×1
rx-android ×1
rx-java ×1
testing ×1