标签: android-fragmentscenario

使用 FragmentScenario 测试片段时如何测试与菜单的交互

我正在尝试使用 FragmentScenario 测试片段。这个片段有自己的菜单。操作栏上有一个添加图标,单击此菜单项会启动一个子片段,用户可以从中添加新项目。所以我试图测试这种行为。但是,您可能知道,FragmentScenario 在 EmptyFragmentActivity 中启动片段,而不启动真正的宿主活动。由于操作栏不是片段布局的一部分,而是属于宿主活动,因此在测试期间操作栏和菜单甚至不可见。那么如何测试与菜单的交互呢?

我从官方文档中找到了这条信息:

如果您需要调用片段本身的方法,例如响应选项菜单中的选择,您可以通过实现 FragmentAction 安全地执行此操作:

@RunWith(AndroidJUnit4::class)
class MyTestSuite {
    @Test fun testEventFragment() {
        val scenario = launchFragmentInContainer<MyFragment>()
        scenario.onFragment(fragment ->
            fragment.onOptionsItemSelected(clickedItem) {
                //Update fragment's state based on selected item.
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如何将正确的项目传递给 onOptionsItemSelected 回调?我试图将 addMenuItem 定义为成员变量并在 onCreateOptionsMenu 内部对其进行初始化,但它返回 null。在测试期间似乎没有调用 onCreateOptionsMenu。所以我不知道如何测试用户与菜单的交互。

android menu ui-testing fragment android-fragmentscenario

8
推荐指数
1
解决办法
440
查看次数

如何测试片段场景测试中可见的矢量可绘制对象?

我编写了一些片段场景测试,这些测试将截取屏幕截图和一些点击事件。由于未显示图像视图,很少有测试失败。

测试库( 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

7
推荐指数
0
解决办法
178
查看次数

如何使用FragmentScenario测试Dagger片段?

我正在尝试使用Android Jetpack导航组件和片段测试库来测试片段交互。我的应用程序使用Java + Dagger2作为DI。

为了测试导航,我创建了一个JUnit测试

    @Test
    public void testNavigationToLoginFragment() {
        // Create a mock NavController
        NavController mockNavController = mock(NavController.class);

        // Create a graphical FragmentScenario for the Intro Fragment
        FragmentScenario<IntroFragment> introFragmentScenario = FragmentScenario.launchInContainer(IntroFragment.class);

        // Set the NavController property on the fragment
        introFragmentScenario.onFragment(fragment ->
                Navigation.setViewNavController(fragment.requireView(), mockNavController)
        );

        // Verify that performing a click prompts the correct Navigation action
        onView(withId(R.id.button_login)).perform(click());
        verify(mockNavController).navigate(R.id.action_intro_fragment_to_login_fragment);
    }

Run Code Online (Sandbox Code Playgroud)

每当我运行测试时,都会出现以下错误:

java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: No injector factory bound for Class<XXX>

Run Code Online (Sandbox Code Playgroud)

我如何在这里注入片段?是否可以将DaggerFragments与FragmentScenario一起使用?

java android android-jetpack android-fragmentscenario

6
推荐指数
1
解决办法
95
查看次数

Android FragmentScenario - 无法找到包 androidx.fragment.app.testing

我在 Android 中尝试使用 FragmentScenario 时遇到此错误

error: package androidx.fragment.app.testing does not exist
import androidx.fragment.app.testing.FragmentScenario;
                                    ^
Run Code Online (Sandbox Code Playgroud)

这是我的简单单元测试示例:

package com.example.myapplication;

import androidx.fragment.app.testing.FragmentScenario;
import android.os.Build;

import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;

@RunWith(AndroidJUnit4.class)
@Config(manifest = Config.NONE, sdk = Build.VERSION_CODES.P)
public class MainActivityTest {
    @Test
    public void testFragmentScenario() {
        FragmentScenario<BlankFragment> scenario = FragmentScenario.launchInContainer(BlankFragment.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

构建.gradle(应用程序):

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    def test_version = '1.2.0'
    def fragment_version = …
Run Code Online (Sandbox Code Playgroud)

android android-junit android-fragmentscenario

6
推荐指数
1
解决办法
2450
查看次数

使用 FragmentScenario.EmptyFragmentActivity 测试 AppCompatActivity 工具栏

对于我的测试,我在空活动根视图容器中启动片段

@Before
fun init() {
    scenario = launchFragmentInContainer(null, R.style.Theme_AppCompat) {
        MyFragment()
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的片段中,我配置工具栏以提供后退按钮

(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)
(activity as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
Run Code Online (Sandbox Code Playgroud)

所以当我运行测试时,我得到一个类强制转换异常

java.lang.ClassCastException: androidx.fragment.app.testing.FragmentScenario$EmptyFragmentActivity cannot be cast to androidx.appcompat.app.AppCompatActivity
Run Code Online (Sandbox Code Playgroud)

所以我必须添加一个守卫

if(requireActivity() !is FragmentScenario.EmptyFragmentActivity)
    configureToolBar()    
Run Code Online (Sandbox Code Playgroud)

那么是否有另一种方法来配置工具栏,以便我可以使用 espresso 测试后退按钮意图启动?

编辑

显然有一种方法可以创建自定义活动/容器。

android android-espresso android-fragmentscenario

5
推荐指数
0
解决办法
1349
查看次数

找不到满足版本约束的“androidx.test:monitor”版本

我在运行片段测试时遇到此错误,这是一个启动 fragmentInContatiner 的简单测试:

    Cannot find a version of 'androidx.test:monitor' that satisfies the version constraints: 
   Dependency path 'Host Work.features:ui-home:unspecified' --> 'androidx.test:runner:1.2.0' --> 'androidx.test:monitor:1.2.0'
   Constraint path 'Host Work.features:ui-home:unspecified' --> 'androidx.test:monitor:{strictly 1.1.1}' because of the following reason: debugRuntimeClasspath uses version 1.1.1
   Dependency path 'Host Work.features:ui-home:unspecified' --> 'androidx.fragment:fragment-testing:1.2.0-alpha02' --> 'androidx.test:core:1.1.0' --> 'androidx.test:monitor:1.1.1'
Run Code Online (Sandbox Code Playgroud)

这是我造成此问题的 gradle 依赖项:

implementation 'androidx.fragment:fragment:1.2.0-alpha02'
debugImplementation 'androidx.fragment:fragment-testing:1.2.0-alpha02'
implementation 'androidx.test:core:1.2.0-alpha02'
implementation 'androidx.test:runner:1.2.0-alpha02'
Run Code Online (Sandbox Code Playgroud)

testing fragment android-fragmentscenario

4
推荐指数
1
解决办法
2190
查看次数

片段测试错误:android.view.InflateException:二进制 XML 文件行 #16:二进制 XML 文件行 #16:错误膨胀类 &lt;未知&gt;

我正在尝试按照以下说明测试片段:https ://developer.android.com/training/basics/fragments/testing

launchFragmentInContainer但是,当我从测试中调用时,我遇到了以下崩溃。

堆栈跟踪:

android.view.InflateException: Binary XML file line #16: Binary XML file line #16: Error inflating class <unknown>

Caused by: android.view.InflateException: Binary XML file line #16: Error inflating class <unknown>
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
...
at android.view.LayoutInflater.$$robo$$android_view_LayoutInflater$createView(LayoutInflater.java:647)
...
at com.myapp.poll.PollHomeFragment.onCreateView(PollHomeFragment.kt:31)
...
Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 13: TypedValue{t=0x2/d=0x7f0301b1 a=-1}
at android.content.res.TypedArray.getDrawableForDensity(TypedArray.java:946)
at android.content.res.TypedArray.getDrawable(TypedArray.java:930)
at android.view.View.__constructor__(View.java:5010)
at android.view.View.<init>(View.java)
at android.widget.TextView.<init>(TextView.java)
...
at com.myapp.poll.PollHomeFragment.onCreateView(PollHomeFragment.kt:31)
Run Code Online (Sandbox Code Playgroud)

这是布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" …
Run Code Online (Sandbox Code Playgroud)

android android-fragments android-testing android-fragmentscenario

3
推荐指数
1
解决办法
1200
查看次数

如何使用 FragmentScenario 测试 DaggerFragment?

我有一个简单的Fragment像这样:

class SomeFragment : DaggerFragment() {
    ...
}
Run Code Online (Sandbox Code Playgroud)

现在我想Fragment用它来测试这个FragmentScenario

class LoginFragmentTest {

    @Test
    fun test() {
        launchFragmentInContainer<SomeFragment>()
        onView(withId(R.id.someButton))
            .check(matches(isDisplayed()))
    }

}
Run Code Online (Sandbox Code Playgroud)

但每次我尝试测试时总是:

java.lang.IllegalArgumentException:找不到 <...SomeFragment> 的注入器

我怎样才能正确运行测试?有人可以帮我吗?

android dagger-2 android-fragmentscenario

2
推荐指数
1
解决办法
1043
查看次数

FragmentScenario 未按预期工作

我使用的架构与 Google 示例几乎相同:GithubBrowserSample

该字段被注入到我的 Fragment 类中:

@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

val viewModel: TrainingListViewModel by viewModels {
    viewModelFactory
}
Run Code Online (Sandbox Code Playgroud)

在我的所有片段测试中,我收到此错误,该错误对应于通过注入实例化的字段:

java.lang.RuntimeException: kotlin.UninitializedPropertyAccessException: lateinit property viewModelFactory has not been initialized
at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:441)
at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:564)
at androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:300)
at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)
at com.maximesarrato.lafayapp.ui.training.TrainingListFragmentTest.init(TrainingListFragmentTest.kt:213)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:76)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:104) …
Run Code Online (Sandbox Code Playgroud)

android kotlin androidx android-fragmentscenario

1
推荐指数
1
解决办法
2176
查看次数