I am doing an instrumentation test of Fragment is displayed or not. When I start the test it execute, I am able to see FragmentLogin view in physical device but test fail by saying androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: view.getId() is <2131296460/com.nano.modularapp:id/fragmentLogin> and app close.
I used Hilt and Navigation Graph in my code for testing.
FragmentLogin.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="login"
type="com.nano.modularapp.login.FragmentLogin" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".login.FragmentLogin">
<TextView
android:id="@+id/tvSignUpTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome in ModularApp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="20dp"
android:layout_marginStart="20dp"
android:textColor="@color/black"
android:fontFamily="@font/mukta_bold"
android:textSize="26sp"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/tvSignUpTitle"
app:layout_constraintStart_toStartOf="parent"
android:text="Login"
android:textColor="@color/black"
android:layout_marginTop="20dp"
android:layout_marginStart="20dp"
android:fontFamily="@font/mukta_medium"
android:textSize="22sp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_margin="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="20sp"
android:layout_marginTop="15dp"
android:textColor="@color/text_color"
android:fontFamily="@font/mukta_medium"/>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editTextEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:layout_marginTop="5dp"
android:textColor="@color/text_color"
android:fontFamily="@font/mukta_regular"
android:textSize="18sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:textColor="@color/text_color"
android:fontFamily="@font/mukta_medium"
android:inputType="textEmailAddress"/>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editTextPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:layout_marginTop="5dp"
android:textColor="@color/text_color"
android:fontFamily="@font/mukta_regular"
android:textSize="18sp"
android:inputType="textPassword"/>
<TextView
android:id="@+id/tvError"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginTop="15dp"
android:fontFamily="@font/mukta_regular"
android:text="@{login.errorMsg}"
android:textColor="@color/error"/>
<Button
android:id="@+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login"
android:textSize="20sp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:layout_marginTop="25dp"
android:layout_gravity="center"
android:fontFamily="@font/mukta_semi_bold"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="Don't have an account?"
android:textColor="@color/black"
android:fontFamily="@font/mukta_regular"/>
<TextView
android:id="@+id/navigateToSignUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text=" Sign Up"
android:textColor="@color/info_blue"
android:fontFamily="@font/mukta_medium"/>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
FragmentLoginInstrumentedTest::class
@HiltAndroidTest
@RunWith(AndroidJUnit4::class)
class FragmentLoginInstrumentedTest {
@get:Rule
val hiltRule:HiltAndroidRule = HiltAndroidRule(this)
@get:Rule
val activityRule: ActivityScenarioRule<HiltTestActivity> = ActivityScenarioRule(HiltTestActivity::class.java)
@Before
fun init(){
hiltRule.inject()
}
@Test
fun test_blankField_expectedEmptyField(){
//Checking LoginFragment is attached and displayed in screen or not
launchFragmentInHiltContainer<FragmentLogin>()
onView(withId(R.id.fragmentLogin)).check(ViewAssertions.matches(isDisplayed()))
}
Above is my complete code. I don't understand the reason, login fragment display and then test case fail.
I am able to solve this issue. A very small point need to look here
When you are using Hilt + Navigation for loading your fragments using NavController. During android instrumentation test few points need to consider
When running instrumentation test annotate @RunwWith(AndroidJUnitRunner::class)
Set another rule on which activity you will launch Fragment. As you are using fragment you need to create HiltTestActivity in debug main folder inside java directory.
List While writing Espresso.onView(withId(R.id.loginFragment)) --> replace it with Espresso.onView(withId(R.id.loginFragmentView)). "loginFragmentView" you need to add it in your root view of fragment layout file name.
for your reference look into this github solution NoMatchingViewException issue