brunch

You can make anything
by writing

C.S.Lewis

by 이지원 Oct 29. 2022

WebdriverIO 살펴보기

비교적 최신 웹 모바일 테스트 프레임워크인 WebdriverIO를 살펴보겠습니다.


사전 조건

1. node.js 설치 완료(버전 무관)

2. 구글 크롬 최신 버전 업데이트 완료(22.10.29 토요일 기준 107.0.5304.87


프레임워크 셋업 및 폴더 구조

https://gist.github.com/Jiveloper/f589ecffd9a88c757cb91897a9b39e89

https://gist.github.com/Jiveloper/cff231570d71c539669910241e31b9ff

WDIO Configuration Helper에서 동일하게 구성했다면 위와 같은 폴더 구조로 생성됩니다.


Autocompletion

https://gist.github.com/Jiveloper/1ae979043fb307a34b0980b2c04d449f

VScode 또는 IntelliJ와 같은 IDE를 사용하시면 자동 완성을 위한 별도 조치가 필요 없지만 만약 특정 문제로 자동 완성이 되지 않을 경우 최상위 디렉터리에 jsconfig.json 파일을 생성하여 위 코드를 작성해주세요.

https://gist.github.com/Jiveloper/d289998f87635fad20c8852962689da5

위와 같이 WDIO에서 제공하는 기능들을 테스트 코드 작성 간에 쉽고 편리하게 타이핑할 수 있도록 자동 완성은 생산성 향상에 꼭 필요합니다. 


eslint-plugin-wdio

eslint가 왜 필요한지 먼저 살펴보겠습니다.

https://gist.github.com/Jiveloper/b9fd586c748919aed51040660b15ed45

위 코드는 런타임 환경에서 에러가 발생합니다. 어느 부분이 문제인지 식별하셨을까요? 지금은 간단한 코드라서 엔지니어가 미리 실수한 부분을 발견할 수도 있습니다. 하지만 실무에서는 위와 같은 코드가 수백 수천 줄 구현됩니다. 런타임 환경전에 실수로 작성된 코드를 미리 발견해야 테스트 자동화 운영이 보다 수월하지 않을까요?

'당연히 오탈자가 있으면 빨간 줄로 에러 표시를 해주지 않나?'라고 생각하실 수도 있는데요. 위 사진은 자동화 엔지니어가 직접 보는 화면이며 빨간 줄이 없습니다. 이러한 문제를 해결하기 위해 eslint을 사용해야 하는데요. Java와 같은 언어를 다뤄보셨다면 제가 지금껏 쌀로 밥 짓는 이야기를 한다고 생각할 수도 있습니다. 


대부분의 프로그래밍 언어에는 컴파일 과정에서 수행되는 Linter가 기본적으로 내장되어 있기 때문에 런타임 환경에서의 실수를 미리 방지할 수 있습니다. 하지만 인터프리터 언어인 자바스크립트는 Linter가 내장되어 있지 않습니다. 이 때문에 런타임 환경에서 에러가 발생할 확률이 높습니다. 


따라서 자바스크립트 코드에서 발견된 문제를 식별하기 위한 정적 코드 분석 도구인 eslint와 같은 도구를 사용하는 것이죠. eslint 플러그인을 사용하면 문법적인 오류나 스타일적인 오류뿐 아니라 적절하지 않은 구조에 대해 미리 파악할 수 있도록 도와줍니다. 왜 사용해야 하는지 알았으니 이제 eslint 플러그인을 셋업 하겠습니다.

https://gist.github.com/Jiveloper/80137c17a60db62b61b722f12eccdbfe

https://gist.github.com/Jiveloper/bac44dfd8109526b333db4a54174200f

eslintrc 파일에 위 코드를 추가합니다. NPM 사이트에서 제공하는 Recommended configuration 이외에 parserOptionsenv를 추가했습니다. 이제 오탈자가 발생하면 빨간 줄 에러가 표시됩니다. 보다 상세한 설정은 ESLint 공식 문서를 참고해주세요.


Page Objects

page.js

https://gist.github.com/Jiveloper/01a66f97338450de4c4ddfb2b76c6877

WebdriverIO에서 Default로 제공하는 Page Objects의 구조입니다. 해당 모듈엔 개체가 하나만 존재한다는 사실을 명확히 나타내고자 export default을 사용합니다. 이처럼 default를 붙여서 모듈을 내보내면 중괄호 없이 모듈을 가져올 수 있습니다. named export 한 모듈은 중괄호가 필요하고 defalut export는 중괄호가 없기 때문에 좀 더 깔끔합니다.


Page 클래스에 open이 구현되어 있는데요, 다른 페이지에서 해당 페이지를 extends 하여 각 페이지에 적합한 페이지가 열리도록 super를 사용하여 활용할 수 있도록 구현되어 있습니다. 각 페이지마다 열려야 하는 기본 페이지가 다를 수 있는데 그러한 로직을 구현할 때에 사용합니다.


login.page.js

https://gist.github.com/Jiveloper/7da9096d97733289e0cdecb3af359929

특정 페이지의 로케이터와 테스트 로직에 필요한 동작을 함수 형태로 만들고 해당 메서드를 테스트 파일에서 사용하게 됩니다. 로케이터를 가져올 땐 일반적으로 getter methods로 정의합니다. 로케이터를 Json 데이터 형식으로 각 환경과 페이지 별로 구분하여 관리할 수도 있는데요. 개인적으로 Page Objects 접근에 맞지 않고 장기적인 관점에서 오히려 유지보수 비용이 증가할 우려가 있습니다. 


각 페이지에 로케이터가 너무 많아질 경우 일반적인 Page Objects의 접근에서 벗어나 변형된 형태의 Page Objects를 활용하는 것도 좋은 방법이 될 테고요. 지나친 페이지 중심의 접근 설계 방법이 아닌, Page Objects로 접근하되 사용자 동작 중심으로 구현하다 보면 각 클래스에 포함되는 로케이터의 개수는 그렇게 많지 않을 거라 생각합니다. 


이러한 부분들을 테스트 코드를 구현하는 엔지니어가 판단해야 하기 때문에 테스트 코드 구현 전, 기술적인 관점보단 사용자 관점에서의 서비스 분석이 필요합니다.


e2e.js

https://gist.github.com/Jiveloper/694623e1331c4a4a6d391ff2f1a732ad

테스트 코드는 비동기 작업인 async/await로 구현되어야 합니다. 2021년 4월 14일부터 Chromium의 변경으로 인해 Node.js v16부터 동기화 모드가 더 이상 지원되지 않기 때문인데요. WebdriverIO로 프로젝트를 시작하는 경우 더 이상 동기화 모드를 사용하지 않는 것이 좋습니다. 동기 비동기와 관련된 자세한 사항은 WDIO 공식 문서를 참고하는 것이 좋습니다.


앞서 LoginPage에 구현된 메서드를 호출하여 페이지 오픈 후 로그인 시나리오가 진행되도록 구현된 모습입니다. Page Objects로 설계하지 않을 경우 e2e.js과 같은 테스트 파일의 내부 코드가 굉장히 지저분해지고 유지 관리가 어려워집니다.


일반적으로 WDIO에서는 각 페이지에서 동작과 검증에 필요한 로케이터 설계 및 메서드를 구현하여 테스트 파일에서 로직으로 활용합니다. expect와 같은 검증 구문은 테스트 파일의 로직 내부에서 처리하는 것이 좋습니다. 

https://gist.github.com/Jiveloper/672639be03be38aeb9ac3fca90a893fe

예를 들어 각 페이지에 구현되어야 할 메서드는 위와 같습니다. 일반적으로 로케이터를 getter method로 정의하여 테스트 파일에서 클릭과 입력과 같은 동작을 구현하지만 로케이터뿐 아니라 테스트 자동화에 필요한 행위 자체 모두 페이지에서 구현합니다. 간단한 테스트 시나리오만 자동화할 수 있는 것이 아니라 HTML에 렌더링 되는 모든 요소는 로직만 잘 구성한다면 자동화 가능합니다.


상품 페이지에 있는 가격의 합이 실제로 동일한지 비교하기 위해 위와 같이 로직을 구성할 수 있습니다. 테스트 파일에서는 sumOfProducts 메서드를 변수에 할당하고 실제 값을 반환하는 메서드 또한 페이지에서 구현 후 최종적으로 expect 구문을 통해 값이 서로 동일한지 체크해보는 테스트 로직을 구현할 수 있습니다. 


또 어떤 로직이 있을 수 있을까요? 원티드 채용 공고 페이지에서 특정 직군을 클릭하여 더 이상 화면에 갱신되는 리스트가 없을 때까지 스크롤 한 뒤 응답률 높은 기업만 북마크 하려면 어떻게 해야 할까요? 이러한 로직은 단순히 로케이터만 설계한다고 해서 구현할 수 있는 자동화 커버리지가 아닙니다. 따라서 페이지에 로케이터뿐 아니라 WebdriverIO에서 제공하는 검증, 클릭, 입력과 같은 기능을 활용 가능토록 원하는 데이터로 구현하는 작업이 필요하겠죠.


위와 같은 메서드는 한번 구현해놓으면 재사용하기 편리하므로 반복적이고 귀찮은 작업들은 가능한 모두 재사용한 형태로 자동화시키는 것이 좋습니다. 또한 유지보수 원활한 구조로 프레임워크를 설계한다면 대규모 테스트 스위트에 도달하더라도 유지 관리 비용이 크지 않습니다.  


package.json && conf.js

https://gist.github.com/Jiveloper/2421f67ad533b0463213ec2a8bb1dbf7

https://gist.github.com/Jiveloper/019930d3648177a8523c9d86ac32cc61

package.json에서 scripts를 원하는 형태로 작성하여 필요한 테스트를 실행할 수 있습니다. 


또한 wdio.conf.js에서 원하는 테스트를 실행하고 제외할 수 있습니다. wdio.conf.js의 웹 모바일 구성은 서로 다르기 때문에 프레임워크를 실무 레벨에서 활용할 경우 공통 conf를 생성하고 웹과 모바일마다 필요한 서로 다른 설정 값들을 세팅하여 구동합니다. 


실행할 테스트를 설정하고 제외하는 부분은 Java 기반의 E2E에서 TestNG를 사용해보셨다면 그와 비슷한 역할을 하는 기능이라고 생각하면 이해하기 쉽습니다.

https://gist.github.com/Jiveloper/440dc17a288ad612888d732cd199a7b8

scriptswdio라는 명칭으로 실행할 수 있도록 작성했기 때문에 wdio run wdio.conf.js가 아니더라도 npm run wdio로 실행 가능합니다. 


일반적으로 실무 레벨에서는 해당 부분에 QA Regression, QA Smoke, Staging Regression(스테이징에서 굳이 리그레션을 할 필요는 없겠지만 예시를 위해), Production Regression, QA Confirmation 등으로 작성하여 환경별로 실행에 필요한 Test Suitesconf로 잘 구성하여 운영하면 좋습니다.


셀레늄과 다르게 driver를 생성하거나 종료하는 작업이 필요치 않습니다. 크롬 드라이버 또한 다운로드할 필요가 없고요. 물론 셀레늄에서도 크롬 드라이버 관리를 위한 기능이 존재하지만 WDIO는 별도 설정 필요 없이 셀레늄에서 귀찮게 느껴지는 작업들을 하지 않아도 됩니다. 


로컬 병렬 테스팅 또한 conf에서 maxInstances만 조정하면 됩니다. 젠킨스 또는 깃 헙 액션에 대한 CI 설정도 문서화가 잘되어 있어서 쉽게 구축할 수 있습니다. 


이상으로 WebdriverIO 살펴보기 블로깅을 마치겠습니다. Python, Java(or Kotlin), JS or TS를 사용하는 WebdriverIO 모두, 자동화 운영에 필요한 실무 레벨에서의 요구 사항들은 비슷한 개념으로 동작 및 해결할 수 있기 때문에 언어와 테스트 환경에 크게 구애받지 않는 것이 좋습니다. 


한 가지 언어를 깊게 이해하고 한 가지 언어에서 활용 가능한 테스트 프레임워크를 초기 구축 단계부터 유지보수까지 필요한 작업들에 익숙해지다 보면 결국 같은 개념이 방법만 다를 뿐 다른 환경에서도 비슷하게 구현할 수 있기 때문입니다. 


레고 블록 조립을 할 줄 안다면 새로운 레고 블록의 설명서를 보아도 어느 정도의 삽질은 필요하겠지만 끝내 구현할 수 있듯이 E2E 테스트 자동화의 환경도 비슷한 맥락이 아닐까 싶습니다. 


SDET를 위한 유료 강의가 포함된 웹사이트를 구현하여 운영하고 싶은데, JavaSpring과 프론트JS가 근본인 React 병행 학습 하기엔 QA 현업을 진행하면서 아무래도 어려움이 많을 것 같고, 프론트의 근본 언어는 반강제이기 때문에 JSTS를 사용하는 WebdriverIOE2E 메인 프레임워크로 활용할 계획입니다. 


다시 현업에 복귀하여 보다 깊이 있는 블로깅을 할 수 있도록 기술과 SW QA 분야의 지식 학습에 매진하여 좋은 강의와 SDET 매거진을 써 내려가도록 하겠습니다. 


감사합니다.


Ref

https://webdriver.io/

https://eslint.org/

매거진의 이전글 페이지 개체 모델의 문제점
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari