Cypress 테스트를 작성할 때 피해야 할 5가지

어플리케이션을 테스트할 때 E2E(End-to-End) 테스트는 최대의 신뢰와 보상을 제공합니다.

반대로 끝까지 테스트하는 것은 의심할 여지없이 어렵고 시간이 걸리며 많은 문제를 해결해야 한다.하지만 작업 중에 잘못된 도구를 사용했을 때만
Cypress 입력: 브라우저에서 실행되는 모든 것에 대해 신속하고 간단하며 신뢰할 수 있는 테스트를 실시합니다.
Cypress는 전체 테스트의 대부분의 난점을 해결하고 작성 테스트를 흥미롭게 하는 데 도움이 된다.
그러나 Cypress를 최대한 활용할 수 있도록 피해야 하는 오류가 있다.
이 블로그에서 우리는 이러한 흔한 오류 5개를 소개할 것이며, Cypress 테스트를 작성할 때 이러한 오류를 피해야 한다.
그러니까 더 이상 귀찮게 하지 말고 시작합시다!

id와 클래스를 사용하여 원소를 선택하십시오

idclass을 사용하여 요소를 선택하는 것은 문제가 있다. 주로 행위와 스타일 디자인에 사용되기 때문에 자주 변경된다.
이렇게 하면 아삭아삭한 테스트를 초래할 수 있는데, 이것은 아마도 네가 원하지 않는 것일 것이다.
대신 항상 data-cy 또는 data-test-id을 사용해 보십시오.
왜?테스트 목적에 전문적으로 사용되기 때문에 행동이나 양식과 분리되기 때문에 더욱 믿을 만하다.
예를 들어, input 요소가 있다고 가정해 봅시다.
<input
  id="main"
  type="text"
  class="input-box"
  name="name"
  data-testid="name"
/>
id 또는 class을 사용하지 않고 data-testid을 사용합니다.
// Don't ❌
cy.get("#main").something();
cy.get(".input-box").something();

// Do ☑️
cy.get("[data-testid=name]").something();
텍스트를 사용하여 요소를 선택하는 것은 어떻습니까?
때때로 단추 탭 등 텍스트를 사용하여 단언이나 조작을 할 필요가 있다.
비록 이것은 좋지만, 텍스트가 바뀌면 테스트가 실패할 것입니다. 만약 텍스트가 응용 프로그램에 매우 중요하다면, 이것은 당신이 원하는 것입니다.

측백나무 명령을 약속으로 여기다


Cypress 테스트는 cy.getcy.visit 등의 Cypress 명령으로 구성됩니다.
Cypress 명령은 약속과 같지만 진정한 약속은 아니다.
이것은 우리가 그것들을 사용할 때 async-await이라는 문법을 사용할 수 없다는 것을 의미한다.예를 들면 다음과 같습니다.
    // This won't work
    const element = await cy.get("[data-testid=element]");

    // Do something with element
만약 명령이 완성된 후에 어떤 조작을 실행해야 한다면 cy.then 명령의 도움 아래 실행할 수 있다.
그것은 이전 명령이 완성된 후에만 다음 명령이 실행될 것을 보장할 것이다.
    // This works
    cy.get("[data-testid=element]").then($el => {
        // Do something with $el
    });

주의: Promise.all과 같은 자구를 Cypress 명령과 함께 사용할 때, Cypress 명령은 Promise와 유사하지만, 진정한 Promise는 아닙니다.

Cypress 테스트에서 아무 때나 대기 사용


Cypress 테스트를 작성할 때 실제 장면에서 실제 사용자의 행동을 모의하기를 원합니다.
네트워크 지연과 장치 제한 등으로 인해 현실 세계의 응용 프로그램은 비동기적이고 느리다.
이러한 응용 프로그램에 대한 테스트를 작성할 때, 우리는 cy.wait 명령에서 임의의 값을 사용하기 쉽다.
이런 방법의 문제는 개발에서 잘 작동하고 있지만 보장할 수 없다는 데 있다.왜?기본적인 네트워크 요청은 거의 예측할 수 없기 때문이다.
    // Might work (sometimes) 🤷
    cy.get("[data-testid=element]").performSomeAsyncAction();
    // Wait for 1000 ms
    cy.wait(1000);
    // Do something else after the action is completed
반대로 우리는 시각 요소의 불러오기를 기다려야 한다.그것은 실제 세계의 용례에 더욱 가까울 뿐만 아니라, 더욱 믿을 만한 결과를 내놓았다.
생각해 보아라. 프로그램을 사용하는 사용자는 임의의 시간이 아니라 동작의 완성을 확인하기 위해 불러오는 시각적 단서를 기다릴 수도 있다.
    // The right way ☑️
    cy.get("[data-testid=element]").performSomeAsyncAction();
    // Wait for loading to finish
    cy.get("[data-testid=loader]").should("not.be.visible");
    // Now that we know previous action has been completed; move ahead
예를 들어 Cypress 명령 cy.get은 단언을 하기 전에 요소를 기다린다. 이것은 당연히 미리 정의된 시간 초과값이다. 당신은 modify을 사용할 수 있다.
시간 초과가 가장 멋있는 것은 cy.wait 명령처럼 완전한 지속 시간을 기다리는 것이 아니라 조건이 충족될 때까지 기다리는 것이다.

다른 Cypress에서 테스트 도메인 사용


Cypress의 한 가지 제한은 한 번의 테스트에서 여러 개의 도메인을 사용할 수 없다는 것이다.
테스트 블록 it(...) 또는 test(...)에서 다중 도메인 사용을 시도하면 Cypress에서 보안 경고가 표시됩니다.
이것이 바로 Cypress의 작업 방식 built이다.
그럼에도 불구하고, 때로는 한 번의 테스트에서 여러 개의 영역에 접근해야 한다.우리는 테스트 논리를 하나의 테스트 파일 중의 여러 개의 테스트 블록으로 나누어 이 점을 실현할 수 있다.너는 그것을 여러 단계의 테스트로 볼 수 있다. 예를 들면,
describe("Test Page Builder", () => {
    it("Step 1: Visit Admin app and do something", {
        // ...
    });

    it("Step 2: Visit Website app and assert something", {
        // ...
    });
});
Webiny에서 비슷한 방법으로 Page Builder application을 테스트했습니다.
이런 방식으로 테스트를 작성할 때 기억해야 할 몇 가지는 다음과 같다.
  • 테스트 블록에서 가변적이든 로컬이든 영구적인 저장소에 의존할 수 없습니다.
    왜?configuration에 정의된 baseURL 이외의 도메인에 Cypress 명령을 실행하면 Cypress가 분해를 수행하고 완전히 다시 로드하기 때문입니다.
  • 블록, 예를 들어 "before", "after" 블록은 상술한 문제가 같기 때문에 각각의 시험 블록에 대해 운행할 것이다.
  • 이런 방법을 채택하기 전에 이 문제들을 주의하고 이에 상응하여 테스트를 조정하십시오.

    비동기식 및 동기식 코드 혼합


    Cypress 명령은 비동기적이며 값을 반환하지 않고 값을 생성합니다.
    Cypress를 실행하면 명령을 즉시 실행하지 않고 명령을 연속으로 읽고 줄을 서게 됩니다.
    하나하나 집행된 뒤에만따라서 비동기식과 동기화 코드를 섞어 테스트를 하면 오류가 발생할 수 있습니다.
    예를 들면 다음과 같습니다.
    it("does not work as we expect", () => {
      cy.visit("your-application") // Nothing happens yet
    
      cy.get("[data-testid=submit]") // Still nothing happening
        .click() // Nope, nothing
    
      // Something synchronous
      let el = Cypress.$("title") // evaluates immediately as []
    
      if (el.length) {
        // It will never run because "el.length" will immediately evaluates as 0
        cy.get(".another-selector")
      } else {
        /*
        * This code block will always run because "el.length" is 0 when the code executes
        */
        cy.get(".optional-selector")
      }
    })
    
    반대로 명령이 완료되면 친구 cy.then 명령을 사용하여 코드를 실행합니다.예를 들어,
    it("does work as we expect", () => {
      cy.visit("your-application") // Nothing happens yet
    
      cy.get("[data-testid=submit]") // Still nothing happening
        .click() // Nope, nothing
        .then(() => {
          // placing this code inside the .then() ensures
          // it runs after the cypress commands 'execute'
          let el = Cypress.$(".new-el") // evaluates after .then()
    
          if (el.length) {
            cy.get(".another-selector")
          } else {
            cy.get(".optional-selector")
          }
        })
    })
    

    결론


    Cypress는 완벽한 테스트를 위한 강력한 도구이지만, 때때로 우리는 약간의 오류를 범하여 체험을 재미없게 할 수도 있다.
    흔히 볼 수 있는 오류를 피함으로써 우리는 끝에서 끝까지 테스트하는 과정을 순조롭고 재미있게 할 수 있다.

    좋은 웹페이지 즐겨찾기