From c1f61eee3b51bc863213190efe9be2e4582fcf8e Mon Sep 17 00:00:00 2001 From: hmalik144 Date: Wed, 22 Apr 2020 15:17:53 +0100 Subject: [PATCH] UI test for repository added --- app/build.gradle | 1 + .../candyspace/ExampleInstrumentedTest.kt | 6 +- .../h_mal/candyspace/ui/main/AppUITest.kt | 135 ++++++++++++++++++ .../candyspace/data/api/ResponseUnwrap.kt | 1 + .../candyspace/data/api/model/ApiResponse.kt | 2 - .../data/repositories/Repository.kt | 2 +- .../h_mal/candyspace/ui/main/MainActivity.kt | 6 +- .../candyspace/ui/user/UserProfileFragment.kt | 7 +- .../h_mal/candyspace/utils/DataBindUtils.kt | 1 - .../h_mal/candyspace/ExampleUnitTest.kt | 3 +- .../data/repositories/RepositoryTest.kt | 4 +- .../candyspace/ui/main/MainViewModelTest.kt | 5 +- 12 files changed, 151 insertions(+), 22 deletions(-) create mode 100644 app/src/androidTest/java/com/example/h_mal/candyspace/ui/main/AppUITest.kt diff --git a/app/build.gradle b/app/build.gradle index 6ba6083..9676032 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,4 +72,5 @@ dependencies { implementation "androidx.preference:preference-ktx:1.1.0" implementation 'com.squareup.picasso:picasso:2.71828' + androidTestImplementation 'androidx.test:rules:1.3.0-alpha05' } diff --git a/app/src/androidTest/java/com/example/h_mal/candyspace/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/h_mal/candyspace/ExampleInstrumentedTest.kt index 527b4be..2fbba2a 100644 --- a/app/src/androidTest/java/com/example/h_mal/candyspace/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/example/h_mal/candyspace/ExampleInstrumentedTest.kt @@ -1,13 +1,11 @@ package com.example.h_mal.candyspace -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * diff --git a/app/src/androidTest/java/com/example/h_mal/candyspace/ui/main/AppUITest.kt b/app/src/androidTest/java/com/example/h_mal/candyspace/ui/main/AppUITest.kt new file mode 100644 index 0000000..6988f7b --- /dev/null +++ b/app/src/androidTest/java/com/example/h_mal/candyspace/ui/main/AppUITest.kt @@ -0,0 +1,135 @@ +package com.example.h_mal.candyspace.ui.main + +import android.view.View +import android.view.ViewGroup +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.UiController +import androidx.test.espresso.ViewAction +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.RootMatchers.withDecorView +import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import com.example.h_mal.candyspace.R +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.Matchers.* +import org.hamcrest.TypeSafeMatcher +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + + +@LargeTest +@RunWith(AndroidJUnit4::class) +class AppUITest { + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(MainActivity::class.java) + + @Test + fun launchApp_SuccessfulLaunch() { + onView(allOf(withId(R.id.action_bar), isDisplayed())).check(matches(withText("Candy Space"))) + onView(allOf(withId(R.id.submit), isDisplayed())).check(matches(isDisplayed())) + onView(allOf(withId(R.id.search_bar), isDisplayed())).check(matches(isDisplayed())) + onView(allOf(withId(R.id.recycler_view), isDisplayed())).check(matches(isDisplayed())) + + } + + @Test + fun RunSearch_SuccessfulReturn() { + onView(allOf(withId(R.id.submit), isDisplayed())).check(matches(isDisplayed())) + onView(allOf(withId(R.id.search_bar), isDisplayed())).perform(replaceText("kenny"), + closeSoftKeyboard()) + onView(allOf(withId(R.id.submit), isDisplayed())).perform(click()) + //wait for load + waitFor(2000) + + onView( + allOf( + childAtPosition( + allOf( + withId(R.id.recycler_view), + childAtPosition( + withId(R.id.main), + 1 + ) + ), + 0 + ) + ) + ).perform(click()) + + onView(allOf(withId(R.id.action_bar), isDisplayed())).check(matches(withText("User"))) + onView(allOf(withId(R.id.username), isDisplayed())).check(matches(isDisplayed())) + + } + + @Test + fun backButtonPressed_SuccessfulResponse() { + onView(allOf(withId(R.id.submit), isDisplayed())).check(matches(isDisplayed())) + onView(allOf(withId(R.id.search_bar), isDisplayed())).perform(replaceText("kenny"), + closeSoftKeyboard()) + onView(allOf(withId(R.id.submit), isDisplayed())).perform(click()) + //wait for load + waitFor(2000) + + onView( + allOf( + childAtPosition( + allOf( + withId(R.id.recycler_view), + childAtPosition( + withId(R.id.main), + 1 + ) + ), + 0 + ) + ) + ).perform(click()) + + onView(allOf(withId(R.id.action_bar), isDisplayed())).check(matches(withText("User"))) + + onView(childAtPosition(withId(R.id.action_bar_container), 0)).perform(click()) + onView(allOf(withId(R.id.action_bar), isDisplayed())).check(matches(withText("Candy Space"))) + } + + private fun childAtPosition( + parentMatcher: Matcher, position: Int + ): Matcher { + + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("Child at position $position in parent ") + parentMatcher.describeTo(description) + } + + public override fun matchesSafely(view: View): Boolean { + val parent = view.parent + return parent is ViewGroup && parentMatcher.matches(parent) + && view == parent.getChildAt(position) + } + } + } + + private fun waitFor(delay: Long): ViewAction? { + return object : ViewAction { + override fun getConstraints(): Matcher { + return isRoot() + } + + override fun getDescription(): String { + return "wait for " + delay + "milliseconds" + } + + override fun perform(uiController: UiController, view: View?) { + uiController.loopMainThreadForAtLeast(delay) + } + } + } + +} diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt index aa898f1..3cf1ed2 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/ResponseUnwrap.kt @@ -7,6 +7,7 @@ import java.io.IOException abstract class ResponseUnwrap { + @Suppress("BlockingMethodInNonBlockingContext") suspend fun responseUnwrap(call: suspend () -> Response) : T{ val response = call.invoke() diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/api/model/ApiResponse.kt b/app/src/main/java/com/example/h_mal/candyspace/data/api/model/ApiResponse.kt index 98aebfe..224d2fd 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/data/api/model/ApiResponse.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/data/api/model/ApiResponse.kt @@ -1,7 +1,5 @@ package com.example.h_mal.candyspace.data.api.model -import com.example.h_mal.candyspace.data.api.model.User - data class ApiResponse( val items : List?, val has_more : Boolean?, diff --git a/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt b/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt index 89a73f9..6befe04 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/data/repositories/Repository.kt @@ -1,8 +1,8 @@ package com.example.h_mal.candyspace.data.repositories import com.example.h_mal.candyspace.data.api.ApiClass -import com.example.h_mal.candyspace.data.api.model.ApiResponse import com.example.h_mal.candyspace.data.api.ResponseUnwrap +import com.example.h_mal.candyspace.data.api.model.ApiResponse class Repository( private val api: ApiClass diff --git a/app/src/main/java/com/example/h_mal/candyspace/ui/main/MainActivity.kt b/app/src/main/java/com/example/h_mal/candyspace/ui/main/MainActivity.kt index 6b22aca..08f984c 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/ui/main/MainActivity.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/ui/main/MainActivity.kt @@ -1,8 +1,8 @@ package com.example.h_mal.candyspace.ui.main -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.MenuItem +import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.example.h_mal.candyspace.R import com.example.h_mal.candyspace.ui.home.MainFragment @@ -34,8 +34,8 @@ class MainActivity : AppCompatActivity(), KodeinAware, CompletionListener { setContentView(R.layout.main_activity) //setup home button for back navigation - supportActionBar?.setDisplayHomeAsUpEnabled(true); - supportActionBar?.setDisplayShowHomeEnabled(true); + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) //retrieve viewmodel from viewmodel factory viewModel = ViewModelProvider(this, factory).get(MainViewModel::class.java) diff --git a/app/src/main/java/com/example/h_mal/candyspace/ui/user/UserProfileFragment.kt b/app/src/main/java/com/example/h_mal/candyspace/ui/user/UserProfileFragment.kt index 9e7cbbe..8187bce 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/ui/user/UserProfileFragment.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/ui/user/UserProfileFragment.kt @@ -1,10 +1,11 @@ package com.example.h_mal.candyspace.ui.user import android.os.Bundle -import android.view.* -import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import androidx.databinding.DataBindingUtil - +import androidx.fragment.app.Fragment import com.example.h_mal.candyspace.R import com.example.h_mal.candyspace.databinding.FragmentUserProfileBinding import com.example.h_mal.candyspace.ui.main.MainActivity.Companion.viewModel diff --git a/app/src/main/java/com/example/h_mal/candyspace/utils/DataBindUtils.kt b/app/src/main/java/com/example/h_mal/candyspace/utils/DataBindUtils.kt index 837ed57..96a0dd3 100644 --- a/app/src/main/java/com/example/h_mal/candyspace/utils/DataBindUtils.kt +++ b/app/src/main/java/com/example/h_mal/candyspace/utils/DataBindUtils.kt @@ -1,6 +1,5 @@ package com.example.h_mal.candyspace.utils -import com.squareup.picasso.Picasso import java.text.SimpleDateFormat import java.util.* diff --git a/app/src/test/java/com/example/h_mal/candyspace/ExampleUnitTest.kt b/app/src/test/java/com/example/h_mal/candyspace/ExampleUnitTest.kt index ba4b928..870f497 100644 --- a/app/src/test/java/com/example/h_mal/candyspace/ExampleUnitTest.kt +++ b/app/src/test/java/com/example/h_mal/candyspace/ExampleUnitTest.kt @@ -1,9 +1,8 @@ package com.example.h_mal.candyspace +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * diff --git a/app/src/test/java/com/example/h_mal/candyspace/data/repositories/RepositoryTest.kt b/app/src/test/java/com/example/h_mal/candyspace/data/repositories/RepositoryTest.kt index c71567c..bd82ae5 100644 --- a/app/src/test/java/com/example/h_mal/candyspace/data/repositories/RepositoryTest.kt +++ b/app/src/test/java/com/example/h_mal/candyspace/data/repositories/RepositoryTest.kt @@ -5,9 +5,9 @@ import com.example.h_mal.candyspace.data.api.model.ApiResponse import kotlinx.coroutines.runBlocking import okhttp3.MediaType import okhttp3.ResponseBody +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull import org.junit.Before - -import org.junit.Assert.* import org.junit.Test import org.mockito.Mock import org.mockito.Mockito diff --git a/app/src/test/java/com/example/h_mal/candyspace/ui/main/MainViewModelTest.kt b/app/src/test/java/com/example/h_mal/candyspace/ui/main/MainViewModelTest.kt index bf3d828..9c29a25 100644 --- a/app/src/test/java/com/example/h_mal/candyspace/ui/main/MainViewModelTest.kt +++ b/app/src/test/java/com/example/h_mal/candyspace/ui/main/MainViewModelTest.kt @@ -1,14 +1,12 @@ package com.example.h_mal.candyspace.ui.main import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.example.h_mal.candyspace.data.api.ApiClass import com.example.h_mal.candyspace.data.api.model.ApiResponse import com.example.h_mal.candyspace.data.api.model.User import com.example.h_mal.candyspace.data.repositories.Repository import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals import org.junit.Before - -import org.junit.Assert.* import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule @@ -16,7 +14,6 @@ import org.mockito.Mock import org.mockito.Mockito import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations -import retrofit2.Response import java.io.IOException class MainViewModelTest {