Add: shortform fragment test

This commit is contained in:
Carlos Martinez
2021-06-17 14:20:25 -04:00
parent 7aa023c417
commit b734faa574
6 changed files with 208 additions and 5 deletions

View File

@@ -29,5 +29,14 @@ dependencies {
api deps.core.rx.android api deps.core.rx.android
api deps.core.thirdparty.timber api deps.core.thirdparty.timber
api deps.testing.junit
api deps.testing.koin
api deps.testing.core
api deps.testing.rules
api deps.testing.runner
api deps.testing.ext
api deps.testing.espresso
api deps.testing.fragments
kapt deps.core.room.compiler kapt deps.core.room.compiler
} }

View File

@@ -0,0 +1,79 @@
package dev.carlos.core.extensions
import android.view.KeyEvent
import androidx.annotation.IdRes
import androidx.annotation.RestrictTo
import androidx.test.espresso.Espresso
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.hamcrest.Matchers
import org.hamcrest.Matchers.allOf
import org.junit.Assert
@RestrictTo(RestrictTo.Scope.TESTS)
fun String.isTextDisplayed() = Espresso.onView(withText(this)).check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.isDisplayed(): ViewInteraction = Espresso.onView(ViewMatchers.withId(this))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.isNotDisplayed(): ViewInteraction = Espresso.onView(ViewMatchers.withId(this))
.check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed())))
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.click(): ViewInteraction = Espresso.onView(ViewMatchers.withId(this))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click())
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.clickOnClickWithId(@IdRes childId: Int): ViewInteraction = Espresso.onView(
allOf(
ViewMatchers.withId(childId),
ViewMatchers.withParent(ViewMatchers.withId(this))
)
)
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click())
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.clickOnClickWithText(text: String): ViewInteraction = Espresso.onView(
allOf(
withText(text),
ViewMatchers.withParent(ViewMatchers.withId(this))
)
)
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click())
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.typeOn(text: String): ViewInteraction = Espresso.onView(ViewMatchers.withId(this)).perform(typeText(text), closeSoftKeyboard())
@RestrictTo(RestrictTo.Scope.TESTS)
fun Int.pressEnterKey(): ViewInteraction = Espresso.onView(ViewMatchers.withId(this))
.perform(ViewActions.pressKey(KeyEvent.KEYCODE_ENTER))
@RestrictTo(RestrictTo.Scope.TESTS)
fun String.isDisplayed(): ViewInteraction = Espresso.onView(ViewMatchers.withSubstring(this))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
@RestrictTo(RestrictTo.Scope.TESTS)
fun String.isHinted(): ViewInteraction = Espresso.onView(ViewMatchers.withHint(this))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
@RestrictTo(RestrictTo.Scope.TESTS)
fun String.isNotDisplayed(): ViewInteraction = Espresso.onView(withText(this))
.check(ViewAssertions.matches(Matchers.not(ViewMatchers.isDisplayed())))
@RestrictTo(RestrictTo.Scope.TESTS)
fun String.click(): ViewInteraction = Espresso.onView(withText(this))
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
.perform(ViewActions.click())
@RestrictTo(RestrictTo.Scope.TESTS)
fun <T> T.isEquals(actual: T) = Assert.assertEquals(this, actual)

View File

@@ -13,4 +13,6 @@ android {
dependencies { dependencies {
implementation project(':core') implementation project(':core')
testImplementation project(':core')
androidTestImplementation project(':core')
} }

View File

@@ -0,0 +1,15 @@
package dev.carlos.shortform.feature
import dev.carlos.shortform.data.models.ShortformModel
import dev.carlos.shortform.domain.ShortformRepository
import io.reactivex.Single
class MockShortformRepository(
private val searchedAcronym: String,
private val response: List<ShortformModel.LongformModel>
) :
ShortformRepository {
override fun getShortformDefinition(acronym: String): Single<ShortformModel> {
return Single.fromCallable { ShortformModel(searchedAcronym, response) }
}
}

View File

@@ -0,0 +1,96 @@
package dev.carlos.shortform.feature
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.test.platform.app.InstrumentationRegistry
import dev.carlos.core.extensions.isTextDisplayed
import dev.carlos.core.extensions.pressEnterKey
import dev.carlos.core.extensions.typeOn
import dev.carlos.core.scheduler.Scheduler
import dev.carlos.core.scheduler.SchedulerProvider
import dev.carlos.shortform.R
import dev.carlos.shortform.data.models.ShortformModel
import dev.carlos.shortform.domain.GetShortformDefinition
import dev.carlos.shortform.domain.ShortformRepository
import dev.carlos.shortform.viewmodels.ShortformViewmodel
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.dsl.module
import java.lang.Thread.sleep
class ShortformFragmentTest {
@Before
fun setupKoin() {
startKoin {
InstrumentationRegistry.getInstrumentation().targetContext
modules(module {
factory { GetShortformDefinition(get(), get()) }
single<Scheduler> { SchedulerProvider() }
viewModel { ShortformViewmodel(get()) }
})
}
}
@After
fun killKoin() {
stopKoin()
}
@Test
fun shouldShowLongforms_whenSearchingForValidAcronym() {
acronyms {
searchValidAcronym()
} should {
showLongforms()
}
}
private fun acronyms(func: AcronymsRobot.() -> Unit) =
AcronymsRobot().apply {
func()
}
}
class AcronymsRobot {
fun searchValidAcronym() {
loadKoinModules(
module {
factory<ShortformRepository> { MockShortformRepository("Valid", loadTwoLongforms()) }
}
)
launchFragmentInContainer<ShortformFragment>()
R.id.shortform_definition_search_field.typeOn("Valid")
R.id.shortform_definition_search_field.pressEnterKey()
}
infix fun should(func: AcronymsResult.() -> Unit) {
AcronymsResult().apply { func() }
}
private fun loadTwoLongforms() = listOf(
ShortformModel.LongformModel(
"Valid 1",
1,
101
),
ShortformModel.LongformModel(
"Valid 2",
2,
102
)
)
}
class AcronymsResult {
fun showLongforms() {
sleep(200)
"Valid 1".isTextDisplayed()
"Valid 2".isTextDisplayed()
}
}

View File

@@ -18,10 +18,11 @@ versions.timber = "4.7.1"
versions.koin = "2.2.3" versions.koin = "2.2.3"
versions.rx_core = "2.2.21" versions.rx_core = "2.2.21"
versions.rx_android = "2.1.1" versions.rx_android = "2.1.1"
versions.junit = "4.13.2" versions.junit = "4.13"
versions.test = "1.3.0" versions.test = "1.2.0"
versions.test_ext = "1.1.2" versions.test_ext = "1.1.1"
versions.espresso = "3.3.0" versions.espresso = "3.2.0"
versions.fragments = "1.2.0"
def build_versions = [:] def build_versions = [:]
build_versions.min_sdk = 21 build_versions.min_sdk = 21
@@ -105,8 +106,9 @@ testing.core = "androidx.test:core:$versions.test"
testing.rules = "androidx.test:rules:$versions.test" testing.rules = "androidx.test:rules:$versions.test"
testing.runner = "androidx.test:runner:$versions.test" testing.runner = "androidx.test:runner:$versions.test"
testing.ext = "androidx.test.ext:junit:$versions.test_ext" testing.ext = "androidx.test.ext:junit:$versions.test_ext"
testing.koin = "org.koin:koin-test:$versions.koin" testing.koin = "io.insert-koin:koin-test:$versions.koin"
testing.espresso = "androidx.test.espresso:espresso-core:$versions.espresso" testing.espresso = "androidx.test.espresso:espresso-core:$versions.espresso"
testing.fragments = "androidx.fragment:fragment-testing:$versions.fragments"
deps.testing = testing deps.testing = testing
ext.deps = deps ext.deps = deps