유용한 도구

자동화된 테스트는 기본적으로 뭔가 잘못되었을 수 있습니다. 대부분의 라이브러리나 테스트 프레임워크는 프리미티브와 같은 프리미티브를 제공합니다.

이전 섹션에서 언급했듯이 이러한 프리미티브는 거의 항상 독립적인 테스트 (테스트 사례라고 함)를 정의하고 어설션을 만들 수 있습니다. 어설션은 결과 확인과 오류가 있는 경우 오류가 발생하며, 모든 오류의 기본 원시값으로 테스트할 수 있습니다.

이 페이지에서는 이러한 프리미티브에 대한 일반적인 접근 방식을 설명합니다. 선택한 프레임워크 이와 유사한 것이 있을 수 있지만 정확한 참조는 아닙니다.

예를 들면 다음과 같습니다.

import { fibonacci, catalan } from '../src/math.js';
import { assert, test, suite } from 'a-made-up-testing-library';

suite('math tests', () => {
  test('fibonacci function', () => {
    // check expected fibonacci numbers against our known actual values
    // with an explanation if the values don't match
    assert.equal(fibonacci(0), 0, 'Invalid 0th fibonacci result');
    assert.equal(fibonacci(13), 233, 'Invalid 13th fibonacci result');
  });
  test('relationship between sequences', () => {
    // catalan numbers are greater than fibonacci numbers (but not equal)
    assert.isAbove(catalan(4), fibonacci(4));
  });
  test('bugfix: check bug #4141', () => {
    assert.isFinite(fibonacci(0)); // fibonacci(0) was returning NaN
  })
});

이 예에서는 '수학'이라는 이름의 테스트 그룹 (도구 모음이라고도 함)을 만듭니다. 테스트'와 함께 작동하며, 각 어설션을 실행하는 세 개의 독립적인 테스트 사례를 정의합니다. 이러한 테스트 사례는 일반적으로 필터 플래그를 설정합니다.

프리미티브로서의 어설션 도우미

Vitest를 비롯한 대부분의 테스트 프레임워크에는 어설션 모음이 포함되어 있습니다. assert 객체에 대한 도우미를 사용하면 반환 값을 빠르게 확인하거나 다른 상태는 몇몇 기대치와 상반됩니다. 이러한 기대는 보통 '잘 알려진' 것으로 인식됩니다. 값으로 사용됩니다. 이전 예에서는 13번째 피보나치 숫자가 233이므로 assert.equal를 사용하여 직접 확인할 수 있습니다.

값이 특정 형태를 취하거나 다른 속성보다 크거나 같거나 다른 속성이 있을 수 있습니다. 이 과정은 가능한 모든 어설션 도우미를 다루지만 테스트 프레임워크는 최소한 다음과 같은 기본 검사를 수행해야 합니다.

  • '진실'은 확인하며 대개 '정상'으로 설명됩니다. 조건이 참인지 확인하고 성공 또는 실패 여부를 확인하는 if 작성 방법과 일치 맞습니다. assert(...) 또는 assert.ok(...)로 제공되는 경향이 있습니다. 는 단일 값과 선택적 주석을 사용합니다.

  • 수학 시험 예와 같이 객체의 상태 또는 값을 반환합니다. 적용 대상 원시 같음 (예: 숫자 및 문자열) 또는 참조 등호 같은 객체입니다. 내부적으로는 이것들은 단지 '진실'일 뿐 확인 == 또는 === 비교를 사용합니다.

    • JavaScript는 느슨한 같음 (==)과 엄격한 (===) 동등성을 구분합니다. 대부분의 테스트 라이브러리는 assert.equal 및 각각 assert.strictEqual입니다.
  • 심층 균등 검사는 균등 검사를 확장하여 객체, 배열 및 기타 복잡한 데이터 유형의 콘텐츠와 객체를 순회하여 객체를 비교하는 내부 로직입니다. 이들은 JavaScript에는 2개 또는 2개의 객체 또는 배열로 구성됩니다. 예를 들어 [1,2,3] == [1,2,3]는 항상 false입니다. 테스트 프레임워크에는 deepEqual 또는 deepStrictEqual 도우미가 포함되는 경우가 많습니다.

'진실' 검사 전용이 아니라 두 값을 비교하는 어설션 도우미 일반적으로 두세 개의 인수를 사용합니다.

  • 테스트 중인 코드에서 생성되거나 확인합니다
  • 일반적으로 하드 코딩된 예상 값입니다 (예: 리터럴 숫자 또는 문자열)입니다.
  • 예상되는 작업이나 실패했을 수 있는 항목을 설명하는 의견(선택사항) 이 행이 실패하면 포함됩니다.
를 통해 개인정보처리방침을 정의할 수 있습니다.

또한 어설션을 결합하여 다양한 계정 상태를 정확하게 확인하는 경우는 드물기 때문에 알아내야 합니다. 예를 들면 다음과 같습니다.

  test('JWT parse', () => {
    const json = decodeJwt('eyJieSI6InNhbXRob3Ii');

    assert.ok(json.payload.admin, 'user should be admin');
    assert.deepEqual(json.payload.groups, ['role:Admin', 'role:Submitter']);
    assert.equal(json.header.alg, 'RS265')
    assert.isAbove(json.payload.exp, +new Date(), 'expiry must be in future')
  });

Vitest는 Chai 어설션 라이브러리를 사용합니다. 어설션 도우미를 제공하도록 내부적으로, 어떤 어설션과 도우미가 코드에 적합한지 확인할 수 있습니다.

유창한 어설션 및 BDD 어설션

일부 개발자는 동작 기반이라고 할 수 있는 어설션 스타일을 선호합니다. 개발 (BDD) 유창 스타일 어설션을 만들 수 있습니다. 이를 '기대'라고도 합니다. kubectl에 대한 진입점은 기대치 확인은 expect()라는 메서드입니다.

도우미는 간단한 메서드로 작성된 어설션과 동일한 방식으로 동작합니다. assert.ok 또는 assert.strictDeepEquals와 같은 호출을 지원하지만 일부 개발자는 더 쉽게 읽을 수 있습니다. BDD 어설션은 다음과 같을 수 있습니다.

// A failure here would generate "Expect result to be an array that does include 42"
const result = await possibleMeaningsOfLife();
expect(result).to.be.an('array').that.does.include(42);

// or a simpler form
expect(result).toBe('array').toContainEqual(42);

// the same in assert might be
assert.typeOf(result, 'array', 'Expected the result to be an array');
assert.include(result, 42, 'Expected the result to include 42');

이러한 어설션 스타일은 메서드 체이닝이라는 기법으로 인해 작동합니다. 여기서 expect에 의해 반환된 객체를 다음과 같이 연속적으로 연결할 수 있습니다. 사용할 수 있습니다. to.be, that.does 등 통화의 일부 함수가 없고 호출에만 포함됩니다. 테스트가 더 간단해지면 자동 댓글이 실패했습니다. 특히 expect는 일반적으로 선택적 주석을 지원하지 않습니다. 체이닝은 실패를 명확하게 설명해야 합니다.)

많은 테스트 프레임워크가 Fluent/BDD와 일반 어설션을 모두 지원합니다. Vitest, 예를 들어 차이는 BDD에 접근하며 약간 더 간결한 접근 방식을 사용합니다. 제스트, 반면에 예상만 포함합니다. 메서드를 기본적으로 제공합니다.

여러 파일에서 테스트 그룹화

테스트를 작성할 때는 이미 테스트를 작성하는 대신 암시적 그룹화를 제공하는 경향이 있습니다. 모든 테스트가 하나의 파일에 있는 것보다 할 수 있습니다. 사실 테스트 실행기는 일반적으로 파일이 테스트용이라는 것만 알고 있습니다. (예: vitest)에는 미리 정의된 필터 또는 정규식에 대한 '.test.jsx'와 같은 확장자로 끝나는 프로젝트 내 파일 또는 '.spec.ts' ('.test', '.spec' 및 여러 유효한 확장자 포함)

구성요소 테스트는 테스트 중인 구성요소의 피어 파일에 있는 경향이 있습니다. 와 같이 입력합니다.

<ph type="x-smartling-placeholder">
</ph> 프로젝트의 파일 목록은
  디렉터리에 대한 테스트 결과를 입력합니다.
구성요소 파일 및 관련 테스트 파일

마찬가지로 단위 테스트는 테스트 중인 코드 근처에 배치하는 경향이 있습니다. 엔드 투 엔드 테스트는 각각 자체 파일에 있을 수 있고 통합 테스트는 고유한 폴더에 배치될 수 있습니다 이러한 구조는 복잡한 테스트 사례가 늘어나면 테스트에만 필요한 지원 라이브러리를 제공합니다.

파일 내 테스트 그룹화

이전 예에서 사용한 것처럼 일반적으로 test()로 설정한 테스트를 그룹화하는 suite()입니다. 스위트룸은 일반적으로 관련 테스트를 그룹화하여 구조를 제공하는 데 도움이 됨 또는 목표를 설정할 수 있습니다. test()의 경우 전달된 메서드는 다음을 설명합니다. 테스트 자체의 액션을 제어합니다.

어설션과 마찬가지로 Fluent/BDD에는 그룹화할 수 있습니다. 다음 코드에서 몇 가지 일반적인 예를 비교합니다.

// traditional/TDD
suite('math tests', () => {
  test('handle zero values', () => {
    assert.equal(fibonacci(0), 0);
  });
});

// Fluent/BDD
describe('math tests', () => {
  it('should handle zero values', () => {
    expect(fibonacci(0)).toBe(0);
  });
})

대부분의 프레임워크에서 suitedescribetestdescribe와 마찬가지로 유사하게 동작합니다. expectassert 사용 간의 큰 차이와 달리 it 어설션을 작성해야 합니다.

도구 모음과 테스트를 정렬하는 방식에는 미묘하게 다른 접근 방식을 사용하는 도구도 있습니다. 대상 예를 들어 Node.js의 기본 제공 테스트 실행기는 다음과 같은 test() 호출 중첩을 지원합니다. 테스트 계층 구조를 암시적으로 만듭니다. 하지만 Vitest는 이러한 종류의 스크립트만 suite()를 사용하여 중첩하고 다른 test() 내에서 정의된 test()를 실행하지 않습니다.

어설션과 마찬가지로 그룹화의 정확한 조합은 기술 스택에서 제공하는 메서드는 그다지 중요하지 않습니다. 이 과정에서는 귀하의 비즈니스 전략에 어떻게 적용되는지 선택의 폭을 넓힐 수 있습니다

수명 주기 메서드

테스트를 그룹화하는 이유 중 하나는 파일에 있습니다. 정의할 수 있습니다 대부분의 프레임워크는 네 가지 메서드를 제공합니다.

모든 `test()` 또는 `it()` 모음에 한 번
테스트 실행 전 `before{/5}()` `beforeAll()`
테스트 실행 후 `after{/5}()` `afterAll()`

예를 들어 각 가상 사용자 데이터베이스를 시작하기 전에 테스트하고 나중에 지울 수 있습니다.

suite('user test', () => {
  beforeEach(() => {
    insertFakeUser('bob@example.com', 'hunter2');
  });
  afterEach(() => {
    clearAllUsers();
  });

  test('bob can login', async () => {  });
  test('alice can message bob', async () => {  });
});

이는 테스트를 단순화하는 데 유용할 수 있습니다. 일반적인 설정 및 코드를 해체하는 대신 또한 해체 코드 자체에서 오류가 발생하며 이는 구조적 문제임을 나타낼 수 있습니다. 관련 없는 문제를 일으킬 수 있습니다.

일반 도움말

다음은 이러한 프리미티브에 대해 생각할 때 기억해야 할 몇 가지 팁입니다.

프리미티브는

여기와 다음 몇 페이지에서는 도구와 프리미티브가 Vitest, Jest, Mocha, Web Test Runner 또는 살펴보겠습니다 저희는 일반적인 가이드로 Vitest를 사용해 왔지만, 개발자가 선택한 프레임워크에 추가할 수 있습니다

필요에 따라 어설션을 조합하여 사용

테스트는 기본적으로 오류를 발생시킬 수 있는 코드입니다. 모든 주자들은 test()와 같은 프리미티브로서 고유한 테스트 사례를 설명합니다.

하지만 이 실행기가 assert(), expect(), 어설션 도우미도 제공하는 경우 이 부분은 편의성에 관한 것이므로 살펴봤습니다 other 어설션 라이브러리 또는 구식 if 문을 사용하는 것이 좋습니다.

IDE 설정으로 수명 절약

VSCode와 같은 IDE가 자동 완성 기능에 액세스하고 생산성 향상에 도움이 될 수 있습니다 대상 예를 들어 Chai 어설션의 assert에는 100개가 넘는 메서드가 컨테이너 이미지 생성과 관련된 문서가 있고 편리할 수 있습니다

이는 API 클라이언트 라이브러리를 채우는 일부 테스트 프레임워크에서 테스트 메서드와 함께 전역 네임스페이스를 사용할 수 있습니다. 이것은 미묘한 차이이지만 테스트 라이브러리가 필요한 경우 가져오지 않고 테스트 라이브러리를 사용할 수 있는 경우가 많습니다. 다음과 같이 전역 네임스페이스에 자동으로 추가됩니다.

// some.test.js
test('using test as a global', () => {  });

이 도우미가 자동으로 지원되더라도 도우미를 가져오는 것이 좋습니다. 그러면 IDE가 이러한 메서드를 명확하게 찾을 수 있기 때문입니다. ( React를 빌드할 때 이 문제가 발생한 것을 볼 수 있습니다. 일부 코드베이스에는 React는 전역으로 제공되지만 일부는 그렇지 않으며, 다음을 사용하여 모든 파일에서 가져와야 합니다. React.)

// some.test.js
import { test } from 'vitest';
test('using test as an import', () => {  });