У меня есть ChipGroup
, содержащий некоторые Chip
представления, которые, когда отмечены, отображают некоторые TextViews
и SeekBars
. Я пытаюсь проверить это с помощью 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
отмечен и не отмечен. Однако созданные мной эспрессо-тесты никогда не проходят. Тестирование вручную все работает как положено, отображаются Seekbars
и TextViews
, а также проверяется кнопка 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 -----
стек Test1Trace
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
}
}