일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 앱바
- 계측
- Flutter
- Navigation
- drift
- CustomScrollView
- activity
- Coroutines
- binding
- android
- Dialog
- textview
- viewmodel
- 앱
- appbar
- Button
- data
- scroll
- tabbar
- ScrollView
- DART
- LifeCycle
- Compose
- 안드로이드
- 테스트
- livedata
- intent
- Kotlin
- TEST
- textfield
- Today
- Total
Study Record
[안드로이드] 계측 테스트 참고 본문
😶 RecyclerView 테스트
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
onView(withId(R.id.recycler_view)).perform(
RecyclerViewActions
.scrollToPosition<RecyclerView.ViewHolder>(9)
)
onView(withId(R.id.recycler_view)).perform(
RecyclerViewActions
.scrollTo<RecyclerView.ViewHolder>(
withText("happy")
)
)
scrollToPosition(9) 으로 지정된 위치로 스크롤한다. RecyclerView 에 사용되는 목록의 길이가 정적이지 않은 경우 scrollTo() 함수와 withText() 를 사용해서 특정 텍스트가 들어간 항목으로 스크롤할 수 있다.
gradle 종속 필요
implementation 'androidx.test.espresso:espresso-contrib:3.5.1'
😶 check()
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withText
onView(withText("happy"))
.check(matches(isDisplayed()))
check() 로 true 인지 아닌지 확인할 수 있다. 특정 텍스트가 들어간 View 가 화면에 있는지 아닌지 확인할 수 있다.
😶 탐색 구성요소 테스트 작성하기
dependencies 추가하기
// Test Dependencies
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.4.0'
androidTestImplementation 'androidx.navigation:navigation-testing:2.5.2'
debugImplementation 'androidx.fragment:fragment-testing:1.5.3'
탐색 구성요소 테스트하기
탐색 구성요소를 테스트할 때는 기기나 에뮬레이터가 눈에 보이게 이동하지 않는다. 테스트하는건 navigation controller 가 올바른 목적지에 도착하도록 하는지를 확인한다.
navController 객체 선언하기
val navController = TestNavHostController(
ApplicationProvider.getApplicationContext()
)
launchFragmentInContainer() 는 탐색하고 있는 액티비티나 다른 프래그먼트를 인식하지 못하기 때문에 실제로 탐색은 불가능하다. (실제 테스트 기기에서 탐색을 볼 수 없다.)
val letterListScenario = launchFragmentInContainer<LetterListFragment>(themeResId = R.style.Theme_Words)
letterListScenario.onFragment {fragment ->
navController.setGraph(R.navigation.nav_graph)
Navigation.setViewNavController(fragment.requireView(), navController)
}
onFragment 함수로 실제로 프래그먼트가 시작할 때 이벤트를 가져와 Nav Controller 의 시작 프레그먼트를 명시해준다.
초기 프래그먼트로 예시에선 LetterListFragment 를 명시했는데 이 프래그먼트의 특정 버튼을 클릭한다던지 RecyclerView 를 클릭한다던지 등의 작업을 실행하면 다른 프래그먼트(WordListFragment)로 탐색을 진행한다고 하면, assertEquls() 함수로 현재 Nav Controller 의 프래그먼트가 다른 프래그먼트(WordListFragment)인지 확인하는 것으로 탐색 테스트 과정을 진행할 수 있다.
// LetterListFragment 의 리스트 목록을 클릭하면 WordListFragment 로 탐색한다.
onView(withId(R.id.list_recycler_view))
.perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click())
)
// 현재 Nav Controller 에 있는 프래그먼트가 WordListFragment 인지 확인한다.
// R.id.wordListFragment 는 NavGraph(xml)에 정의되어 있다.
assertEquals(navController.currentDestination?.id, R.id.wordListFragment)
😶 계측 테스트 동시에 진행하기
만약 탐색 과정 테스트 중 시작 프래그먼트에서 버튼 10개 당 탐색하는 프래그먼트가 다르다고 가정하면, 테스트 코드를 버튼 10개를 클릭하는 고정을 10번 반복해야할 것이다. 이렇게 같은 환경에서 반복되는 코드를 작성하지 않고 클래스에 대해 모든 동일한 환경을 설정할 수 있다.
바로 @Before 어노테이션으로 가능하다.
class NavigationTests {
private lateinit var letterListScenario: FragmentScenario<LetterListFragment>
private lateinit var navController: NavController
@Before
fun setUp() {
navController = TestNavHostController(
ApplicationProvider.getApplicationContext()
)
letterListScenario = launchFragmentInContainer(themeResId = R.style.Theme_Words)
letterListScenario.onFragment {fragment ->
navController.setGraph(R.navigation.nav_graph)
Navigation.setViewNavController(fragment.requireView(), navController)
}
}
@Test
fun navigate_to_words_nav_component() {
onView(withId(R.id.list_recycler_view))
.perform(
RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click())
)
assertEquals(navController.currentDestination?.id, R.id.wordListFragment)
}
@Test
fun navigate_to_blank_nav_component() {
onView(withId(R.id.letter_black_btn)).perform(click())
assertEquals(navController.currentDestination?.id, R.id.blankFragment)
}
}
이 예시는 LetterListFragment 에서 RecyclerView 의 목록을 클릭하면 WordListFragment 로 탐색하고 버튼을 클릭하면 BlankFragment 로 넘어가는 탐색 과정을 테스트한다. 먼저 @Before 어노테이션을 달고 있는 함수가 실행되면서 Nav Controller 와 초기 프레그먼트를 LetterListFragment 로 명시한다. 그 뒤, navigate_to_words_nav_component() 와 navigate_to_blank_nav_component() 가 실행되면서 @Before 함수가 실행된 후의 같은 환경에서 테스트 작업을 할 수 있다.
@Before 어노테이션 말고 유용한 어노테이션이 있는데 바로 @After, @AfterClass, @BeforeClass 이다.
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.After
import org.junit.AfterClass
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
@RunWith((AndroidJUnit4::class))
class TestAnnotations {
@Before
fun setup() {
println("Set Up function")
}
@Test
fun test_a() {
println("Test a")
}
@Test
fun test_b() {
println("Test b")
}
@After
fun testAfter() {
println("Test After Function")
}
companion object {
@BeforeClass
@JvmStatic
fun setupClass() {
println("set up Class")
}
@AfterClass
@JvmStatic
fun testAfterClass() {
println("Test After Class")
}
}
}
실행 결과는 다음과 같다. @Before 은 각 테스트가 실행되기 전 실행되고 @After 은 각 테스트가 끝난 후 진행된다. @BeforeClass 는 테스트 클래스가 실행될 때 한 번 실행되고 @AfterClass 는 테스트가 모두 종료된 후 실행된다.
set up Class
started: test_a(com.example.wordsapp.TestAnnotations)
Set Up function
Test a
Test After Function
finished: test_a(com.example.wordsapp.TestAnnotations)
started: test_b(com.example.wordsapp.TestAnnotations)
Set Up function
Test b
Test After Function
finished: test_b(com.example.wordsapp.TestAnnotations)
Test After Class
'안드로이드' 카테고리의 다른 글
[안드로이드] 메뉴 만들기 (0) | 2023.07.20 |
---|---|
[안드로이드] Activity 시작하기 (0) | 2023.07.20 |
[안드로이드] 간단한 단위 테스트 실행해보기 (0) | 2023.07.18 |
[안드로이드] 어노테이션 (0) | 2023.07.18 |
[안드로이드] RecyclerView 살펴보기 (0) | 2023.07.18 |