AI Briefing
KO

Kakao Brunch and Tistory: A Journey into Test Code: From Architecture to Coverage Measurement

·2021.11.08 00:00

Key point

The Kakao Creator App team shared their architectural challenges, Coroutines testing techniques, and the journey to achieving 11% coverage while introducing test code to Brunch and Tistory.

1 / 16

Details

The Kakao Creator App Development Team shared the trial and error and solutions encountered while introducing test code to the Brunch and Tistory Android apps. The team began building a test environment for technical practices central to Agile methodology (such as TDD and refactoring), but faced several hurdles with the existing architecture and asynchronous processing methods.

Background of Test Introduction and Architecture

Brunch and Tistory had a multi-module structure applying Clean Architecture, MVVM, and Hilt. The transition to MVVM began in 2018 and was completed in 2020, with migrations from Java to Kotlin and from Rx to Coroutines. These refactorings laid the foundation for testable code, but additional preparation was required for actual test writing.

Coroutines and LiveData Testing Techniques

The biggest difficulty in writing tests was the mismatch between the main thread and the test thread. Main thread exceptions occurred when changing LiveData or calling viewModelScope.launch. To resolve this, InstantTaskExecutorRule was applied, and a test Dispatcher was injected using Dispatchers.setMain from kotlinx-coroutines-test. Additionally, to handle cases where various Dispatchers are used, a DispatcherProvider interface was introduced to configure the test environment via dependency injection. For timing control of asynchronous tasks, pauseDispatcher and resumeDispatcher were used to verify state changes at specific points.

JUnit5 Migration and Error Resolution

When introducing JUnit5, the team had to handle changes where existing JUnit4 Rules were replaced by Extensions. InstantTaskExecutorRule and MainCoroutineRule were migrated to Extension classes implementing BeforeEachCallback and AfterEachCallback. Furthermore, the team emphasized that directly removing or modifying unnecessary stub code is more effective for maintaining test code quality than using lenient mode or MockitoSettings to resolve UnnecessaryStubbingException caused by unnecessary stubs.

Coverage Measurement and Results

The test scope was limited to ViewModels that manage UI state. Due to the complexity of UI tests and the lack of data layer mappers, the team initially focused solely on ViewModels. Coverage for ViewModel classes was measured using the Jacoco plugin, and the internal build system, MoBil, automatically calculates and records coverage during Release builds. Current coverage is at the 11% level, and the team prioritizes the trend of coverage growth with each deployment over fixed target figures. It took approximately three months from the introduction to the application of tests, which served as an opportunity to overcome vague fears about testing and establish a sustainable testing culture.

This summary was generated automatically by AI. Check the original for the author's claims and context. Copyright belongs to the original author.

Our guide explains how the AI works. Report summary errors, attribution issues, or removal requests via Contact.