나의 앱의 기능들이 짤처럼 작동한다면?
E2E(End to End) 테스트는 개발물을 사용자 관점에서 테스트 하는 방법이다. 페이지에서 원하는 텍스트가 제대로 출력이 되었는지, 버튼을 클릭 했을 때 올바른 동작을 수행하는 지 등을 테스트한다.
왜 E2E Test를 해야할까?
Why is End to End Testing necessary?에서 발췌하였습니다.
모든 애플리케이션은 다양한 시스템, DB와 연결되고 통합되어있다. 따라서 앱의 Workflow는 복잡해졌다. 그래서 이러한 앱의 올바른 작동을 사용자 관점에서 확인할 수요가 늘어났다.
E2E테스트는 다양한 앱의 의존관계가 정확히 작동하는지 확인한다. 또한 정확한 정보가 다양한 시스템 컴포넌트 사이에서 전달하는지 체크할 수 있다.
E2E테스트는 진짜 사용자의 시나리오대로 시뮬레이션하고, 본질적으로 사용자가 어떻게 앱을 사용할지 테스트한다.
Cypress가 정보가 많고 Mocha를 기반으로 만들어졌기에 좀 더 친숙한 부분이 있었다.
먼저 여러 프레임워크를 Selenium기반을 기준으로 나눌 수 있다. Selenium은 웹 어플리케이션을 위한 테스팅 프레임워크로 자동화 테스트를 위한 여러가지 강력한 기능을 지원해준다. Selenium기반 프레임워크는 웹드라이버를 사용하여 브라우저와 상호작용을 하지만 non-selenium 프레임워크는 브라우저와 직접 상호작용한다. 이러한 점에서 Cypress와 TestCafe를 후보군으로 올렸고, 최종적으로는 다운로드 수가 많은 Cypress를 사용하게 되었다.
먼저 cypress를 해당 프로젝트에 설치하자
npm install --save-dev cypress
정상적으로 설치가 완료되었다면 script에 아래와 같은 내용을 추가한다.
{
"scripts": {
...
"e2e": "cypress run",
"e2e:open": "cypress open"
}
}
cypress run은 모든 테스트를 실행하는 명령어이고, open은 Cypress Test Runner를 실행하는 명령어이다.
이후 npm run e2e:open
명령어를 실행하면 자동으로 cypress.json 파일과 cypress Directory가 생성된다. cypress.json에는 설정을 할 수 있다. 설정은 다음과 같이 진행했다.
{
"baseUrl": "https://futchall.com",
"videoRecording": false
}
cypress는 프로젝트를 테스트하는 도구라서 Cypress로 애플리케이션에 접속하기 전에 먼저 애플리케이션을 실행해야 합니다. 이러한 기준이 되는 url값을 설정해줘야한다. 필자는 배포중이기에 현재 배포중인 사이트를 넣었다. 로컬에서 개발중이라면 "http://localhost:3000"과 같이 설정해주면 된다. 로컬에서 개발할 경우 로컬에서 서버를 시작한 후 cypress를 해야한다. 다음과 같은 로컬 서버를 먼저 켜주는 라이브러리도 있다.
videoRecording설정값은 테스트를 실행하면 video폴더에 저장이 되는데 false를 통해 저장되지 않도록 했다.
다양한 설정값은 공식문서를 참고하면 된다.
테스트는 cypress/integration 폴더에 작성하면 된다. App.js
와 같이 파일을 작성하자. 내용은 다음과 같다.
describe('Main Test', () => {
it('Click into main', () => {
cy.visit('/');
})
})
describe는 테스트 설명이고 it은 테스트 제목이라고 생각하면 된다.
cy.visit('/')
은 cypress.json에 설정한 baseurl경로로 이동한다는 뜻이다.
이제 npm run e2e:open
을 통해 실행하면 아래와 같은 화면이 뜬다.
이후 만들었던 app.js를 클릭하면 브라우저 새 창이 뜨면서 설정해두었던 사이트로 이동된다.
이제 사이트에서 버튼 클릭과 같은 테스트를 하려면 버튼이 무엇인지 알아내야하는데 방법은 쉽다.
아까와 같은 창에서 주황색 상자로 표시된 해당 버튼을 누른 뒤 원하는 버튼으로 커서를 옮기면
연두색 상자에 해당 selector가 뜬다. 주황색 상자는 원하는 버튼이다 이제 연두색 상자의 selector를 복사해서 다시 App.js를 변경해보자
describe('Main Test', () => {
it('Click into main', () => {
cy.visit('/');
cy.get(':nth-child(2) > :nth-child(2) > a').click();
})
})
이렇게 cy.get()을 통해 selector를 찾고 이후 click()함수를 통해 버튼을 클릭한 모습이다.
다시 실행해보면 왼쪽에 로그가 잘 출력되고, 오른쪽 영역에서 실제로 실행되는 화면을 볼 수 있다.
테스트에 여러 테스트가 많지만 E2E테스트를 통해 사용자의 관점에서 서비스를 실제와 같이 테스트 한다는 점에서 필요하다고 느꼈다. 더불어 이전에 진행한 Jest와 Enzyme을 활용한 상태관리 테스트를 통합해서 사용자의 시각에서 결과물을 확인하는 테스트라 생각되어 재밌기도 하고 효율적이라고 느껴졌다.
다른 여러 command를 활용해서 좀 더 실제와 같은 시나리오를 테스트해야겠다.