Jest

ํ•™์Šต ํ‚ค์›Œ๋“œ

  • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ •์˜ ํ•˜๋Š” ๋ฐฉ๋ฒ•

    • BDD

  • Jest

    • ์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•

    • ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

    • Describe - Context - It ํŒจํ„ด

๐Ÿค– ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ •์˜ ํ•˜๋Š” ๋ฐฉ๋ฒ•

1. test ํ•จ์ˆ˜๋กœ ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋‚˜์—ดํ•˜๋Š” ๋ฐฉ์‹

test('add', () => {
 expect(add(1, 2)).toBe(3);
});

2. BDD ์Šคํƒ€์ผ๋กœ ์ฃผ์ฒด-ํ–‰์œ„ ์ค‘์‹ฌ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์กฐ์งํ™”ํ•˜๋Š” ๋ฐฉ์‹

describe('add', () => { // ์ฃผ์ฒด : add ํ•จ์ˆ˜ 
  it('returns sum of two numbers', () => { // ํ–‰์œ„ : add ํ•จ์ˆ˜๊ฐ€ ๋‘ ์ˆซ์ž๋ฅผ ๋”ํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    expect(add(1, 2)).toBe(3);
  });
});

๐Ÿค” BDD ์Šคํƒ€์ผ์€ ๋ญ˜๊นŒ?

  • BDD(Behavior-driven development)

  • ์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก 

  • ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์— ์ง‘์ค‘ํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๊ฐœ๋ฐœํ•œ๋‹ค๋Š” ๊ฒƒ

  • Facebook์ด ๊ฐœ๋ฐœํ•˜์—ฌ ์˜คํ”ˆ ์†Œ์Šค๋กœ ๊ณต๊ฐœํ•œ JavaScript ํ…Œ์ŠคํŒ… ํ”„๋ ˆ์ž„์›Œํฌ

  • ์„ค์ •์ด ๊ฑฐ์˜ ํ•„์š” ์—†๋Š” ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ

๐Ÿ› ๏ธ Jest ์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•

1. Jest ์„ค์น˜

# 1.Jest ์„ค์น˜
npm i -D jest @types/jest @swc/core @swc/jest \
  jest-environment-jsdom \
  @testing-library/react @testing-library/jest-dom@5.16.4

2. Jest์—์„œ TypeScript ์‚ฌ์šฉํ•˜๋„๋ก jest.config.js ํŒŒ์ผ ์ž‘์„ฑ

module.exports = {
 testEnvironment: 'jsdom',
 setupFilesAfterEnv: [
  '@testing-library/jest-dom/extend-expect',
 ],
 transform: {
  '^.+\\.(t|j)sx?$': ['@swc/jest', {
   jsc: {
    parser: {
     syntax: 'typescript', 
     jsx: true,
     decorators: true,
    },
    transform: { 
     react: {
      runtime: 'automatic',
     },
    },
   },
  }],
 },
};

3. Jest ์‹คํ–‰

# jest ์‹คํ–‰
npx jest

#jest ์ž๋™ ์‹คํ–‰
npx jest --watchAll

โš™๏ธ Jest ๊ธฐ๋ณธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

import { sum } from './sum';

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
  1. test ํ•จ์ˆ˜๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ ์ด ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋–ค ๊ฒƒ์„ ์„ค๋ช…ํ•˜๋Š”์ง€ ์ œ๋ชฉ์„ ์ž…๋ ฅํ•œ๋‹ค.

  2. ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์ด ์•ˆ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

  3. ์ฝœ๋ฐฑํ•จ์ˆ˜ ์•ˆ์— ์žˆ๋Š” expect๋Š” return๊ฐ’์„ ๊ฐ€์ง€๋Š” ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  4. expect๋œ ๊ฐ์ฒด๋ฅผ toBe๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ค ๊ฐ’์ด ๋‚˜์˜ฌ์ง€ ์ธ์ž๋กœ ๋‹ด๋Š”๋‹ค.

test ๋Œ€์‹  it์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. Also under the alias

๐ŸŽฏ Matchers๋กœ ๋‹ค์–‘ํ•œ ๊ฒฐ๊ณผ ์˜ˆ์ธกํ•˜๊ธฐ

.toBe

toBe์˜ ๊ฒฝ์šฐ Object.is๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์„œ ๋น„๊ตํ•˜๋Š” ๋‘ ๊ฐ์ฒด๋ฅผ ๋น„๊ตํ–ˆ์„ ๋•Œ ===์ด ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋กœ ์ดํ•ดํ•˜๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

.toEqual

test('object assignment', () => {
  const data = {one: 1};
  data['two'] = 2;
  expect(data).toEqual({one: 1, two: 2});
});

toEqual์€ ๋ฐฐ์—ด ๋˜๋Š” ๊ฐ์ฒด์˜ ๊ฐ’(์ฃผ์†Œ ๋ง๊ณ !)์ด ๊ฐ™์€์ง€ ํ™•์ธํ•œ๋‹ค.

์ด์™ธ์—๋„ ๋‹ค์–‘ํ•œ Matchers๋“ค์ด ์กด์žฌํ•œ๋‹ค.

๐Ÿงฉ Describe-Context-It (Describe-It) ํŒจํ„ด

describe ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ž‘์€ ๋‹จ์œ„์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๊ทธ๋ฃนํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿค” ๊ทธ๋ฃนํ™” ํ•œ๋‹ค๋Š”๊ฒŒ ๋ฌด์Šจ ์˜๋ฏธ ์ผ๊นŒ?

ํŠน์ • component์— ์†ํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ผ๋ฉด describe ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋“ค์„ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์ด๋ ‡๊ฒŒ ๊ทธ๋ฃนํ™”๋ฅผ ํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด ๋‚˜์ค‘์— ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธ์‹œ ๋” ๊ฐ€์‹œ์ ์œผ๋กœ ๋ณด๊ธฐ ํŽธํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋“ค์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Jest๋ฅผ ์ด์šฉํ•œ ๊ฐ„๋‹จํ•œ TDD ์˜ˆ์ œ

๐Ÿ“„ ํŒŒ์ผ๋ช… : ํŒŒ์ผ์ด๋ฆ„.test.ํ™•์žฅ์ž

  • sample.test.ts

  • sample.spec.ts (์ฃผ๋กœ BDD ์Šคํƒ€์ผ๋กœ ์‚ฌ์šฉ ์‹œ)

๐Ÿค– test ํ•จ์ˆ˜๋กœ ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋‚˜์—ดํ•˜๋Š” ๋ฐฉ์‹

  • ์‹คํŒจ ์ผ€์ด์Šค๋กœ ์šฐ์„  add ํ•จ์ˆ˜ ์ž‘์„ฑ

function add(x: number, y: number): number {
 return 0;
}

test('add', () => {
 expect(add(1, 2)).toBe(3);
});
  • ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผ ๋  ์ˆ˜ ์žˆ๋„๋ก add ํ•จ์ˆ˜ ์ˆ˜์ •

function add(x: number, y: number): number {
 return 3;
}

test('add', () => {
 expect(add(1, 2)).toBe(3);
});
  • ๋ฐ˜๋ณต์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธ ํ•˜๋ฉด์„œ ์ค‘๋ณต์ œ๊ฑฐ

function add(x: number, y: number): number {
 // return 0
 // return 3
 // return 1 + 2; // ์˜๋„๋ฅผ ๋‚˜ํƒ€๋ƒ„์œผ๋กœ์จ ์ค‘๋ณต ์ œ๊ฑฐ
 return x + y;
}

test('add', () => {
 expect(add(1, 2)).toBe(3);
});

๐Ÿค– BDD ์Šคํƒ€์ผ๋กœ ์ฃผ์ฒด-ํ–‰์œ„ ์ค‘์‹ฌ์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์กฐ์งํ™”ํ•˜๋Š” ๋ฐฉ์‹

  • BDD ์Šคํƒ€์ผ๋กœ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ๊ณผ ํ–‰์œ„๋ฅผ ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚ด์ž.

function add(x: number, y: number): number {
 return x + y;
}

test('add ํ…Œ์ŠคํŠธ', () => {
 expect(add(1, 2)).toBe(3);
});

describe('add', () => { // ๋Œ€์ƒ 
 it('returns sum of two numbers', () => { // ํ–‰์œ„ 
  expect(add(1, 2)).toBe(3);
 });
});

// ์ด์ •๋Š” BDD๋ณด๋‹ค๋Š” ํ•จ์ˆ˜๋กœ ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ ์ง„ํ–‰

๐Ÿค” ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๊ณ ๋ ค ๋˜์–ด์•ผ ํ•œ๋‹ค๋ฉด? โ‡’ Describe-Context-It ํŒจํ„ด

function add(...number: number[]): number {
 // Return number[0] + (number[1] || 0);
 // return (number[0] ?? 0) + (number[1] ?? 0) + (number[2] ?? 0); //์ฝ”๋“œ์˜ ๋ฐ˜๋ณต์ด ๋ณด์—ฌ์ง

 // return (number[number.length - 3] ?? 0) + (number[number.length - 2] ?? 0) + (number[number.length - 1] ?? 0);

 if (number.length === 0) {
  return 0;
 }

 // If (number.length === 1) {
 //  return number[0];
 // }

 // If (number.length === 2) {
 //  return number[0] + number[1];
 // }

 // If (number.length === 3) {
 //  return number[0] + number[1] + number[2];
 // }

 // if (number.length >= 2) {
 //  return add(number[0] + number[1]) + number[2];
 // }

 // if (number.length >= 2) {
 //  return add(...number.slice(0, number.length - 1)) + number[number.length - 1];
 // }

 // return add(...number.slice(0, number.length - 1)) + number[number.length - 1];

 return number.reduce((acc, current) => acc + current);
}

const context = describe;

test('add ํ…Œ์ŠคํŠธ', () => {
 expect(add(1, 2)).toBe(3);
});

describe('add', () => {
 context('with no argument', () => {
  it('returns zero', () => {
   expect(add()).toBe(0);
  });
 });

 context('with only one number', () => {
  it('returns the same numbers', () => {
   expect(add(2)).toBe(2);
  });
 });

 context('with two numbers', () => {
  it('returns sum of two numbers', () => {
   expect(add(1, 2)).toBe(3);
  });
 });
  // ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋“ค์ด ์ถ”๊ฐ€ ๋  ๋•Œ ๋งˆ๋‹ค add ํ•จ์ˆ˜ ๋กœ์ง ๋ณ€๊ฒฝ 
 context('with three numbers', () => {
  it('returns sum of three numbers', () => {
   expect(add(1, 2, 3)).toBe(6);
  });
 });

 context('with ten numbers', () => {
  it('returns sum of ten numbers', () => {
   expect(add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)).toBe(55);
  });
 });
});

๐Ÿ”— ์ฐธ๊ณ 

Last updated