dev.toPatricia Nicole 이 작성한 Basics of Javascript Test Driven Development (TDD) with Jest 번역 자료입니다. 번역에 문제가 있다면 댓글 달아주시구요. 원문을 보시기를 추천드립니다

[JS#4 WIL 🤔 포스트]

테스트 주도 개발(TDD)의 주요 아이디어는 테스트 중인 코드를 작성하기 전에 자동화된 테스트를 작성하여 코드 작업을 시작하는 것입니다. Javascript에는 Jasmine , Jest , TapeMocha 등 많은 테스트 실행(test-running) 시스템이 있습니다. 그들은 특별한 기능을 가지고 있지만 구문(syntax)은 매우 유사합니다. 선택한 프레임워크가 문제가 되어서는 안 됩니다.

테스트 작성은 구문(syntax)보다는 TDD 철학에 더 가깝습니다.

그래서 Jest를 사용하여 개념을 내재화하려고 시도했습니다. 연습의 주요 목표는 테스트의 이유와 내용을 아는 것입니다.

뛰어들기 전에 훌륭한 강연인 Magic of Testing에서 제가 메모한 몇 가지를 소개합니다.

  1. 대부분의 개발자가 테스트를 싫어하는 이유는 무엇입니까? 느리고 깨지기 쉽고 비용이 많이 들기 때문입니다(시간).
  2. 일부 테스트를 삭제하는 것은 완벽하게 유효합니다.
  3. 단위 테스트 목표: 철저하고 (우리는 테스트 중인 단일 오브젝트가 올바르게 작동하고 있음을 논리적이고 완전하게 증명하기를 원합니다.), 안정적이어야 하며(구현 세부 사항이 변경될 때마다 테스트를 중단하고 싶지 않습니다 😟), 빠르고 적어야 합니다(가장 간결한 표현을 위한 테스트 작성 [mmmmm 🤔]).
  4. 프라이빗 메서드를 테스트하지 마십시오. 그러나 개발 중에 비용을 절약할 수 있다면 이 규칙을 어기십시오.
  5. 모의(mock)는 테스트 더블이며 실제 앱에서 일부 오브젝트의 역할을 합니다. 테스트 더블이 API와 동기화 상태를 유지하는지 확인합니다.
  6. 협력자들이 옳은 일을 할 것이라고 신뢰하십시오. 단순함을 주장하십시오.
  7. 테스트를 더 잘하려면 시간과 연습이 필요합니다.

테스트 중인 오브젝트에는 세 가지 메시지 출처가 있습니다 :

📌 들어오는(Incoming) - 외부에서 오브젝트로의 메시지

📌 자신(Self) - 테스트 대상이 자신에게 보내는 메시지

📌 나가는(Outgoing) - 오브젝트가 외부로 보낸 메시지.

메시지에는 쿼리(query)명령(command) 두 가지 유형이 있습니다 . 쿼리는 무언가를 반환하거나 아무 것도 변경하지 않습니다. 명령 유형은 아무것도 반환하지 않고 무언가를 변경합니다.

📌 테스트 규칙 그리드

아래의 테스트 결과 그리드는 각 메시지 유형을 단위 테스트할 수 있는 방법을 보여줍니다.

메시지 유형 쿼리 명령
들어오는(Incoming) Assert result 들어오는 쿼리 메시지가 반환하는 내용에 대해 assertion을 만들어 테스트합니다. 구현(implementation)이 아닌 인터페이스를 테스트하십시오. 직접적인 공개 부작용에 대한 assertions을 만들어 들어오는 명령 메시지를 테스트합니다. DRY 밖으로. 들어오는 메시지의 수신자는 직접적인 공개 부작용(side effects)의 결과의 asserting에 전적인 책임이 있습니다.
자신에게 보냄 (Sent to Self) 무시: 프라이빗 메서드를 테스트하지 마십시오. 무시: 프라이빗 메서드를 테스트하지 마십시오.
나가는 (Outgoing) 무시. 들어오는 쿼리의 수신자는 상태와 관련된 assertion만 책임집니다. 메시지에 눈에 보이는 부작용이 없는 경우 보낸 사람은 메시지를 테스트하지 않아야 합니다. 모의(mock)를 사용하여 나가는 명령 메시지를 보낼 것으로 예상(Expect)

📌 TDD 의 장점

  1. 새로운 기능을 추가하거나 기존 기능을 수정할 때 발생할 수 있는 버그를 줄입니다.
  2. 코드의 특정 부분에 영향을 줄 수 있는 다른 프로그래머의 변경에 대한 안전망 구축
  3. 코드가 새 변경 사항과 계속 작동하도록 하여 변경 비용을 줄입니다.
  4. 테스터와 개발자가 수동(멍키) 검사의 필요성을 줄입니다.
  5. 코드에 대한 신뢰도 향상
  6. 리팩터링 중에 변경 사항을 깨는 것에 대한 두려움을 줄입니다.

📌 Jest 시작하기

Jest는 단순성에 중점을 둔 자바스크립트 테스트 프레임워크이지만 여전히 자바스크립트 코드 베이스의 정확성을 보장합니다. 고유한 글로벌 상태와 병렬로 테스트를 안정적으로 실행하는 빠르고 안전함을 자랑합니다. 작업을 빠르게 하기 위해 Jest는 이전에 실패한 테스트를 먼저 실행하고 테스트 파일에 걸리는 시간에 따라 실행을 재구성(re-organizes)합니다.

또한 Jest는 문서화되어 있으며 구성이 거의 필요하지 않습니다. 실제로 자바스크립트 테스트를 즐겁게 만듭니다. yarn 또는 npm을 사용하여 설치할 수 있습니다.

📌 세 가지 TDD 모드

  1. 명백한 구현(Obvious implementation). 테스트할 메서드를 구현하는 방법을 알고 있기 때문에 구현과 함께 테스트를 작성합니다.
  2. 당신이 그것을 만들 때까지 그것을 속이십시오(Fake it til you make it). 문제와 솔루션을 알고 있지만 코드를 작성하는 방법이 즉시 명확하지 않은 경우 “할 때까지 가짜”라는 트릭을 사용할 수 있습니다.
  3. 삼각측량(Triangulation). 이것은 TDD를 수행하는 가장 보수적인 방법입니다. 해법조차 모른다면, 적-녹, 적-녹 루프, 무슨 수를 써서라도 녹색에 도달하게 됩니다.

📌 Jest Matchers 사용하기

공통 매처 (Common Matchers)
test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

위의 코드 조각은 “expectation(기대)” 오브젝트를 반환합니다. toBe(3) 부분은 매처입니다. Jest가 실행되면 모든 실패한 매처를 추적하여 멋진 오류 메시지를 인쇄할 수 있습니다. toBe 매처는 Object.is를 사용하여 동등성을 테스트합니다.

진실성 (Truthiness)

단위 테스트에서 undefined, null, false 특수 값도 확인해야 할 수 있습니다. Jest에는 개발자가 무엇을 기대해야 하는지 명시적으로 알려주는 헬퍼가 포함되어 있습니다. 그런 다음 코드가 수행하는 작업과 가장 정확하게 일치하는 매처를 사용하는 것이 좋습니다.

  • toBeNullnull만 일치합니다.
  • toBeUndefinedundefined와만 일치합니다.
  • toBeDefinedtoBeUndefined의 반대입니다.
  • toBeTruthyif 문이 true로 취급하는 모든 것과 일치합니다.
  • toBeFalsyif 문이 false로 취급하는 모든 것과 일치합니다.
Numbers

toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual과 같은 숫자를 비교하기 위한 Jest 매처도 있습니다. 부동 소수점 숫자의 경우 toBeCloseTo와 같은 동등 일치가 있습니다.

Strings

toMatch를 사용하여 정규 표현식에 대해 문자열을 확인할 수 있습니다.

배열과 이터러블

toContain을 사용하여 특정 항목이 배열이나 반복 가능에서 찾을 수 있는지 확인할 수 있습니다.

예외 (Exceptions)

toThrow는 특정 함수에서 특정 오류가 발생하는지 확인하는 데 사용할 수 있습니다. toThrow 예외가 작동하려면 검사 중인 함수를 래핑 함수 내에서 호출해야 합니다.

비동기 코드 테스트, 즉 콜백 및 약속에 사용되는 고급 Jest 매처도 있습니다.

📌 Jest 테스트 연습

Jest를 사용하여 자바스크립트 단위 테스트를 작성하는 것은 이번이 처음입니다. 😄 너무 새롭기 때문에 연습이 필요했습니다. 아래 방법 중 일부에 대한 테스트 의 명백한 구현(Obvious implementation)삼각 측량(Triangulation) 모드를 사용해 보았습니다 . 메소드의 전체 구현 및 해당 테스트는 Jest practice github 저장소 에서 찾을 수 있습니다 .

  • capitalize(string) 문자열을 받아 첫 번째 문자가 대문자로 된 문자열을 반환합니다.

capitalize.test.js

const capitalize = require('../capitalize');

test('should capitalize lowercase string correctly', () => {
  expect(capitalize("capitalize")).toBe("Capitalize");
});

test("should return '' for strings with length 0", () => {
    expect(capitalize("")).toBe("");
});

// other tests here
  • reverseString(string)문자열을 가져와 반대로 반환합니다. 다음은 일반적인 시나리오에 대해 작성한 테스트 스니펫입니다.

reverse-string-test.js

const reverseString = require('../reverse-string');

test('should reverse normal strings', () => {
  expect(reverseString("reverse")).toBe("esrever");
});

//other tests here
  • calculator기본적인 작업을 포함 오브젝트 : add, subtract, dividemultiply. 아래의 다음 테스트 스니펫은 제수가 0인 경우 메서드에서 오류 메시지가 발생함을 보여줍니다.

calculator.test.js

const calculator = require("../calculator");

//other tests here

test("should throw an error if divisor is 0", () => {
    expect(() => calculator.divide(20, 0)).toThrow("cannot divide by 0");
});
  • caesar cipher. 시저 암호는 텍스트의 각 문자가 알파벳 아래로 특정 위치로 이동하는 대체 암호입니다. 자세한 정보는 여기에서 읽을 수 있습니다 .

caesar-cipher.test.js

const caesar = require("../caesar-cipher");

//other tests here

test('wraps', function() {
    expect(caesar('Z', 1)).toEqual('A');
});

test('works with large shift factors', function() {
    expect(caesar('Hello, World!', 75)).toEqual('Ebiil, Tloia!');
});

test('works with large negative shift factors', function() {
    expect(caesar('Hello, World!', -29)).toEqual('Ebiil, Tloia!');
});
  • 배열 분석. 이 기능은 숫자의 배열을 다음과 같은 특성을 가진 오브젝트를 반환 : average, min, maxlength.

analyze.test.js

const analyze = require("../analyze");
const object = analyze([1,8,3,4,2,6]);

test("should return correct average", () => {
    expect(object.average).toEqual(4);
});

test("should return correct min", () => {
    expect(object.min).toEqual(1);
});

// other tests here

테스트의 전체 그림을 보려면 여기 에 포함된 스니펫의 github 리포지토리를 확인하세요 .

위의 개념과 요점은 Jest를 사용하는 TDD의 가장 기본입니다. 공통매처, 모의(mocking), 코드의 비동기 부분 테스트 등 배울 것이 많습니다. 나는 아직 그것들을 배우는 중이고 그것은 또 다른 개발 포스트에 대한 것입니다 😆.

계속되는 배움을 응원합니다! 🍷

[참고문헌]

  1. TDD의 중요성
  2. TOP 테스트 기본 사항
  3. Jest 시작하기 문서
  4. Jest 공식 문서