라이킷 13 댓글 공유 작가의 글을 SNS에 공유해보세요

You can make anything
by writing

C.S.Lewis

WDIO는 왜 Hooks 동작을 고려하지 않았을까?

reloadSession

by 이지원 Mar 22. 2025
브런치 글 이미지 1

최근 모바일 자동화 프로젝트를 WebdriverIO(WDIO) V9 Mocha 기반으로 마이그레이션 하면서, "WDIO는 왜 테스트 프레임워크의 Hooks 동작을 고려하지 않을까?"라는 궁금증이 생겼습니다. 


WDIO Cucumber를 사용할 때는 "시나리오 1개당 Feature 파일 1개"라는 설계 원칙을 유지했기 때문에, 모든 테스트 시나리오는 Cucumber 내부 동작에 의해 고유한 WebDriver 세션에서 실행되었습니다. 덕분에 Appium Device Farm DB에도 각 테스트가 독립된 결과로 저장되었고, Hooks 동작에 대한 고민을 할 필요가 없었습니다. 


제가 담당하는 여러 프로덕트 중 SDK를 테스트하기 위해 개발된 TestApp에서는 테스트의 신뢰성을 확보하기 위해, 각 시나리오가 항상 동일한 초기 상태에서 실행되어야 합니다. 즉, 앱의 캐시 및 로컬 스토리지 초기화 등을 통해 테스트 간 데이터 및 환경이 서로 영향을 주지 않도록 보장해야 합니다. Cucumber에서는 "시나리오 1개당 Feature 파일 1개"라는 설계 원칙으로 인해 Cucumber 내부 동작에 의해 각 시나리오가 새로운 WebDriver 세션에서 시작되기 때문에 이런 초기화 작업을 별도로 고려하지 않아도 됐습니다. 


그런데 V9 Mocha로 마이그레이션 하면서, 하나의 spec 파일 내에서 describe 블록이 여러 개의 테스트(it)를 포함하는 구조가 되었습니다. 이때, 각 테스트를 독립된 세션에서 실행하기 위해 beforeEach에서 WDIO command인 reloadSession을 사용했는데, 테스트 자동화 인프라인 Appium Device Farm DB에 불필요한 세션 데이터가 쌓이는 문제가 발생했습니다. 


이 문제의 원인을 WebdriverIO와 Mocha의 공식 문서를 통해 분석하면서, WDIO의 reloadSession이 왜 Hooks 동작을 고려하지 않는지에 대해 고민하게 되었고, 이에 대한 제 생각과 결론을 정리했습니다.


reloadSession을 사용하지 않을 경우 생기는 문제점

브런치 글 이미지 2

예를 들어 Android와 iOS는 Spec 파일이 분리되어 있고 1개의 descrbe에 2개의 it이 존재하는 구조에서 Android와 iOS를 병렬로 실행할 경우, 위와 같이 각 시나리오마다 독립된 세션에서 실행되지 않고 Android, iOS 각각 처음 생성된 세션에서 모든 테스트가 수행되고 있습니다.

undefined
undefined

에이슬립에서는 테스트 자동화 결과 디버깅 간에 핵심 데이터들은 모두 Json으로 생성되도록 처리했습니다. 자동화 인프라에서 발생한 문제와 클라이언트에서 발생한 문제를 보다 쉽게 파악할 수 있기 때문인데요. 위 데이터에서 sessionId를 살펴보면 Android, iOS 각각 처음 생성된 세션에서 모든 테스트가 수행되고 있습니다. 1개의 세션에서 2개의 시나리오가 실행되고 있습니다. SDK를 테스트하기 위해 개발된 TestApp에서는 테스트의 신뢰성을 확보하기 위해 각 시나리오가 항상 동일한 초기 상태에서 실행되어야 합니다. 즉, 앱의 캐시 및 로컬 스토리지 초기화 등을 통해 테스트 간 데이터 및 환경이 서로 영향을 주지 않도록 보장해야 하는데, 이렇게 실행될 경우 1개의 세션에서 다음 시나리오를 계속해서 수행하는 방식이기 때문에 SDK 테스트 신뢰성 확보에 영향을 끼치게 됩니다. 테스트 실행 속도 측면에서 1개의 세션에서 모든 시나리오가 수행되는 방식도 좋은 접근이지만 에이슬립 SDK 검증을 위해서는 지양해야 하는 방식입니다.

브런치 글 이미지 5

더 큰 문제는 Appium Device Farm 대시보드에서 1개의 세션에서 수행된 마지막 데이터만 보이는 점입니다. 실제로 테스트 수행한 시나리오는 4개이지만 대시보드에서는 특정 세션의 마지막 데이터만 보이므로 수십 수백 개의 시나리오가 실행되어도 상세 결과 확인 가능한 데이터는 세션별로 1개만 존재하게 됩니다. 


WDIO reloadSession command 사용하여 문제 해결(1)

브런치 글 이미지 6

WDIO는 새 세션을 생성하는 reloadSession command를 제공하는데요. 수백 개의 단일 테스트 파일을 생성하는 것을 피하기 위해 각 테스트 사이의 세션을 정리해야 하는 경우 유용하게 활용할 수 있습니다. 당연하게도 각 테스트마다 고유한 세션을 생성하므로 테스트 시간에 영향을 끼칠 수 있기 때문에 서비스와 프로젝트 특성에 맞춰서 활용 여부를 결정해야 합니다. 에이슬립의 SDK 제품은 테스트 속도보단 테스트 신뢰성 확보에 더 중요하기 때문에 reloadSession을 적극 활용하고 있습니다. 

브런치 글 이미지 7

그런데 위 코드(1개의 describe에 2개의 it 존재)를 실행할 경우 Appium Device Farm DB에 3개의 데이터가 저장되는데, 2개는 정상적인 데이터이고 1개는 name이 Null이고 status가 Unmarked인 데이터가 생성되는 문제가 발생합니다. 

undefined
undefined

Unmarked와 같이 불필요한 데이터가 계속해서 쌓이면서 Test Trends 분석에 영향을 끼칠 수 있고, 서비스 규모가 커질수록 품질 매트릭 관리가 중요해지는 시점이 찾아오는데, 불필요한 데이터로 인해 전체적인 매트릭 관리에 어려움이 생길 수 있습니다.


WDIO reloadSession command 사용하여 문제 해결(2)

브런치 글 이미지 10
브런치 글 이미지 11

앞선 문제를 해결하기 위해선 WDIO에서 제공하는 reloadSession command를 그대로 사용하면 안 되고 현재 달성하고자 하는 동작에 맞게 수정하는 과정이 필요한데요. 이번 게시글과 같은 상황에서는 reloadSession을 두 번째 테스트 시나리오부터 동작시키면 불필요한 데이터가 DB에 쌓이는 문제는 해결됩니다.


WDIO는 왜 Hooks 동작을 고려하지 않았을까?

WDIO에서의 Mocha 역할

이 궁금증을 해소하기 위해 먼저 WDIO와 Mocha의 역할에 대해 고민해 볼 필요가 있었습니다. WDIO는 Selenium WebDriver를 쉽게 다룰 수 있도록 도와주는 WebDriver 클라이언트 라이브러리 역할을 하면서도, wdio CLI를 통해 테스트 실행을 제어하고 보고서를 생성할 수 있는 테스트 러너(Test Runner) 기능도 포함하고 있습니다. 하지만 WDIO 자체적으로 it() 같은 테스트 함수를 제공하지 않기 때문에, 테스트를 구조화하고 실행하는 역할은 Mocha와 같은 테스트 프레임워크와 통합해서 수행해야 합니다. 물론 Mocha 자체적으로도 mocha CLI를 제공하여 테스트를 실행할 수 있지만, WDIO 환경에서는 최종적으로 WDIO가 테스트 실행을 제어하는 상위 러너 역할을 합니다. 즉, WDIO가 Mocha를 실행하는 형태로 동작하며, Mocha는 WDIO 내부에서 테스트 구조화 및 실행을 담당하게 됩니다.


기술적 관점에서의 이유

WDIO가 WebDriver 세션 관리 및 실행을 담당하고, 테스트의 라이프사이클은 Mocha 등의 프레임워크가 제어하는 구조에서는 reloadSession()이 WDIO의 고유 기능이므로, 테스트 프레임워크와 직접적인 통합이 없습니다.

이로 인해 beforeEach 같은 Hooks에서 reloadSession()을 호출하면, Mocha가 예상하는 테스트 실행 흐름과 맞지 않는 세션 종료 및 재시작이 발생할 수 있습니다. 다시 말해, 세션 관리가 Mocha의 Hooks 동작과 충돌하게 되는 것이죠. 또한 일반적으로 Hook은 테스트 간 공유 리소스를 재설정하는 용도로 활용되지만, WDIO의reloadSession()은 단순한 리소스 재설정이 아니라 기존 WebDriver 세션을 종료하고 새로운 세션을 생성하는 동작을 수행합니다. 따라서 Hooks에서 reloadSession()을 활용하려면, 이러한 특성을 충분히 고려한 후 사용해야 합니다.


철학적 관점에서의 이유

WDIO는 WebDriver 세션을 다루는 것에 집중하고, 테스트 실행의 세부 로직은 프레임워크에 맡기는 철학을 가지고 있습니다. 따라서 Hooks와 같은 개념을 WDIO에서 직접적으로 고려한 설계를 하지 않은 것으로 보입니다.

실제로 WDIO 공식 문서를 살펴보면, 세션 관리와 관련된 API만 제공하며, 테스트 프레임워크의 라이프사이클을 직접적으로 제어하지 않음을 명확히 하고 있습니다. 또한 WDIO는 단순한 UI 테스트뿐만 아니라 대규모 병렬 실행, CI/CD, 모바일 자동화 등 다양한 사용 사례를 지원하도록 설계되었습니다. 만약 특정 테스트 프레임워크(Mocha, Jasmine, Cucumber)의 Hook 동작을 고려하여 reloadSession()을 설계하면, 특정 프레임워크에 종속될 위험이 생기고, 오히려 서로 다른 프레임워크를 사용하는 사용자들에게 불필요한 복잡성을 초래할 수 있습니다. 이러한 이유로 WDIO는 Hooks와의 직접적인 통합보다는 유연한 API를 제공하고, 개발자가 직접 이를 활용하도록 유도하는 방향을 선택한 것으로 보입니다.


WDIO 철학을 이해하게 된 과정

이 문제를 처음 발견했을 때는, "Hooks에서 reloadSession()을 수행하는 경우는 결국 테스트 간 데이터 및 환경을 서로 독립적으로 유지하기 위함인데, 그렇다면 WDIO가 애초에 테스트 프레임워크의 동작 방식을 고려해서 reloadSession()을 구현했으면 어땠을까?" 하는 의문이 들었습니다. WDIO가 테스트 프레임워크로서의 역할을 온전히 수행하지 못하므로 반드시 Mocha 같은 프레임워크와 통합해서 사용할 것이고, 그렇다면 테스트 프레임워크의 Hooks 동작을 고려하는 것이 자연스럽지 않을까? 하는 불편함도 있었습니다. 하지만 WDIO의 등장 배경과 철학, 그리고 WDIO에서 테스트 프레임워크가 수행하는 역할을 다시금 정리하는 과정을 거치면서, WDIO의 설계 방향을 이해하고 받아들이는 시간이 되었습니다.


마치며

요즘 저는, 백엔드 개발 분야를 기반으로 Selenium 프로젝트의 리더이자 WebDriver를 만든 Simon Stewart를 커리어 마지막 롤모델로 삼고 Selenium과 Appium의 내부 구조를 깊이 이해하며 세계적인 자동화 엔지니어들과 교류하는 것을 목표로 하고 있습니다. Selenium & Appium 오픈소스 공식 Contributor가 되겠다는 목표도 함께 가지고 있습니다. 그리고 그 목표를 이루기 위해, 기업에서의 성과와 개인적인 목표를 함께 이루어가는 한 해를 만들어가고 싶습니다. 그 과정에서 이렇게 실무에서 사용하는 기술에 대해 끊임없이 고민하고, 하나의 결론을 내리는 시간이 더없이 소중하게 느껴집니다.

매거진의 이전글 소프트웨어 품질 커리어 목표

브런치 로그인

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari