Espresso测试,单击Chip view无效

问题描述 投票:0回答:1

我有一个ChipGroup,其中包含一些Chip视图,选中这些视图时会显示一些TextViewsSeekBars。我正在尝试使用Espresso进行测试,但结果却很奇怪。

因为以下测试失败:(Test1)

@Test
fun whenEuropeChipIsSelected_DisplaySeekBarsAndTextViews() {
    launchFragmentInContainer<GameConfigSurvivalFragment>()

    onView(withId(R.id.europeSurvChip)).perform(click())

    onView(withId(R.id.countriesNumberSeekBar)).check(matches(isDisplayed()))
    onView(withId(R.id.selectCountriesNumberTv)).check(matches(isDisplayed()))
    onView(withId(R.id.selectedCountriesTV)).check(matches(isDisplayed()))
    onView(withId(R.id.timeLimitSeekBar)).check(matches(isDisplayed()))
    onView(withId(R.id.timeLimitTv)).check(matches(isDisplayed()))
    onView(withId(R.id.selectTimeLimitTv)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}

我创建了以下简单测试以查看正在发生的情况:(Test2)也失败了。 (请参阅下面的堆栈跟踪)

@Test
fun whenEuropeChipIsClicked_CheckIsSelected() {
    launchFragmentInContainer<GameConfigSurvivalFragment>()

    onView(withId(R.id.europeSurvChip)).perform(click())

    onView(withId(R.id.europeSurvChip)).check(matches(isChecked()))
}

我的一些此功能的生产代码看起来像这样,当我单击芯片时,我插入了一些日志以查看chip的状态:

binding.europeSurvChip.setOnCheckedChangeListener { isChecked ->
        if (isChecked) {
            counter.value = counter.value!!.plus(Europe.totalCountries)
            continentsList.add(Europe)
            Log.d("ChipSelected", "EuropeChipSelected: isChecked: ${europeSurvChip.isChecked}")
        } else {
            counter.value = counter.value!!.minus(Europe.totalCountries)
            continentsList.remove(Europe)
            Log.d("ChipSelected", "EuropeChipSelected: isChecked: ${europeSurvChip.isChecked}")
        }
    }

[在仿真器上手动测试Chip的选择时,我达到了预期的结果,并且我在日志中可以看到Chip被选中和未选中。但是,我创建的Espresso测试从未通过。手动测试一切正常,显示SeekbarsTextViews并检查Chip按钮。

我禁用了动画,因为其他问题向Espresso's click()方法无法正常工作的人们建议使用动画。

知道我在做什么错吗? (一切都在主线程中发生)

想法,我对以下内容没有信心:

  • 这与我使用观察者有关吗?

  • Espresso的click()方法是否不适用于Chip视图? (难以置信)


Test2的堆栈跟踪

    E/TestRunner: failed: whenEuropeChipIsClicked_CheckIsSelected(com.example.capitalcityquizktx.ui.survivalmode.config.GameConfigSurvivalFragmentTest)
    ----- begin exception -----
E/TestRunner: androidx.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with checkbox state: is <true>' doesn't match the selected view.
    Expected: with checkbox state: is <true>
         Got: "Chip{id=2131230840, res-name=europeSurvChip, visibility=VISIBLE, width=315, height=88, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.widget.TableRow$LayoutParams@b19ff14, tag=null, root-is-layout-requested=false, has-input-connection=false, x=11.0, y=11.0, text=Europe, input-type=0, ime-target=false, has-links=false, is-checked=false}"

        at dalvik.system.VMStack.getThreadStackTrace(Native Method)
        at java.lang.Thread.getStackTrace(Thread.java:1720)
        at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:94)
        at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:57)
        at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:318)
        at androidx.test.espresso.ViewInteraction.check(ViewInteraction.java:300)
        at com.example.capitalcityquizktx.ui.survivalmode.config.GameConfigSurvivalFragmentTest.whenEuropeChipIsClicked_CheckIsSelected(GameConfigSurvivalFragmentTest.kt:63)
        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 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
        at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
        at androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
        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)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        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 org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
        at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
        at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
     Caused by: junit.framework.AssertionFailedError: 'with checkbox state: is <true>' doesn't match the selected view.
    Expected: with checkbox state: is <true>
         Got: "Chip{id=2131230840, res-name=europeSurvChip, visibility=VISIBLE, width=315, height=88, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layou
    ----- end exception -----

Test1的stackTrace

    E/TestRunner: failed: whenEuropeChipIsSelected_DisplaySeekBarsAndTextViews_numberOfCountriesAndTimeLimit(com.example.capitalcityquizktx.ui.survivalmode.config.GameConfigSurvivalFragmentTest)
    ----- begin exception -----
E/TestRunner: androidx.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'is displayed on the screen to the user' doesn't match the selected view.
    Expected: is displayed on the screen to the user
         Got: "SeekBar{id=2131230817, res-name=countriesNumberSeekBar, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=true, is-selected=false, layout-params=androidx.constraintlayout.widget.ConstraintLayout$LayoutParams@1f49905, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}"

        at dalvik.system.VMStack.getThreadStackTrace(Native Method)
        at java.lang.Thread.getStackTrace(Thread.java:1720)
        at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:94)
        at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:57)
        at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:318)
        at androidx.test.espresso.ViewInteraction.check(ViewInteraction.java:300)
        at com.example.capitalcityquizktx.ui.survivalmode.config.GameConfigSurvivalFragmentTest.whenEuropeChipIsSelected_DisplaySeekBarsAndTextViews_numberOfCountriesAndTimeLimit(GameConfigSurvivalFragmentTest.kt:49)
        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 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
        at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
        at androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:527)
        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)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        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 org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
        at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:388)
        at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
     Caused by: junit.framework.AssertionFailedError: 'is displayed on the screen to the user' doesn't match the selected view.
    Expected: is displayed on the screen to the user
         Got: "SeekBar{id=2131230817, res-name=countriesNumberSeekBar, visibility=GONE, width=0, height=0, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=fals
    ----- end exception -----


生产代码类。 (它按预期工作):
class GameConfigSurvivalFragment : Fragment(),
GameConfigSurvivalView {

override val continentsList = MutableLiveData<List<Continent>>().default(arrayListOf())
private val displayTimeLimitSeekBar = MutableLiveData<Boolean>().default(false)
private val displayQuestionNumberSeekBar = MutableLiveData<Boolean>().default(false)

override fun showQuestionsNumberSelection() {
    displayQuestionNumberSeekBar.value = true
}

override fun showTimeLimitSelection() {
    displayTimeLimitSeekBar.value = true
}

override fun hideQuestionsNumberSelection() {
    displayQuestionNumberSeekBar.value = false
}

override fun hideTimeLimitSelection() {
    displayTimeLimitSeekBar.value = false
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val binding: GameConfigSurvivalFragmentBinding = inflate(
        inflater, R.layout.game_config_survival_fragment, container, false
    )

    val presenter = GameConfigSurvivalPresenter(this)
    presenter.receiveContinentSelection()

    //Minimum amount of seconds that will be added to timeLimitSeekbar
    val minTimeLimit = 5

    // This counter is used to count the amount of countries to set up the seekBar acording to its value
    val counter = MutableLiveData<Int>()
    counter.value = 0

    // This val is used to gather information about the number of chips that are checked
    // in order to show the seekBar if there are any of them checked
    val continentsSelected = MutableLiveData<Int>()
    continentsSelected.value = 0

    displayQuestionNumberSeekBar.observe(this,
        Observer { displayIt ->
            if (displayIt){
                binding.selectCountriesNumberTv.isVisible = true
                binding.countriesNumberSeekBar.isVisible = true
                binding.selectedCountriesTV.isVisible = true
                binding.countriesNumberSeekBar.max = counter.value!!
                binding.countriesNumberSeekBar.progress = binding.countriesNumberSeekBar.max
            }else{
                binding.selectCountriesNumberTv.isVisible = false
                binding.countriesNumberSeekBar.isVisible = false
                binding.selectedCountriesTV.isVisible = false
            }
        })

    displayTimeLimitSeekBar.observe(this,
        Observer { displayIt ->
            if (displayIt){
                binding.selectTimeLimitTv.isVisible = true
                binding.timeLimitSeekBar.isVisible = true
                binding.timeLimitTv.isVisible = true
            }else{
                binding.selectTimeLimitTv.isVisible = false
                binding.timeLimitSeekBar.isVisible = false
                binding.timeLimitTv.isVisible = false
            }
        })

    /* The following listeners check the state of the chips whether they are checked or not,
    in order to count the number of countries and to count the number of continents selected */

    binding.europeSurvChip.setOnCheckedChangeListener { buttonView, isChecked ->
        if (isChecked) {
            counter.value = counter.value!!.plus(Europe.totalCountries)
            continentsList.add(Europe)
            Log.d("ChipSelected", "EuropeChipSelected: isChecked: ${europeSurvChip.isChecked}")
        } else {
            counter.value = counter.value!!.minus(Europe.totalCountries)
            continentsList.remove(Europe)
            Log.d("ChipSelected", "EuropeChipSelected: isChecked: ${europeSurvChip.isChecked}")
        }
    }

    return binding.root
  }
}
android android-espresso
1个回答
1
投票

通过使Chip在XML文件中可单击和可检查来修复。

我猜它在代码中的某个位置以编程方式使其可单击和可检查。

© www.soinside.com 2019 - 2024. All rights reserved.