...
Cypress 소개
소프트웨어 테스팅은 소프트웨어의 품질을 보장하고 결함을 예방하고 수정하는 데 매우 중요한 과정이다. 특히 지속적이고 반복적이고 자주 일어나는 작업들은 가능한 자동화하고 효율적으로 수행하는 것이 좋다.
cypress는 웹애플리케이션을 테스트하기 위한 자바스크립트로 작성된 가벼운 라이브러리로, 실제 애플리케이션과 테스트 코드를 동일한 브라우저에서 실행하는 방식을 취하고 있다. 브라우저 기반의 GUI를 사용하여 테스트의 실행 상태를 확인하고 디버깅할 수 있는 다양한 편의 기능을 제공한다.
예를들어 실행된 모든 테스트 명령과 각 명령이 실행될 때의 UI 상태를 스냅샷 형태로 모두 저장해 특정 시점의 UI 상태를 눈으로 확인할 수 있다. 또한 전체 테스트 진행 과정을 동영상으로 저장하거나 테스트가 실패했을 때 자동으로 스크린샷을 남길 수 있어 테스트가 실패했을 때 원인을 파악하기가 매우 쉽다.
브라우저에서 실행되기 때문에 필요한 경우 크롬 개발자 도구를 사용해 디버깅을 할 수도 있으며, 무엇보다 자바스크립트로 작성되었기 때문에 테스트 코드 역시 사용자가 웹 페이지에서 요소를 찾는 방식과 유사한 메서드를 제공하여 큰 러닝커브 없이 빠르게 학습이 가능하다는 장점이 있다.
E2E 테스트 도구
E2E( End-to-End ) 테스트란 '시작부터 끝까지'라는 의미로, 애플리케이션이 제대로 작동하는지, 사용자 관점에서 시스템 흐름을 테스트하는 소프트웨어 테스트 방법이다. 이 테스트의 목적은 실제 생산 환경과 유사한 환경에서 시스템이 전체적인 비즈니스 목표에 충족하는지 확인하기 위해 실제 사용자 시나리오를 시뮬레이션하고 해당 구성 요소의 통합 및 데이터 무결성을 검증하는 것이다.
쉽게 말해 실제 사용자 시나리오를 모방해 사용자가 개발한 시스템을 오류나 버그없이 예상대로 작동하는지에 대한 검증이라고 보면 된다. 예를 들어, 사용자가 쇼핑몰 사이트에 접속하고, 로그인하고, 상품을 검색하고, 장바구니에 담고, 결제하고, 주문 확인하는 일련의 사용 시나리오를 테스트 한다고 이해하면 된다.
이처럼, E2E 테스트는 테스트 방법론이며, Cypress는 이 방법론을 실제로 구현하기 위한 도구인 것이다.
Cypress vs Selenium
웹애플리케이션을 테스트 자동화할때 가장 유명한 도구를 고르자면 이구동성으로 Seleniun(셀레니움)을 고를 것이다.
Cypress와 Selenium은 웹 테스팅을 위한 도구로 각각 장단점과 차이점을 가지고 있다. 그렇다면 이 둘 중 어떤 도구를 선택해야 할까? 어떤 도구를 선택해야 할지는 테스팅의 목적, 범위, 요구사항, 환경 등에 따라 달라질 수 있다.
cypress | selenium | |
언어 | JavaScript만 지원 | Java, Python, JavaScript, C#, Ruby 등 다양한 언어 지원 |
지원 브라우저 | Chrome, Edge, Electron 일부 브라우저만 지원 | Chrome, Firefox, Edge, Safari, Opera 등 대부분의 브라우저 지원 |
난이도 | 개발자 친화적이고, 테스트 환경 구축이 쉬움 | 테스트 환경 구축이 복잡하고, 드라이버나 서버가 필요함 |
테스트 속도 | 브라우저 내부에서 직접 테스트를 수행하므로 빠름 | 브라우저 드라이버를 통해 테스트를 수행하므로 상대적으로 느림 |
테스트 결과 | 테스트 러너에서 테스트 과정과 결과를 시각적으로 확인 가능 | 테스트 과정과 결과를 시각적으로 확인하기 어려움 |
테스트 범위 | 프론트엔드 테스트에 특화되어 있음 | 프론트엔드와 백엔드 테스트 모두 가능 |
정리하자면 다음과 같은 상황에서는 Cypress를 선택하는 것이 좋다.
- 프론트엔드 개발자가 자바스크립트로 테스트를 작성하고자 할 때
- 모던 웹 애플리케이션의 UI와 기능을 테스트하고자 할 때
- 테스트 환경을 쉽게 설정하고, 테스트 결과를 실시간으로 확인하고, 테스트를 디버깅하고자 할 때
- 테스트 주도 개발을 수행하고자 할 때
다음과 같은 상황에서는 Selenium을 선택하는 것이 좋다.
- 다양한 언어로 테스트를 작성하고자 할 때
- 다양한 브라우저와 플랫폼에서 테스트를 수행하고자 할 때
- 웹 서버를 통해 분산 테스팅이나 병렬 테스팅을 수행하고자 할 때
Cypress 설치하기
https://www.cypress.io/ 홈페이지에 들어가면 설치를 진행 할 수가 있다. 두가지 방법으로 가능한데, 모두 소개해본다.
Node.js 패키지 설치
npm 명령으로 cypress를 설치하고 open 명령을 통해 cypress 앱을 실행 시킬 수 있다.
> npm install cypress -D
> npx cypress open # cypress 앱 오픈
cypress를 실행하면 아래와 같은 화면으로 넘어가게 되고 사진에 따라 진행해준다.
exe 설치
노드 생태계가 없어도 바로 직접 실행 파일로도 cypress 앱을 다운 받을 수가 있다. 압축 파일을 다운받으면, 파일을 적절한곳에 압축을 풀고 경로의 파일을 실행하면, 런치패드(Launchpad) 화면이 띄워지게 된다.
exe 버전은 Cypress를 빠르게 사용해 볼 수 있는 방법으로만 시험적으로 제작된 도구이며, 몇가지 기능 제한이 따라 붙는다. 예를들어 Cypress Cloud로의 녹화 실행이 불가능하다고 한다.
위 창에서 Drag your project directory here or browse manually 문구 버튼을 클릭하고 테스트 코드를 관리할 프로젝트 폴더를 선택해준다. 처음이라면 빈 폴더를 생성하고 등록해 주면 된다. 그리고 위에 Node.js 패키지 설치방법에 연재한 순서와 같이 똑같이 진행해주면 된다.
Cypress 실행하기
테스트 프로젝트 생성
브라우저를 선택하면, 마치 웹앱과 같이 cypress 전용 GUI창이 새 브라우저 창으로 열리게 된다. 그리고 아래와 같이 새 테스트 파일을 생성하도록 하자.
테스트 시나리오 작성
테스트 동작 코드를 수정하려면 위에서 생성한 spec.cy.js 파일을 수정하면 된다.
우선 에디터로 돌아와서 spec.cy.js 파일을 오픈해보자. 그러면 아래와 같이 적혀져 있을 것이다.
describe('template spec', () => {
it('passes', () => {
cy.visit('https://example.cypress.io')
})
})
위의 api 설명은 아래와 같다.
describe(): 테스트 할 동작들을 묶어주는 전체 그룹.it(): 테스트 할 동작의 세부 단위 케이스.cy.visit(): 웹사이트 방문.
코드를 보면 JEST 테스트 라이브러리 코드 양식과 굉장히 유사하다고 볼 수 있다.
연습겸 간단하게 아래와 같이 바꿔보자.
describe('네이버 사이트 테스트 시트', () => {
it('네이버 사이트 방문', () => {
cy.visit('https://www.naver.com')
})
})
그리고 cypress GUI 앱에서 아래와 같이 js 파일을 더블클릭하게 되면, 코드에 따라 자동화 테스트가 수행되게 된다.
위 처럼 실제 테스트가 시각적으로 진행되는 것을 볼 수 있다. 왼쪽 명령 로그 영역에는 위에서 작성한 코드의 명령들이 로그로 기록되며, 각 명령줄들에 마우스를 클릭하면 해당 명령이 실행될 때의 화면 상태를 각각 확인도 가능하다.
버튼 클릭 자동화
cypress의 자바스크립트 코드는 jQuery 함수 형식과 되게 비슷하게 되어있다. 예를들어 자바스크립트나 제이쿼리에서 버튼 엘리먼트를 가져오려면 아래와 같이 코드를 작성하는데,
document.querySelector('button');
$('button')
cypress도 이와 비슷하게 cy 객체의 get() 함수를 통해 안에 엘리먼트의 id값이나 class값을 적으면 자동으로 html의 엘리먼트를 가져오게 된다.
cy.get('button')
cy.get('.className');
cy.get('#idName');
cy.get('[class^="button_"]')
참고로 엘리먼트의 id값이나 class값은 개발자도구를 열어서 직접 추적해 얻는 방식도 있지만, cypress GUI 앱에서 더 간단히 얻을 수 있는 방법이 있다.
상단의 저격 크로스헤어 버튼을 누르고 아래처럼 클릭을 진행하면, 자동으로 cy 객체 코드가 완성되게 되고, 우측의 복사 버튼을 눌러 코드에 적용하면 되게 된다. 다만 복잡한 트리 구조의 구성일 경우 직접 개발자도구로 찾는것이 더 정확할 수도 있다.
그렇게해서 얻은 엘리먼트 객체를 뒤에 동작을 행하는 함수를 체이닝(chaining)으로 붙여주면 간단하게 버튼 클릭 행위를 자동화 할 수 있게 된다.
cy.get('#button').click()
버튼 클릭에 대한 시나리오를 짜고 싶다면 아래 처럼 wait() 함수와 적절히 섞어주면 마치 이른바 매크로를 구현할 수 있게 되는 것이다.
describe('무신사 사이트 테스트 시트', () => {
it('쇼핑몰 버튼 클릭', () => {
cy.visit('https://www.musinsa.com/app/'); // 무신사 방문
cy.get('[u_cat_cd="001"] > a').click(); // 특정 버튼 클릭
cy.wait(1000); // 1초 대기
cy.get('[u_cat_cd="002"] > a').click();
cy.wait(1000);
cy.get('[u_cat_cd="003"] > a').click();
cy.wait(1000);
cy.get('[u_cat_cd="004"] > a').click();
});
});
타이핑 자동화
이른바 쇼핑몰의 검색창에 검색 텍스트를 자동으로 써서 검색을 수행하는 매크로를 만들어보자. 사용하는 함수 역시 직관적으로 type() 을 통해 아주 간단히 구현할 수 있다.
describe('무신사 사이트 테스트 시트', () => {
it('쇼핑몰 버튼 클릭', () => {
// 무신사 사이트 방문
cy.visit('https://www.musinsa.com/app/');
// 무신사 검색
cy.get('input#commonLayoutSearchForm').type('구찌 가방'); // 검색 입력창 엘리먼트를 가져와서 텍스트 타이핑
cy.get('.sc-1ppcy5v-5').click(); // 돋보기 버튼 클릭
});
});
이를 응용해서 검색창이 아닌 로그인 화면의 아이디와 패스워드 창에 텍스트를 타이핑하고 로그인 버튼을 누르도록 테스트케이스를 짜면, 로그인 매크로를 구현하는것과 같다
describe('네이버 테스트', () => {
it('네이버 로그인', () => {
cy.visit('https://nid.naver.com/nidlogin.login');
cy.get('#id').type('test');
cy.get('#pw').type('123123');
cy.get('#log\\.login').click();
})
})
드롭박스 자동 선택
<select> 태그의 엘리먼트를 선택하는 자동화 테스트를 구현해 보자. 직관적으로 select() 함수를 통해 드롭다운 메뉴를 얻을 수 있다. 이밖에도 체크박스나 라디오버튼도 비슷한 과정이다.
describe('무신사 사이트 테스트 시트', () => {
it('상품 메뉴 선택하기', () => {
cy.visit('https://www.musinsa.com/app/goods/3791036?loc=goods_rank');
// 상품 옵션 선택하기
cy.get('.product-detail__sc-1d13nsy-1').select('M');
cy.get('.product-detail__sc-1k1gum8-0').select('589908')
});
});
cypress의 함수 코드들은 기본적으로 비동기 함수들이며 실행 방식은 마치 자바스크립트의 await 비동기 방식
으로 동작된다. 그래서 별도로 Promise나 await 처리 없이 테스트 코드들을 써내려가도 충돌없이 사용이 가능하다.
Cypress 문법 정리
다양한 종류의 api 문법을 알고하고 싶다면 아래 공식문서를 참고해보자. 이번 글은 cypress의 기본적인 뼈대 구조를 이해하는데 초점을 두어 설명해본다.
Cypress 그룹핑
각 명령어들을 보기좋게 모듈화하여 묶는 그룹 함수들이다.
describe(): 테스트 코드를 묶는 가장 큰 단위. 테스트 스위트context(): describe 내부에서 새로운 테스트 그룹을 정의하는 함수 (context는 describe와 기능적으로는 차이가 없거 단지, 의미적으로 구분하기 위해 사용한다. 생략해도 문제 없다)it(): 실제 테스트 케이스를 정의하는 함수
// 'My App'이라는 테스트 스위트를 정의합니다.
describe('My App', () => {
// 'Login'이라는 테스트 그룹을 정의합니다. 이 테스트 그룹은 로그인 기능과 관련된 테스트 케이스들을 묶어줍니다.
context('Login', () => {
// 'Valid user'라는 테스트 케이스를 정의합니다. 이 테스트 케이스는 유효한 사용자 정보로 로그인하는 것을 테스트합니다.
it('Valid user', () => {
// 테스트할 내용을 작성합니다.
cy.visit('/login'); // 로그인 페이지에 접속합니다.
cy.get('#username').type('test'); // 아이디 입력창에 'test'라고 입력합니다.
cy.get('#password').type('1234'); // 비밀번호 입력창에 '1234'라고 입력합니다.
cy.get('#login-button').click(); // 로그인 버튼을 클릭합니다.
cy.url().should('include', '/dashboard'); // 로그인이 성공하면 대시보드 페이지로 이동합니다.
});
// 'Invalid user'라는 테스트 케이스를 정의합니다. 이 테스트 케이스는 유효하지 않은 사용자 정보로 로그인하는 것을 테스트합니다.
it('Invalid user', () => {
// 테스트할 내용을 작성합니다.
cy.visit('/login'); // 로그인 페이지에 접속합니다.
cy.get('#username').type('wrong'); // 아이디 입력창에 'wrong'이라고 입력합니다.
cy.get('#password').type('4321'); // 비밀번호 입력창에 '4321'이라고 입력합니다.
cy.get('#login-button').click(); // 로그인 버튼을 클릭합니다.
cy.contains('Invalid username or password'); // 로그인이 실패하면 에러 메시지를 표시합니다.
});
});
// 'Logout'이라는 테스트 그룹을 정의합니다. 이 테스트 그룹은 로그아웃 기능과 관련된 테스트 케이스들을 묶어줍니다.
context('Logout', () => {
// 'Logout from dashboard'라는 테스트 케이스를 정의합니다. 이 테스트 케이스는 대시보드 페이지에서 로그아웃하는 것을 테스트합니다.
it('Logout from dashboard', () => {
// 테스트할 내용을 작성합니다.
cy.login('test', '1234'); // cy.login()은 커스텀 커맨드로, 로그인을 수행하는 함수입니다.
cy.visit('/dashboard'); // 대시보드 페이지에 접속합니다.
cy.get('#logout-button').click(); // 로그아웃 버튼을 클릭합니다.
cy.url().should('include', '/login'); // 로그아웃이 성공하면 로그인 페이지로 이동합니다.
});
});
});
Cypress Hook
Cypress hook는 테스트 스위트의 실행 전후에 특정한 작업을 수행할 수 있게 해주는 기능이다. 이를 이용해 테스트 환경을 설정하거나, 테스트 데이터를 준비하거나, 테스트 결과를 정리하거나, 테스트 로그를 기록하거나, 테스트 에러를 처리하거나 등의 작업을 할 수 있다.
before(): 테스트 스위트의 첫 번째 테스트 케이스가 실행되기 전에 한 번만 실행after(): 테스트 스위트의 마지막 테스트 케이스가 실행된 후에 한 번만 실행beforeEach(): 테스트 스위트의 각 테스트 케이스가 실행되기 전에 매번 실행됩afterEach(): 테스트 스위트의 각 테스트 케이스가 실행된 후에 매번 실행
Cypress hook은 describe()나 context() 안에 작성할 수 있으며, it()안에는 작성할 수 없다
describe('Test E2E by Cypress', () => {
context('Mobile Version', () => {
// 이 hook은 Mobile Version 테스트 그룹의 각 테스트 케이스가 실행되기 전에 매번 실행.
beforeEach(() => {
// ... Codes executed before each test case inside it() hooks ...
});
// 이 테스트 케이스는 beforeEach() hook이 실행된 후에 실행
it('Login Button Should be Somewhere', () => {
// ... Real Executing test codes for some application ...
});
});
});
Cypress Assertion
Cypress Assertion이란 Cypress에서 테스트의 결과가 예상한 값과 일치하는지 검증하는 방법을 말한다. 예를들어 어느 제목의 텍스트가 특정 문자열과 일치하는지 확인하는데 이용된다.
// h2태그의 text가 특정 제목인지 확인
cy.get('h2').should('have.text', '특정 제목');
// button을 클릭하고 나면 class에 active가 있어야 하는 경우
cy.get('button').click().should('have.class', 'active')
// 해당 객체가 없어야 하는 경우
cy.get('button').should('not.exist')
// 두 조건을 만족해야 하는 경우 (and)
cy.get('#header a')
.should('have.class', 'active') // 클래스명이 active 일 경우
.and('have.attr', 'href', '/users') // href 속성 값이 /users 일경우
// 체크박스가 disabled된 경우
cy.get(':checkbox').should('be.disabled')
// input에 특정 값이 없어야 하는 경우
cy.get('input').should('not.have.value', 'US')
// URL 로 호출을 하고, 해당 주소 RETURN BODY에 {name: 'inpa'}이 있어야 하는 경우
cy.request('/users/1').its('body').should('deep.eq', { name: 'inpa' })
Cypress Assertion은 비동기적으로 동작하며, 테스트 대상이 조건을 만족할 때까지 기다린다. 만약 조건을 만족하지 못하면, Cypress는 에러를 발생시키게 된다. 또한 체이닝(chaining)역시 가능하며, and나 or를 사용하여 여러 개의 조건을 연결할 수 있다.
Cypress Commands
프로그래밍에서 반복되는 코드가 있으면 이를 함수로 묶어 모듈화 하는것이 중요하다. cypress 역시 테스트를 자동화시킴에 따라 즐비하게 중복 및 반복되는 코드들이 많아질수 있는데, 이 역시 함수 단위로 묶어 사용하는 기능을 '사용자 정의 명령어' 라고 한다.
우선 사용자 정의 명령어를 사용하기 위해서는, cypress 프로젝트의 support 폴더 내의 commands.js 파일을 이용할 필요가 있다.
그리고 새로운 사용자 정의 명령어를 추가하려면 commands.js 파일 안에 Cypress.Commands.add 메소드를 사용하여 추가해주면 된다. 예를들어 로그인 프로세스는 아이디 입력, 비밀번호 입력, 로그인 버튼 클릭 이렇게 3개의 프로세스로 이루어져 있는데, 만일 로그인을 테스트하는데 있어 자주 이용하여 모듈화를 시킨다고 하면 아래와 같다.
Cypress.Commands.add('login', (email, password) => {
cy.get('input[name=email]').type(email);
cy.get('input[name=password]').type(password);
cy.get('form').submit();
});
/*
어렵게 생각할 필요없이 아래의 함수를 새로 만들어 사용한다고 보면 된다.
const login = (email, password) => {
cy.get('input[name=email]').type(email);
cy.get('input[name=password]').type(password);
cy.get('form').submit();
}
*/
이렇게 추가된 사용자 정의 명령어는 별도의 require나 import 없이도, Cypress에서 자동으로 인식하기 때문에 테스트 파일 어디에서나 전역적으로 사용할 수 있게 된다.
describe('네이버 테스트', () => {
it('네이버 로그인', () => {
cy.visit('https://nid.naver.com/nidlogin.login');
// commands.js에 정의된 사용자 정의 명령어 수행
cy.login('test', '123123')
})
})
Cypress then
cypress then() 메소드는 명령어와 결과를 콜백 함수의 인자로 전달해, 명령 결과에 액세스하고 이에 대한 추가 로직을 수행하는데 사용된다.
cy.get('.list-item').then(($listItem) => {
// $listItem은 .list-item의 첫 번째 DOM 요소를 jQuery 객체로 감싼 것입니다.
// 여기서 추가 작업을 수행할 수 있습니다.
$listItem.css('color', 'red');
});
cy.get('.element').then(($el) => {
if ($el.hasClass('active')) {
// .element가 'active' 클래스를 가지고 있으면 추가 작업을 수행합니다.
}
});
cy.request('https://jsonplaceholder.typicode.com/posts/1').then((response) => {
cy.log(response)
expect(response.status).to.equal(200);
expect(response.status).to.eq(200);
});
cypress then 과 promise then 은 서로 연관 없다
다만 유의할점은, Cypress의 then 키워드는 자바스크립트의 Promise.then 과 전혀 아무런 관련이 없다는 점이다. 아무래도 코드 구문 생김새가 매우 비슷하여 이러한 착각을 할 수도 있지만, Cypress의 then 키워드는 동기/비동기와 관련이 없는 명령어이다. 실지로 catch 문은 통하지 않는다는걸 확인할 수 있다.
정리하자면, Cypress의 then 은 단순히 명령 결과에 액세스하고 이에 대한 추가 작업을 수행하는 데 사용되는 것일 뿐이다. 예를들어 cy 객체에서 지원하는 메소드로 체이닝해서 사용해도 충분하지만, 가져온 값에 뭘 더하거나 하는 등 별도의 추가 연산 작업이 필요할때 연산 코드를 then 블록 안에 쓰는 용도인 것이다.
cy.get('option:first')
.should('be.selected')
.then(($option) => {
// $option is yielded
})
Cypress Wrapping
cy.wrap() 은 자바스크립트 객체나 값을 Cypress 명령어 체인에 포함시키기 위해 사용되는 메소드이다.
쉽게 생각해서 간단하게 비유를 들자면 제이쿼리에서 제이쿼리 전용 체이닝 메소드를 사용하기 위해서는 $(obj) 와 같이 $ 괄호 안에 객체를 넣어서 사용해야 했다. 이와 똑같은 원리라고 보면 된다.
// JavaScript 객체를 cy.wrap()으로 감싸고, .should() 명령어를 사용하여 객체의 속성을 검사
const object = { name: 'Cypress' };
cy.wrap(object).should('have.property', 'name', 'Cypress');
이러한 래핑 기능은 주로 비동기적으로 반환된 값들을 cy 객체로 감싸 Cypress 명령어 체인에 포함시켜 테스트의 유연성을 높일 수가 있다.
cy.get('button').then(($button) => {
if ($button.hasClass('active')) {
cy.wrap($button).click();
}
});
Cypress Window
테스트할 웹페이지의 DOM에 접근해서 조작을 하고 싶을 상황이 있을 것이다. 이때 cy.window 를 통해 현재 테스트 중인 페이지의 window 객체를 반환받을 수 있다. cy.window 는 비동기적으로 실행되므로, 역시 위에서 배운 .then() 메소드를 사용하여 결과를 처리해야 한다.
cy.window().then((win) => {
// win은 현재 페이지의 window 객체입니다.
console.log('Window object:', win);
// DOM 요소에 직접 접근하여 조작합니다.
win.document.querySelector('button').click();
// 페이지에 정의된 전역 변수나 함수에 접근합니다.
console.log('Page title:', win.title);
});
Cypress Cookie
테스트 중에 사용자 인증 상태를 유지하거나, 특정 쿠키 값을 검사하는 등의 작업을 지원한다. cy.getCookies() 명령어는 현재 브라우저의 모든 쿠키를 가져와 쿠키 객체 배열을 반환하며, 각 객체는 쿠키의 이름, 값, 도메인 등의 정보를 포함한다.
cy.getCookies().then((cookies) => {
// cookies는 쿠키 객체 배열입니다.
});
cy.setCookie('auth_key', '123key');
cy.getCookie('auth_key').should('have.property', 'value', '123key');
Cypress는 테스트 실행 시 기본적으로 모든 쿠키를 지우므로, 필요한 경우 테스트 시작 전에 쿠키를 설정해야 할 수도 있다.
Cypress 설정 옵션
Cypress를 처음 시작하면 Cypress 구성 파일인 cypress.config.js이 파일이 생성되게 되는데, 여기서 전반적은 cypress의 전역 설정들을 지정할 수가 있다. 자세한 여러 세팅값들은 아래 공식문서를 참고하면 된다.
브라우저 출처 정책 비활성화
만일 로그인과 같은 브라우저의 보안 정책과 연관된 테스트케이스를 수행하게 된다면 높은 확률로 아래와 같이 블락되며 제대로 테스트 코드 수행이 안될 것이다.
훌륭한 보안 정책이지만 아무래도 테스트 하는 입장에서는 불필요한 부분이기 마련이다. 따라서 chromeWebSecurity 옵션을 비활성함에 따라 동일 출처 정책 및 안전하지 않은 혼합 콘텐츠에 대해 Chromium 기반 브라우저의 웹 보안을 끌 수가 있다.
module.exports = {
e2e: {
// 크로미움 동일 출처 정책 보안 비활성화
chromeWebSecurity: false,
},
};
페이지 로딩 제한시간 설정
기본적으로 테스트 페이지 로딩 제한 시간이 60초로 설정이 되어잇기 때문에, 만일 로딩이 좀 오래걸리는 사이트를 테스트할 예정이라면 로딩 시간 초과로 테스트가 실패하기 때문에 추가 설정을 통해 로딩 제한 시간을 늘려주어야 한다.
module.exports = {
e2e: {
// 자동 테스트 코드 생성 설정
experimentalStudio: true,
// 페이지 로드 제한 시간 설정
pageLoadTimeout: 120000 // 120sec
},
};
페이지 크기 설정
기본적으로 테스트할 웹페이지의 크기는 1000x660 으로 설정하였기 때문에 아래와 같이 웹페이지의 스타일에 따라 짤리는 현상이 발생하기도 한다. 추가 설정을 통해 페이지의 뷰포트를 맞출 수 있다.
module.exports = {
e2e: {
// 테스트 페이지 뷰포트 설정
viewportWidth: 1600,
viewportHeight: 900,
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
};
참고문헌
https://microsoft.github.io/code-with-engineering-playbook/automated-testing/e2e-testing/
https://docs.cypress.io/guides/overview/why-cypress
ttps://rae-gi.tistory.com/23
https://blog.naver.com/o_zak/222671883835
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.