From 1fd2cb5e74715df3579ffe073b021097d5cc23db Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sun, 15 Aug 2021 18:38:55 +0530 Subject: [PATCH 1/2] Added auto testing from "Record Espresso Tool" --- app/build.gradle | 3 +- .../keypass/ui/auth/MainActivityTest.kt | 396 ++++++++++++++++++ 2 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt diff --git a/app/build.gradle b/app/build.gradle index 7d7a7e4b..98acdc41 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,7 +79,7 @@ dependencies { implementation 'androidx.preference:preference-ktx:1.1.1' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation ('androidx.appcompat:appcompat:1.3.0') @@ -96,6 +96,7 @@ dependencies { implementation "androidx.room:room-runtime:$room_version" + androidTestImplementation 'androidx.test:rules:1.4.0' kapt "androidx.room:room-compiler:$room_version" implementation "androidx.room:room-ktx:$room_version" diff --git a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt new file mode 100644 index 00000000..1ee05c5a --- /dev/null +++ b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt @@ -0,0 +1,396 @@ +package com.yogeshpaliyal.keypass.ui.auth + + +import androidx.test.espresso.DataInteraction +import androidx.test.espresso.ViewInteraction +import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.AndroidJUnit4 +import android.view.View +import android.view.ViewGroup +import android.view.ViewParent + +import androidx.test.InstrumentationRegistry.getInstrumentation +import androidx.test.espresso.Espresso.onData +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.* +import androidx.test.espresso.matcher.ViewMatchers.* + +import com.yogeshpaliyal.keypass.R + +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.TypeSafeMatcher +import org.hamcrest.core.IsInstanceOf +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +import org.hamcrest.Matchers.allOf +import org.hamcrest.Matchers.anything +import org.hamcrest.Matchers.`is` + +@LargeTest +@RunWith(AndroidJUnit4::class) +class MainActivityTest { + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(AuthenticationActivity::class.java) + + @Test + fun mainActivityTest() { + val floatingActionButton = onView( + allOf( + withId(R.id.btnAdd), + childAtPosition( + childAtPosition( + withClassName(`is`("androidx.constraintlayout.widget.ConstraintLayout")), + 1 + ), + 3 + ), + isDisplayed() + ) + ) + floatingActionButton.perform(click()) + + val textInputEditText = onView( + allOf( + withId(R.id.etAccountName), + childAtPosition( + childAtPosition( + withId(R.id.tilAccountName), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText.perform(replaceText("test acco"), closeSoftKeyboard()) + + val textInputEditText2 = onView( + allOf( + withId(R.id.etUsername), + childAtPosition( + childAtPosition( + withId(R.id.tilUsername), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText2.perform(replaceText("yogeshpaliyal123"), closeSoftKeyboard()) + + val checkableImageButton = onView( + allOf( + withId(R.id.text_input_start_icon), + childAtPosition( + childAtPosition( + withClassName(`is`("android.widget.FrameLayout")), + 1 + ), + 0 + ), + isDisplayed() + ) + ) + checkableImageButton.perform(click()) + + val editText = onView( + allOf( + withId(R.id.etPassword), + withParent(withParent(withId(R.id.tilPassword))), + isDisplayed() + ) + ) + editText.check(matches(withText("W47@OHW5KZ"))) + + val textInputEditText3 = onView( + allOf( + withId(R.id.etTag), + childAtPosition( + childAtPosition( + withId(R.id.tilTags), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText3.perform(replaceText("test tag"), closeSoftKeyboard()) + + val textInputEditText4 = onView( + allOf( + withId(R.id.etWebsite), + childAtPosition( + childAtPosition( + withId(R.id.tilWebsite), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText4.perform(replaceText("https://yoge"), closeSoftKeyboard()) + + val textInputEditText5 = onView( + allOf( + withId(R.id.etNotes), + childAtPosition( + childAtPosition( + withId(R.id.tilNotes), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText5.perform(replaceText("notrs1"), closeSoftKeyboard()) + + val textInputEditText6 = onView( + allOf( + withId(R.id.etNotes), withText("notrs1"), + childAtPosition( + childAtPosition( + withId(R.id.tilNotes), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText6.perform(click()) + + val textInputEditText7 = onView( + allOf( + withId(R.id.etNotes), withText("notrs1"), + childAtPosition( + childAtPosition( + withId(R.id.tilNotes), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText7.perform(click()) + + val textInputEditText8 = onView( + allOf( + withId(R.id.etNotes), withText("notrs1"), + childAtPosition( + childAtPosition( + withId(R.id.tilNotes), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText8.perform(replaceText("notes1")) + + val textInputEditText9 = onView( + allOf( + withId(R.id.etNotes), withText("notes1"), + childAtPosition( + childAtPosition( + withId(R.id.tilNotes), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + textInputEditText9.perform(closeSoftKeyboard()) + + val floatingActionButton2 = onView( + allOf( + withId(R.id.btnSave), + childAtPosition( + childAtPosition( + withId(android.R.id.content), + 0 + ), + 2 + ), + isDisplayed() + ) + ) + floatingActionButton2.perform(click()) + + val appCompatImageButton = onView( + allOf( + childAtPosition( + allOf( + withId(R.id.bottomAppBar), + childAtPosition( + withClassName(`is`("androidx.coordinatorlayout.widget.CoordinatorLayout")), + 2 + ) + ), + 0 + ), + isDisplayed() + ) + ) + appCompatImageButton.perform(click()) + + val view = onView( + allOf( + withId(R.id.scrim_view), + childAtPosition( + childAtPosition( + withId(R.id.bottom_nav_drawer), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + view.perform(click()) + + val view2 = onView( + allOf( + withId(R.id.scrim_view), + childAtPosition( + childAtPosition( + withId(R.id.bottom_nav_drawer), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + view2.perform(click()) + + val maskedCardView = onView( + allOf( + childAtPosition( + childAtPosition( + withId(R.id.recycler_view), + 0 + ), + 0 + ), + isDisplayed() + ) + ) + maskedCardView.perform(click()) + + val editText2 = onView( + allOf( + withId(R.id.etAccountName), withText("test acco"), + withParent(withParent(withId(R.id.tilAccountName))), + isDisplayed() + ) + ) + editText2.check(matches(withText("test acco"))) + + val editText3 = onView( + allOf( + withId(R.id.etUsername), withText("yogeshpaliyal123"), + withParent(withParent(withId(R.id.tilUsername))), + isDisplayed() + ) + ) + editText3.check(matches(withText("yogeshpaliyal123"))) + + val editText4 = onView( + allOf( + withId(R.id.etPassword), withText("W47@OHW5KZ"), + withParent(withParent(withId(R.id.tilPassword))), + isDisplayed() + ) + ) + editText4.check(matches(withText("W47@OHW5KZ"))) + + val editText5 = onView( + allOf( + withId(R.id.etTag), withText("test tag"), + withParent(withParent(withId(R.id.tilTags))), + isDisplayed() + ) + ) + editText5.check(matches(withText("test tag"))) + + val editText6 = onView( + allOf( + withId(R.id.etWebsite), withText("https://yoge"), + withParent(withParent(withId(R.id.tilWebsite))), + isDisplayed() + ) + ) + editText6.check(matches(withText("https://yoge"))) + + val editText7 = onView( + allOf( + withId(R.id.etNotes), withText("notes1"), + withParent(withParent(withId(R.id.tilNotes))), + isDisplayed() + ) + ) + editText7.check(matches(withText("notes1"))) + + val cardView = onView( + allOf( + withParent( + allOf( + withId(R.id.nestedScrollView), + withParent(IsInstanceOf.instanceOf(android.view.ViewGroup::class.java)) + ) + ), + isDisplayed() + ) + ) + cardView.check(matches(isDisplayed())) + + val floatingActionButton3 = onView( + allOf( + withId(R.id.btnSave), + childAtPosition( + childAtPosition( + withId(android.R.id.content), + 0 + ), + 2 + ), + isDisplayed() + ) + ) + floatingActionButton3.perform(click()) + } + + 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) + } + } + } +} From 6be6e99d844b92d1f7699e144cff93ba54228a6c Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Mon, 16 Aug 2021 22:49:16 +0530 Subject: [PATCH 2/2] Testing Setup --- app/build.gradle | 16 ++++--- .../ui/auth/AuthenticationActivityTest.kt | 48 +++++++++++++++++++ .../DashboardActivityTest.kt} | 6 +-- 3 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/AuthenticationActivityTest.kt rename app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/{auth/MainActivityTest.kt => nav/DashboardActivityTest.kt} (98%) diff --git a/app/build.gradle b/app/build.gradle index 98acdc41..6fc82648 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -65,6 +65,8 @@ android { abortOnError false } + testOptions.unitTests.includeAndroidResources = true + } @@ -72,17 +74,17 @@ android { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.5.0' - implementation 'androidx.appcompat:appcompat:1.3.0' - implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'androidx.preference:preference-ktx:1.1.1' - testImplementation 'junit:junit:4.+' - androidTestImplementation 'androidx.test.ext:junit:1.1.2' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - implementation ('androidx.appcompat:appcompat:1.3.0') + implementation ('androidx.appcompat:appcompat:1.3.1') implementation "androidx.documentfile:documentfile:1.0.1" // ViewModel diff --git a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/AuthenticationActivityTest.kt b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/AuthenticationActivityTest.kt new file mode 100644 index 00000000..16fa90e5 --- /dev/null +++ b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/AuthenticationActivityTest.kt @@ -0,0 +1,48 @@ +package com.yogeshpaliyal.keypass.ui.auth + + +import androidx.test.espresso.DataInteraction +import androidx.test.espresso.ViewInteraction +import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.AndroidJUnit4 +import android.view.View +import android.view.ViewGroup +import android.view.ViewParent + +import androidx.test.InstrumentationRegistry.getInstrumentation +import androidx.test.espresso.Espresso.onData +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.Espresso.pressBack +import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.* +import androidx.test.espresso.matcher.ViewMatchers.* + +import com.yogeshpaliyal.keypass.R + +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.TypeSafeMatcher +import org.hamcrest.core.IsInstanceOf +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +import org.hamcrest.Matchers.allOf +import org.hamcrest.Matchers.anything +import org.hamcrest.Matchers.`is` + +@LargeTest +@RunWith(AndroidJUnit4::class) +class AuthenticationActivityTest { + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(AuthenticationActivity::class.java) + + @Test + fun authenticationActivityTest() { + + } +} diff --git a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt similarity index 98% rename from app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt rename to app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt index 1ee05c5a..1f02a855 100644 --- a/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/auth/MainActivityTest.kt +++ b/app/src/androidTest/java/com/yogeshpaliyal/keypass/ui/nav/DashboardActivityTest.kt @@ -1,4 +1,4 @@ -package com.yogeshpaliyal.keypass.ui.auth +package com.yogeshpaliyal.keypass.ui.nav import androidx.test.espresso.DataInteraction @@ -35,11 +35,11 @@ import org.hamcrest.Matchers.`is` @LargeTest @RunWith(AndroidJUnit4::class) -class MainActivityTest { +class DashboardActivityTest { @Rule @JvmField - var mActivityTestRule = ActivityTestRule(AuthenticationActivity::class.java) + var mActivityTestRule = ActivityTestRule(DashboardActivity::class.java) @Test fun mainActivityTest() {