Cypress 테스트의 모든 것을 TypeScript #frontend@twiliosendgrid
게시 됨: 2020-11-14Twilio SendGrid에서 우리는 코드베이스의 더 나은 유형 검사, 유지 관리 및 문서화를 위해 오늘날 TypeScript 및 React를 사용하여 대부분의 프론트엔드 웹 애플리케이션, 특히 새로운 페이지와 기능을 작성합니다. 2년 전에 Cypress 테스트를 처음 작성하기 시작했을 때 대부분의 페이지 개체, 도우미 및 사양 파일은 여전히 JavaScript로 구현되었으며 대부분 Cypress 버전 3.xx를 사용했습니다. 더 최근의 테스트는 이미 TypeScript로 작성되었지만 우리는 TypeScript로 변환하고 마이그레이션할 파일이 여전히 많습니다.
우리는 구성 요소, 단위 테스트 및 Cypress E2E 테스트를 완전히 입력하는 이점을 얻고 싶었습니다 . 프로세스를 더 쉽게 만든 것은 Cypress 4.4.0 이후 기본 지원되는 TypeScript를 활용하기 위해 최신 버전의 Cypress로 마이그레이션하는 것입니다.
한 걸음 물러서서 E2E 테스트 작성에 대해 생각하는 방법을 더 일반적으로 배우고 싶다면 이 블로그 게시물을 자유롭게 확인하십시오. 또한 다양한 환경에서 Cypress 테스트를 작성할 때 사용하거나 수행한 가장 일반적인 작업에 대한 1,000피트 개요를 보려면 Cypress 테스트에 TypeScript를 추가하기 시작하기 전에 이 블로그 게시물을 참조하십시오. 이 블로그 게시물은 사용자가 Cypress 테스트에 익숙하고 이전에 해당 API를 사용한 적이 있다고 가정합니다.
우리가 어떻게 입력했는지 볼 준비가 되었다면 먼저 이전 버전에서 오는 경우 Cypress에 TypeScript 지원을 추가하는 것과 같은 몇 가지 초기 변경 사항을 살펴보겠습니다.
Cypress 3.x에서 >= 4.4.0으로 마이그레이션
Cypress 버전 3.xx ~ 4.4.3에서 TypeScript와 작동하도록 Cypress 인프라를 이미 구성한 사용자의 경우 plugins/index.js
에서 적절한 Webpack 전처리기 구성을 설정하는 데 몇 가지 시행착오를 경험했을 가능성이 큽니다. Twilio SendGrid 팀의 경우 특정 파일이 plugins
및 support
폴더에서 JavaScript 파일이어야 하는 일부 문제가 있었고 디버그하기 어려운 Cypress 오류가 표시되었습니다. 일단 작동하면 다음과 같이 보일 것입니다.
3.xx의 이전 버전에서 업그레이드한 후 Webpack 전처리기 구성을 삭제하고 plugins/index.js
파일을 index.ts
파일로 교체하고 Cypress 폴더의 tsconfig.json
을 약간 수정하고 마지막으로, Cypress 폴더에 있는 TS 파일 사용( some_page.spec.ts
, index.d.ts
또는 page_object.ts
) – 더 이상 Webpack 전처리기 구성이 필요 없고 바로 작동했습니다! 우리는 웹팩 전처리기 설정을 관리하지 않고 아래와 같이 파일에 대해 더 나은 TypeScript 적용 범위를 갖는 것이 얼마나 더 깨끗하고 더 좋았는지에 대해 기쁘게 생각합니다.
TypeScript 지원이 포함된 상태에서 우리는 타이핑을 더 잘하는 방법에 대해 더 배우기 위해 Cypress 팀의 실제 응용 프로그램 예제인 cypress-real-world-app repo를 살펴보았습니다. cy.task(“pluginName”, { … })
및 Cypress.env(“someEnvVar”)
함수 호출을 입력하여 파일 업데이트 시 더 나은 연결 및 Intellisense 지원을 입력하는 방법을 발견했습니다. 또한 함께 제공되는 TypeScript 문서도 살펴보았습니다. 이를 통해 cy.login()
사용자 지정 명령과 같은 항목을 입력하는 방법과 tsconfig.json
구성 파일을 설정하는 방법을 배웠습니다. 예제 애플리케이션에는 참조할 수 있는 tsconfig.json
도 있으며, 이를 통해 기본 설정에 맞게 사용자 지정할 수 있는 훌륭한 기본 TypeScript 구성을 제공할 수 있습니다. 최신 Cypress 버전을 유지하고 공식 Cypress 리소스를 살펴보고 유형 정의 파일을 실험하는 것이 좋습니다.
사용자 지정 명령 입력
API를 통한 로그인을 처리하기 위해 cy.login()
과 같은 몇 가지 전역 사용자 지정 명령을 생성하여 모든 사양 파일에서 재사용할 수 있습니다. 다음은 사용자 자격 증명이 제공된 고유한 로그인 사용자 지정 명령을 입력하고 인증 토큰을 반환하는 방법의 예입니다.
환경 변수 입력
dev 및 스테이징과 같은 여러 테스트 환경을 처리하기 위해 다음과 같은 환경 변수를 구성하는 이점을 활용했습니다. 스테이징과 같이 현재 테스트 중인 환경을 유지하기 위한 "testEnv", 백엔드 API 호스트를 유지하기 위한 "apiHost" 및 기타 변수. Cypress.env()
호출을 입력하여 이와 같은 환경 변수 값을 사용하는 데 의존하는 함수 및 기타 개체를 더 잘 입력할 수 있습니다.
플러그인 입력
API 호출, 서비스 폴링, 테스트 이메일 받은 편지함에서 일치하는 이메일 확인을 처리하기 위해 많은 cy.task()
플러그인 함수를 만들었습니다. 이전에는 cy.task().then((data) => {})
와 같은 이러한 함수 호출을 연결할 때 연결된 데이터 주체가 any
또는 unknown
으로 입력되어 TypeScript 파일에 적합하지 않았습니다. 우리는 Cypress 예제를 통해 플러그인 이름과 함수 호출에서 전달된 인수를 기반으로 플러그인을 더 잘 입력하는 방법을 발견했습니다. 이를 통해 TypeScript 파일이 연결된 데이터 유형이 무엇인지 감지할 수 있었습니다.
우리가 경험한 한 가지 미묘한 문제는 플러그인 이름과 인수가 입력한 방식과 정확히 일치해야 한다는 것이었습니다. 편집기에서 연결된 .then()
유형 및 cy.task()
인수 객체 위로 마우스를 가져가면 유형이 올바르게 일치하는지 확인하십시오. 때때로 cy.getCookie(“auth_token”).its(“value”).then((token) => { })
또는 cy.wrap(data).then((data) => {})
, cy.task(..., { token, data })
함수 인수로 전달하기 전에 연결된 데이터 인수도 입력해야 합니다. 그렇지 않으면 여전히 cy.task(...).then((data) => { })
가 표시됩니다. cy.task(...).then((data) => { })
데이터 부분이 any
또는 unknown
으로 입력되었습니다. .its(“value”).then((token: string) => {})
또는 cy.wrap(data).then((data: DataType) => {})
cy.task()
인수 객체의 일부로 전달하기 전에 유형이 다시 작동하는지 확인합니다.
우리는 plugins/index.ts
에서 다시 사용할 함수를 내보내는 별도의 플러그인 Typescript 파일을 만들었습니다. 플러그인 수가 증가함에 따라 이러한 플러그인 기능 구현을 페이지 또는 기능별로 구성하여 plugins/index.ts
파일을 작게 유지하는 것이 좋습니다. plugins/index.ts
파일에서 모든 cy.task(...)
함수를 정의한 위치를 한 눈에 읽기 쉽게 만들어야 합니다. 마지막으로 다음과 같은 방법으로 index.d.ts
에 이러한 작업 기능을 입력할 수 있습니다.
유형 선언 파일에 모두 합치기
사용자 지정 명령, 환경 변수 및 플러그인에 대한 모든 유형을 support
폴더의 index.d.ts
파일에 배치했습니다. 모든 Cypress 유형과 기본 TypeScript 정의 파일을 정리하여 정리하는 것이 좋습니다. Cypress 테스트 코드에 사용된 외부 종속성에서 누락된 유형을 우회하기 위해 "some-lib.d.ts"와 같은 모듈 파일을 정의할 수도 있습니다. 여기에는 declare module 'some-lib'
가 포함되어 라이브러리의 TypeScript 경고를 해결할 수 있습니다. TypeScript의 유형 가져오기 기능을 사용하여 다른 플러그인/유틸스 파일 내에 정의된 유형/인터페이스를 가져와서 유형 정의가 여러 파일에 중복되는 것을 방지할 수도 있습니다. Cypress 네임스페이스 내에 이러한 유형을 추가하고 다음과 같은 방식으로 구성할 수 있습니다.
테스트 픽스처 개체, 페이지 개체 및 사양 파일 입력
테스트 환경에 대한 다양한 사용자 및 메타데이터를 로드하려는 경우 이전에 "testEnv"와 같은 환경 변수를 "testing" 또는 "staging" 값과 결합하여 "testing" 또는 " 전체 테스트 픽스처 개체에서 "스테이징" 개체를 가져옵니다. 모든 사양이 공유할 수 있도록 일관된 구조를 위해 제네릭을 사용하여 이러한 테스트 픽스처 환경 개체를 입력할 수 있습니다. 각 테스트 환경에 대해 일반 유형을 사용하여 동일한 사용자 자격 증명과 메타 필드를 사용하여 테스트에 필요한 만큼 속성을 추가할 수 있습니다. 아래 예를 참조하십시오.
페이지 개체를 입력하고 해당 사양 파일을 입력하는 것은 사용 중인 Cypress 명령, 플러그인 및 기타 유틸리티에 따라 다릅니다. 대부분의 경우 페이지 개체 또는 사양 파일을 입력하는 데 해당 JavaScript에서 많은 변경 사항이 필요하지 않습니다(플러그인 및 환경 변수 호출을 이미 입력했다고 가정). 경우에 response.body as SomeType
정의한 페이지 객체 cy.request()
함수는 일부 인수를 입력해야 as
수 있습니다. 전반적으로 VSCode와 같은 편집기는 TypeScript 경고를 보상하기 위해 사양 파일에 더 많은 유형을 추가할 필요 없이 cy.task cy.task()
또는 cy.customCommand()
호출의 연결된 유형을 자동으로 감지할 수 있습니다.
다음은 페이지 개체, 로그인 사용자 지정 명령 및 플러그인 작업을 사용하는 일부 도우미 기능과 사양 파일이 있는 페이지 개체의 일부에 대한 예입니다.
결론
Cypress 테스트에 TypeScript를 추가하여 Cypress 테스트를 작성할 때 버그를 방지하고 개발자 경험을 개선할 수 있었습니다. cy.task()
, Cypress.env()
및 cy.customCommand()
함수 호출을 사용할 때 함수 인수 및 출력에서 더 나은 유형 검사를 얻을 수 있을 뿐만 아니라 VSCode와 같은 IDE에서 코드 완성을 활용할 수 있습니다.
핵심은 사용자 정의 명령, 환경 변수 및 작업 플러그인 기능을 기반으로 "Cypress" 및 "Chainable" 인터페이스를 재정의하거나 확장할 수 있는 index.d.ts
파일과 같은 고유한 유형 선언 파일을 만드는 것입니다. 사용. 페이지 개체 및 사양 TypeScript 파일에서 해당 Cypress 기능을 활용하고 예상되는 입력 및 출력 유형의 정의 위로 마우스를 이동하거나 따를 수 있습니다.
또한 최신 버전에서 TypeScript를 즉시 지원하므로 Cypress와 함께 TypeScript를 사용해 보십시오. 기능을 보다 명확하게 문서화하고 잘못된 API 사용을 방지하는 데 도움이 되는지 테스트합니다. TypeScript 테스트는 여전히 JavaScript Cypress 테스트와 유사하게 보일 수 있으므로 한 번에 몇 가지 테스트를 꾸준히 변환하여 접근 방식을 비교하고 대조할 수 있습니다.
Cypress 테스트에서 배운 내용과 관련된 더 많은 게시물에 관심이 있는 경우 확인해야 할 몇 가지 기사가 있습니다.
- E2E 테스트를 작성할 때 고려해야 할 사항
- Cypress 테스트 작성에 대한 1,000피트 개요
- Cypress 테스트에서 이메일 흐름 다루기
- Cypress 테스트 구성, 구성 및 통합을 위한 아이디어
- Docker, Buildkite 및 CICD와 Cypress 테스트 통합