지난번 발견한 올리브영 페이지의 결함 확인 기능을 Playwright를 활용하여 자동화해보려고 합니다.
Playwright가 지원하는 언어는 다양하지만 주로 사용하는 언어는 Javascript, Typescript라고 알고있고 현재 업무 진행할 때 Javascript를 활용하고 있기 때문에 Javascript 언어로 예제를 보여드리겠습니다.
기능 자동화 업무를 시작한지는 얼마 안된 기간이기에 부족한 점이 있을 수 있습니다!
또한 이미 자동화를 구축한 분들은 다들 알고 계신 내용 일 수 있어요 😀
포스팅 관련 조언해주시면 좋을 것 같아요 :)
관련 포스팅
2024.06.06 - [QA/기능 자동화] - 기능 테스트 자동화, 왜 Playwright를 선정했을까? (1)
2024.06.09 - [QA/기능 자동화] - 기능 테스트 자동화, 왜 Playwright를 선정했을까? (2)
자동화 시나리오 구성
기능 자동화 동작을 수행하려면 어떤 방식으로 자동화 시나리오를 구상할건지부터 생각해야합니다.
기존에 관리하던 기능 TC 가 있다면 참고해서 자동화 테스트 시나리오를 작성하는 것이 좋습니다.
기능 TC가 있다고해도 자동화 케이스를 별도 분리하지 않으면 잘못된 판단이 될 수 있기에 저는 별도로 빼서 케이스를 관리하는것을 추천 드립니다. 테스트 시나리오 작성 시 확인할 부분은 아래와 같습니다.
- 시나리오엔 어떤 페이지를 거쳐가며 목표하는 시나리오를 위해 사전 조건 확인 (로그인 등)
- 처음 시작 ~ 마지막 페이지, 기능까지 코드를 추가해야 함
- 동작 수행 외 성공 실패 기준 수립
- 타임 오버로 인한 실패 조건 추가 여부
- 동작은 정상 수행 했으나 오류 메시지가 출력 된 경우
- 전체 동작이 정상 수행되었을 때 성공
- 테스트 대상 브라우저 선정 (Chrome, Edge, Safari 등)
더 많은 조건이 있겠지만 당장 생각나는건 이것 뿐이네요.. 😥 생각 날 때 추가하도록 하겠습니다
자동화 테스트 예제
우선 저는 Playwright를 사용하고, 언어는 Javascript를 사용해서 예제를 작성해 볼 생각입니다.
이번 예제로는 결함 등록 방법에서 다뤘던 단순 결함건을 확인하는 과정을 자동화로 구성해보겠습니다.
Playwright를 설치하고 환경 세팅하는 것은 별도 포스팅으로 작성해보겠습니다. 지금은 Javascript 프로젝트가 구성되어 있다고 생각하고 진행하겠습니다 😏
우선 수행한 결과부터 첨부하겠습니다.
Chrome, Edge를 사용하여 2가지 테스트를 병렬로 수행한 모습입니다.
진행 속도가 빨라서 순식간에 지나갔지만 내용은 아래와 같습니다
- 올리브영 페이지 접속
- 상단 메뉴 중 세일 항목을 찾아서 클릭
- 중간에 '더모 코스메틱' 클릭 (다른 시나리오는 '맨즈케어' 클릭)
- 가장 하단 마지막 페이지 이동 아이콘 클릭
- 화면에 " 전체 0 개의 상품이 등록되어 있습니다." 문구가 표시 되는지 확인
- 문구가 있으면 성공, 없으면 실패
시나리오를 수행 후 "Allure" 라이브러리를 사용해서 리포트를 생성한다면 아래와 같은 리포트를 확인할 수 있습니다.
"Allure" 라이브러리 설치 및 구동 환경에 대한 포스팅은 추후 작성하도록 하겠습니다.
Playwright 자동화 코드 추가 및 설명
우선 Mainpage를 관리하는 js 파일입니다.
올리브영 URL은 별도 Json 파일에 저장하였습니다.
URL을 별도 파일로 관리한다면, URL이 변경되었을때 혹은 개발 서버에서 테스트해야할 때 수정하기 편리하겠죠?
//Mainpage.js
const { expect } = require('@playwright/test');
const fs = require('fs');
const rawData = fs.readFileSync('dataSet.json', 'utf8');
const jsonData = JSON.parse(rawData);
const saleMenuButton = "a[data-attr=\"공통^GNB^세일\"]";
class MainPage {
constructor(page) {
this.page = page;
}
async gotoPage() {
await this.page.goto(jsonData.oliveDomain);
}
async clickSaleMenuButton(){
this.page.locator(saleMenuButton).click();
}
}
module.exports = MainPage;
{
"oliveDomain": "https://www.oliveyoung.co.kr/"
}
저는 세일 버튼을 찾기 위해 속성 중 data-attr 라는 식별자를 사용했습니다. 다른 식별자로 설정하셔도 동작할 것이라고 생각됩니다!
locator 함수를 통해 위치를 지정하고, 클릭을 수행합니다.
this.page.locator(saleMenuButton).click();
다음은 SalePage.js 파일입니다.
세일 페이지로 이동한 뒤 세일 페이지에서 동작하는 기능들을 정의했습니다.
위와 같은 방식으로 버튼이나 카테고리와 관련된 식별자를 찾아서 위치를 지정해줍니다.
그리고 파라미터로 받은 문자가 화면에 표시되는지를 확인하는 expect 함수도 추가해줍니다.
//SalePage.js
const { expect } = require('@playwright/test');
const mansButton ='button >> text="맨즈케어"';
const cosmeticButton ='button >> text="더모 코스메틱"';
const pageLayer = 'div.pageing';
const nextPageButton = 'a.next';
const categoryInfoLayer ='div.TabsConts.on >> p.cate_info_tx';
class SalePage {
constructor(page) {
this.page = page;
}
async clickCosmeticButton() {
await this.page.locator(cosmeticButton).click();
}
async clickMansButton() {
await this.page.locator(mansButton).click();
}
async clickNextPageButton() {
await this.page.locator(pageLayer).locator(nextPageButton).click();
}
async expectCategoryText(text) {
await expect(this.page.locator(categoryInfoLayer)).toHaveText(text);
}
}
module.exports = SalePage;
마지막으로 실제 테스트를 실행하는 테스트 파일 부분입니다.
맨즈케어를 확인하는 케이스와, 더모 코스메틱을 확인하는 테스트 케이스로 분리하였습니다.
// tests/oliveTests/SalePage.test.js
const { test } = require('@playwright/test');
const MainPage = require('../../olivePage/MainPage');
const SalePage = require('../../olivePage/SalePage');
let mainPage;
let salePage;
const expectMessage = '전체 0 개의 상품이 등록되어 있습니다.';
test.beforeEach(async ({page}) => {
console.log('SalePage.test.js 테스트 수행 시작');
mainPage = new MainPage(page);
salePage = new SalePage(page);
await mainPage.gotoPage();
});
test.afterEach(async () => {
console.log('SalePage.test.js 테스트 수행 완료');
});
test('세일 페이지에서 맨즈케어 마지막 페이지도 이동 시 결함 확인', async ({ page }) => {
await mainPage.clickSaleMenuButton();
await salePage.clickMansButton();
await salePage.clickNextPageButton();
await salePage.expectCategoryText(expectMessage);
await page.waitForTimeout(2000);
});
test('세일 페이지에서 코스메틱 마지막 페이지도 이동 시 결함 확인', async ({ page }) => {
await mainPage.clickSaleMenuButton();
await salePage.clickCosmeticButton();
await salePage.clickNextPageButton();
await salePage.expectCategoryText(expectMessage);
await page.waitForTimeout(2000);
});
항목에서 테스트 수행 전 모델을 선언해주고 페이지를 여는 작업은 공통 작업이기에 전처리 부분으로 분류했습니다.
test.beforeEach(async ({page}) => {
console.log('SalePage.test.js 테스트 수행 시작');
mainPage = new MainPage(page);
salePage = new SalePage(page);
await mainPage.gotoPage();
});
모델과 테스트 파일 구조는 아래와 같은 상태입니다.
이렇게 세팅 후 테스트 수행은 Terminal에서 Playwright 명령어로 수행합니다.
npx playwright test
테스트가 잘 수행 되었다면, 아래 화면처럼 수행이 될 것입니다.
이후 Playwright에서 자동 생성되는 결과 비디오는 아래와 같습니다.
이렇게 생성된 동영상은 리포트에 첨부되어 "Allure" 리포트 페이지에 첨부됩니다.
자동화 동작 예시를 설명하다가 코드 설명까지 해야할 부분이 많았는데 작성할 내용이 많다보니 슥슥 넘어간 것 같네요
Playwright 코드 설명이나 설치, 세팅방식 그리고 Allure 설정 방식은 다음 포스팅에서 작성해보도록 하겠습니다 :)
'QA > 기능 자동화' 카테고리의 다른 글
기능 자동화, POM(Page Object Model) 구조 만들기 (1) | 2024.09.08 |
---|---|
기능 자동화를 만들면 살충제 패러독스에 걸리지 않나요? (0) | 2024.07.04 |
기능 자동화 동작 방식과 식별자 (0) | 2024.06.15 |
기능 테스트 자동화, 왜 Playwright를 선정했을까? (2) (2) | 2024.06.09 |
기능 테스트 자동화, 왜 Playwright를 선정했을까? (1) (1) | 2024.06.06 |