๋จ์ผ it
์ ์ฌ๋ฌ ๊ธฐ๋์น๊ฐ ์๋ ๊ฒฝ์ฐ ํ์ฌ ์ฝ๋์ ์ค ๋ฒํธ์ ์คํจ๋ฅผ ์ํธ ์ฐธ์กฐํ์ง ์๊ณ ์ค์ ๋ก ์คํจํ ๊ธฐ๋์น๋ฅผ ํ์
ํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค.
test('api works', () => {
expect(api()).toEqual([]) // api without magic provides no items
expect(api(0)).toEqual([]) // api with zero magic also provides no items
expect(api(true)).toEqual([1,2,3]) // api with magic enabled provides all items
})
์ด๋ค ๊ธฐ๋๊ฐ ์คํจํ์ต๋๊น? ์ฒซ ๋ฒ์งธ ๋๋ ๋ ๋ฒ์งธ?
์คํ ์ถ์ ์ ๋งจ ์์์ ์ค ๋ฒํธ๋ฅผ ์ฐพ์ ๋ค์ ๋งคํํ์ง ์๊ณ ๋ ์ด๋ค ๊ธฐ๋๊ฐ ์คํจํ๊ณ ๊ธฐ๋ ์ถ๋ ฅ์ด ์ค์ ๋ก ์ธ๊ฐ์ ๊ด์ ์์ ์๋ฏธํ๋์ง ์ฆ์ ๋ช ํํ๊ฒ ํด์ฃผ๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ปจํ ์คํธ๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค. ์ํธ.
์๋์์ tape
์ ํด๋นํ๋ ํญ๋ชฉ์ ๋น๊ตํ์ญ์์ค. ์ฒซ ๋ฒ์งธ ์ด์ค์
์คํจ ํ ํ
์ดํ๊ฐ ๋ณต๊ตฌ๋์ง ์๋๋ค๋ ์ ์ ๋ฌด์ํ์ญ์์ค. tape
๋ ๊ฐ ์์ ์คํจ ์์ ์ฌ๋์ด ์ฝ์ ์ ์๋ ๋ฉ์์ง๋ฅผ ์ธ์ํ์ฌ ํ
์คํธ ํ์ผ๋ก ๋์๊ฐ์ง ์๊ณ ๋ ์ด๋ค ํ
์คํธ๊ฐ ์คํจํ๋์ง ์ ํํ ์ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๋ํ ์ฌ๋์ด ์ฝ์ ์ ์๋ ๋ ธ์ด์ฆ๋ฅผ ํ ์คํธ ์์ค์ ์ค ๋์ผ๋ก ๋ฐ์ด๋ด์ด ์ด์จ๋ ์ฃผ์์ ์์ฑํ ์ ์์ต๋๋ค.
test('api works', t => {
t.deepEquals(api(), [], 'api without magic provides no items')
t.deepEquals(api(0), [], 'api with zero magic also provides no items')
t.deepEquals(api(true), [1,2,3], 'api with magic enabled provides all items')
})
jest
์ค๋ฅ์ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ ๋ณด๋ฅผ ์ฒจ๋ถํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ ๋ถํ์ํ๊ฒ ์ฅํฉํ IMO์ธ ์ถ๊ฐ it
์ ๋ชจ๋ ๊ฒ์ ๋ํํ๋ ๊ฒ์
๋๋ค.
describe('api works', () => {
test('api without magic provides no items', () => {
expect(api()).toEqual([])
})
test('api with zero magic also provides no items', () => {
expect(api(0)).toEqual([])
})
test('api with magic enabled provides all items', () => {
expect(api(true)).toEqual([1,2,3])
})
})
์ด์์ ์ผ๋ก๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ปจํ
์คํธ๋ฅผ expect
๋์ ์ด๋ป๊ฒ๋ ์ฒจ๋ถํ ์ ์์ต๋๋ค.
์
์ด์ค์ ๋ฐฉ๋ฒ์ ๋ํ ์ถ๊ฐ ์ ํ์ ๋งค๊ฐ๋ณ์๋ก์์ ์ปจํ ์คํธ ๋ฉ์์ง:
test('api works', () => {
expect(api()).toEqual([], 'api without magic provides no items')
expect(api(0)).toEqual([], 'api with zero magic provides no items')
expect(api(true)).toEqual([1,2,3], 'api with magic enabled provides all items')
})
๋๋ ์ฐ๊ฒฐ๋ .because
๋๋ .why
๋๋ .comment
๋๋ .t
๋๋ ๊ธฐํ์ ๊ฐ์ ์ปจํ
์คํธ ๋ฉ์์ง:
test('api works', () => {
expect(api()).toEqual([]).because('api without magic provides no items')
expect(api(0)).toEqual([]).because('api with zero magic provides no items')
expect(api(true)).toEqual([1,2,3]).because('api with magic enabled provides all items')
})
๋๋ jest๊ฐ ๋จ์ํ ํ์ผ์ ์ฝ๊ณ ๊ธฐ๋ ์์ฒด๊ฐ ์๋ ์ค์ ์์ค ์ฝ๋ ๋ผ์ธ์ ์ธ์ํ ์ ์๋ค๋ฉด ๋ ์ข์ ๊ฒ์ ๋๋ค.
์ผ! ๊ทธ๋์ ์ฐ๋ฆฌ๋ ์ค์ ๋ก Jasmine์ ์ด๊ฒ์ ๊ฐ์ง๊ณ ์์์ง๋ง FB์์ ์์ฒ ๊ฐ์ ํ ์คํธ ํ์ผ์ด ์์ง๋ง ์๋ฌด๋ ๊ทธ๊ฒ์ ์ฌ์ฉํ์ง ์๋๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ทธ๋์ ์ง๊ธ ์ฐ๋ฆฌ๋ ๋๋ต์ ์ธ ์ ๋ณด์ ์์์ผ๋ก ์ด์ด์ง๋ ์คํ ์ถ์ ์ด ํฌํจ๋ ๋ฉ์ง ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ธ์ํ๊ณ ์์ต๋๋ค(์คํฌ๋ฆฐ์ท์์์ ๊ฐ์ด). ๋๋ ์ฐ๋ฆฌ๊ฐ ๋์ง๋ ์ค์ ์ธ์ํ ์ ์๋ค๋ ๋ฐ ๋์ํ์ง๋ง ์ข ์ข ์ฃผ์ฅ์ด ์ฌ๋ฌ ์ค๋ก ๊ธธ์ด์ง๋๋ค.
expect(a).toEqual({
โฆ
});
๊ทธ๋์ ์ด๊ฒ์ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ์ข์ ๋ณด์ด์ง ์์ ๊ฒ์ด๊ณ ํ์๋ฅผ ์ฌ์ฉํ์ฌ JS๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๊ณ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ถ์ถํ๊ฑฐ๋(๊ธด ์ค์ ์ถ์) ๋ณด๊ธฐ ์ข๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ด์ ์ ์ฌํ ๊ฒ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ํ์ฌ๋ก์๋ ์ถฉ๋ถํ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์๋ค๊ณ ์๊ฐํ์ง๋ง ์ฌ๊ณ ํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค. ๊ทธ๋ค์ง ๋ณต์กํ์ง ์์ง๋ง ๋ฌธ์ ๋ฅผ ๋ ๋นจ๋ฆฌ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๋ ์ปจํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
์ฐ๋ฆฌ๋ ์ค์ ๋ก Jasmine์ ์ด๊ฒ์ ๊ฐ์ง๊ณ ์์์ง๋ง FB์์ ์์ฒ ๊ฐ์ ํ ์คํธ ํ์ผ์ด ์์ง๋ง ์๋ฌด๋ ๊ทธ๊ฒ์ ์ฌ์ฉํ์ง ์๋๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค.
@cpojer ๊ทธ๋์ ํจํด์ it
์์ ๊ฐ ์ฃผ์ฅ์ ๋ํํ๋ ๊ฒ์
๋๊น? ๋ฐ/๋๋ ํ ๋ฒํธ๋ฅผ ์ ๋ขฐํฉ๋๊น?
์ด ํจํด์ด ๋ ์ข๊ฑฐ๋ ๋์๊ธฐ ๋๋ฌธ์ ๋ ์ฑํ๋์์ง๋ง ๊ธฐ์กด ํ ์คํธ์์ ์ผ๊ด์ฑ์ ์ํด ๋ ๋ง์ด ์ฑํ๋์์ ์ ์์ต๋๊น? ๋๋ ๊ธฐ๋ฅ์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด์ญ๋๊น? ์ด๊ฒ์ด ์์ค๋ฏผ์ ์๋์ง ๋ชฐ๋์ต๋๋ค.
๋๋ ์ฐ๋ฆฌ๊ฐ ๋์ง๋ ์ค์ ์ธ์ํ ์ ์๋ค๋ ๋ฐ ๋์ํ์ง๋ง ์ข ์ข ์ฃผ์ฅ์ด ์ฌ๋ฌ ์ค๋ก ๊ธธ์ด์ง๋๋ค.
ํ ์ค๋ก ๋ฆฌํฉํ ๋งํ๋ฉด ์ด์ค์ ์ ๋ ๋ง์ ์๋ฏธ ์ ๋ณด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๊น? ์๋ง๋?
const adminUser = {
โฆ
}
expect(a).toEqual(adminUser);
๊ฐ์ธ์ ์ผ๋ก ํ์ฌ๋ก์๋ ์ถฉ๋ถํ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์๋ค๊ณ ์๊ฐํ์ง๋ง ์ฌ๊ณ ํ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค.
์์ ์๋ ๋ชจ๋ ๊ฒ์ ์ฅํฉํ(IMO) ๋ํผ๋ฅผ ์ถ๊ฐํ์ง ์๋ ํ ์ด๋ค ์ด์ค์ ์ด ์คํจํ๋์ง ์ ํํ ๋ฐ๊ฒฌํ๊ธฐ ์ด๋ ต๋ค๋ ๊ฒ์ ๋ณด์ฌ์ค๋๋ค. ์ด๊ฒ์ ์์ค๋งต ํ ๋ฒํธ๊ฐ ํญ์ ์ ํํ์ง ์์ ํธ๋์คํ์ผ ํ๊ฒฝ์์ ํนํ ๊ทธ๋ ์ต๋๋ค. ๊ฐ๊ฒฐํ ํ ์คํธ์ฒ๋ผ ๋น ๋ฅด๊ณ ์ ํํ๊ฒ ์ดํด๊ฐ ๊นจ์ง๊ณ ์ด๋๊ฐ ์ค์ํ์ง ์๊ฐํฉ๋๋ค.
๊ทธ๋ค์ง ๋ณต์กํ์ง ์์ง๋ง ๋ฌธ์ ๋ฅผ ๋ ๋นจ๋ฆฌ ํด๊ฒฐํ๋ ๋ฐ ๋์์ด ๋๋ ์ปจํ ์คํธ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
์์์ ๋ช ๊ฐ์ง ์ ์์ ํ์ต๋๋ค.
๋ ๊ฐ๋จํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฒ์ ์ฐพ๊ณ ์์ต๋๊น?
์๋ ํ์ธ์ @timoxley์ ๋๋ค! ์ฐ๋ฆฌ๋ ์ด๋ฏธ ์ด์ ๊ฐ์ ๊ฒ์ ์ถ๊ฐํ๋ ๊ฒ์ ๋ํด ์๊ฐํ์ต๋๋ค.
๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ ์ต์ ์ ๋ฌธ์ ๋ ์ผ๋ถ ๋งค์ฒ์ ์ ํ์ ์ธ์๊ฐ ์์ด ์ํฉ์ด ๋ ๋ณต์กํด์ง๋ค๋ ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด ์ฌ๊ธฐ ๋ ๋ฒ์งธ ๊ฒฝ์ฐ์๋ ์ธ์๊ฐ ๊ทผ์ ์ฑ์ธ์ง ์ค๋ฅ ๋ฉ์์ง์ธ์ง ์ ์ ์์ต๋๋ค.
expect(555).toBeCloseTo(111, 2, 'reason why');
expect(555).toBeCloseTo(111, 'reason why');
๋ฌด์ธ๊ฐ๊ฐ ๊ธฐ๋๋ฅผ ์ถฉ์กฑํ์ง ๋ชปํ๋ ์ฆ์ match๊ฐ ๋์ง๊ธฐ ๋๋ฌธ์ ๋ ๋ฒ์งธ ์ ์์ ์๋ํ์ง ์์ต๋๋ค.
expect(1).toBe(2)/* will throw here */.because('reason');
๋ค์๊ณผ ๊ฐ์ด ๋งค์ฒ๊ฐ ์คํ๋๊ธฐ ์ ์ ์ด์ ๋ฅผ ์ฒจ๋ถํ ์ ์์ต๋๋ค.
expect(1).because('reason').toBe(2);
// or
because('reason').expect(1).toBe(2);
ํ์ง๋ง ์ด API๋ ๊ทธ๋ค์ง ์ข์ ๋ณด์ด์ง ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์ต์
์ expect
์ ๋ ๋ฒ์งธ ์ธ์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค.
expect(1, 'just because').toBe(2);
๊ทธ๋ฌ๋ ์ด์ ์ต์ ๊ณผ ๊ฑฐ์ ๋์ผํฉ๋๋ค.
์ด๊ฒ์ด ๋ณ๋ก ์ ์ฉํ์ง ์๋ค๊ณ ์๊ฐํ๋ ์ด์ ๋ ์์ง๋์ด๊ฐ ํ ์คํธ ์์ฑ์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ค์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ํ๋ ๋ชจ๋ ์ผ์ ๋ ๋์ ํ ์คํธ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค.
๊ณผ๊ฑฐ์๋ ์ค์ ๋ก ์ฌ์ฉ์ ์ง์ ๋งค์ฒ๋ฅผ ๋ง๋๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ์๋ฃจ์
์ด์์ต๋๋ค. Jest์ ๋ค์ ๋ฒ์ ์์ expect.extend
๋ฅผ ์๊ฐํ ์์ ์ด๋ฉฐ ์ด๋ฅผ ํตํด ๋ค์๊ณผ ๊ฐ์ ๋งค์ฒ๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
expect(a).toEqualMySpecificThing(โฆ)
์ด๋ฅผ ํตํด ๋ณด๋ค ํํ์ ์ธ ์คํจ ๋ฉ์์ง๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋๋ ์ด๊ฒ์ด Relay์ ๊ฐ์ ํ๋ก์ ํธ์์ ๋ง์ด ์ฌ์ฉ๋๋ ๊ฒ์ ๋ณด์์ต๋๋ค. ๋ชจ๋ ๋งค์ฒ ๋ณด๊ธฐ: https://github.com/facebook/relay/blob/master/src/tools/__mocks__/RelayTestUtils.js#L281
ํ๋์ด ์์ด ๋ฌธ์ ๋ซ์ง๋ง ์ข์ ์์ด๋์ด๊ฐ ์์ผ๋ฉด ๋ค์ ์ด ์ ์์ต๋๋ค.
@cpojer @dmitriiabramov ์ง์ฐ์ ๋ํด ์ฌ๊ณผ๋๋ฆฝ๋๋ค.
expect
์ ๋ํ ๋ ๋ฒ์งธ ์ธ์ ๋๋ .because
๋ก ์ด์ ๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํ๊ฑฐ๋ ํ์ง ์๊ธฐ ์ํด ๋ฌด์์ ํด์ผ ํฉ๋๊น?
์์ง๋์ด๋ ํ ์คํธ ์์ฑ์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์์ต๋๋ค.
@cpojer ๋์ํฉ๋๋ค! ํ ์คํธ ๋๋ฒ๊น ์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์์ ๊ฒ ์ธ์๋ ์ด๊ฒ์ด ๋ ๋ง์ ์คํจ ์ปจํ ์คํธ๊ฐ ์๋ ๋ ์ฅํฉํ API๊ฐ ๋ ๋ฐ๋์งํ๋ค๊ณ ์๊ฐํ๋ ๋ฐ๋ก ๊ทธ ์ด์ ์ ๋๋ค.
์ผ๋ถ ๊ตฌ์ฒด์ ์ธ ์ซ์์ ๊ฒฝ์ฐ ์์ ๋ด ์ค๋ช ์ ์๋ ๊ฐ๋จํ ์๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ดํ๋ฅผ ์ฌ์ฉํ์ฌ ๋๋ฑํ ์ฃผ์ฅ + ์ปจํ ์คํธ๋ฅผ ์ป์ผ๋ ค๋ฉด Jest๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์์์ฉ ์์ฉ๊ตฌ ์์ ๊ฑฐ์ ๋ ๋ฐฐ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ๊ฐ์ ๋ ์ ์์ต๋๋ค!
// tape
test('api works', t => {
t.deepEquals(api(), [], 'api without magic provides no items')
t.deepEquals(api(0), [], 'api with zero magic also provides no items')
t.deepEquals(api(true), [1,2,3], 'api with magic enabled provides all items')
t.end()
})
// jest
describe('api works', () => {
test('api without magic provides no items', () => {
expect(api()).toEqual([])
})
test('api with zero magic also provides no items', () => {
expect(api(0)).toEqual([])
})
test('api with magic enabled provides all items', () => {
expect(api(true)).toEqual([1,2,3])
})
})
์ ๋ฐ์ดํธ : ํ์ดํ๊ฐ ์๋ ํ ์ค์ ๋๋ด ํ ์คํธ๋ฅผ ์์ฑํ ์ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
// jest
describe('api works', () => {
test('api without magic provides no items', () => expect(api()).toEqual([]))
test('api with zero magic also provides no items', () => expect(api(0)).toEqual([]))
test('api with magic enabled provides all items', () => expect(api(true)).toEqual([1,2,3]))
})
์ด๋ ๊ฒ ํ๋ฉด ์ค์ด ๋ ๊ธธ์ด์ง์ง๋ง ์ด์ ์ ๋น๊ตํ ํต๊ณ๊ฐ ๋ค์ ํฅ์๋ฉ๋๋ค.
๊ทธ๋ฌ๋ ์ค ๋ฐ๊ฟ ์์ด ์ค ์์ ๋ถ๋ถ์ ํ ์คํธ ์ค๋ช ์ด ์์ผ๋ฉด ํ ์คํธ์ "ํต์ฌ", ์ฆ ์ค์ ์ด์ค์ ์ ์์์ ์ด ์์น์ ๋ฐฐ์นํ๊ธฐ ๋๋ฌธ์ ๋ ผ๋ฆฌ๋ฅผ ์๊ฐ์ ์ผ๋ก ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ๊ฐ ๋ ์ด๋ ค์์ง๋๋ค.
์ฝ๋๋ฅผ ํ์ฑํ๋ ๊ฒ์ ํ ์คํธ ์ค๋ช ์ ์ฝ๋ ๊ฒ๋ณด๋ค ๋ ์ค์ํฉ๋๋ค. ์ด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฐฌ์ฌ๋ฅผ ๋ฐ๋ ์ค๋ช ์ผ ๋ฟ์ ๋๋ค. ์ด๊ฒ์ด ํ์ ์์ ๋ถ๋ถ์ ์๋ฌด๋ ์ฃผ์์ ์ฐ์ง ์๋ ์ด์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด ์ด๊ฒ์ ์ฌ๋๋ง์กฐํ์ฆ์ ๊ด๊ธฐ์ผ ๊ฒ์ ๋๋ค:
/* api without magic provides no items */ expect(api()).toEqual([])
/* api with zero magic also provides no items */ expect(api(0)).toEqual([])
/* api with magic enabled provides all items */ expect(api(true)).toEqual([1,2,3])
์ด์์ ์ผ๋ก๋ ๋ชจ๋ ์ด์ค์
์ฝ๋๊ฐ ๋์ผํ ์ด์ ๊น๋ํ๊ฒ ์ ๋ ฌ๋์ด ์ฌ๋์ด ์ฝ๊ฒ ๊ตฌ๋ฌธ ๋ถ์ํ ์ ์์ต๋๋ค. ์ด ์๊ฐ์ ๋ฐํ์ผ๋ก expect
์ ๋ํ ๋ ๋ฒ์งธ ์ธ์์ ๋์ ์ ์๋ณด๋ค๋ ํํ .because
ํ์์ ๊ฐ๋ ฅํ๊ฒ ์ ํํฉ๋๋ค.
๋ํ๋ฅผ ๊ณ์ํด์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋ํ ์ค๋ช
๋ธ๋ก์ด ํ์ํ์ง ์์ผ๋ฏ๋ก ๋ ์๊ฒ ๋ง๋ญ๋๋ค. .because
๋ ๋ถํํ๋ ์๋ํ์ง ์์ต๋๋ค. ์๋ํ๋ฉด matcher๊ฐ ๋์ง ๋( .because
๊ฐ ํธ์ถ๋๊ธฐ ์ ์ ๋ฐ์ํจ), ์ด๋ฆ์ ์ถ์ถํ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๊ทธ๋ฌ๋ฉด ๊ฐ ๋งค์ฒ ํจ์์ ๋ง์ง๋ง ์ธ์๋ฅผ ์ฌ์ฉํ์๊ฒ ์ต๋๊น?
expect
์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ถ๊ฐํ๋ ๊ฒฝ์ฐ์๋ง ์๋ํฉ๋๋ค.
๋ชจํธ์ฑ ๋๋ฌธ์ ๋ชจ๋ ๋งค์ฒ ํจ์์ ๋ง์ง๋ง ์ธ์๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค.
์
expect(obj).toHaveProperty('a.b.c', 'is that a reason or a value of the property?');
ํ๋์ด ์์ด ๋ฌธ์ ๋ซ์ง๋ง ์ข์ ์์ด๋์ด๊ฐ ์์ผ๋ฉด ๋ค์ ์ด ์ ์์ต๋๋ค.
@cpojer expect(value).toBe(something, 'because message')
์ ์ฌ์ค๋ฏผ(๋ฐ ๊ธฐํ) ๋ฐฉ์์ด ๋ฐฐ์ ๋์๋์ง ์ฌ๋ถ๊ฐ ๋ถ๋ถ๋ช
ํฉ๋๊น?
ํ ๊ฐ์ง ์๋ ์ํ ๋จธ์ ์ ํ ์คํธํ๋ redux-saga/redux-observable ํญ๋ชฉ์ ํ ์คํธํ๋ ๊ฒ์ ๋๋ค. ์ด๋ค ์ํ์์ ์คํจํ๋์ง์ ๋ํ ์ค๋ช ๋ฉ์์ง๊ฐ ์์ผ๋ฉด ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ์ ์์๋ ์ธ์์ ์ธ๊ฑฐ๋ผ ์ค๋ช ๋ ๊ทธ๋ ๊ณ ..
@jayphelps ๋ชจ๋ ์ฌ์ค๋ฏผ ๋งค์ฒ๋ฅผ ๋ค์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ ์ด์ ์ฌ์ค๋ฏผ ๋ฐฉ์์ ์ฌ์ฉํ์ง ์์ต๋๋ค.
@dmitriiabramov ์ฃ์กํฉ๋๋ค. ์ ์ง๋ฌธ์ด ๋ช ํํ์ง ์์์ต๋๋ค. ์ฌ์ค๋ฏผ _way_ ๊ทธ๊ฒ์ ๋ค์ ์ถ๊ฐํ๋๋ก ํ๊ฒฐ์ ๋ฐ์์ต๋๊น? ๊ทธ๋ค์ด ํ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ผ์ ํฉ๋๋ค.
@jayphelps ์ ์ ๋งํ๋ฏ์ด ๋ชจํธ์ฑ ๋๋ฌธ์ ๋ชจ๋ ๋งค์ฒ์์ ์๋ํ์ง ์์ต๋๋ค.
expect(obj).toHaveProperty('a.b.c', 'is that a reason or a value of the property?');
๋ ธ๋ jest matchers๋ ํ์ฌ ํจํค์ง๋ก ํ์ฅํ ์ ์์ต๋๋ค. ์ธ์ ๋ชฉ๋ก์ ์๋ง์ผ๋ก ๋ง๋๋ ๊ฒ์ ์ข์ ์๊ฐ์ด ์๋๋๋ค.
๊ฐ์ฅ ๊น๋ํ ์ต์
์ expect
์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ํญ์ ์ ํํ ํ๋์ ์ธ์๋ฅผ ์ทจํ๊ธฐ ๋๋ฌธ์
๋๋ค.
expect(123, 'jest because').toEqual(123);
๊ทธ๋๋ API๋ฅผ ์ค๋ฒ๋ก๋ํ๊ณ ์ถ์์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ฐ๋ฆฌ๋ ํ์ด์ค๋ถ ํ ์คํธ ์ค์ํธ์์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์์์ผ๋ฉฐ ํน๋ณํ ๊ฒฝ์ฐ์๋ ์ ํ ์คํธ๋ฅผ ์ ์ํ๋ ๊ฒ์ด ๋ ์ฝ๋ค๊ณ ์๊ฐํฉ๋๋ค.
beforeEach(someSharedSetup);
test('reason or description', () => expect(1).toBe(1));
๋ช ์ค๋ง ๋ํ๋ฉด ๋ฉ๋๋ค :)
๋๋ ๋ค๋ฅธ describe()
ํธ์ถ์ ๋ฃ์ ์๋ ์์ต๋๋ค.
@dmitriiabramov ์ฑ๊ฐ์ ๊ฒฝ์ฐ๋ ์ฌ๊ฐ, ์์ฌ์ ๋ฑ์ ์ํ ๋จธ์ ์์์ ๊ฐ์ด ์ํ๋ฅผ ๊ตฌ์ถํ ๋์ ๋๋ค. ๊ฐ ํ ์คํธ์๋ ์ด์ ์ํ ๋ณ๊ฒฝ์ด ํ์ํ๋ฉฐ, ์ด๋ฅผ ๋ถ๋ฆฌํ๋ ค๋ฉด AFAIK ์ด๋ ์์ด ์์ฒญ๋ ์์ ๋ณต์ ๊ฐ ํ์ํฉ๋๋ค.
it('stuff', () => {
const generator = incrementAsync();
expect(generator.next().value).toBe(
call(delay, 1000)
);
expect(generator.next().value).toBe(
put({ type: 'INCREMENT' })
);
expect(generator.next()).toBe(
{ done: true, value: undefined }
);
});
๋๋ ๋ค๋ฅธ describe() ํธ์ถ์ ๋ฃ์ ์๋ ์์ต๋๋ค.
์ด๊ฒ์ ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น? ์ค์ฒฉ ์ค๋ช ํธ์ถ AFAIK๋ ์น์ ์ ๋ชฉ์ ๋๋๊ธฐ ์ํ ๊ฒ์ด์๊ณ ํ ์คํธ๋ ์ฌ์ ํ ๋์์ ์คํ๋ฉ๋๊น?
ํ
์คํธ ์ค์ํธ(ํ์ผ)๋ ๋์์ ์คํ๋์ง๋ง test()
ํธ์ถ์ ์คํ๋์ง ์์ต๋๋ค.
๋๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ์๊ฐํ๊ธฐ ์์ํ์ต๋๋ค.
test('111' () => {
jest.debug('write something only if it fails');
expect(1).toBe(2);
});
์ผ์ด ๋ ์ ์์ต๋๋ค
์ด ํ ๋ก ๊ณผ ์ด ์ ์ฅ์ ์์ ๋ฉ์ง๊ณ ์๋ฏธ ์๋ ์ ์ฅ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
it('has all the methods', () => {
since('cookie is a method').expect(reply.cookie).toBeDefined();
since('download is a method').expect(reply.download).toBeDefined();
since('end is a method').expect(reply.end).toBeDefined();
// ...
});
์ฌ์ฉ๋ฒ์ because
์ ๋น์ทํ์ง๋ง ์๋ฏธ์ ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.
๋น์ ์ด ์ด๊ฒ์ ์ข์ํ๋ค๋ฉด ๋๋ since
๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ PR์ ํ ์ ์์ ๊ฒ์
๋๋ค.
์ด ์์ ์ ์ํํ๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ๊ตฌํํ์ญ์์ค. ๋๋ ๊ทธ๊ฒ์ ์์ฃผ ์ฌ์ฉํ์ง ์์ง๋ง ํนํ ๋ ๋ณต์กํ ํ ์คํธ์ ๊ฒฝ์ฐ ํ๊ณ ๋ค์ง ์๊ณ ๋ ๋ฌด์์ด ์คํจํ๋์ง ์ ํํ ์๋ ๊ฒ์ด ๋์์ด ๋ฉ๋๋ค.
"ํ ์คํธ ์ค์ํธ๋ฅผ ๋ ๊ฐ๋จํ๊ฒ ๋ค์ ์์ฑํ์ญ์์ค"๋ผ๊ณ ๋งํ์ง ๋ง์ญ์์ค. ์์ง๋์ด๊ฐ _writing_ ํ ์คํธ ์ค์ํธ๋ณด๋ค ๋ ์ซ์ดํ๋ ์ ์ผํ ๊ฒ์ _rewriting_ ํ ์คํธ ์ค์ํธ์ ๋๋ค.
๋ด๊ฐ ์ด๋์ ๊ฐ ๋ณธ ๋ ๋ค๋ฅธ ์ ์์ ์ด๊ฒ์ด ์๋ํ์ง ์๋ ์ด์ ์ ๋ํ ์ค๋ช
๊ณผ ํจ๊ป ์ด ๋์ผํ ๋ฌธ์ ์ ์์น๋ฅผ โโ์์ด๋ฒ๋ ธ์ต๋๋ค . ์ข ์์ผ๊ฒ ๋ค์ :)
๊ฐ๋จํ "ํ๋กํ ํ์ " ๋ฐ๋ชจ๊ฐ ์๋ ์ค์ ๋๋ค. ์ด์ ์ฌ๊ท๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค. ์ ์ญ ๋ณ์ ์ฃผ์์ ํ๋ก์๋ฅผ ์ฌ์ฉํ ๋ค์ ๊ฐ ๋ฉ์๋์ ๋ํด ์ฌ์ฉํ๋ ์์ ๋ํผ์ ๋๋ค. ๊ทธ๋ฌ๋ ํ๋ก์๋ ์ด์ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ๋์ง ์์ผ๋ฉฐ ํด๋ฆฌํํ ์ ์์ผ๋ฏ๋ก Jest์์ ํ์ฉ๋์ง ์์ ์ ์์ต๋๋ค. ๋ค์์ ๋ํผ์ ์ผ๋ฐ ๊ตฌ์กฐ์ ๋๋ค.
const since = (text) => {
return new Proxy(global, {
get: (orig, key) => {
return (...args) => {
try {
const stack = orig[key](...args);
return new Proxy(stack, {
get: (orig, key) => {
return (...args) => {
try {
const ret = orig[key](...args);
// ... implement recursion here
} catch (err) {
console.log('2', key, text, err);
throw err;
}
}
}
});
} catch (err) {
console.log('1', key, text, err);
throw err;
}
};
}
});
};
์ธ ๊ฐ์ง ํ์ค์ ์ธ ์ต์ ์ด ์์ต๋๋ค.
ํธ์ง: ์ค์ ์ฌ์ฉ:
describe('Test', () => {
it('works', () => {
since('It fails!').expect('a').toEqual('b');
});
});
์ฌ์ํ์ง ์์ ํ ์คํธ๊ฐ ์์ ๋ ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ์ ์์ผ๋ก ๋ง๋ค๋ ค๋ฉด ๊ธฐ๋ ์ปจํ ์คํธ๊ฐ ํ์ํฉ๋๋ค. ์ค์ ํ ์คํธ๊ฐ ํญ์ ๊ทธ๋ ๊ฒ ๊ฐ๋จํ ๊ฒ์ ์๋๋๋ค.
์ฌ์ฉ์ ์ง์ ๋งค์ฒ๋ฅผ ๊ธฐ์ตํ์ญ์์ค - ์ํ ๋ณต์ก์ฑ์ ์จ๊น๋๋ค. ๊ทธ๋ฌ๋ ํ ์คํธ๊ฐ ์คํจํ๋ฉด ์คํจ์ ๋ํ ์ต๋ ์ ๋ณด๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ณต์ก์ฑ์ ์จ๊ธฐ๋ ๊ฒ์ ์ํ๋ ๊ฒ์ด ์๋๋๋ค. ๊ธฐ๋ ์ปจํ ์คํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ์ปจํ ์คํธ๋ฅผ ์๋์ผ๋ก ์ ๊ณตํ ์ ์์ต๋๋ค. ๋ด ์๊ฐ์ ์ด์์ ์ด์ง๋ ์์ง๋ง ์ผ์ข ์ ์๋ ์ปจํ ์คํธ๊ฐ ๋ ๋์ ๊ฒ์ด์ง๋ง ์ง๊ธ๊น์ง ๋ณธ ์ ์ผํ ๋ฐฉ๋ฒ์ ๋๋ค.
๋ด๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ ๋ถ์๊ณ ์คํจํ๋ฉด Jest๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ๋๋ฒ๊น
ํ๊ฑฐ๋ ๋ก๊น
๋๋ _modifications._๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์ด๋ ํ
์คํธ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ํธ๋ฆฌํฉ๋๋ค.
์๋ฅผ ๋ค์ด Jasmine์๋ ์คํจ์ ๋ํด ๋ ์ดํดํ๊ธฐ ์ํด ์ผ๋ถ ์ปจํ
์คํธ๋ฅผ ์ธ์ํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
Java์ ๊ฐ์ฅ ์ธ๊ธฐ ์๋ ํ
์คํธ ํ๋ ์์ํฌ์ธ JUnit์๋ ๋๊ฐ์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ๋ฏธ์ํ์ง๋ง ์ฌ๊ธฐ์ ์ด โโ๊ธฐ๋ฅ์ ๋ํ _๊ธฐ์ ์ _ ๋ฐ๋ก ์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ "๋ณด๊ธฐ์ ์ข์ง ์๊ธฐ ๋๋ฌธ์ ์ถ๊ฐํ๋ฉด ์ ๋๋ค"์ ๊ฐ์ ๊ฒ์ ๊ทธ์ ์ฐ์ค๊ฝ์ค๋ฝ์ต๋๋ค.
๋ค์ ์ด ์ ์์ต๋๊น? ์์ @aaronabramov ๊ฐ ์ ์ํ jest.debug()
์กฐ์ฐจ๋ ์ ์๊ฒ ๋์์ด ๋ ๊ฒ์
๋๋ค.
This:
it('has all the methods', () => {
since('cookie is a method', () => expect(reply.cookie).toBeDefined());
});
can be supported by adding this:
// setupTestFrameworkScriptFile.js
// http://facebook.github.io/jest/docs/configuration.html#setuptestframeworkscriptfile-string
global.since = (explanation, fn) => {
try {
fn();
} catch(e) {
e.message = explanation + '\n' + e.message;
throw e;
}
};
๋ํ jasmine-custom-message ๋ ์์ฒญํ ๊ฒ๊ณผ ์ ์ฌํ๊ฒ ๋ณด์ ๋๋ค.
describe('test', function() {
it('should be ok', function() {
since(function() {
return {'tiger': 'kitty'};
}).
expect(3).toEqual(4); // => '{"tiger":"kitty"}'
});
});
๋ค์ ์ด ๊ณํ์ด ์์ต๋๊น? ์ต๊ทผ์ ์ด ๋ฌธ์ ๊ฐ ์ค๋ณต๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ํ ํ ์คํธ๊ฐ ์คํจํ ๋ ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง๋ฅผ ํ์ํ๋ ค๊ณ ํฉ๋๋ค.
ํ .. ์ด๊ฒ๋ ์์๋ฆฌ์คํธ์ ์๋ ๊ฒ. ์ด ์ค๋ ๋๋ฅผ ์ฝ์ ํ Facebook์์ Jest ์ฌ์ฉ๊ณผ ๊ด๋ จ๋ ์๋ต์ ์ดํดํ ์ ์๊ณ ์์ ์ ์ํฌํ๋ก์ ์ํฅ์ ๋ฏธ์น๊ณ ์ถ์ง ์์ง๋ง ๊ธฐ์กด ํ ์คํธ๋ฅผ ๋ฐฉํดํ์ง ์๋ ๋ช ๊ฐ์ง ์ ์์ด ์์๊ณ ์ฌ๋ฌ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๊ฒ์ ๋๋ค. (์ ํฌํจ) ์์ต๋๋ค.
๋ ๋ฒ์งธ ์ธ์๊ฐ expect() ๋๋ since() ํ์์ด PR๋ก ํ์ฉ๋๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น? ๋๋ ์ด๊ฒ์ ๋๊ธฐ ์ํด ๊ธฐ๊บผ์ด ์๊ฐ์ ํ ์ ํฉ๋๋ค.
๋ฐฉ๊ธ ์ค๋ ๋๋ฅผ ์ฝ๊ณ ์์ชฝ์์ ์ข์ ์ฃผ์ฅ์ ๋ณด์์ต๋๋ค. @timoxley๊ฐ ์๋ ๊ฒ์ํ ๊ฒ๊ณผ ๊ฐ์ ์ด์ ๋ก ์ฌ์ฉ์ ์ง์ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ ๋ฉ์ปค๋์ฆ์ ํ์คํ ์ํฉ๋๋ค. ์ง๊ธ์ ๋ค์๊ณผ ๊ฐ์ด ํ๊ณ ์์ต๋๋ค.
import assert from 'assert'
import chalk from 'chalk'
test('api works', () => {
assert.deepEqual(
api(),
[],
chalk.red('api without magic provides no items')
)
assert.deepEqual(
api(0),
[],
chalk.red('api with zero magic also provides no items')
)
assert.deepEqual(
api(true),
[1, 2, 3],
chalk.red('api with magic enabled provides all items')
)
})
์ด๊ฒ์ ์ค์ ๋ก ๋งค์ฐ ์ ์๋ํ์ง๋ง ๋ถํ์ ์ฌ์ฉํ์ฌ ๋นจ๊ฐ์์ ์ป๋ ๊ฒ์ ํผํ๊ณ ์ถ์ต๋๋ค expect
๋๋ ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ์ ์งํ๊ฒ ๊ตฌํ๋์๋์ง์ ๋ํด ๋ณ๋ก ์ ๊ฒฝ ์ฐ์ง ์๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ฌ๋๋ค์ด ์ ํธํ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ since
์ ๋ํ ๋์์ด ์์ต๋๋ค.
const expectWithMessage = expect.withMessage(
'api with magic enabled provides all items'
)
expectWithMessage(api(true)).toEqual([1, 2, 3])
// could be rewritten like
expect
.withMessage('api with magic enabled provides all items')(api(true))
.toEqual([1, 2, 3])
since
๋ณด๋ค ๋ ์ข์ํ๋์ง ํ์ ํ ์ ์์ต๋๋ค. ๋ญ๋ ์ง ๋ค ์์ด์ธ๋ ค์ ์ ๋ง ๊ฐ๊ณ ์ถ๋ค์ :)
์, ๊ทธ๋ฆฌ๊ณ ๋๊ธ์ ๋ตํ์๋ฉด:
์ด๊ฒ์ด ๋ณ๋ก ์ ์ฉํ์ง ์๋ค๊ณ ์๊ฐํ๋ ์ด์ ๋ ์์ง๋์ด๊ฐ ํ ์คํธ ์์ฑ์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ค์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ํ๋ ๋ชจ๋ ์ผ์ ๋ ๋์ ํ ์คํธ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค.
ํ ์คํธ ์์ฑ์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ณ ์ถ์ง ์๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ์ด๊ฒ์ด ์ถ๊ฐ ๋ณ๊ฒฝ์ด ๋๋ ์ด์ ์ ๋๋ค. ๋ฐ๋ผ์ ํ ์คํธ๋ฅผ ๋๋ฒ๊ทธํ๊ธฐ ์ฝ๊ฒ ๋ง๋๋ "์๊ฐ ๋ญ๋น"๋ฅผ ์ํ์ง ์๋ ์ฌ๋๋ค์ ์ ์ฉํ ๋ฉ์์ง๋ฅผ ๊ฑด๋๋ธ ์ ์์ต๋๋ค. ์๊ฐ์ ๋ด์ด ์ฃผ์ฅ์ ์กฐ๊ธ ์ค๋ช ํด์ฃผ์ ์์ง๋์ด :wink:
์๋ ํ์ธ์ @cpojer ์ด์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
Jest๋ ์ด ๋ฌธ์ ๋ฅผ ์ ์ธํ๊ณ ๋ ํ๋ฅญํ๊ฒ ์๋ํ๊ณ ์์ต๋๋ค... ํ์ฌ ์ ๋ for ๋ฃจํ ๋ด์์ ์คํจํ ์ด์ค์
์ ์์ ํ๊ธฐ ์ํด ๊ณ ๊ตฐ๋ถํฌํ๊ณ ์์ต๋๋ค.
expectationsArray.forEach(expectation => expect(...))
์ฌ์ฉ์ ์ ์ ์ค๋ฅ ๋ฉ์์ง ์์ด ์ด๋ค ๊ธฐ๋๊ฐ ์คํจํ๋์ง ์ ํํ ํ์ ํ๊ธฐ ์ด๋ ต์ต๋๋ค(๋ด๊ฐ ์๋ชปํ์ง ์๋ ํ..?)
๊ฐ์ฌํฉ๋๋ค
@mj-airwallex ์๋ฅผ ๋ค์ด for ๋ฃจํ์์ test
๋ก ๊ธฐ๋์น๋ฅผ ๊ฐ์ ์ ์์ต๋๋ค.
const expectationsArray = [[0, 'a'], [1, 'b']];
expectationsArray.forEach(([expectation, desc]) => {
test(`test ${desc}`, () => {
expect(expectation).toBeGreaterThanOrEqual(2);
});
});
๋ํ ๊ธฐ๋ํ๋ ๋์ ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง๋ฅผ ์ ๊ณตํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ด์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. test
์๋์ ๊ธฐ๋์น๋ฅผ ๋ํํ๋ ๊ฒ์ ๋น๋๊ธฐ์ ํธ์ถ์ด ํ์ํ์ง ์์ ๊ฒฝ์ฐ์ ์๋ํ๋ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฌ๋ Jest๋ ํ๋ผ๋ฏธ์ค๋ฅผ ๋ฐํํ๋ describe
(#2235 )๋ฅผ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก test
๋ก ๋ํํ๋ ๊ฒ๊ณผ ํจ๊ป ๋น๋๊ธฐ ํธ์ถ๋ก ํ
์คํธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ๋ฌ test
์ค์ฒฉํ ์ ์์ต๋๋ค.
๋ค์์ ๋ฌธ์ ๋ฅผ ์ค๋ช ํ๋ ์์ ๋๋ค.
async function getArray() {
return [0,0,0,0,0,0]
}
describe('Custom messages with async', async () => {
const array = await getArray();
array.forEach((item) => {
test(`test${item}`, () => {
expect(item).toBe(0)
});
});
})
์ด๊ฒ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ต๋๊น?
OP์ ๋ฌธ์ ๋ฅผ ์ดํด๋ณด๋ฉด("์ด๋ค ๊ธฐ๋๊ฐ ์คํจํ๋์ง ์ฆ์ ๋ช ํํ๊ฒ ํด์ฃผ๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ปจํ ์คํธ๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค"), ์ด์ ํด๊ฒฐ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค. Jest 22๋ถํฐ ์ฐ๋ฆฌ๋ ์คํจํ ์ฃผ์ฅ์ ์ปจํ ์คํธ๋ฅผ ์ธ์ํฉ๋๋ค. ์ถ๊ฐ ๋ฉ์์ง๊ฐ ์ฌ์ ํ ํ์ํฉ๋๊น? _is_์ธ ๊ฒฝ์ฐ ์ด์ค์ ์ ๋๋ ์์ ์๋ ์ฝ๋ ์ฃผ์์ผ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ค๋ช ์ ๋ ๋ค๋ฅธ ๋ฌธ์ ์ ๋๋ค(์ถ๊ฐ๋ ์ฝ๋ ํ๋ ์์ผ๋ก๋ ๋์์ด ๋์ง ์์).
๋น๋๊ธฐ ์ค๋ช
์ ์ฌ์ฉํ์ง ์๊ณ ๋์ beforeEach
๋๋ beforeAll
๋ฅผ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@kentcdodds beforeEach
๋๋ beforeAll
๋ก ์ด๊ฒ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์๋ฅผ ์ ๊ณตํ ์ ์์ต๋๊น? beforeEach
๋ฐ beforeAll
์ ํ์ํ ๋ชจ๋ ๋น๋๊ธฐ ํธ์ถ ๊ฒฐ๊ณผ๋ฅผ ๋น๋ํ๋ ค๊ณ ํ๋ฉด ๊ฒฐ๊ตญ ํ์ฉ๋์ง ์๋ ์ค์ฒฉ๋ test
๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
์, ๋น์ ์ด ๊ทธ ๋น๋๊ธฐ ํตํ๋ก ๋ฌด์์ ํ๊ณ ์์๋์ง ๋ณด๊ณ ์ถ์์ต๋๋ค. ์ฃ์กํฉ๋๋ค ๐ ๋ค, beforeEach
๋๋ beforeAll
์(๋ฅผ) ์ํํ ์ ์์ต๋๋ค.
@SimenB , ์ปจํ ์คํธ๋ฅผ ์ธ์ํ๋ฉด ์ด๋ฏธ ๋ง์ ๋์์ด ๋๋ฉฐ ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง์ ๊ด๋ จ๋ ๋๋ถ๋ถ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค! ๊ทธ๋ฌ๋ ๋ฃจํ ๋ด์์ ์์์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ํฉ์์ ๋์์ด ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง๋ฅผ ์ธ์๋ก ๋ช ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
@tojuhaka ์ด๊ฒ์ ์๋ํ์ญ์์ค : https://github.com/negativetwelve/jest-plugins/tree/master/packages/jest-plugin-context
OP์ ๋ฌธ์ ๋ฅผ ์ดํด๋ณด๋ฉด("์ด๋ค ๊ธฐ๋๊ฐ ์คํจํ๋์ง ์ฆ์ ๋ช ํํ๊ฒ ํด์ฃผ๋ ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ปจํ ์คํธ๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค"), ์ด์ ํด๊ฒฐ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์, ๋๋ถ๋ถ์ Jest ์ฌ์ฉ์๊ฐ ๊ฐ๊ฒ ๋๋ ๋ณํ ์ ์ ์๋ณธ ์์ค์ ์ก์ธ์คํ ์ ์๋ ํ ์๋ณธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. IMO๋ ์ฌ์ฉ์๊ฐ ์คํจ์ ํจ๊ป ์ฌ์ฉ์๊ฐ ์ ๊ณตํ ๋ฉ์์ง๋ฅผ ์ธ์ํ ์ ์๋๋ก ํ์ฉํ๋ ๊ฒ์ ๋นํด ์ฝ๊ฐ ๋ฌด๊ฒ์ง๋ง ์ถฉ๋ถํ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
Jest๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ๋๋ฐ ์ด์ ๊ฐ์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ด ์ฌ์ฉ ์ฌ๋ก:
๊ฐ์ฒด์ ์์ฑ์ด ์ง์ค์ด๋ผ๊ณ ์ฃผ์ฅํ๋ ํ
์คํธ๋ ์คํจํฉ๋๋ค. ์ด์ค์
์ด ์คํจํ ๊ฒฝ์ฐ ๊ฐ์ฒด๋ฅผ ๊ธฐ๋กํ ์ ์๋ค๋ฉด ์คํจ๋ฅผ ๋ ๋นจ๋ฆฌ ์ดํดํ๋ ๋ฐ ๋์์ด ๋ ๊ฒ์
๋๋ค.
์ด๋ฅผ ์ํด toHaveProperty
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
test('property', () => {
expect({foo: 'bar'}).toHaveProperty('baz', 'foobar');
});
๊ฑฐ๊ธฐ์ ์๋์ง ํ์ธํ๋ ค๋ฉด ๋ ๋ฒ์งธ ์ธ์๋ฅผ ์ญ์ ํ์ญ์์ค. _some_ ๊ฐ์ด ์๋ค๊ณ ์ฃผ์ฅํ๋ ค๋ ๊ฒฝ์ฐ expect.anything()
์ฌ์ฉํ ์ ์์ต๋๋ค.
toMatchObject
๋ ๋ ๋ค๋ฅธ ๋์์
๋๋ค.
์ํ๋ ๊ฒฝ์ฐ assert
๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
test('property', () => {
const obj = {foo: 'bar'};
assert.equal(obj.baz, 'foobar', JSON.stringify(obj));
});
ํ ๊ณ ๋ง์. assert.equal(obj.baz, 'foobar', JSON.stringify(obj));
๋ ๋ด ํน๋ณํ ๊ฒฝ์ฐ์ ์์
์ ์ํํฉ๋๋ค.
@SimenB @mpseidel ์ฃผ์ฅ์ด๋ ๋ฌด์์ ๋๊น? ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๊น? jest ๋ฌธ์์์ ์๋ฌด๊ฒ๋ ์ฐพ์ ์ ์์ต๋๋ค.
@sharikovvladislav assert
๋ ๋
ธ๋ ์ฝ์ด ๋ชจ๋์
๋๋ค https://nodejs.org/api/assert.html
@mpseidel ์ ! ๋๋ ๋ชฐ๋๋ค. ๊ฐ์ฌํฉ๋๋ค. ํจ๊ณผ๊ฐ์๋ค.
๋ค์ ์ฝ๋ ์กฐ๊ฐ์ ์ฌ์ฉํ์ฌ ํ๋ ์์ํฌ์ ์ด๋ฌํ ์ ํ์ ํด๊ฒฐํ๊ณ ์์ต๋๋ค(TypeScript์์ JS์ ๋ํ ์ ํ ์ฃผ์์ ์ ๊ฑฐํ๋ฉด ๋ฉ๋๋ค).
export const explain = (expectation: () => void, explanation: string) => {
try {
expectation();
} catch(e) {
console.log(explanation)
throw e;
}
}
์๋
,
์๋ฌด๋ ๋ฃจํ์ ๋ํด ์ธ๊ธํ์ง ์์๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค. ๋ฉ์์ง๋ ๋จ์ํ ๋ฌธ์์ด์ด ์๋๋ผ ๋ฃจํ ๋ฐ๋ณต์ ๋ฐ๋ฅธ ๋์ ๋ฌธ์์ด์
๋๋ค.
jest-plugin-context
๋ ํ๋ฅญํฉ๋๋ค. ๋๋ถ์ ์๋ํ์ง๋ง ์ฝ๊ฐ ๋ฌด๊ฒ๊ณ ์ด๊ธฐ ๋ฌธ์ ๋ ์ฌ์ ํ ๊ด๋ จ์ด ์์ต๋๋ค.
์ด ํ
์คํธ๋ฅผ ๋ด
describe('MyStuff', () => {
it('should render and contain relevant inputs', () => {
const wrapper = shallowWrapped(<MyStuff />);
const expectedKeys = ['love','jest','but','need','details','for','expect'];
expectedKeys.forEach((key) => {
expect(wrapper.find({ id: key }).length).toEqual(1);
});
});
});
๋น์ ์ ๋ฒ์ธ์ ์ฐพ๋ ํ์ด์ ๋น๋๋ค. ์ง๊ธ ๋น์ฅ {len:.., key:..}
์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋์ ์ถ๊ฐํ๊ฑฐ๋ ํ
์คํธํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ ๊นจ๋ํ์ง ์๊ณ ์ฌ์ฉ์ ์นํ์ ์ด์ง ์์ต๋๋ค.
์ด ์ฌ์ฉ ์ฌ๋ก๋ ์๋ฅผ ๋ค์ด ์์ ๋ฐ ํญ๋ชฉ ๋ ๋๋ง ํ์ธ๊ณผ ๊ด๋ จ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ตฌ๋ฌธ์ toEqual(1).context("my message")
๋๋ toEqual(1, "my message")
๋งํผ ๊ฐ๋จํ ์ ์์ต๋๋ค(๋ฌผ๋ก ๊ตฌํ์ด ํญ์ ๋ ์ด๋ ต๋ค๋ ๊ฒ์ ์๊ณ ์์ผ๋ฉฐ Jest์์ ์ํํ ํ๋ฅญํ ์์
์ ์กด๊ฒฝํฉ๋๋ค).
chai
์ ๊ฐ์ ํ์์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ์ฆ, ๋ฉ์์ง๋ฅผ ์์ ํธ์ถ์ ๋ ๋ฒ์งธ ์ธ์๋ก ์ถ๊ฐํฉ๋๋ค.
expect(foo, 'this detail').toEqual(2)
ํฐ
์ด์ ์ ์ฌ์ค๋ฏผ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ง์๋์ง ์๋ ๊ฒ์ ์ฐพ์ ์ฌ๊ธฐ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ afik ์ด๋ฌํ ๊ฒ๋ค์ ๋ชจ๋ ํจ์์
๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ํ๋ฉด ์ ๋ ๊น์?
describe('MyStuff', () => {
describe('should render and contain relevant inputs', () => {
const wrapper = shallowWrapped(<MyStuff />);
const expectedKeys = ['love','jest','but','need','details','for','expect'];
expectedKeys.forEach((key) => {
it(`contains key "${key}"`, () =>
expect(wrapper.find({ id: key }).length).toEqual(1)
)
})
});
});
@akkerman ์ข์ ์๋ฃจ์ ์ ๋๋ค. describe ๋ฐ it์ jest์์ ์ ๊ณตํ๋ ๋ง๋ฒ์ ์ ์ญ์ด๋ฏ๋ก ๋ชจํธํ๊ฒ ๋๊ปด์ง ์ ์๋ค๋ ์ ์ ์ธ์ ํด์ผ ํ๋ฏ๋ก ๋ฃจํ์์ 't'๋ฅผ ์ฐ๋ ๊ฒ์ด ์๋ํ ์ ์๋์ง ํ์ ํ ์ ์์์ต๋๋ค.
๋ค๋ฅธ ์์ ์๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
expect(foo).toEqual(bar).because('reason with %s placeholders')
๋๋ ์๋ง๋ ๊ธฐ๋ฅ
expect(foo).toEqual(bar).explainedBy((result) => `Lorem ipsum ${result}`)
๋ค๋ฅธ ์์์ด๋ ๋นจ๋ฆฌ ์ฝ์ ์ ์๊ฒ ๋๋ ๊ฒ ๊ฐ์์.
ํฐ
2018-04-19 13:47 GMT+02:00 ฮป โข Geovani de Souza [email protected] :
๋ค๋ฅธ ์์ ์๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
expect(foo).toEqual(bar).because('%s ์๋ฆฌ ํ์์๊ฐ ์๋ ์ด์ ')
๋๋ ์๋ง๋ ๊ธฐ๋ฅ
๊ธฐ๋(foo).toEqual(bar).explainedBy((๊ฒฐ๊ณผ) =>
Lorem ipsum ${result}
)โ
๋น์ ์ด ๋๊ธ์ ๋ฌ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ฐ๋ ๊ฒ์ ๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/facebook/jest/issues/1965#issuecomment-382705387 ๋๋ ์์๊ฑฐ
์ค๋ ๋
https://github.com/notifications/unsubscribe-auth/AAM5PwBCvET1KdEDeDEF7gGo708Naj8oks5tqHlSgaJpZM4Kc6Uu
.
--
ํ๋ฅด์ ์ด ํ์ธ
๋ชจ๋น: 920 63 413
expect
์๋ ๋ฐฉ์์ ๋์ง๋ ๊ฒ์ด๋ฏ๋ก ์ด์จ๋ ์๋ํ์ง ์์ต๋๋ค.
expect(something, 'some helpful text on failure').toEqual(somethingElse)
๋๋ expect.context(something, 'some helpful text on).toEqual(somethingElse)
๊ฐ ๊ฐ์ฅ ์ข์ ๋์์ด๋ผ๊ณ ์๊ฐํ์ง๋ง ๋ ์ค ์ด๋ ๊ฒ๋ ๋ง์์ ๋ค์ง ์์ต๋๋ค.
์ด๊ฑฐ ์ฌ๊ฐ๋ด ๊ฐ๋ฅํ๊ฐ์? Jest๋ ์ฌ์ ํ ์ฌ๋ฌ ์ํธ ์์ฉ์์ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋๋์ง ํ ์คํธํ๊ธฐ ์ํ ์ข์ ์๋ฃจ์ ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ด ๋ ๊ฒฝ์ฐ ๋ชจ๋ ์ผ๋ จ์ ์์
์ ์ํํ๊ณ ๊ฐ ์์
ํ์ ์ํ๊ฐ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋์๋์ง(๋๋ ๋ณ๊ฒฝ๋์ง ์์๋์ง) ์ฃผ์ฅํด์ผ ํ๋ฏ๋ก ๋ค์ค ์ฃผ์ฅ ํ
์คํธ๊ฐ ๋๋๋ก ํ์ํฉ๋๋ค. beforeEach
๋ก ์ด๋ฐ ์ข
๋ฅ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ํญ์ ๊ฐ๋ฅํ ๊ฒ์ ์๋๋๋ค.
์ ๋ ์ด๊ฒ์ด ์ ๋ง ์ ์ฉํ ์ํฉ์ ๊ณ์ ์ฐพ์ต๋๋ค. ํนํ @callumlock์ด ์ค๋ช ํ๋ ๊ฒ์ฒ๋ผ ์ฌ๋ฌ ์ํธ ์์ฉ ๋ฐ ์ด์ค์ ์ ์คํํ ๋.
์ฌ๋๋ค์ด ์ซ์ดํ์ง ์๋ API๋ฅผ ์๊ฐํด ๋ธ๋ค๋ฉด ์ด๊ฒ์ด ๋น์ ์ด ์ถ๊ตฌํ ์ํฅ์ด ์์ต๋๊น? ์ ๋ง ์ ์ฉํ๊ณ ๋ง์ด ์ฌ์ฉ๋๋ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ ์๋ ์๋ฃจ์ ์ ์์ฝํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
expect(api()).toEqual([]) // api without magic provides no items
it('api without magic provides no items', () => expect(api()).toEqual([]))
test('api without magic provides no items', () => expect(api()).toEqual([]))
expect(api()).toHaveNoItems()
expect(api(), 'api without magic provides no items').toEqual([])
expect(api()).because('api without magic provides no items').toEqual([])
since('api without magic provides no items').expect(api()).toEqual([]))
because('api without magic provides no items').expect(api()).toEqual([]))
jest.debug('api without magic provides no items'); expect(api()).toEqual([]))
.because()
ํํ์ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ์ต์
์ผ๋ก ํฌํจ๋์ง ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๊ทธ๋ฃน์ ๋ค ๊ฐ์ง ์ต์ ์ด ๋ชจ๋ ์ค๋ ์ง์๋ฉ๋๋ค. ๊ฐ์ธ์ ์ผ๋ก ์ฒซ ๋ฒ์งธ ์ต์ (์ฃผ์์ด ์๋ ์ฝ๋ ํ๋ ์)์ด ํ๋ฅญํ๊ฒ ์๋ํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค. ์ปค์คํ ๋งค์ฒ(์ต์ 4)๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ์ข์ต๋๋ค.
์ด์ ๋ํ ์์ง์์ ๋ง๋ค๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ์ดํดํด์ผ ํ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๊ทธ๋ฃน์ ์ต์ ๋ณด๋ค ๋ ๋ฒ์งธ ๊ทธ๋ฃน์ ์ต์ ์ ๋ํด ๋ ๋งค๋ ฅ์ ์ธ ์ ์ ๋ฌด์์ ๋๊น? ๋ ๋ฒ์งธ ๊ทธ๋ฃน์ ์ฐ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ๋ชจ๋ ๋งค์ฒ(๋น๋๊ธฐ ๋งค์ฒ, ๋น๋์นญ ๋งค์ฒ, ์คํ์ด ๋งค์ฒ, throw ๋งค์ฒ, ์ฝ์ ๋งค์ฒ ๋ฐ ์ฌ์ฉ์ ์ง์ ๋งค์ฒ)์ ๋ํ ํต์ฌ ์ ์ง ๊ด๋ฆฌ๋ฅผ ์ ๋นํํ ์ ์๋ ๋ฌด์์ ์ถ๊ฐํฉ๋๊น?
์๋
,
๊ธฐ๋ณธ์ ์ผ๋ก ๋ช ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๊ทธ๋ฃน ์ต์
์ ์ฃผ๋ก ์ฒซ ๋ฒ์งธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ํ ๊ฒ์
๋๋ค. ์ ์๋ ๋๋ก ๋์ ์ผ๋ก ์์ฑ๋ ์ด์ค์
์ด ํ์ํ ๊ฒฝ์ฐ ํ
์คํธ๊ฐ ๋ฃจํ์์ ์ ํ
์คํธ๋ฅผ ์์ฑํ ์ ์๋๋ก it
๋ฐ test
์ ๋ํ ํธ์ถ์ ์ค์ฒฉํ ์ ์์ต๋๋ค. ๋ฌธ์ ๋ ์ฃผ์ฅ ์ด ์๋๋ผ ํ
์คํธ ๋ฅผ ์์ฑํ๋ค๋ ๊ฒ์
๋๋ค. 1000๊ฐ ์์ ๋ฐฐ์ด์ ๊ฐ ์์์ ๋ํด ๋ฌด์ธ๊ฐ๋ฅผ ์ฃผ์ฅํ๊ณ ์ถ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ํ
์คํธ ์์ฝ์ด ๋ถํ๋ ค์ง๋๋ค.
์ด๋ฌํ ๋์ ์ฌ์ฉ ์ฌ๋ก๋ ์ฌ์ ํ ๋๋ฌผ๊ธฐ ๋๋ฌธ์ ์ ์ง ๊ด๋ฆฌ์์๊ฒ ์ต์ํ์ ์์
์ด ํ์ํ ์๋ฃจ์
์ ๊ณ ์ํด์ผ ํฉ๋๋ค. ์ ๋ ๊ฐ์ธ์ ์ผ๋ก because/since
์๋ฃจ์
์ ์ข์ํฉ๋๋ค. ๋งค์ฐ ๊ฐ๋จํ๊ฒ ๋ค๋ฆฌ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ตฌํ์ ๋๋ถ๋ถ expect
๋ฅผ try/catch
์ ๋ํํ์ฌ ๋ฉ์์ง๋ฅผ ์ธ์ํ๊ณ ๋ฐํํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
jest.debug
์ด์ํ๊ฒ ๋ค๋ฆฝ๋๋ค. ํ
์คํธ๊ฐ ์ค์ ๋ก ํต๊ณผํ๋๋ผ๋ ๋๋ฒ๊น
์ด ๋ฉ์์ง๋ฅผ ์ธ์ํ๋ ๊ฒ์
๋๋ค.
"๋ง์ง๋ง ์ธ์" ์ต์
๋ ์ข์ง๋ง expect
๊ฐ ๋ค์ํ ์ธ์๋ฅผ ํ์ฉํ ์ ์์ผ๋ฏ๋ก ์คํ ๊ฐ๋ฅํ์ง ํ์คํ์ง ์์ต๋๋ค.
๋๋ ์ด๋ค ์ต์
๋ ๊ด์ฐฎ์ต๋๋ค. ๋๋ ๋จ์ง ๊ทธ ๊ธฐ๋ฅ์ ์ํ๋ค. ์ ๋ jest.debug
API์ ๋ํด ๋ณ๋ก ๊ด์ฌ์ด ์์ง๋ง ์ด ๊ธฐ๋ฅ์ ์ํ๊ธฐ ๋๋ฌธ์ ์๋ฏธ๊ฐ ์๋ ์ ์ผํ API๋ผ๋ฉด ๊ด์ฐฎ์ต๋๋ค.
@kentcdodds ๊ธฐ์กด ์ต์ 4๊ฐ๋ ์ด๋ป์ต๋๊น?
@eric-burel test.each
๋ฐ describe.each
๊ฐ Jest 23์ ์ถ๊ฐ๋ ๊ฒ์ ๋ณด์์ต๋๊น(Jest <23์ ๊ฒฝ์ฐ ๋
๋ฆฝ ์คํํ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅ)?
๋ด๊ฐ ๋งํ๋ฏ์ด, ๋๋ ์ฐ๋ฆฌ๊ฐ ์ด๋ค ์ต์ ์ ์ ํํ๋์ง ๋ณ๋ก ์ ๊ฒฝ ์ฐ์ง ์์ต๋๋ค. ๊ธฐ๋ฅ์ด ์๊ธฐ๋ฅผ ๋ฐ๋ ๋ฟ์ ๋๋ค. ์ฐ์ ์์๋ฅผ ์ง์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ ๋๋ค.
expect(api(), 'api without magic provides no items').toEqual([])
because('api without magic provides no items').expect(api()).toEqual([]))
since('api without magic provides no items').expect(api()).toEqual([]))
expect(api()).because('api without magic provides no items').toEqual([])
jest.debug('api without magic provides no items'); expect(api()).toEqual([]))
(test|describe).each
๋ ํ๋ฅญํ์ง๋ง ๋จ์ผ ํ
์คํธ์์ ์ฌ๋ฌ ์์
/์ด์ค์
์ ์ฌ์ฉํ๋ ค๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง ๋ชปํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ํ์ฌ 4๊ฐ์ง ์ต์ ์ด ์์ต๋๋ค.
expect(api()).toEqual([]) // api without magic provides no items
it('api without magic provides no items', () => expect(api()).toEqual([]))
test('api without magic provides no items', () => expect(api()).toEqual([]))
expect(api()).toHaveNoItems()
์ด๊ฒ๋ค์ด ๋ญ๊ฐ ์๋ชป๋๋์? ์ ์๋ _new_ ์๋ฃจ์ ์ ์ด๋ฌํ ๊ธฐ์กด ์๋ฃจ์ ๋ณด๋ค ์ฝ๊ฐ ๋ ๋์ ๊ฒ ๊ฐ์ต๋๋ค. ์ ์ง ๊ด๋ฆฌ ๋น์ฉ์ ์ ๋นํํ ์ ์๋ ์ด์ ์ ๋ฌด์์ ๋๊น?
@rickhanlonii ๋์ค test.each
์ ๋ํด ๋ชฐ๋์ต๋๋ค. ์ ๋ง ์ข์ ๊ธฐ๋ฅ์
๋๋ค. ์ง์ ํด ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ๋ฐฐ์ด์์ ๋์ ์ผ๋ก ์์ฑ๋ ํ
์คํธ์ธ ๋ด ์ธ ๋ฒ์งธ ์ฌ์ฉ ์ฌ๋ก์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋์ ๊ทธ๊ฒ์ ๋ด๊ฐ ๋์ดํ ๋ ๋ฒ์งธ ํญ๋ชฉ์ ๋จ๊ฒผ์ต๋๋ค: ๋์ ์ผ๋ก ์์ฑํ๋ ์คํจ ๋ฉ์์ง๊ฐ ์์ด์ ๋๋ฒ๊น
์ด ๋ ๋นจ๋ผ์ก์ต๋๋ค. ์ง๊ธ์ ์ฌ์ฉ ์ฌ๋ก๊ฐ ๋ง์ง ์์ต๋๋ค. ์๋ง๋ ๊ฐ์ฒด ํ๋ ๊ฐ์ ํ
์คํธํ ๋ ์คํจ ์ ์ ์ฒด ๊ฐ์ฒด๋ฅผ ์ธ์ํ๊ณ ์ถ์ ๊ฒ์
๋๋ค. ๋ฏธ๋ฏธํ๊ฑฐ๋ ์ฝ๊ฐ ์ค๋ณต๋๋๋ผ๋ ํ
์คํธ ์์ฑ์ ๋ ์ฝ๊ฒ ๋ง๋๋ ๊ฒ์ ํฉ๋ฒ์ ์ธ imo์
๋๋ค. ๊ฒฐ๊ตญ ์ฐ๋ฆฌ๋ it
๋ฐ test
๋ ๋ค ์ธ ์ ์์ต๋๋ค. ์ฐจ์ด์ ์ด ์๋ ํ ์ด๊ฒ์ ๋๋ถ๋ถ ํธ์ํจ์ ์ํ ๊ฒ์
๋๋ค.
๋ฏธ๋ฏธํ์ง๋ง ์ด ์ค๋ ๋์์ ๋ณผ ์ ์๋ฏ์ด ์ฌ์ฉ์๊ฐ ์ค์ ๋ก ๊ธฐ๋ํ๋ ๊ฒ(๋ง์ฅ๋ ์์)์
๋๋ค.
ํธ์ง: it
๋๋ test
๋ฅผ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ํ
์คํธ์์ ํ
์คํธ๋ฅผ ์์ฑํ๊ณ ํ
์คํธ์ ๋ํด ๋์ ์ผ๋ก ์์ฑ๋ ์ด๋ฆ์ ์ ํจํ ์๋ฃจ์
์ด์ง๋ง ์ด์ค์
์์ฑ์ ์๋ฏธํ ๋ ํ
์คํธ ์์ฑ์ ์ ๋ง ์ข์ํ์ง ์์ต๋๋ค. . ์ด ์ค๋ ๋์์ ์๋ฃจ์
์ด ์ ๊ณต๋์ง ์์๋ค๋ฉด ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ์ง ์์์ ๊ฒ์
๋๋ค.
์ด๊ฑด ๋ฏธ์ณค์ด. expect()์ ๋ ๋ฒ์งธ ์ ํ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ณ ์ถ์ ์ฌ๋์ (์ ํ์ ์ผ๋ก), ์ฌ์ฉํ์ง ์๋ ์ฌ๋์ ์ฌ์ฉํ์ง ์์ ๊ฒ์ ๋๋ค.
Mocha๋ ์ด๊ฒ์ ์์ํ ํด์์ต๋๋ค... ๊ทธ๊ฒ์ ์ ๊ฐ ๋ช ๋ ์ ์ Jasmine์ ํฌ๊ธฐํ ์ด์ ์ค ํ๋์ ๋๋ค. ๋ค๋ฅธ ์ฌ์ค๋ฏผ ํ์๋ฌผ.
์ค๋ฅ ์ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ์ ๋ค๋ฅธ ๋ง์ ํ ์คํธ ํ๋ ์์ํฌ์ ๊ด๋ก์ด๋ฉฐ Jest์์๋ ์ด๋ฅผ ๋ณผ ์ ์๋ค๋ ์ฌ์ค์ ๋๋์ต๋๋ค. ์ด ์ค๋ ๋์์ ๋ง์ ์ ์ฉํ ์์ ๋ฅผ ์ฐพ์์ง๋ง(๊ฐ์ฌํฉ๋๋ค) ํ ์คํธ ์คํจ ์ ์ฌ์ฉ์ ์ง์ ์ค๋ฅ๋ฅผ ์ธ์ํ๋ ๋ช ์์ ์ธ ๋ฐฉ๋ฒ์ ์ถ๊ฐํ๋ ๊ฒ์ Jest์ ์ ์ฉ์ฑ์ ์ข์ ์ถ๊ฐ ์ฌํญ์ด ๋ ๊ฒ์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ค๋ฅธ ํ ์คํธ ํ๋ ์์ํฌ(JS๊ฐ ์๋ ํ๋ ์์ํฌ ํฌํจ)์ ์ต์ํ ๊ฐ๋ฐ์๊ฐ Jest๋ฅผ ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
@mattphillips ์ฌ์ฉ์ ์์ญ์ ์๋ฃจ์
์ด ์กด์ฌํ๋๋ก ํ๊ธฐ ์ํด ์ฌ๊ธฐ์์ jest-chain๊ณผ ์ ์ฌํ ์์
์ ์ํํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๊ณ ์๊ฐํ์ญ๋๊น? ์: expect
์ ๋ํ ๋ ๋ฒ์งธ ์ธ์
์์งํ ์ด๊ฒ์ ๋๋ถ๋ถ์ JS ํ ์คํธ ํ๋ ์์ํฌ์์ ๋งค์ฐ ํ์ค์ ์ธ ๊ฒ์ ๋๋ค. ์ฌ์ฉ์ ์ ์ ์ค๋ฅ ๋ฉ์์ง๋ก ๋ชจ๋ ํ ์คํธ๋ฅผ ์์ฑํ ๋ Jest์์ ์ฐพ์ง ๋ชปํ ๊ฒ์ ๋งค์ฐ ์ค๋งํ์ต๋๋ค.
@SimenB ์ฃ์กํฉ๋๋ค ์ค๋ ์์นจ์์์ผ ๊ทํ์ ๋ฉ์์ง๋ฅผ ํ์ธํ์ต๋๋ค!
์, ์ด๊ฒ์ userland์์ ํ ์ ์์ต๋๋ค. ๋ฐฉ๊ธ jest-expect-message
๋ก ์ถ์ํ์ต๋๋ค. https://github.com/mattphillips/jest-expect-message
ํผ๋๋ฐฑ ํ์:๋ฏธ์:
๊ต์ฅํฉ๋๋ค, ํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
@cpojer
์ด๊ฒ์ด ๋ณ๋ก ์ ์ฉํ์ง ์๋ค๊ณ ์๊ฐํ๋ ์ด์ ๋ ์์ง๋์ด๊ฐ ํ ์คํธ ์์ฑ์ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ค์ ๋ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ์ํด ์ฐ๋ฆฌ๊ฐ ํ๋ ๋ชจ๋ ์ผ์ ๋ ๋์ ํ ์คํธ๋ก ์ด์ด์ง ๊ฒ์ ๋๋ค.
๋๊ฐ์ง:
Jest์ ์ค๊ธฐ ์ ์ Mocha/Chai์ ํ ์ดํ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ด๊ฒ์ ์ ๋ง ๊ฑฐ๋ ์ฐจ๋จ๊ธฐ์ ๋๋ค. ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง ์ง์์ ๊ธฐ๋ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์ฌ์ฉ์ ์ ์ ๋งค์ฒ๋ฅผ ์์ฑํ๊ธฐ ์ํด expect.extend๋ฅผ ๋งํ๋ ๊ฒ์ "์์ง๋์ด๋ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๋ฐ ์๊ฐ์ ๋ญ๋นํ๊ณ ์ถ์ง ์์ต๋๋ค."๋ผ๋ ์ฒซ ๋ฒ์งธ ์ฃผ์ฅ์์ ํผํ๋ ค๊ณ ํ๋ ๊ฒ๊ณผ ์ ํํ ๊ฐ์ต๋๋ค.
๋๋ ๋จ์ ํ ์คํธ๋ฅผ ์ด๊ณ ์ค ๋ฒํธ๋ฅผ ๋ณด๋ ๊ฒ์ด ์ฝ๋ค๋ ๊ฒ์ ์์์ผ๋ฏ๋ก OP์ ์ ์ค ์ผ์ด์ค๋ ๋๋ฅผ ๊ท์ฐฎ๊ฒํ์ง ์์ต๋๋ค.
๋๋ฅผ ๊ดด๋กญํ๋ ์ฌ์ฉ ์ฌ๋ก๋ ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์ด๊ฑฐํ์ ๋ชจ๋ ๊ฐ์ ํ ์คํธํ๊ธฐ ์ํด ํ ์คํธ ๋ด๋ถ์ ๋ฃจํ๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค.
it("Should contain at least one word of every wordType", () => {
for (const wordType of wordTypes) {
expect(words.find((word) => word.wordType === wordType)).toBeTruthy();
}
});
์คํจํ๋ฉด ์ด๋ค wordType ๊ฐ์ด ์คํจํ๋์ง ๋ชจ๋ฆ ๋๋ค.
๋ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํ ์คํธ ๊ฒฐ๊ณผ๊ฐ ํฌํจ๋ ๋ฉ์์ง๋ก ๋์ฒดํ๊ณ ๋ฉ์์ง์ ์์ ํ ์คํธ ๊ฒฐ๊ณผ(์: true)๊ฐ ํฌํจ๋์ด ์์ ๊ฒ์ผ๋ก ์์ํ๋ ๊ฒ์ ๋๋ค. ์คํจํ๋ฉด Jest๋ ์ถ๊ฐ ์ ๋ณด๊ฐ ํฌํจ๋ ๋ฉ์์ง๋ฅผ ์ธ์ํฉ๋๋ค.
expect(`${wordType} ${!!words.find((word) => word.wordType === wordType)}`).toEqual(`${wordType} ${true}`);
Jest๋ ์ด๊ฒ์ ์ธ์ํฉ๋๋ค ...
expect(received).toEqual(expected)
Difference:
- Expected
+ Received
- 6 true
+ 6 false
... ์คํจํ์ ๋ wordType์ด 6์์ ์๋ ค์ค๋๋ค.
๋๋ ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ...
if (!words.find((word) => word.wordType === wordType)) {
expect(`Didn't find a word with wordType '${wordType}'`).toEqual(null);
}
@cwellsx test.each
๋ก ๋งค๊ฐ๋ณ์ํ๋ ํ
์คํธ๋ฅผ ํ์ธํ์ญ์์ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ฐ wordType์ด ์ค๋ช
์ ์ธ ์ ๋ชฉ์ด ์๋ ๋
๋ฆฝ์ ์ธ ํ
์คํธ๊ฐ ๋ฉ๋๋ค(๊ฐ ๊ธฐ๋ฐ).
์ด๊ฒ์ ๋ค์๊ณผ ๊ฐ์ ํ ์คํธ์์ ๋งค์ฐ ์ ์ฉํ ๊ฒ์ ๋๋ค.
test("compare ArrayBufferCursors", () => {
const orig: ArrayBufferCursor;
const test: ArrayBufferCursor;
expect(test.size).toBe(orig.size);
while (orig.bytes_left) {
expect(test.u8()).toBe(orig.u8());
}
});
์ง๊ธ์ ArrayBufferCursor์ ์ผ๋ถ ๋ฐ์ดํธ๊ฐ ์๋ชป๋์๋ค๋ ๊ฒ๋ง ์์ง๋ง ์ด๋ ๋ฐ์ดํธ์ธ์ง๋ ๋ชจ๋ฆ ๋๋ค. ์ธ๋ฑ์ค๋ฅผ ์ปจํ ์คํธ๋ก ์ถ๊ฐํ ์ ์์ผ๋ฉด ๋๋ฒ๊น ์ด ํจ์ฌ ์ฌ์์ง๋๋ค. ๊ณ ๋ง๊ฒ๋ ์ผ๋ถ ์ฌ๋๋ค์ ์ฌ๊ธฐ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ์ํ์ง๋ง ๋ชจ๋ ์ถํ๊ณ ๋๋ฆฝ๋๋ค.
@rickhanlonii , ๋๋ ๋น์ ์ด jest์ ์ ์ง ๊ด๋ฆฌ ๋น์ฉ์ ์ค์ด๊ณ ์ถ์ดํ๋ค๋ ๊ฒ์ ์ดํดํ์ง๋ง ๊ทํ์ ์๊ฒฌ ์์ ์ ๊ณตํ๋ ์ต์
์ ๋ค๋ฅธ ๋ชจ๋ ํ๋ก์ ํธ์ ๋จ์ ํ
์คํธ ์ ์ง ๊ด๋ฆฌ๋ฅผ ์ฆ๊ฐ์ํต๋๋ค. toEqual
๋ฅผ ์ฌ์ฉํ์ฌ assertion์ ์ค๋ช
ํ๊ณ ์ถ๋ค๋ฉด ์ด ์ ๋๋ฉด ์ถฉ๋ถํฉ๋๋ค. ์ ๋ง ์ปค์คํ
๋งค์ฒ๋ฅผ ์๊ฐํ๋ ๊ฑด๊ฐ์?!
it.each
๊ฐ ์ ์ฉํ ๋ฐ๋ณต ํ
์คํธ์ ๊ฒฝ์ฐ๊ฐ ์์ง๋ง ์ฃผ์ฅ์ ๋ํ ๊ฐ๋จํ ์ฃผ์์ ๋ถํ์ํ ์ฝ๋๋ฅผ ์ถ๊ฐํด์ผ ํ๋ฏ๋ก ์ด ํ
์คํธ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๊ธฐ๊ฐ ๋ ๋ฌด๊ฑฐ์์ง๋๋ค.
์ด ํ ๋ก ๊ณผ jest-expect-message
์ ์ถํ์ Jasmine์ beforeAll
๋ฌธ์ ์ ๋ํด ์๊ฐ๋๊ฒ ํฉ๋๋ค...
์ฌ๊ธฐ์์ OP์ ์์ฒญ์ ์คํดํ๊ณ ์์ ์ ์์ง๋ง ํด๊ฒฐํ๋ ค๊ณ ํ๋ ๋ฌธ์ ๋ ๊ฐ๋จํ try / catch
๋ฐ jest.expect
์ฃผ์์ ๋ํผ๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐ๋์์ต๋๋ค. ๋ด๊ฐ ํ๊ณ ์ถ์๋ ๋ชจ๋ ๊ฒ์ ๋ด๊ฐ ๊ธฐ๋ํ๋ ๊ฒ๊ณผ ๋ด๊ฐ ๋ฐ์ ๊ฒ๋ค + ๊ทธ ์ค์์ฑ์ ์ค๋ช
ํ๋ ๋ช ๊ฐ์ง ๊ธฐ๋ณธ ๋ก๊ทธ์ ์ ์ฒด๋ฅผ ๊ธฐ๋กํ๋ ๊ฒ์ด์์ต๋๋ค. ๋ฌผ๋ก ์ด๊ฒ์ ์ํ๋ ๋ชจ๋ ์์
์ ์ํํ๋๋ก ํ์ฅ๋ ์ ์์ต๋๋ค.
์ด๊ฒ์ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฒ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
in some test utility file...
const myExpect = (expectFn, errorCallback) => {
try {
expectFn();
} catch (err) {
errorCallback();
throw new Error(err);
}
};
// in the actual test suite...
const context = { hello: "world", results, expected };
myExpect(
() => expect(results).toEqual(expected),
() => console.error("[Error] -- context:", JSON.stringify(context))
);
+1
์๋
ํ์ธ์, ์ ๋ ์ด ๊ธฐ๋ฅ์ ์ ๋ง ์ข์ํฉ๋๋ค. ๊ทธ๊ฒ์ ๋ด ์ถ์ ํจ์ฌ ๋ ์ฝ๊ฒ ๋ง๋ค ๊ฒ์
๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด ํ ๋ก ๊ณผ ์ด ์ ์ฅ์ ์์ ๋ฉ์ง๊ณ ์๋ฏธ ์๋ ์ ์ฅ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ฌ์ฉ๋ฒ์
because
์ ๋น์ทํ์ง๋ง ์๋ฏธ์ ๋ ์๋ฏธ๊ฐ ์์ต๋๋ค.๋น์ ์ด ์ด๊ฒ์ ์ข์ํ๋ค๋ฉด ๋๋
since
๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ PR์ ํ ์ ์์ ๊ฒ์ ๋๋ค.