>  기사  >  웹 프론트엔드  >  Jest를 사용한 한 예제의 단위, 통합 및 ETesting

Jest를 사용한 한 예제의 단위, 통합 및 ETesting

DDD
DDD원래의
2024-11-20 19:53:15238검색

소개

많은 개발자가 코드를 테스트할 때 어려움에 직면합니다. 적절한 테스트가 없으면 버그가 빠져나가 사용자가 불만을 느끼고 수정 비용이 많이 들 수 있습니다.

이 기사에서는 Node.js 및 MongoDB를 사용하여 구축된 매우 간단한 예제에서 Jest, Supertest 및 Puppeteer를 사용하여 단위, 통합 및 엔드투엔드 테스트를 효과적으로 적용하는 방법을 보여줍니다.

이 기사를 마치면서 이러한 유형의 테스트를 자신의 프로젝트에 적용하는 방법을 명확하게 이해하게 되기를 바랍니다.

?‍? 이 저장소에서 전체 예를 찾아보세요.

종속성 소개

종속성을 설치하기 전에 먼저 예제를 소개하겠습니다. 이는 사용자가 등록 페이지를 열고, 등록 세부 정보를 설정하고, 등록 버튼을 클릭하고, 해당 정보를 데이터베이스에 저장할 수 있는 매우 간단한 예입니다.

이 예에서는 다음 패키지를 사용합니다.

npm install --save jest express mongoose validator
npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all

이러한 종속성은 대부분 간단하지만 몇 가지에 대한 설명은 다음과 같습니다.

  • puppeteer: 자동 테스트 및 웹 스크래핑을 위해 헤드리스 브라우저(Chrome)를 제어할 수 있습니다.
  • Jest-Puppeteer: Puppeteer를 통합한 Jest용으로 사전 설정되어 있어 브라우저 환경에서 엔드 투 엔드 테스트를 실행하기 위한 설정을 단순화합니다. 이를 jest.config.js 파일의 사전 설정으로 사용할 수 있으며 jest-puppeteer.config.js라는 파일을 통해 Puppeteer 동작을 사용자 정의할 수 있습니다.
  • mongodb-memory-server: 데이터베이스 상호 작용을 빠르고 독립적으로 테스트하기 위해 인메모리 MongoDB 인스턴스를 구동하는 유틸리티입니다.
  • npm-run-all: 여러 npm 스크립트를 병렬 또는 순차적으로 실행하는 CLI 도구입니다.

단위 테스트

  • 정의: 단위 테스트는 개별 구성요소나 기능을 개별적으로 테스트하는 데 중점을 둡니다. 목표는 각 코드 단위가 예상대로 작동하는지 확인하는 것입니다.
  • 속도: 단위 테스트는 외부 시스템이나 데이터베이스에 의존하지 않고 작은 코드 조각을 테스트하기 때문에 일반적으로 매우 빠릅니다.
  • : 사용자 등록 예에서 단위 테스트는 이메일 주소를 확인하는 기능을 확인할 수 있습니다. 예를 들어, 함수가 user@.com 또는 user.com을 거부하면서 user@example.com을 유효한 것으로 올바르게 식별하는지 확인합니다.

좋습니다. 이것을 코드로 번역해 보겠습니다.

단위 테스트 환경 설정

예측할 수 없는 동작 없이 단위 테스트를 실행하려면 모든 테스트 전에 모의 기능을 재설정해야 합니다. beforeEach 후크를 사용하여 이를 달성할 수 있습니다.

// setup.unit.js

beforeEach(() => {
  jest.resetAllMocks();
  jest.restoreAllMocks();
}); 

이메일 검증 테스트

이 경우에는 verifyInput 함수를 테스트하고 싶습니다.

npm install --save jest express mongoose validator
npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all

제공된 입력에 유효한 이메일이 포함되어 있는지 확인하는 매우 간단한 기능입니다. 단위 테스트는 다음과 같습니다.

// setup.unit.js

beforeEach(() => {
  jest.resetAllMocks();
  jest.restoreAllMocks();
}); 

await Expect(async () => {}).rejects: Jest 문서에 따르면 이는 Promise 거부의 이유를 예상하는 방법입니다.

중복된 이메일 테스트

데이터베이스에 중복된 이메일이 있는지 확인하는 또 다른 기능을 테스트해 보겠습니다. 사실 이것은 데이터베이스를 다루어야 하고 동시에 단위 테스트가 외부 시스템을 다루어서는 안 되기 때문에 흥미롭습니다. 그렇다면 우리는 어떻게 해야 할까요? 글쎄, 우리는 Mocks를 사용해야 합니다.

먼저 테스트해야 하는 emailShouldNotBeDuplicated 함수를 살펴보세요.

// register.controller.js
const validator = require('validator');

const registerController = async (input) => {
  validateInput(input);
  ...
};

const validateInput = (input) => {
  const { name, email, password } = input;
  const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 });
  if (!isValidName) throw new Error('Invalid name');
  ...
};

보시다시피 이 함수는 동일한 이메일을 가진 다른 사용자가 있는지 확인하기 위해 데이터베이스에 요청을 보냅니다. 데이터베이스 호출을 모의하는 방법은 다음과 같습니다.

// __tests__/unit/register.test.js
const { registerController } = require('../controllers/register.controller');

describe('RegisterController', () => {
  describe('validateInput', () => {
    it('should throw error if email is not an email', async () => {
      const input = { name: 'test', email: 'test', password: '12345678' };
      await expect(async () => await registerController(input)).rejects.toThrow('Invalid email');
    });
  });
});

모의 함수를 생성하고 해당 호출을 추적하는 jest.spyOn(object, methodName)을 사용하여 데이터베이스 findOne 메서드를 모의(스파이)했습니다. 결과적으로 toHaveBeenNthCalledWith를 사용하여 염탐된 findOne 메소드의 호출 수와 전달된 매개변수를 추적할 수 있습니다.

통합 테스트

  • 정의: 통합 테스트는 여러 구성 요소가 함께 작동하는 방식을 평가합니다. 다양한 기능, 모듈 또는 서비스 간의 상호 작용을 확인합니다.
  • 속도: 통합 테스트는 여러 구성 요소를 포함하고 데이터베이스 액세스 또는 네트워크 호출이 필요할 수 있으므로 단위 테스트보다 느립니다.
  • : 사용자 등록 프로세스의 경우 통합 테스트를 통해 등록 요청을 보낼 때 사용자 데이터가 올바르게 검증되고 데이터베이스에 저장되는지 확인할 수 있습니다. 이 테스트를 통해 입력 유효성 검사, API 엔드포인트, 데이터베이스 상호 작용 등 모든 구성 요소가 의도한 대로 함께 작동하는지 확인할 수 있습니다.

통합 테스트 환경 설정

통합 테스트를 작성하기 전에 환경을 구성해야 합니다.

npm install --save jest express mongoose validator
npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
  • 보시다시피 통합 테스트에 필요하기 때문에 TestingApp을 내보냅니다. 그리고 완전히 초기화되기 전에 내보내지기 때문에 함수로 내보냅니다. beforeAll이 비동기식이기 때문에 module.exports 문은 testingApp에 값이 할당되기 전에 실행되어 테스트에서 사용하려고 하면 정의되지 않게 됩니다. 파일.
  • Jest Hooks를 사용하여 다음을 수행할 수 있었습니다.
    • beforeAll: Express 서버를 시작하고 인메모리 MongoDB 데이터베이스에 연결합니다.
    • afterAll: Express 서버를 닫고 실행 중인 인메모리 MongoDB 데이터베이스를 중지합니다.
    • beforeEach: 각 테스트 사례 전에 사용자 컬렉션을 삭제하여 데이터베이스를 정리합니다.

이제 통합 테스트를 실행할 준비가 되었습니다.

등록 API 요청 테스트

등록 요청 전송부터 데이터베이스에 사용자 세부정보 저장, 성공 페이지로 리디렉션까지 전체 서버측 등록 프로세스를 테스트해 보겠습니다.

// setup.unit.js

beforeEach(() => {
  jest.resetAllMocks();
  jest.restoreAllMocks();
}); 

보시다시피,registerController 함수는 여러 구성 요소(함수), verifyInput, emailShouldNotBeDuplicated 및 createUser 함수를 통합합니다.

이제 통합 테스트를 작성해 보겠습니다.

// register.controller.js
const validator = require('validator');

const registerController = async (input) => {
  validateInput(input);
  ...
};

const validateInput = (input) => {
  const { name, email, password } = input;
  const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 });
  if (!isValidName) throw new Error('Invalid name');
  ...
};
  • 보시다시피 이 테스트 사례에서는 supertest 패키지를 사용하여 API에 등록 요청을 보냅니다. 이는 등록 프로세스 중 실제 사용자 행동을 시뮬레이션합니다.
  • 이 경우 실제 동작을 테스트해야 하기 때문에 데이터베이스 호출을 모의하지 않았습니다.

엔드투엔드(E2E) 테스트

  • 정의: E2E 테스트는 실제 사용자 시나리오를 시뮬레이션하여 처음부터 끝까지 전체 애플리케이션 흐름을 검증합니다. 사용자 인터페이스와 백엔드 서비스를 포함하여 애플리케이션 전체를 테스트합니다.
  • 속도: E2E 테스트는 애플리케이션 인터페이스를 탐색하고 다양한 구성 요소와 상호 작용하며 종종 여러 네트워크 요청이 필요하기 때문에 세 가지 유형 중에서 가장 느립니다.
  • : 사용자 등록의 맥락에서 E2E 테스트는 사용자가 등록 페이지를 열고 세부 정보(예: 이름, 이메일, 비밀번호)를 입력하고 '등록' 버튼을 클릭하는 것을 시뮬레이션합니다. , 그런 다음 성공 페이지로 리디렉션되는지 확인합니다. 이 테스트는 사용자 관점에서 등록 프로세스의 모든 부분이 원활하게 작동하는지 확인합니다.

예제를 살펴보겠습니다.

E2E 테스트 환경 설정

실제로 이 예에서는 엔드 투 엔드 테스트를 위한 환경 구성이 통합 테스트의 환경 구성과 유사합니다.

테스트 등록 프로세스 처음부터 끝까지

이 경우 등록 페이지 열기, 세부 정보(이름, 이메일, 비밀번호) 입력, '등록' 버튼 클릭, 마지막으로 성공 페이지로 리디렉션되는 실제 사용자 등록 동작을 정확하게 시뮬레이션해야 합니다. . 코드를 살펴보세요:

npm install --save jest express mongoose validator
npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all

이 코드를 분석해 보겠습니다.

  • 엔드투엔드 테스트를 구현하는 데 사용할 수 있는 도구가 많이 있습니다. 여기서는 Puppeteer와 함께 Jest를 사용하여 엔드투엔드 테스트를 구현합니다.
  • 페이지 변수가 무엇인지 궁금하시죠? Jest의 예상과 마찬가지로 Puppeteer에서 제공하는 전역 변수로, 요소 탐색 및 상호작용과 같은 작업을 수행할 수 있는 브라우저의 단일 탭을 나타냅니다.
  • Puppeteer를 사용하여 goto 기능을 사용하여 해당 페이지를 열고, type 기능을 사용하여 입력을 채우고, 클릭 기능을 사용하여 등록 버튼을 클릭하는 방식으로 사용자 행동을 시뮬레이션하고 있습니다.

다양한 구성으로 모든 테스트를 함께 실행

Unit, Integration, and ETesting in One Example Using Jest

Unsplash의 Nathan Dumlao 사진

이 시점에서는 각각 고유한 구성이 있는 모든 테스트 유형을 동시에 실행하는 방법이 궁금할 것입니다. 예:

  • 단위 테스트에서는 모든 테스트 케이스 전에 모든 모의 객체를 재설정해야 하지만 통합 테스트에서는 이것이 필요하지 않습니다.
  • 통합 테스트에서는 테스트를 실행하기 전에 데이터베이스 연결을 설정해야 하지만 단위 테스트에서는 필수가 아닙니다.

그렇다면 각 테스트 유형이 해당 구성을 준수하는지 확인하면서 동시에 모든 테스트 유형을 실행할 수 있는 방법은 무엇일까요?

이 문제를 해결하려면 다음 단계를 따르세요.

1. 세 가지 구성 파일인 jest.unit.config.js를 만들어 보겠습니다.

// setup.unit.js

beforeEach(() => {
  jest.resetAllMocks();
  jest.restoreAllMocks();
}); 

jest.integration.config.js:

// register.controller.js
const validator = require('validator');

const registerController = async (input) => {
  validateInput(input);
  ...
};

const validateInput = (input) => {
  const { name, email, password } = input;
  const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 });
  if (!isValidName) throw new Error('Invalid name');
  ...
};

jest.e2e.config.js:

// __tests__/unit/register.test.js
const { registerController } = require('../controllers/register.controller');

describe('RegisterController', () => {
  describe('validateInput', () => {
    it('should throw error if email is not an email', async () => {
      const input = { name: 'test', email: 'test', password: '12345678' };
      await expect(async () => await registerController(input)).rejects.toThrow('Invalid email');
    });
  });
});

2. 다음으로 package.json 파일에서 npm 스크립트를 다음과 같이 업데이트하세요.

// register.controller.js
const { User } = require('../models/user');

const registerController = async (input) => {
    ...
  await emailShouldNotBeDuplicated(input.email);
  ...
};

const emailShouldNotBeDuplicated = async (email) => {
  const anotherUser = await User.findOne({ email });
  if (anotherUser) throw new Error('Duplicated email');
};

--config: Jest 구성 파일의 경로를 지정합니다.

npm-run-all --parallel: 모든 테스트를 병렬로 실행할 수 있습니다.

3. 그런 다음 이전 섹션에서 사용한 필수 설정 코드가 포함된 setup.unit.js, setup.integration.js 및 setup.e2e.js라는 세 개의 설정 파일을 만듭니다.
4. 마지막으로 npm run test 명령을 실행하여 모든 테스트를 실행합니다. 이 명령은 해당 구성에 따라 모든 단위, 통합 및 엔드투엔드 테스트를 병렬로 실행합니다.

결론

이 기사에서는 단위, 통합 및 E2E(엔드 투 엔드) 테스트를 살펴보며 안정적인 애플리케이션 구축에 대한 중요성을 강조했습니다. Node.js 및 MongoDB를 사용한 간단한 사용자 등록 예제에서 Jest, Supertest 및 Puppeteer를 사용하여 이러한 테스트 방법을 구현하는 방법을 시연했습니다.

실제로 탄탄한 테스트 전략은 코드 품질을 향상시킬 뿐만 아니라 개발자의 자신감과 사용자 만족도도 높여줍니다.

이 기사가 귀하의 프로젝트에 적용할 수 있는 유용한 통찰력을 제공하였기를 바랍니다. 즐거운 테스트 되세요!

생각해 보세요

이 기사가 유용했다면 다음 기사도 확인해 보세요.

  • MongoDB GridFS가 단순해졌습니다
  • FFmpeg 및 Node.js를 사용하여 비디오 스트리밍을 개선한 방법
  • 비동기 JavaScript를 처리하는 4가지 방법

지금까지 함께해주셔서 정말 감사드립니다. 이 글을 재미있게 읽어주시길 바랍니다.

위 내용은 Jest를 사용한 한 예제의 단위, 통합 및 ETesting의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.