Android

[안드로이드] 테스트 라이브러리 Robolectric

베르_최성훈 2023. 9. 3. 17:34

 

안드로이드 테스트 피라미드

피라미드를 올라갈수록 비용 증가, 아래로 내려갈수록 더 많은 테스트가 작성되어야 한다.

안드로이드 테스트를 작성해 봤거나 그렇지 않더라도 두 가지 패키지를 보았을 것이다.

  1. androidtest : 실제 또는 가상 디바이스에서 실행할 테스트를 작성한다. JVM 만으로는 검증할 수 없는 테스트가 포함된다.
  2. test : 로컬 JVM에서 실행되는 테스트이다. 단위 테스트를 작성한다.

안드로이드 의존성이 있는 테스트는 모두 androidTest 하위에 위치해야 하는걸까?

UI 로직을 검증하기 위한 테스트를 단위 테스트로 만들 수는 없을까?

Robolectric

Robolectric을 사용하면 JVM 내에서 "시뮬레이션된" 안드로이드 환경에서 테스트가 실행된다. 즉, 한마디로 안드로이드 의존적인 테스트도 JVM 환경에서 실행할 수 있다.

 

에뮬레이터 없이 JVM에서 테스트를 실행할 수 있어 비용이 적게 들고 속도가 빠르다.

일반적으로 androidTest 에 사용되는 에뮬레이터는 Cold 부팅되는데 이 테스트보다 10배 빠르게 실행할 수 있다.

 

SDK, 리소스, 네이티브 메서드 시뮬레이션으로 실제 장치와 유사한 테스트 수행이 가능하다.

Android의 구현이 아닌 애플리케이션의 동작에 중점을 둘 수 있게 해준다.

사용 방법

1. Robolectric 사용을 위해 Runner 설정해 줘야 한다. 

@RunWith(RobolectricTestRunner::class)
class ExampleActivityTest { ... }

 

2. Activity 인스턴스를 생성할 수 있다.

 

Activity 의 인스턴스를 생성할 수 있다고? 그 놀라운 것을. Robolectric 이 해준다.


	@Test
	fun `Activity 실행 테스트`() {
		// given : 액티비티 생성
		val activity = Robolectric
			.buildActivity(ExampleActivity::class.java)
			.create()
			.get()

		// then
		assertThat(activity).isNotNull
}

3. ViewModel 인스턴스를 생성하고 활용할 수 있다.

Acitivity 를 사용해서 ViewModelProvider 로 부터 ViewModel 을 가져올 수 있다.


	@Test
	fun `ViewModel 생성 테스트`() {
		// given : ViewModel 
		val activity = Robolectric
			.buildActivity(ExampleActivity::class.java)
			.create()
			.get()
		val viewModel = ViewModelProvider(activity)[ExampleViewModel::class.java]

		// then
		assertThat(viewModel).isNotNull
	}

함수 호출도 가능


val viewModel = ViewModelProvider(activity)[ExampleViewModel::class.java]
viewModel.doSomthing()

4. View 인스턴스를 활용 가능하다.

에스프레소를 사용해 본 사람은 비슷하다고 생각할 수 있다. findViewById 로 찾고 performClick() 등의 함수로 View 인스턴스를 사용할 수 있다. 


	@Test
	fun `버튼 클릭 시 결과가 노출된다`() {
		// given
		val activity = Robolectric
			.buildActivity(ExampleActivity::class.java)
			.create()
			.get()
		val button = activity.findViewById<Button>(R.id.btnExample)
		val result = activity.findViewById<TextView>(R.id.tvResult)

		// when : 버튼을 클릭한다.
		button.performClick()

		// then
		assertThat(results.text.toString()).isEqualTo("테스트 성공!")
	}
}