Cypress의 경우 End-To-End에 테스트에 적합하고 Cypress Stuido를 통해 테스트에 대한 레코딩도 가능하여, 업무 QA단계에서 스프레드 시트를 통해 테스트를 진행 해온걸 조금 더 개선시킬 수 있을거라 생각되어 공부하려고 한다.
우선 대표적으로 마음에 드는게 테스팅 과정에서의 케이스를 적어오는데 구두로 하거나 최대한 압축해서 글로 표현하던걸 재현을 위해 재차 묻던 문제를 cypress 코드로 전달받을 수 있을거라고 생각되어 도입해볼 예정이다.
여유가 된다면 컴포넌트 테스트도 공부하며 정리할 예정이다.
Cypress도 Config 파일을 별도로 생성하여 설정이 가능하다.
옵션은 추후 알아보고 우선 기본적인걸 튜토리얼을 하면서 알아보았다.
우선 테스트 코드 파일은 ~.cy.ts, ~.cy.js 로 사용한다.
/**
* Visit: https://example.cypress.io
* Find the element with content: type
* Click on it
* Get the URL
* Assert it includes: /commands/actions
* Get the input with the action-email class
* Type fake@email.com into the input
* Get the input again and assert that it reflects the new value
*/
describe('My First Test', () => {
it('finds the content "type"', () => {
cy.visit('https://example.cypress.io');
// cy.contains('type'); // 요소 찾기, 없는 요소찾을시 기본값 4초간 찾다가 오류 출력
cy.contains('type').click(); // 요소 찾고, 클릭 / cypress에서 명령을 함께 연결하여 수행하는걸 chaining 이라고 한다.
// 여기서 type 클릭에 대한 페이지 이동이 있고, 이 페이지가 로드 단계에서 완료하지 않았다면 cypress는 테스트 종료 및 오류 표시
// 페이지 로드의 경우 기본값 60초의 이벤트 대기를 함
cy.url().should('include', '/commands/actions'); // url이 맞는지 확인, baseURL 이 이미 설정되어있으니 그 이후 URL 입력
cy.get('.action-email').type('fake@email.com'); // class가 action-email 인것을 찾아 fake@email.com 입력
cy.get('.action-email').should('have.value', 'fake@email.com'); // 값을 가졌는지 확인
/**
* 클래스 이름으로 요소를 선택하는 방식은 추천되는 방식은 아니다.
* 예제의 경우 외부사이트를 기준으로 하는 방식이므로 이 방법을 사용
*/
});
});
주석에도 잘 적어놓았지만, 위 테스트 코드는 아래와 같다.
각 단계마다 테스트 브라우저를 통해 클릭하며 확인할 수 있다.
테스트 코드를 수정하고 저장할 때 마다 자동으로 테스트 브라우저도 새로고침되며 테스트 기능 로직을 수행한다.
cy.get('.action-email').type('fake@email.com');
위 코드처럼 또 다른 명령을 연결하는것을 chaining 이라고 한다.
또한, 위 코드처럼 클래스명이나 ID명을 기준으로 요소를 선택하는것은 바람직하지 않다.
=> 클래스명이나 ID명은 언제나 바뀔 수 있기 때문에. 주로 데이터 속성 을 요소선택자로 사용한다.
=> 데이터 속성을 사용함으로 인해 사이트 디자인이 변경되더라도 클래스명이나 ID명에 의존하지 않을 수 있다.
그렇다면 배운것처럼 적용을 해보자.
<h1
data-test="hero-heading"
className="mt-4 text-4xl tracking-tight font-extrabold text-white sm:mt-5 sm:text-6xl lg:mt-6 xl:text-6xl"
>
<span className="block text-gray-900">
Testing Next.js Applications with Cypress
</span>
</h1>
기존 HTML 태그의 h1 요소에 data-test 속성으로 hero-heading 이라는 내용을 넣어준다.
describe("home page", () => {
it("the h1 contains the correct text", () => {
cy.visit("http://localhost:3000")
// cy.get("h1") // h1 를 찾는다.
// cy.get("h1").contains("Testing Next.js Applications with Cypress") // h1를 찾고 Testing~ 를 포함하고 있는지 확인한다.
cy.get("[data-test='hero-heading']").contains(
"Testing Next.js Applications with Cypress"
) // 기존 h1 선택방식에서 data-test 선택으로 방식 변경
})
})
테스트 코드에서 get의 선택을 data-test 속성으로 수정한다.
코드의 길이가 길어졌지만, 더 개선된 데이터 속성 테스트 방법은 다음에 적용해보자.
자 그럼 위의 코드의 it 코드가 수십 개 있다고 할시, 특정 테스트만 실행하고자 한다면?
it.only 를 사용하자.
describe("home page", () => {
it("the h1 contains the correct text", () => {
cy.visit("http://localhost:3000")
cy.get("[data-test='hero-heading']").contains(
"Testing Next.js Applications with Cypress"
)
})
it.only("the features on the homepage are correct", () => {
cy.visit("http://localhost:3000")
cy.get("dt")
})
})
아 물론, 테스트 파일이 하나가 아니고 여러개라면 거기서도 only 를 사용해야 한다.
위 코드를 실행한다면 테스트 브라우저에서 get dt 3 이라는 출력 부분을 볼 수 있다.
3개의 dt요소가 있다는걸 알려준다.
여러개의 요소 중 0번째 요소에 접근하고 싶다면 ? eq 를 사용한다.
cy.get("dt").eq(0)
이후 내용도 확인해보자.
cy.get("dt").eq(0).contains("4 Courses")
위 코드에서 중복되는 부분이 있다.
=> cy.visit
코드를 줄여보자.
Mocha 라이브러리의 beforeEach를 사용한다.
describe("home page", () => {
beforeEach(() => { // 기존 cy.visit의 중복코드를 줄였다.
cy.visit("http://localhost:3000")
})
it("the h1 contains the correct text", () => {
cy.get("[data-test='hero-heading']").contains(
"Testing Next.js Applications with Cypress"
) // 기존 h1 선택방식에서 data-test 선택으로 방식 변경
})
it("the features on the homepage are correct", () => {
cy.get("dt").eq(0).contains("4 Courses") // dt요소 중 0번째 요소 액세스 후 4 courses 텍스트 포함 확인
})
})
참고