Pytest-bdd와 Selenium을 이용한 웹 UI 테스트 자동화

Image not Found

안녕하세요, 버즈빌 QA 매니저 Erica입니다. 버즈빌에서는 Dash라고 불리는 광고 관리 보드를 운영하고 있습니다. QA 파트에서는 이 중 광고주 대상 시스템 영역에 대해 웹 UI 테스트 자동화를 진행하고 있습니다. 이 글을 통해 현재까지 진행된 테스트 자동화 사례를 소개하며 테스트 자동화를 처음 시작할 때 고려해야 할 점을 함께 나눠보고자 합니다.

UI 자동화의 대상과 프로젝트 소개

광고 관리 보드에서는 광고주의 광고 항목에 대한 설정 기능을 지원합니다. 이 기능 안에서 광고를 보여줄 이미지나 동영상 설정, 광고가 나가는 지면 설정, 광고 예산 설정, 광고 집행 시간과 타겟팅 설정, 성과 보고서 생성 등 다양한 세부 기능에서 여러 변경 사항이 발생합니다. 이로 인해 기존 기능이 영향을 받았는지 확인하기 위한 회귀 테스트를 매번 진행하고 있는데요, 이번 자동화 프로젝트는 보드 웹 UI 상에서 보이는 광고 항목의 회귀 테스트 자동화를 목표로 하고 있습니다.

TMI. 현재 진행 중인 웹 UI 테스트 자동화 프로젝트의 이름은 ‘라떼’입니다. 프론트엔드에서는 자스민, 모카, 차이 등 차 이름을 딴 테스트 프레임워크가 많다 보니 이전에도 녹차라는 이름의 자동화 프로젝트가 진행되었었고 자연스레 같은 맥락에서 프로젝트 이름을 짓게 되었습니다. ‘예전에는 자동화 없이 수동으로 테스트했었다’라는 뜻에서 라떼이기도 합니다 :)

UI 자동화는 어떻게 시작해야 할까?

라떼 프로젝트는 처음에 파일럿 프로젝트로 시작했습니다. 파일럿 프로젝트는 Selenium과 pytest로 BDD 기반 자동화 구현이 쉽게 가능한지, 자동화 프로젝트와 테스트케이스를 관리하고 있는 Testrail과의 연동이 가능한지 테스트하는 용도로 3 달여 남짓 진행했습니다. 파일럿 프로젝트를 진행해 보니 이대로 전체 영역을 대상으로 한 자동화 구현이 가능하겠다는 확신을 얻게 되어 이후 Selenium, pytest-bdd, pytest-testrail-client의 조합으로 본 프로젝트에 돌입할 수 있었습니다. 이와 같이 테스트 자동화 프로젝트 도입을 고민하는 단계에서는 파일럿 프로젝트를 통해 현재 선정한 툴의 조합으로 프로젝트를 진행해도 될지를 가늠해 볼 수 있습니다.

파일럿 프로젝트의 또 다른 장점은 처음부터 완벽한 구조를 고민하지 않아도 된다는 데 있습니다. 라떼 파일럿 프로젝트의 경우, 처음에는 Selenium의 WebDriver API를 통해 크롬 브라우저를 열고 로그인 창의 아이디와 패스워드 Input 필드를 선택하고 값을 넣는 코드에서 시작했습니다. 그러다가 page, element, locator 클래스를 도입해 구조를 잡아나가고 pytest-bdd를 적용해 시나리오와 자동화 스크립트를 디렉토리 단위로 분리해 냈습니다. 자동화 스크립트 중에서도 특정 기능이나 전체 세션에서 공통으로 쓰이는 기능은 conftest.py 내에 fixture로 다시 분리해 내고, pytest에 대한 지식이 늘어나면서 pytest hook과 pytest.ini에서의 환경 설정 코드도 하나둘씩 추가되었습니다. 최종적으로 pytest-testrail-client 플러그인을 통해 Testrail에 테스트 결과를 전송할 수 있게 되었을 때에는 이미 작은 영역에 대해 프로젝트 전체 구조가 잡혀 있었기 때문에 망설임 없이 본 프로젝트에 같은 구조를 적용할 수 있었습니다.

Testrail로 전송된 자동화 프로젝트 수행 결과

UI 자동화를 할 때 어떤 고민이 들까?

웹 UI 테스트 자동화를 처음 진행할 때는 어디까지 테스트 자동화의 대상으로 삼을 것인지, 어떤 툴을 쓰는 게 좋을지, 프로젝트 구조를 어떻게 잡을 것인지에 대해 고민하게 됩니다.

구조

다행히 이번 프로젝트의 경우 ‘광고 항목의 회귀 테스트’라는 대상이 처음부터 설정되어 있었기 때문에 첫 번째 사항에 대해서는 크게 고민하지 않았습니다. 다만 대상 영역 중 어떤 부분을 먼저 자동화할 것인지에 대해서는 대개 ‘수동으로 확인하기 번거롭거나 어려운 부분’을 먼저 자동화해야겠다는 목표가 있었습니다. 프로젝트 구조에 대해서는 파일럿 프로젝트를 진행하다 보니 크게 테스트 시나리오, 테스트 스크립트, 웹 페이지 객체로 자연스럽게 상위 디렉토리 구조가 나뉘게 되었습니다.

├── features
│   ├── account
│   │   └── advertiser.feature
│   ├── ad
│   └── ad_group
├── step_definitions
│   ├── account
│   │   ├── conftest.py
│   │   └── test_advertiser.py
│   ├── ad
│   └── ad_group
├── page_objects
│   ├── locators
│   ├── page.py
│   └── element.py
├── pytest.ini
└── conftest.py

툴(tool)

툴에 대해서는 프론트엔드에서 사용하는 자바스크립트 기반으로 갈지 아니면 코드 구현이 직관적이고 배우기 쉬운 파이썬 기반으로 갈지에 대한 고민이 있었습니다. 라떼에서는 후자를 선택해 진행했고 결과적으로 파이썬의 직관성과 pytest와 연동되는 풍부한 라이브러리를 활용할 수 있게 되었습니다.

유지 보수성

자동화 프로젝트의 뼈대를 잡아가며 가장 많이 신경 쓴 부분은 앞으로의 유지 보수 가능성이었습니다. 라떼 이전에도 진행되었던 자동화 프로젝트가 있었지만 광고 관리 보드 UI의 업데이트에 따라 웹 페이지 요소 객체들이 변경되면서 스크립트의 상당 부분이 깨져 있는 상태였습니다. 라떼는 두 번째로 진행되는 프로젝트인 만큼 이 부분을 보강하기 위해 테스트 자동화에 사용할 요소 객체에 최대한 id를 많이 부여하고 xpath의 상대 경로를 통해 요소 객체를 선택함으로써 UI 변경 사항에 최대한 덜 민감해지도록 했습니다. 자동화 스크립트 작성도 쉽고 실용적이며 직관적이어야 한다는 판단하에 page object 내에 정의된 클래스를 활용해 요소 객체는 이미 정의된 클래스를 불러서 쓰고 스크립트 작성 시에는 필요한 동작을 잘 구현하는 데 집중할 수 있도록 했습니다.

시나리오와 대응되는 테스트 스크립트

확장성

추가적으로 확장성을 고려해 개발 순서는 BDD를 기반으로 테스트 시나리오를 먼저 작성하고 테스트 시나리오에 대응하는 스크립트를 짜는 방식으로 가져갔습니다. BDD를 실제 적용해 보니 시나리오가 이미 정의되어 있기 때문에 테스트 스크립트를 짜기도 쉬워지고, 시나리오를 작성할 때 현재 광고 관리 보드의 QA를 맡고 계신 QA 매니저 Amy의 도움을 받을 수 있어서 프로젝트를 진행하기 한결 수월하다는 인상을 받았습니다.

pytest-bdd로 작성된 테스트 시니리오

UI 자동화의 끝은 어디일까?

자동화 프로젝트의 개발 방식이 자리 잡아감에 따라 프로젝트 자체도 조금씩 개선해 나가고 있습니다. 처음에는 광고 관리 보드 시스템에 접속하기 위한 로그인 정보를 콘솔에서 입력하다가 불편하다고 느껴서 pytest.ini로 로그인 정보를 옮기게 되었고, 크롬 브라우저 버전이 올라갈 때 수동으로 업데이트해야 했던 크롬 드라이버를, 현재는 라이브러리를 적용해 크롬 브라우저 버전에 맞게 크롬 드라이버 버전을 자동으로 맞춰주도록 변경했습니다. 그 외에 아직 적용되지 못한 과제로는 로그인 세션이 브라우저에 걸쳐 유지되는 테스트 병렬 실행 적용, 서버에 자동화 프로젝트를 올려 누구나 사용 가능할 수 있게 만드는 작업 등이 있습니다. 그런 와중에 코드가 늘어갈수록 리팩토링 해야할 코드도 보이고 광고 관리 보드의 UI가 지속적으로 업데이트되면서 이미 작성된 테스트 코드도 수정하거나 추가해야 할 부분이 늘어나고 있습니다. 결과적으로 자동화 프로젝트도 결국 코드를 다루는 행위이기에 끊임없이 유지 보수하지 않으면 도태될 운명이 아닐까 합니다. 그러니 반대로 지속적인 유지 보수를 통해 테스트 대상과 보조를 맞춰 진행해 나간다면, 테스트에 대한 부담감을 줄이고 자신 있게 프로덕트를 내놓는 데 도움이 되리라고 확신합니다.

버즈빌 개발자 지원하기 (클릭)

버즈빌 테크 리크루터와 Coffee Chat하기 (클릭)

You May Also Like

버즈빌, 아마도 당신이 원하던 회사!

지원하기