기능 테스트 자동화를 구성하면서 가장 어려웠다고 생각하는 부분인 식별자가 없을 때 자동화 스크립트 작성 방식에 대해 포스팅 해보도록 하겠습니다.
제 방법이 정답은 아니니까 이런 방식으로도 자동화를 구성하는구나 정도로 알아주시면 감사하겠습니다 😎
이번 포스팅은 업무를 진행하면서 가장 힘들었던 부분인 식별자가 많이 부족한 상태에서 기능 테스트 자동화 구현하는 방법에 대해 포스팅 해보려고 합니다.
기능 테스트 자동화를 구현해보신 분이라면, 각 메뉴나 버튼에 대해 식별자가 있다는 것이 얼마나 큰 행복인지 잘 아실 것이라 생각됩니다 😵
하지만 당연하게도 모든 버튼이나 모든 기능에 대한 식별자를 넣는다는 것은 너무너무 어려운 일입니다.
반응형 웹 페이지나 동작에 의해 특정 기능이 추가되는 등 항상 동일한 화면을 표시하는 웹 페이지가 아니라면 유동적인 기능들에 대해 모두 식별자를 주기는 어려울 것입니다.
저는 처음에 기능 테스트 자동화를 구현했을 때 식별자가 정말 많이 없었고 지정할 수 없는 환경이었습니다. 자동화를 하려는 웹 페이지는 Material-UI 스타일링 시스템으로 구성되어 있어서, 페이지를 새로고침 하는 경우 div의 class가 변경되어 class 값을 지정할 수 없는 상태였습니다.
이런 상태에서 사용할 수 있는 방법은 어떤 것이 있을까요 ?
업무에 사용한 코드는 첨부할 수 없기에 말로 잘 설명해보겠습니다 😮
오늘의 테스트 페이지는 무신사 페이지로 해보겠습니다 :)
1. 기능 동작 요소 검색 범위 줄이기
무신사 페이지에서 세일 페이지 화면입니다.
무신사 개발자 도구를 보면 무수히 많은 데이터들이 있습니다. 무신사 페이지로 이동하여 세일 버튼을 클릭하기 위해 어떤 코드를 만들어야할까요 ?
const saleButton = 'a[data-content-name="세일"]';
this.page.locator(saleButton).click();
"세일"이라는 버튼을 특정할 수 있는 요소들이 엄청 많기 때문에 골라서 사용할 수 있을 것 같네요!
이런 경우 대상 요소를 특정할 수 있는것이 쉽지만, 데이터가 없는 경우는 어떤 방식으로 찾아야 할까요 ?
const saleButton = 'a >> text="세일"';
this.page.locator(saleButton).click();
// 혹은
this.page.locator('a', {hasText: '세일'}).click();
이렇게 수행한다면 어떤 결과를 가지고 올까요?
현재 들어가있는 페이지에 a 태그에 '세일'이라는 값을 가진 요소가 딱 하나만 있다면 정상 동작할 것입니다.
하지만 다른 부분에도 있다면 오류를 발생할 것입니다.
그래서 저는 특정 영역을 한번 지정해주고 있습니다.
위의 이미지에서 보이듯 특정 요소들이 포함된 div 태그 값을 설정해줍니다.
const headerList = 'div.sc-zoxh15-0.eTwMyr';
this.page.locator(headerList).locator('a', {hasText: '세일'}).click();
이렇게 그룹을 지정해주고 그 안에서 a 태그의 '세일' 텍스트를 찾도록 수행한다면 전체 페이지에서 찾는 것 보다 좀 더 확실한 선택을 하겠죠?
2. xpath와 혼합하여 사용하기
기능 변경이나 화면 변경이 되는 경우 취약할 수 있는 xpath를 활용하는 방식입니다.
xpath만 사용한다면 나중에 정말 유지보수가 힘들기 때문에 xpath를 지정할 영역을 최소화하여 사용하는 것이 중요합니다.
상단 메뉴 중 무신사 배너 옆 드롭다운 버튼은 어떻게 찾아서 눌러야할까요?
const gatewayButton = 'button[data-button-id="gateway"]';
this.page.locator(gatewayButton).click();
물론 저 드롭다운 버튼은 하나의 버튼으로 구성되어있기 때문에 위 코드로도 정상 수행됩니다.
하지만 저 드롭다운 아이콘만 선택하고 싶다면 더 상세하게 지정해줘야겠죠.
물론 <div class="sc-fgkle0-5 cVNPlj"> 항목을 지정해줄 수 있지만 이번엔 button 위치에서 상대경로로 선택해보도록 하겠습니다.
const gatewayButton = 'button[data-button-id="gateway"]';
const dropdownButton = 'xpath=./div[1]/div';
this.page.locator(gatewayButton).locator(dropdownButton).click();
버튼이 있는 위치를 기준으로 2번째 div의 하위 div를 선택하는 방식입니다. 하드코딩 방식처럼 UI 변경 시 자동화가 깨질 위험이 높지만 없는 살림에서 동작을 꼭 수행해야한다면 xpath와 혼합하여 기능 자동화를 구현하는 방식을 채택하였습니다.
3. CSS 선택자 사용하기
xpath와 유사한 부분이 많은 css 선택자 사용하는 방법입니다.
같은 div에 포함되어 있는 항목 중 형제 관계에 있는 요소를 선택할 때 사용합니다.
위 이미지처럼 <div class="sc-zqckxd-1 iQDPkA">로 묶여있는 버튼들을 확인할 수 있습니다.
버튼들을 특정할 수 없는 경우 "nth-of-type"를 활용하여 요소를 선택할 수 있습니다.
const saleButtonList = 'div.sc-zqckxd-1.iQDPkA';
const secondButton = 'button:nth-of-type(2)';
this.page.locator(saleButtonList).locator(secondButton).click();
이렇게 사용하면 리스트 중 2번째 항목의 버튼을 클릭할 수 있습니다.
버튼 태그가 아니라 div 태그 등 다른 태그를 사용할 수도 있습니다.
4. 개발팀에 요청하기
정말 특정할 수 없고, 자동화를 어찌어찌 개발한다해도 UI가 조금만 틀어져도 기능 테스트가 무너질 것 같은 경우는 요청해야합니다 😂
제가 했던 방식은 식별자가 있는 부분에 대해 자동화를 구현하고 개발팀에 데모해주면서, 이런 그룹핑 ID 식별자를 넣어주시면 좀 더 안정성 있게 자동화를 구현할 수 있을 것 같아요!! 라고 설명을 드렸습니다.
개발자분들도 자동화 데모를 확인하면서 조금만 도와준다면 개발팀에 더 좋은 효과가 올 수 있겠는데?라고 생각하셨고 도움을 주셨습니다. 막무가내로 "이렇게 ID가 없으면 자동화 작업 못해요!"라고 말하는 것보다 더 효과적이었습니다.
그리고 모든 요소에 ID를 추가해 달라고 전달하는 것이 아닌 그룹만 있으면 내부적인 요소는 알아서 찾겠다고 하면 대부분 긍정적으로 ID 추가하는 작업을 진행해주셨습니다. 정말정말 요소에 대한 ID가 없는 경우 꼭 개발팀에 요청해주세요 😫
이상 식별자 ID나 특정할 수 있는 값이 없는 경우 자동화를 구성하는 방식에 대해 알아봤습니다.
조금 더 다양한 방법이 있을 수 있는데 제가 자주 사용하는 방법으로 작성해보았고, 더 좋은 아이디어가 있다면 댓글로 남겨주세요 :)
'QA > 기능 자동화' 카테고리의 다른 글
기능 자동화 기술조사부터 환경 구성까지 (6) | 2024.11.04 |
---|---|
기능 자동화, POM(Page Object Model) 구조 만들기 (1) | 2024.09.08 |
기능 자동화를 만들면 살충제 패러독스에 걸리지 않나요? (0) | 2024.07.04 |
Playwright를 활용한 자동화 연습 (1) | 2024.06.16 |
기능 자동화 동작 방식과 식별자 (0) | 2024.06.15 |