[Android] Espresso 를 이용한 초간단 XML UI 테스트!

윤호이·2023년 11월 21일
0

Test

목록 보기
10/13
post-thumbnail

서론

요즘 컴포즈로 넘어가고 있고 xml은 레거시 뷰 취급이지만

아직 까지는 xml 기반의 뷰가 많을 것입니다.

컴포즈로 새로운 뷰를 만든다 하더라도 기존 xml 뷰도 유지보수 해줘야겠죠?

espresso를 이용해서 아주 간단한 UI 테스트를 보여드리겠습니다.

의존성 추가

androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

사실 의존성은 기본적으로 추가 되어있을 것이기 때문에 굳이 추가 안해주셔도 됩니다.

XML Layout 작성

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/searchBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toStartOf="@id/search_button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/search_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="search"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/search_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="nothing.."
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

아~~주 간단한 뷰죠?


초기화면입니다.


검색창에 test를 치고서 버튼을 누르면?


결과에 test가 땋!~

Activity 작성

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.searchButton.setOnClickListener {
            val input = binding.searchBar.text.toString()
            binding.searchResult.text = input
            binding.searchBar.text.clear()
        }
    }
}

뷰 바인딩으로 작성했습니다.

Espresso Test 작성 하는 법

onView().perform().check()
ViewMatcher.ViewAction.ViewAssertion

어떤 뷰에서 어떤 행동을 하고 특정 조건을 검증한다.

아주 간단하죠?

UI Test

class SearchFeatureTest {

    @get:Rule
    val activityRule = ActivityScenarioRule(MainActivity::class.java)

    @Test
    fun `초기화면은_nothing을_보여줘야_한다`() {
        onView(withId(R.id.searchBar)).check(matches(withText("")))
        onView(withId(R.id.search_button)).check(matches(withText("search")))
        onView(withId(R.id.search_result)).check(matches(withText("nothing..")))
    }

    @Test
    fun searchBar에_test_를_입력했을_때_test_를_띄워준다() {
        Thread.sleep(1000)
        onView(withId(R.id.searchBar)).perform(typeText("test")).check(matches(withText("test")))
        Thread.sleep(1000)
        onView(withId(R.id.search_button)).perform(click())
        onView(withId(R.id.searchBar)).check(matches(withText("")))
        Thread.sleep(1000)
        onView(withId(R.id.search_result)).check(matches(withText("test")))
        Thread.sleep(1000)
    }

}

중간중간에 Thread.sleep 을 넣은 이유는 UI 동작을 확인하기 위해서입니다.

ActivityScenarioRule 을 통해 MainActivty를 Test하도록 설정합시다.

searchBar에test입력했을test를_띄워준다 이 테스트 함수를 보도록 합시다.

    1. EditText에 test 를 타이핑하고 test가 잘 타이핑 됐는지 확인한다.
onView(withId(R.id.searchBar)).perform(typeText("test")).check(matches(withText("test")))
    1. 버튼을 클릭한다.
onView(withId(R.id.search_button)).perform(click())
    1. EditText의 내용이 지워졌는지 확인한다.
onView(withId(R.id.searchBar)).check(matches(withText("")))
    1. 결과에 test가 잘 나오는지 확인한다.
onView(withId(R.id.search_result)).check(matches(withText("test")))

한번 풀어서 봅시다.

onView(withId(R.id.search_result)).check(matches(withText("test")))

R.id.search_result 란 Id를 가진 뷰에서 "test" 란 텍스트를 가지고 있는지 check 한다.

느낌 오시나요?

Thread.sleep을 하지 않는다면 순식간에 테스트가 완료돼서 UI 테스트 과정을 확인하기 힘듭니다.

하고 싶은 말

요즘 compose 밖에 안쓰지만 espresso 사용법을 익히는 것도
좋다고 생각합니다.

기존 앱도 유지보수 해야죠 ^^

참조

https://developer.android.com/training/testing/espresso/basics?hl=ko#finding-view-considerations
espresso cheatsheet <-- 꼭 보세요!

profile
열정은 내 삶의 방식, 꾸준함은 내 삶의 증명

0개의 댓글