-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
STEP 9 : write integration tests to check our screens
- Loading branch information
Showing
6 changed files
with
327 additions
and
24 deletions.
There are no files selected for viewing
24 changes: 0 additions & 24 deletions
24
app/src/androidTest/java/com/devmind/devoxx/ExampleInstrumentedTest.kt
This file was deleted.
Oops, something went wrong.
24 changes: 24 additions & 0 deletions
24
app/src/androidTest/java/com/devmind/devoxx/MainActivityTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.devmind.devoxx | ||
|
||
import androidx.test.espresso.Espresso | ||
import androidx.test.espresso.assertion.ViewAssertions | ||
import androidx.test.espresso.matcher.ViewMatchers | ||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner | ||
import androidx.test.rule.ActivityTestRule | ||
import org.junit.Ignore | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4ClassRunner::class) | ||
class MainActivityTest{ | ||
|
||
@get:Rule | ||
val activityRule = ActivityTestRule(MainActivity::class.java) | ||
|
||
@Test | ||
fun shouldDisplayTitle(){ | ||
Espresso.onView(ViewMatchers.withId(R.id.title)) | ||
.check(ViewAssertions.matches(ViewMatchers.withText(R.string.app_name))) | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
app/src/androidTest/java/com/devmind/devoxx/SpeakerListActivityTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.devmind.devoxx | ||
|
||
import androidx.arch.core.executor.testing.CountingTaskExecutorRule | ||
import androidx.test.espresso.Espresso | ||
import androidx.test.espresso.action.ViewActions | ||
import androidx.test.espresso.assertion.ViewAssertions | ||
import androidx.test.espresso.contrib.RecyclerViewActions | ||
import androidx.test.espresso.matcher.ViewMatchers | ||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import androidx.test.rule.ActivityTestRule | ||
import com.devmind.devoxx.model.Speaker | ||
import com.devmind.devoxx.model.SpeakerAdapter | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import java.util.concurrent.TimeUnit | ||
|
||
|
||
@RunWith(AndroidJUnit4ClassRunner::class) | ||
class SpeakerListActivityTest { | ||
|
||
@get:Rule | ||
val activityRule = ActivityTestRule<SpeakerListActivity>(SpeakerListActivity::class.java, false, false) | ||
|
||
@get:Rule | ||
val countingTaskExecutorRule = CountingTaskExecutorRule() | ||
|
||
constructor() { | ||
val application = | ||
InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as DevoxxApplication | ||
application.deleteDatabase("devoxx2") | ||
val dao = application.speakerDao() | ||
if (dao.readAll().isEmpty()) { | ||
dao.create(Speaker("Romain", "Guy")) | ||
dao.create(Speaker("Chet", "Haase")) | ||
} | ||
} | ||
|
||
@Before | ||
fun init() { | ||
activityRule.launchActivity(null) | ||
} | ||
|
||
@Test | ||
fun shouldDisplaySpeakers() { | ||
drain() | ||
Espresso.onView(ViewMatchers.withText("Romain Guy")).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) | ||
Espresso.onView(ViewMatchers.withText("Chet Haase")).check(ViewAssertions.matches(ViewMatchers.isDisplayed())) | ||
|
||
} | ||
|
||
@Test | ||
fun shouldCreateSpeaker() { | ||
drain() | ||
Espresso.onView(ViewMatchers.withId(R.id.buttonAddSpeaker)).perform(ViewActions.click()) | ||
// After this click we should be on speaker view in creation mode | ||
Espresso.onView(ViewMatchers.withId(R.id.speakerFirstname)).check(ViewAssertions.matches(ViewMatchers.withText(""))) | ||
Espresso.onView(ViewMatchers.withId(R.id.speakerLastname)).check(ViewAssertions.matches(ViewMatchers.withText(""))) | ||
} | ||
|
||
@Test | ||
fun shouldUpdateSpeaker() { | ||
drain() | ||
Espresso.onView(ViewMatchers.withId(R.id.speakerList)).perform( | ||
RecyclerViewActions.actionOnItemAtPosition<SpeakerAdapter.ViewHolder>(0, ViewActions.click())) | ||
// After this click we should be on speaker view in update mode | ||
Espresso.onView(ViewMatchers.withId(R.id.speakerFirstname)).check(ViewAssertions.matches(ViewMatchers.withText("Romain"))) | ||
Espresso.onView(ViewMatchers.withId(R.id.speakerLastname)).check(ViewAssertions.matches(ViewMatchers.withText("Guy"))) | ||
} | ||
|
||
fun drain() { | ||
countingTaskExecutorRule.drainTasks(1, TimeUnit.MINUTES) | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
app/src/androidTest/java/com/devmind/devoxx/SpeakerListViewModelTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package com.devmind.devoxx | ||
|
||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule | ||
import androidx.lifecycle.Observer | ||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner | ||
import com.devmind.devoxx.model.Speaker | ||
import com.devmind.devoxx.model.SpeakerDao | ||
import com.google.common.truth.Truth | ||
import io.mockk.MockKAnnotations | ||
import io.mockk.every | ||
import io.mockk.mockk | ||
import io.mockk.verify | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4ClassRunner::class) | ||
class SpeakerListViewModelTest { | ||
|
||
/** | ||
* Swaps background executor used by the Architecture Components with a different one which executes | ||
* each task synchronously. | ||
*/ | ||
@get:Rule | ||
val instantTaskExecutorRule = InstantTaskExecutorRule() | ||
|
||
lateinit var viewModel: SpeakerListViewModel | ||
lateinit var speakerDao: SpeakerDao | ||
lateinit var observer: Observer<List<Speaker>> | ||
|
||
|
||
@Before | ||
fun onInit() { | ||
speakerDao = mockk(relaxUnitFun = true) | ||
observer = mockk(relaxed = true) | ||
|
||
val devoxxApplication = mockk<DevoxxApplication>(){ | ||
every { speakerDao() } returns speakerDao | ||
} | ||
viewModel = SpeakerListViewModel(devoxxApplication) | ||
} | ||
|
||
@After | ||
fun onTearDown(){ | ||
viewModel.speakersLiveData.removeObserver(observer) | ||
} | ||
|
||
@Test | ||
fun shouldLoadSpeakers() { | ||
val speakers = arrayListOf(Speaker("Romain", "Guy")) | ||
every { speakerDao.readAll() } returns speakers | ||
|
||
viewModel.speakersLiveData.observeForever(observer) | ||
|
||
verify { speakerDao.readAll() } | ||
verify { observer.onChanged(any()) } | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
app/src/androidTest/java/com/devmind/devoxx/SpeakerViewModelTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package com.devmind.devoxx | ||
|
||
import androidx.arch.core.executor.testing.CountingTaskExecutorRule | ||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule | ||
import androidx.lifecycle.Observer | ||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner | ||
import com.devmind.devoxx.model.Speaker | ||
import com.devmind.devoxx.model.SpeakerDao | ||
import io.mockk.every | ||
import io.mockk.mockk | ||
import io.mockk.verify | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Rule | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import java.util.concurrent.TimeUnit | ||
|
||
|
||
@RunWith(AndroidJUnit4ClassRunner::class) | ||
class SpeakerViewModelTest { | ||
|
||
/** | ||
* Swaps background executor used by the Architecture Components with a different one which executes | ||
* each task synchronously. | ||
*/ | ||
@get:Rule | ||
val instantTaskExecutorRule = InstantTaskExecutorRule() | ||
|
||
// @get:Rule | ||
// val countingTaskExecutorRule = CountingTaskExecutorRule() | ||
|
||
lateinit var viewModel: SpeakerViewModel | ||
lateinit var speakerDao: SpeakerDao | ||
lateinit var observer: Observer<Speaker> | ||
|
||
|
||
@Before | ||
fun onInit() { | ||
speakerDao = mockk(relaxUnitFun = true) | ||
observer = mockk(relaxed = true) | ||
|
||
val devoxxApplication = mockk<DevoxxApplication>(){ | ||
every { speakerDao() } returns speakerDao | ||
} | ||
viewModel = SpeakerViewModel(devoxxApplication) | ||
} | ||
|
||
@After | ||
fun onTearDown(){ | ||
viewModel.speakerLiveData.removeObserver(observer) | ||
} | ||
|
||
@Test | ||
fun shouldLoadSpeaker() { | ||
val speaker = Speaker("Romain", "Guy") | ||
|
||
every { speakerDao.readOne(speaker.uuid) } returns speaker | ||
|
||
instantTaskExecutorRule.run { | ||
viewModel.speakerLiveData.observeForever(observer) | ||
viewModel.loadSpeaker(speaker.uuid) | ||
|
||
drain() | ||
verify { speakerDao.readOne(speaker.uuid) } | ||
verify { observer.onChanged(speaker) } | ||
} | ||
} | ||
|
||
@Test | ||
fun shouldSaveSpeaker() { | ||
val speaker = Speaker("Romain", "Guy") | ||
|
||
instantTaskExecutorRule.run { | ||
viewModel.speakerLiveData.observeForever(observer) | ||
viewModel.createSpeaker(speaker) | ||
|
||
drain() | ||
verify { speakerDao.create(speaker) } | ||
verify { observer.onChanged(speaker) } | ||
} | ||
} | ||
|
||
@Test | ||
fun shouldUpdateSpeaker() { | ||
val speaker = Speaker("Romain", "Guy") | ||
|
||
instantTaskExecutorRule.run { | ||
viewModel.speakerLiveData.observeForever(observer) | ||
viewModel.updateSpeaker(speaker) | ||
|
||
verify { speakerDao.update(speaker) } | ||
verify { observer.onChanged(speaker) } | ||
} | ||
drain() | ||
// verify { speakerDao.update(speaker) } | ||
// verify { observer.onChanged(speaker) } | ||
} | ||
|
||
fun drain(){ | ||
instantTaskExecutorRule.run { } | ||
// countingTaskExecutorRule.drainTasks(1, TimeUnit.MINUTES) | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
app/src/androidTest/java/com/devmind/devoxx/model/SpeakerDaoTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.devmind.devoxx.model | ||
|
||
import androidx.room.Room | ||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner | ||
import androidx.test.platform.app.InstrumentationRegistry | ||
import com.google.common.truth.Truth | ||
import org.junit.After | ||
import org.junit.Before | ||
import org.junit.Ignore | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4ClassRunner::class) | ||
class SpeakerDaoTest{ | ||
|
||
lateinit var database: DevoxxDatabase | ||
lateinit var dao: SpeakerDao | ||
private val speaker = Speaker("Chet", "Haase", "USA") | ||
|
||
@Before | ||
fun onInit(){ | ||
val testContext = InstrumentationRegistry.getInstrumentation().context | ||
|
||
database = Room.inMemoryDatabaseBuilder(testContext, DevoxxDatabase::class.java).allowMainThreadQueries().build() | ||
dao = database.speakerDao() | ||
dao.create(speaker) | ||
} | ||
|
||
@After | ||
fun onClose() = database.close() | ||
|
||
@Test | ||
fun readAll(){ | ||
val speakers = dao.readAll() | ||
Truth.assertThat(speakers).containsExactly(speaker) | ||
} | ||
|
||
@Test | ||
fun readOne(){ | ||
val speaker = dao.readOne(speaker.uuid) | ||
Truth.assertThat(speaker).isEqualTo(speaker) | ||
} | ||
|
||
@Test | ||
fun readOneByUnknownId(){ | ||
val speaker = dao.readOne("unknown") | ||
Truth.assertThat(speaker).isNull() | ||
} | ||
|
||
@Test | ||
fun update(){ | ||
dao.update(Speaker("Chet", "Guy", "USA", speaker.uuid)) | ||
val speaker = dao.readOne(speaker.uuid) | ||
Truth.assertThat(speaker.lastname).isEqualTo("Guy") | ||
} | ||
|
||
@Test | ||
fun delete(){ | ||
dao.delete(speaker) | ||
val speakers = dao.readAll() | ||
Truth.assertThat(speakers).isEmpty() | ||
} | ||
} |