치춘짱베리굿나이스
Cypress로 첫 E2E 테스트 수행하기 본문
Cypress
JavaScript Web Testing and Component Testing Framework | cypress.io
설치
npm
npm install cypress --save-dev
yarn
yarn add cypress
개요
요즘 Next 스터디를 하면서 뚝딱뚝딱 웹페이지를 만들어보고 있는데, (여기서 볼 수 있다) 스터디 내용 중 테스팅 관련 내용이 있기도 하고… 리팩터링 책에서도 꾸준히 언급하는 것이 테스팅이기도 하지만! 아직도 테스트를 한 번도 해보지 않았다는 사실이 경악스러워서 테스트에 도전해 보기로 했다
만들던 웹 페이지가 비즈니스 로직을 많이 필요로 하는 페이지가 아니라서, Jest보단 Cypress로 E2E 테스팅을 시작해 보기로 했다
유닛 테스트
함수 하나하나, 컴포넌트 하나하나와 같이 프로젝트 소스의 매우 작은 일부분에 수행하는 테스트이다
가장 짧고, 가장 자주 수행되는 테스트로, 함수가 어떠한 Input 에 대하여 일정한 Output 을 반환하는 것을 보장해주어 안전성을 높이는 테스트이다
또한 테스트 단위가 작게 쪼개져 있기 때문에, 코드 전체에서 어떤 부분에 문제가 발생했는지 알아채기도 쉽다
통합 테스트
유닛 테스트가 각 컴포넌트, 함수 조각마다 개별적으로 (독립적으로) 수행되었다면, 통합 테스트는 다수의 함수가 상호작용하는 경우를 테스트한다
예를 들어, 외부에서 REST API를 통해 응답을 받아 사용하는 컴포넌트가 있다면, 컴포넌트에 더미 데이터를 넣어 독자적으로 테스팅하는 경우는 유닛 테스트에 가깝고, 응답을 받아오는 함수와 연결하여 동작을 테스트하는 경우는 통합 테스트에 가깝다
유닛 테스트보다는 드물게, E2E보다는 자주 수행하며, 테스트 작성 자체도 유닛 테스트보다 오래 걸린다
E2E 테스트
End-to-End 테스트라는 의미로, 개발자의 관점이 아니라 사용자의 관점에서 프로그램을 사용할 때를 가정하고 수행하는 테스트이다
보통 사용자가 직접 마주하는 GUI 기준에서 테스트를 수행하며, 사용자에게 노출되는 부분이 테스트된다
E2E 테스트를 통과한다면 사용자 입장에서는 눈에 띄는 문제가 없다는 의미이니, 보통 다른 모든 테스트를 마치고 배포 전 단계에서 수행하는 경우가 잦다
모든 함수와 컴포넌트가 유기적으로 엮여서 의도한 동작을 잘 수행하는지 테스트하므로, 테스트 시나리오 작성과 테스트 코드 작성이 매우 오래 걸리고 복잡하다 ⇒ 따라서 세 테스트 중 가장 드물게 수행한다
Cypress 시작하기
Cypress
E2E 테스트를 중점적으로 수행하기 위한 도구로, 따라서 사용자 입장에서 버튼을 클릭하고, 어떤 요소가 보이고… 등등을 체크하는 데에 도움을 준다
- npm 또는 yarn을 이용하여 설치가 매우 간단하다
- 브라우저 상에서 GUI로 동작하며, 따라서 즉석에서 크롬 개발자 도구 등을 이용하여 디버깅이 가능하다
- 유닛 테스트와 통합 테스트도 지원한다
- Hot Reload를 지원한다
단점으론 테스트를 순차적으로 수행하기 때문에 엄청 느리다는 것? 이것은 E2E 테스팅의 특성 같기도 하다
유료 구독을 하면 테스트를 병렬로 수행해준다곤 하는데 미니 프로젝트 수준에서 그정도는 필요 없을 것 같다
설치 및 설정
// package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"cypress": "cypress open" // <-------- 이거
},
yarn 또는 npm 으로 패키지 설치를 완료했다면, package.json
에 단축어를 추가하자
이 부분은 취향차이이긴 하다
첫 테스트
페이지의 “프로젝트” 탭을 클릭하면 URL이 제대로 변경되는지 확인하는 테스트를 짜 보자
프로젝트의 루트 폴더 (src 아님) 에 cypress/e2e
폴더를 만들고, [테스트명].cy.ts
파일을 추가한다
파일에는 아래와 같이 작성하자
describe('프로젝트 탭', () => {
it('/project 로 연결되는지 확인', () => {
cy.visit('http://localhost:3000'); // baseURL
cy.get('a[href*="projects"]').click();
cy.url().should('include', 'projects');
});
});
describe
: 테스트 범위에 관한 설명 (jest, mocha 문법)- 첫 번째 인자에는 범위에 관한 설명을 적는다
- 두 번째 인자로 프로젝트 탭과 관련된 모든 테스트를 담은 콜백을 넘긴다
it
: 단위 테스트에 관한 설명 (jest, mocha 문법)- 첫 번째 인자에는 단위에 관한 설명을 적는다
- 두 번째 인자로 해당 설명과 관련된 모든 테스트를 담은 콜백을 넘긴다
cy
: cypress 테스트용 객체visit
: 특정 URL에 방문하여 테스트를 수행한다- baseURL을 넣음으로서 우리가 테스팅할 페이지로 보내주자
get
: CSS 선택자와 동일하게 작동하는 선택자를 통해 요소를 선택한다- 이번에는
a
태그 중href
속성에projects
문구가 포함 된 태그들을 선택해 볼 것이다
- 이번에는
click
: 선택한 요소 (체이닝된 요소) 를 클릭한다url
: 현재 페이지 URL을 가져온다should
: Cypress에서 가장 많이 쓰이는 구문으로, 말 그대로 “~ 해야 한다” 를 의미한다- 어서션 (가정) 을 생성하며, 실제로 어떤 것을 테스팅할 지가 결정되는 중요한 메서드이다
- 무엇을 해야 하는지는 내부 인자로 정의하며, 첫 번째 인자는 동작 (포함하다, 가지다 등), 두 번째 인자는 요소 (문자열, 숫자 등) 를 넘긴다
describe
은 테스트의 범위를 지정해주는 코드이므로 (테스트에 영향을 주지 않으므로) 사용하지 않아도 상관없지만, 가급적 범위를 지정해서 테스트 결과를 보기 편하게 해 주자
it
은 사용하지 않으면 Cypress 상에서 오류가 발생한다 (ㅋㅋ)
Cypress 실행
$> npm run cypress
$> yarn run cypress
$> npm run cypress open // 단축어 추가 안했을 경우
$> yarn run cypress open // 단축어 추가 안했을 경우
간단하게 cypress open
만으로 실행이 된다
어떤 방식으로 테스팅을 할 건지 고른다
왼쪽은 E2E 테스트, 오른쪽은 컴포넌트별로 테스트하는 유닛 테스트라고 보면 된다
브라우저를 고르라고 한다
평소에는 사파리를 사용하지만 그냥 무난하게 크롬으로 했다
UI 사용법은 위와 같다
Cypress Cloud 는 아직 가입을,,. 안했기 때문에…
테스트 결과 보기
describe
로 묶어놓은 테스트들이 탭으로 묶여져서 출력되므로, describe
를 효율적으로 사용하면 좋다
각각의 체크 표시는 it
의 콜백 함수에 작성한 테스트들을 의미하며, 통과하면 체크, 오류가 발생하면 빨간 경고 창이 나온다
고의로 오류를 발생시킨 모습이다
왜 오류가 발생했는지도 자세히 알려주므로 디버깅에 용이하다
문제가 발생했어요
IDE에서 describe, it에 빨간 줄이 출력될 때
$> npm install --save @types/jest
$> yarn add @types/jest
@types/jest
를 설치한다
describe
, it
은 jest (또는 mocha) 문법이라 해당 타입을 설치해주어야 타입 추론이 된다
IDE에서 cy 객체에 빨간 줄이 출력될 때 or 메서드 체인 자동완성이 안 될때
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}
위의 tsconfig
을 그대로 복사하여 /cypress
폴더의 tsconfig.json
에 저장한다
해당 범위 내에서 cypress 타입을 사용하겠다는 의미이므로, cy 객체가 정상적으로 타입추론되어 출력된다
참고자료
https://leehyungi0622.github.io/2021/02/17/202102/210217-JS_Jest_test_it/
'ClientSide > 라이브러리' 카테고리의 다른 글
Storybook, sass 붙이기 + 전역변수 사용하기 (0) | 2023.06.28 |
---|---|
axios - instance 사용하기 (0) | 2023.04.18 |
웹팩과 웹팩 설정하기 (0) | 2022.09.18 |
commander (0) | 2022.08.02 |
Victory (0) | 2022.05.30 |