프론트엔드 개발 과정에는 대중과의 상호 작용을 위해 시각적으로 매력적이고 사용자 친화적인 애플리케이션을 제작하는 작업이 수반됩니다. 그러나 사용자 여정 전반에 걸쳐 중단 없는 사용자 경험을 보장하는 것이 필수적입니다.

단위 및 통합 테스트는 애플리케이션의 개별 구성 요소가 더 큰 시스템 내에서 올바르게 작동하는지 확인하여 애플리케이션의 성능을 검증하는 데 중요한 역할을 합니다. 그러나 이러한 유형의 테스트는 가능한 모든 사용자 시나리오 또는 상호 작용을 적절하게 설명하지 못할 수 있습니다. 실제 조건에서 애플리케이션이 어떻게 작동하는지 완벽하게 평가하려면 사용자가 수행하는 전체 작업 순서를 모방하는 엔드투엔드 테스트를 수행해야 합니다. 이를 통해 소프트웨어가 프로세스의 모든 단계에서 일관되게 작동하여 의도한 설계를 반영하고 고객의 기대치를 충족하는지 확인할 수 있습니다.

Cypress를 사용하여 엔드투엔드 테스트 시작하기

프런트엔드 애플리케이션 내에서 엔드투엔드 테스트의 주요 목표 중 하나는 기본 비즈니스 로직이 작동하는 방식에 대한 세부 사항에 초점을 맞추기보다는 최종 결과물의 정확성과 유효성을 보장하는 것입니다.

로그인 양식을 평가할 때는 특정한 기술적 복잡성에 관계없이 인터페이스의 의도된 기능이 제대로 실행되는지 확인하는 것이 중요합니다. 사용자 중심의 관점을 채택하면 사용자의 관점에서 전반적인 사용자 경험을 효과적으로 평가할 수 있습니다.

Cypress 는 가장 널리 사용되는 JavaScript 프레임워크와 호환되는 훌륭한 자동화 테스트 프레임워크입니다. 브라우저에서 직접 테스트를 실행할 수 있는 기능과 포괄적인 테스트 기능 세트를 통해 테스트를 원활하고 효율적으로 수행할 수 있습니다. 또한 다음과 같은 다양한 테스트 접근 방식을 지원합니다:

단위 테스트는 개별 구성 요소 또는 코드 단위를 개별적으로 테스트하여 기능과 안정성을 보장하는 소프트웨어 개발의 중요한 구성 요소입니다. 이러한 테스트는 코드가 시스템의 다른 부분과 통합되기 전에 코드에 존재하는 결함, 버그 또는 오류를 식별하는 데 도움이 됩니다. 단위 테스트를 수행함으로써 개발자는 코드베이스의 전반적인 품질을 개선하고 향후 업데이트 또는 변경 시 새로운 문제가 발생할 가능성을 줄일 수 있습니다.

엔드투엔드 테스트는 실제 시나리오와 사용자 상호 작용을 시뮬레이션하여 전체 시스템의 기능 및 성능을 처음부터 끝까지 평가하는 포괄적인 접근 방식입니다. 이러한 유형의 테스트를 통해 시스템의 모든 구성 요소가 실제 사용 시와 마찬가지로 원활하고 효과적으로 함께 작동하는지 확인할 수 있습니다. 이 과정에서 문제나 오류를 식별함으로써 개발자는 최적의 성능을 위해 필요한 조정과 개선을 수행할 수 있습니다.

통합 테스트는 여러 구성 요소 또는 모듈을 함께 결합하여 전체 시스템으로 올바르게 작동하는지 확인하는 소프트웨어 테스트의 한 유형입니다. 이러한 테스트는 각 개별 구성 요소가 제대로 작동하는지, 구성 요소의 상호 작용이 결합되었을 때 예상되는 결과를 생성하는지 확인합니다. 통합 테스트의 목표는 최종 제품을 사용자에게 출시하기 전에 버그나 오류와 같은 문제를 식별하는 것입니다.

개별 컴포넌트에 대한 단위 테스트 또는 통합 테스트를 따로 작성하는 대신 엔드투엔드 테스트는 React 애플리케이션의 모든 부분이 의도한 대로 원활하게 함께 작동하는지 확인하는 데 필수적입니다. 이 접근 방식을 효과적으로 구현하려면 실제 사용 사례와 사용자 상호 작용을 기반으로 포괄적인 테스트 시나리오를 만드는 데 집중해야 합니다. 이렇게 하면 실제 사용자의 관점에서 애플리케이션의 기능뿐만 아니라 시각적 표현과 성능 측면도 검증할 수 있습니다.

이 글도 확인해 보세요:  Nextra를 사용하여 Next.js로 기술 문서 사이트 구축하기

인터페이스와 상호 작용할 때 최종 사용자는 데이터 입력 및 제출을 용이하게 하는 제출 버튼과 함께 지정된 입력 필드를 접하게 됩니다.

개인은 데이터베이스 또는 데이터 수집에서 관련 정보를 검색할 의도로 용어 및 구문을 제출할 수 있는 해당 텍스트 입력 인터페이스(일반적으로 검색창 또는 문의 상자라고 함) 내에 쿼리를 입력할 수 있습니다.

‘제출’ 버튼을 누르면 관련 텍스트 입력 상자 바로 아래에 표시되는 개체 열거가 사용자에게 표시되어야 합니다.

이 사용자 스토리를 따라 사용자가 제품을 검색할 수 있는 간단한 React 애플리케이션을 구축할 수 있습니다. 이 앱은 DummyJSON API 에서 제품 데이터를 가져와서 페이지에 렌더링합니다.

이 프로젝트의 소스 코드는 전용 GitHub 리포지토리를 통해 액세스할 수 있습니다.

React 프로젝트 설정하기

시작하려면 Vite를 사용하여 React 프로젝트를 설정하거나 create-react-app 명령을 사용하여 기본 React 애플리케이션을 설정할 수 있습니다. 설정 절차가 완료되면 프로젝트 범위 내에서 Cypress 패키지를 개발 종속 요소로 설치하여 진행합니다.

 npm install cypress --save-dev 

`package.json` 파일을 수정하고 새 스크립트를 통합하려면 다음 단계를 따르세요: 1. 텍스트 편집기 또는 IDE에서 프로젝트의 루트 디렉터리를 엽니다. 2. 프로젝트 폴더 내에서 `package.json` 파일을 찾습니다. 3. 파일 하단으로 스크롤하여 기존 스크립트 배열 아래에 새 스크립트 항목을 추가합니다. 새 스크립트의 형식은 다음과 같아야 합니다: “`bash “스크립트”: { “build”: “반응 네이티브 빌드”, “test”: “농담”, “eject”: “리액트 네이티브 이젝트”, “install_dependencies”: “npm 설치 && npm 실행 리액트 네이티브 업그레이드”, “run_linting”: “eslint . –ext js,jsx”, }

 "test": "npx cypress open" 

함수형 컴포넌트 생성

좀 더 정교하게 고칠 수 있도록 원본 텍스트를 제공해 주세요.

 import React, { useState, useEffect } from 'react';
import "./style.component.css"

export default function Products(prop) {
  const [products, setProducts] = useState([]);
  const [error, setError] = useState(null);
  const { searchInput } = prop;


  return (
    <div className="product-catalogue">
      {error ? (
        <p>Product not found</p>
      ) : (
        <div className="product-list">
          {products.slice(0, 6).map((product) => (
            <div className="product" key={product.id}>
              <h2>Title: {product.title}</h2>
              <p>Price: ${product.price}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

함수형 컴포넌트의 맥락에서는 주어진 검색 쿼리에 대한 응답으로 제품 데이터를 검색하는 비동기 작업의 실행을 용이하게 하는 `useEffect` 훅을 구현하는 것이 필수적입니다.

  useEffect(() => {
    const fetchProducts = async () => {
      if (searchInput) {
        const apiUrl = `https://dummyjson.com/products/category/${searchInput}`;
        try {
          const response = await fetch(apiUrl);
          if (!response.ok) {
            throw new Error('Error fetching products');
          }
          const json = await response.json();
          setProducts(json.products);
          setError(null);
        } catch (error) {
          setError(error.message);
        }
      }
    };
    fetchProducts();
  }, [searchInput]);

App.jsx 파일 업데이트

다음은 최신 자바스크립트 구문과 컴포넌트를 사용하여 `App.jsx` 파일을 업데이트한 버전입니다: ”’자바스크립트 ‘에서 React를 가져옵니다; ‘react-router-dom’에서 { BrowserRouter를 라우터, 라우트, 스위치 }로 임포트합니다; import LoginPage from ‘./LoginPage’; // 컴포넌트 가져오기 import SignupPage from ‘./SignupPage’; // 컴포넌트를 임포트합니다. import Dashboard from ‘./Dashboard’; // 컴포넌트 불러오기 함수 App() { […] […]

 import React, { useState,useRef } from 'react'
import './App.css'
import Products from './components/Products'

function App() {
  const [searchInput, setSearchInput] = useState('')
  const searchInputRef = useRef('');

  const handleSubmit = (e) => {
    setSearchInput(searchInputRef.current.value);
  }

  return (
    <div>
      <h1>Cypress Testing Library tutorial</h1>
        <label htmlFor="input">Input</label>
      
        <input
          id="text"
          type="text"
          ref={searchInputRef}
        />

        <button id="btn" type="button" onClick={handleSubmit}>Submit</button>
      <Products data-testid="products-component" searchInput={searchInput} />
    </div>
  )
}

export default App

개발 서버를 활성화하는 프로세스를 시작하세요.

 npm run dev 

환상적입니다! 모의 JSON API에서 정보를 성공적으로 검색하여 지정된 제품과 관련된 특정 세부 정보에 액세스하고 추출할 수 있는 것으로 보입니다.

이 글도 확인해 보세요:  Python을 사용하여 할 일 목록 프로그램 만들기

테스트 환경 설정

터미널 명령 인터페이스를 사용하여 “python3 .py”를 입력하고 Enter 키를 눌러 테스트 스크립트를 실행합니다.

 npm run test 

이 지침을 실행하여 Cypress 클라이언트 인터페이스 내에 있는 “E2E 테스트” 버튼을 클릭하여 Cypress 테스트 환경을 시작하십시오.

Cypress 구성 파일을 통합하려면 “계속”을 클릭하여 계속 진행하십시오.

이 절차를 실행한 후 프로젝트 내에 Cypress 테스트와 관련된 새로운 디렉터리가 생성되었음을 알 수 있습니다. 또한 Cypress의 자동화된 클라이언트가 사용자의 개입 없이 cypress.config.js 파일을 동시에 추가합니다. 특정 요구 사항에 따라 테스트 환경, 수행 및 구성과 관련된 다양한 특성을 미세 조정하기 위해 이 문서를 수정할 수 있습니다.

Cypress를 사용하여 엔드투엔드 테스트 작성

초기 테스트를 실행하기 위해서는 테스트를 수행할 웹 브라우저를 선택해야 합니다. Cypress 인터페이스에서 제공되는 옵션 중 원하는 옵션을 선택하여 테스트에 사용하십시오.

테스트를 용이하게 하기 위해 Cypress는 선택한 웹 브라우저의 간소화된 반복을 시작하여 테스트 실행을 위한 규정된 설정을 설정합니다.

테스트 파일을 생성하려면 사용 가능한 선택 항목에서 “새 사양 생성” 옵션을 선택합니다.

선호하는 코드 편집 소프트웨어로 이동하여 e2e 디렉터리 내의 Cypress 폴더에 액세스하고 제공된 콘텐츠를 삽입하여 App.spec.cy.js 파일을 편집합니다.

 describe('App Tests', () => {
  beforeEach(() => {
    cy.visit('http://127.0.0.1:5173/');
  });

  it('Renders input field and submit button', () => {
    cy.get('#text').should('exist').should('be.visible');
    cy.get('#btn').should('exist').should('be.visible').contains('Submit');
  });

  it('Enters a search query', () => {
    const searchQuery = 'laptops';
    cy.get('#text').type(searchQuery);
  });
});

1. 시스템에서 프로세스 중 오류나 예외 없이 유효한 정보로 새 클라이언트를 성공적으로 등록할 수 있습니다. 이는 애플리케이션의 등록 기능이 의도한 대로 작동하고 클라이언트가 플랫폼에서 계정을 생성할 수 있도록 보장하기 때문에 중요합니다. 등록 과정에서 문제가 발생하면 사용자는 서비스를 사용할 수 없게 되고 비즈니스는 매출 손실로 인해 손실을 입을 수 있습니다. 따라서 등록 프로세스가 처음부터 올바르게 작동하는지 확인하는 것이 중요합니다. 2. 이메일 주소 필드 또는 비밀번호 필드(또는 둘 다)에 중복 데이터를 입력하면 시스템에서 예외를 발생시켜 등록 시도를 거부해야 합니다. 이는 클라이언트가 동일한 이메일 주소 또는 비밀번호 조합을 사용하여 여러 개의 계정을 만들지 못하도록 하기 때문에 중요합니다. 중복 계정은 사용자에게 혼란을 야기하고 보안 위험을 초래할 수 있습니다.

웹 애플리케이션의 사용자 인터페이스는 사용자가 데이터를 입력하거나 작업을 수행하여 시스템과 상호 작용할 수 있도록 입력 필드 및 제출 버튼과 같은 대화형 요소를 제공해야 합니다.

사용자는 시스템의 검색 기능을 통해 검색 문의를 입력할 수 있습니다.

Cypress는 테스트 사례를 정의하기 위해 선언적 구문을 사용하여 Jest 및 Supertest와 같은 다른 인기 있는 JavaScript 테스트 프레임워크와 유사한 접근 방식을 활용합니다.

이 글도 확인해 보세요:  개발자와 디자이너를 위한 10가지 UI/UX 영감 사이트

테스트를 실행하려면 Cypress가 감독하는 간소화된 웹 애플리케이션으로 돌아가서 수행하려는 특정 테스트 스크립트를 선택합니다.

테스트가 실행되면 Cypress는 테스트 플레이그라운드의 왼쪽 패널에 테스트 결과를 표시합니다.

애플리케이션 프로세스 시뮬레이션

이 특정 시나리오에서 완전한 사용자 경험을 검증하려면 소프트웨어가 사용자의 입력을 처리하고 필요한 정보를 검색하여 최종적으로 웹 브라우저 화면에 결과를 표시할 수 있는지 확인하는 것이 필수적입니다.

이해도를 높이기 위해, 특정 테스트 시나리오와 관련된 고유한 테스트 세트를 포용하기 위해 e2e 디렉토리 내에 추가 시험 파일을 설정할 수 있습니다. 또한, 특정 테스트 인스턴스를 조사하는 모든 테스트 시리즈를 단일 평가 문서 내에 통합하도록 선택할 수 있습니다.

“e2e” 디렉터리 내에 다음 코드를 포함하는 “Products.spec.cy.js”라는 이름의 새 파일을 생성하십시오:

 describe('Products Tests', () => {
    it(' fetches and displays the data', () => {
      const searchQuery = 'laptops';
      cy.visit('http://127.0.0.1:5173');
  
      cy.get('#text').type(searchQuery);
      cy.get('#btn').contains('Submit').click();
  
      cy.get('.product').should('have.length.greaterThan', 0);
  
      cy.get('.product').first().should('contain', 'Title');
      cy.get('.product').first().should('contain', 'Price: $');
    });

  });

본 테스트 절차는 사용자가 특정 검색어를 입력하면 애플리케이션이 웹 브라우저 인터페이스 내에서 관련 정보를 검색하여 표시하는지 검증합니다.

이 도구는 검색어를 입력하고, 엔터 키를 누르고, 결과가 나타날 때까지 기다린 다음, 상품명 및 가격을 포함하는 표시된 정보를 검사하는 동작을 복제합니다. 이 방법은 최종 사용자의 관점에서 전체 프로세스를 효과적으로 미러링합니다.

오류 및 반응 시뮬레이션

다양한 오류 상황과 반응을 시뮬레이션하여 불리한 조건에서 시스템 동작을 종합적으로 평가할 수 있는 테스트 용도로 Cypress를 활용할 수 있습니다.

Cypress에 대한 오류 사양을 생성하려면 “e2e” 디렉터리 내에 “Error.spec.cy.js”라는 새 파일을 생성해야 합니다. 이 파일에는 다음과 같이 제공된 코드 스니펫이 포함되어야 합니다:

 describe('Error Handling Tests', () => {
    it('Displays error message for incorrect search query', () => {
  
      cy.intercept('GET', /https:\/\/dummyjson\.com\/products\/category\/.*/, {
        statusCode: 404, // Not Found
        body: 'Product not found'
      }).as('fetchProducts');

      cy.visit('http://127.0.0.1:5173');

      const incorrectSearchQuery = 'rocket';
      cy.get('#text').type(incorrectSearchQuery);
      cy.get('#btn').click();

      cy.wait('@fetchProducts');

      cy.contains('Product not found').should('be.visible');
    });
  });

본 테스트 모음은 고객이 검색 작업의 일부로 잘못된 문의를 제출할 때마다 식별 가능한 알림을 표시해야 한다는 요구 사항을 준수하도록 보장합니다.

테스트 케이스가 성공적인 것으로 간주되기 위해 테스트는 Cypress의 차단 기능을 활용하여 네트워크를 시뮬레이션된 오류 응답으로 대체합니다. 그 후 지정된 입력 필드에 잘못된 검색어를 입력하고 데이터 검색 프로세스가 트리거되면 시스템에 “제품을 찾을 수 없음”이라는 가시적인 오류 메시지가 표시되어야 합니다.

앞서 언급한 결과는 시스템의 오류 완화 프로토콜이 의도된 설계 및 기능에 따라 작동하고 있음을 시사합니다.

테스트 중심 개발에 Cypress 사용

테스트는 소프트웨어 개발의 필수 요소이지만, 오랜 시간이 걸리고 힘든 프로세스가 될 수 있습니다. 그럼에도 불구하고 Cypress를 활용하면 테스트 케이스가 원활하게 실행되는 것을 관찰하는 만족감을 얻을 수 있습니다.

Cypress를 활용하면 다양한 테스트 방법론을 지원하면서 광범위한 테스트 기능을 제공하므로 소프트웨어 애플리케이션 내에서 테스트 중심 개발을 구현하는 데 큰 도움이 됩니다. 이 강력한 도구의 잠재력을 최대한 활용하고자 하는 경우, 공식 문서를 자세히 살펴보면 수많은 추가 테스트 가능성을 발견할 수 있으므로 적극 권장합니다.

By 김민수

안드로이드, 서버 개발을 시작으로 여러 분야를 넘나들고 있는 풀스택(Full-stack) 개발자입니다. 오픈소스 기술과 혁신에 큰 관심을 가지고 있고, 보다 많은 사람이 기술을 통해 꿈꾸던 일을 실현하도록 돕기를 희망하고 있습니다.