๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐Ÿญ front-end์—์„œ ์ถ”๊ฐ€์ ์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋…์„ฑ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด๊ฐ€๋Š” ๊ณผ์ •์„ ์ •๋ฆฌ

jest-plugin-contextโ€‹

describe๋Š” ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์ด๋ผ๋ฉด context๋Š” ๋œป์ฒ˜๋Ÿผ ๋ฌธ๋งฅ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒƒ context๋Š” jest์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ๊ฑด ์•„๋‹ˆ๊ณ , ๋ฃจ๋น„์—์„œ ์‚ฌ์šฉํ•˜๋Š” BDD ํ˜•์‹์˜ TDD RSpec ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์šฉ๋„์ž…๋‹ˆ๋‹ค.

RSpec์—์„œ๋Š” describe๋Š” ํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ์„ธํŠธ์„ ๋ž˜ํ•‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๊ณ , context ๋™์ผํ•œ ์ƒํƒœ์—์„œ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ ์„ธํŠธ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

In RSpec, describe it used to wrap a set of tests against one functionality while context is to wrap a set of tests against one functionality under the same state.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋ฐ”์ผ์ธ ๊ฒฝ์šฐ ๋ฒ„ํŠผ์„ ๋ณด์—ฌ์ฃผ๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋Š” ์ธ ๋‘๊ฐ€์ง€์˜ ๋ฌธ๋งฅ์ด ์กด์žฌํ•œ ๊ฒฝ์šฐ ์•„๋ž˜์™€ ๊ฐ™์ด context๋ฅผ ์‚ฌ์šฉํ•ด ๋‘˜์„ ๋‚˜๋ˆ„์–ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

describe('Some Component', () => {
const renderComponent = () => render((
<Test />
));

context('๋ชจ๋ฐ”์ผ์ธ ๊ฒฝ์šฐ', () => {
it('๋ฒ„ํŠผ์ด ๋ณด์—ฌ์•ผ ํ•œ๋‹ค', () => {
const { container } = renderComponent();

// ...
});
});

context('๋ชจ๋ฐ”์ผ์ด ์•„๋‹Œ ๊ฒฝ์šฐ', () => {
it('๋ฒ„ํŠผ์€ ๋ณด์ด์ง€ ์•Š์•„์•ผ๋งŒ ํ•œ๋‹ค', () => {
const { container } = renderComponent();

// ...
});
});
});

์ด๊ฑธ ํ’€์–ด์„œ ์ฝ์–ด๋ณด๋ฉด ๋‘ ๊ฐœ์˜ ๋ฌธ๋งฅ์œผ๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์–ด์š”.

  • ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ชจ๋ฐ”์ผ์ธ ๊ฒฝ์šฐ ๋ฒ„ํŠผ์ด ๋ณด์—ฌ์•ผ ํ•œ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ชจ๋ฐ”์ผ์ด ์•„๋‹Œ ๋ฒ„ํŠผ์ด ๋ณด์ด์ง€ ์•Š์•„์•ผ๋งŒ ํ•œ๋‹ค.

์˜์–ด๋กœ๋Š” ๋ณดํ†ต context์—์„œ with, without, has, is ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ €๋Š” ~ํ•œ ๊ฒฝ์šฐ, ~์ผ ๋•Œ ์ด๋Ÿฐ์‹์œผ๋กœ ์ž‘์„ฑํ•˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค. (example)

๋งŒ์•ฝ context๋„ describe์œผ๋กœ ์ž‘์„ฑํ–ˆ์œผ๋ฉด ์•Œ์•„๋ณด๊ธฐ์— ํ–‡๊ฐˆ๋ฆผ์ด ์žˆ์—ˆ์„ํ…๋ฐ context์œผ๋กœ ๋ฌธ๋งฅ์„ ๋‚˜๋ˆ„์–ด์ฃผ๋‹ˆ๊นŒ ํ›จ์”ฌ ๋” ํ…Œ์ŠคํŠธ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

given2โ€‹

์ด ๊ฒฝ์šฐ์—๋„ ๊ฒฐ๊ตญ ํ…Œ์ŠคํŠธ ๊ฐ€๋…์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ข€ ๋” ์„ ์–ธ์ ์ด๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„ ์˜ˆ์‹œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋งŒ์•ฝ์— ๋ชจ๋ฐ”์ผ ์œ ๋ฌด๋ฅผ ํŒ๋‹จํ•˜๊ธฐ ์œ„ํ•ด์„œ ์–ด๋–ค ๊ฐ’์„ ๋„˜๊ฒจ์ค˜์•ผํ•œ๋‹ค๋ฉด ๋ณดํ†ต

const renderComponent = (isMobile: boolean) => render((
<Test isMobile={isMobile} />
));

const { container } = renderComponent(true);

์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉ๋ ๊บผ์—์š”.
์ด๋•Œ ํ•จ์ˆ˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ฃผ๋Š”๊ฒŒ ์ด ํ…Œ์ŠคํŠธ๋ฅผ ์ฝ๊ธฐ ์‰ฝ๋‚˜์š”? renderComponent ๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋ผ๊ฐ€์„œ isMobile์„ ๋„˜๊ฒจ์ฃผ๊ณ  ์ด๊ฑธ๋กœ ํŒ๋‹จํ•˜๋Š”๊ตฌ๋‚˜๋ผ๋Š” ๊ฒƒ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ์ˆ˜๊ฐ€ ์žˆ์–ด์š”.

๊ทธ๋Ÿฌ๋ฉด given2๋ฅผ ์‚ฌ์šฉํ•ด๋ณผ๊ป˜์š”.

describe('Some Component', () => {
const renderComponent = () => render((
<Test isMobile={given.isMobile} />
));

context('๋ชจ๋ฐ”์ผ์ธ ๊ฒฝ์šฐ', () => {
given('isMobile', () => true);

it('๋ฒ„ํŠผ์ด ๋ณด์—ฌ์•ผ ํ•œ๋‹ค', () => {
const { container } = renderComponent();

// ...
});
});

context('๋ชจ๋ฐ”์ผ์ด ์•„๋‹Œ ๊ฒฝ์šฐ', () => {
given('isMobile', () => false);

it('๋ฒ„ํŠผ์€ ๋ณด์ด์ง€ ์•Š์•„์•ผ๋งŒ ํ•œ๋‹ค', () => {
const { container } = renderComponent();

// ...
});
});
});

์–ด๋–ค๊ฐ€์š”?
์œ„์—์„œ ์•„๋ž˜๋กœ ๋ชจ๋ฐ”์ผ์ธ ๊ฒฝ์šฐ isMobile์ด true์ธ ๊ฒฝ์šฐ ๋ฒ„ํŠผ์ด ๋ณด์ด๊ฒ ๊ตฌ๋‚˜๋ผ๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ฝํžˆ์ง€ ์•Š๋‚˜์š”?
given2์˜ ์žฅ์ ์€ ํ•ด๋‹น ๊ฐ’์ด ์‚ฌ์šฉ๋  ๋•Œ๊นŒ์ง€ ์ง€์—ฐ ํ‰๊ฐ€๋ฅผ ํ•˜๊ฒŒ๋˜์–ด์„œ ์ด๋Ÿฐ ํ˜•ํƒœ๋กœ ์ž‘์„ฑ์ด ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Note that given variables is lazy-evaluated: data in the variables are not calculated until they are accessed for the first time.