[vue 3] 05. vitest를 이용한 단위 테스팅 2
- -
이번 포스트에서는 vitest에서 assertions을 작성하기 위해 사용하는 다양한 matcher들에 대해 살펴보자. 아래 내용들은 https://vitest.dev/api/expect.html 의 api들을 일부 요약한 것이므로 한번쯤 사이트에 방문하여 어떤 기능들이 있는지 가볍게 살펴보는 것을 권한다.
toBeXX
toBe
toBe는 기본형과 객체형을 === 연산자로 비교한 결과를 사용한다. 따라서 기본형은 형변환 없이 값이 같음, 참조형의 경우 같은 객체를 참조하고 있는지 즉 동일성을 검사한다.
test('toBe: 기본형과 객체형의 === 비교', () => {
const user = { age: 10 }
expect.soft(Math.sqrt(100)).toBe(10)
expect.soft(user).not.toBe({...user}) // not : !==
expect.soft(user).toBe(user)
expect.soft(1).not.toBe(true)
})
toBeXX
나머지 toBeXX들은 이름으로 뭐하는 녀석들인지 쉽게 추축이 가능하다. 그냥 toBe를 써도 충분하지만 뭔가 좀더 편하게 사용하려면 이녀석들을 써볼 수 있다. 가지수는 많지만 읽고 분석하는데 큰 어려움을 없을 것이다.
test('toBeUndefined, toBeDefined, toBeNull, toBeNaN', () => {
const myvar = undefined
expect(myvar).toBeUndefined()
expect(myvar).not.toBeDefined()
expect(myvar).not.toBeNull()
expect('a' / 100).toBeNaN()
})
test('toBeTruthy, toBeFalsy: true로 평가되거나 false로 평가되거나', () => {
const age = 10
expect(age).toBeTruthy()
expect(age).not.toBeFalsy()
})
test('부등호: toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual', () => {
const num1 = 1, num2 = 2
expect(num2).toBeGreaterThan(num1)
expect(num1).toBeLessThanOrEqual(num2)
})
test('toBeTypeOf, toBeInstanceOf: 특정 타입이거나, 특정 타입의 객체이거나', () => {
function User() {}
const user1 = new User()
expect(user1).toBeTypeOf('object')
expect(user1).toBeInstanceOf(User)
})
toBeCloseTo
toBe 계열에서 하나 기억해둘 녀석은 toBeCloseTo 이다.
실수를 이용한 연산은 부정확하기 때문에 늘 조심해야 한다. 예를 들어 0.1+0.2는 당연히 0.3이지만 연산을 해보면 0.30000000000000004이 나온다. 이런 경우 toBe 대시 toBeCloseTo를 사용해야 한다.
test('toBeCloseTo: 실수에 대한 toBe', () => {
expect.soft(0.1+0.2).not.toBe(0.3)
expect.soft(0.1 + 0.2).toBeCloseTo(0.3)
})
toXXEquals 계열
toEquals
toEquals는 객체형에서 사용하며 recursive 하게 속성의 값, 구조를 비교해서 동등성을 비교한다. 즉 toBe와 달리 내용을 비교하는 것이다. 이때 undefined는 무시한다.
test('toEqual: 객체형에 대해 recursive하게 속성 값, 구조 비교. undefined는 무시', () => {
const user1 = { name: 'quietjun', age: 30, addr: undefined }
const user2 = { name: 'quietjun', age: 30 }
expect(user1).not.toBe(user2)
expect(user1).toEqual(user2)
})
toStrictEqual
toStrictEqual은 좀 더 엄격한(strict) 동등성 비교로 toEqual은 3가지 정도 차이점이 있다.
- undefined 항목의 체크: {a:1, b:undefined}와 {a:1}은 다름.
-
sparseness(드문드문한) 배열 체크: [, 1]과 [undefined, 1]은 다름
-
개체 유형 검사: 클래스를 통한 instance와 리터럴을 통한 instance는 다름
test('toStrictEqual: 객체형에 대해 recursive하게 속성 값, 구조 비교', () => {
const user1 = { name: 'quietjun' }
const user2 = { name: 'quietjun', age: undefined }
expect(user1).toEqual(user2)
expect(user1).not.toStrictEqual(user2)
})
포함 여부 판단
toContain
toContain은 문자열 또는 배열에 대상이 포함되어있는지 판단한다. 특히 배열에서 대상의 포함 여부를 판단할 때는 toBe를 사용함에 주의하자.
const arr = ['Hello', 'vue', { name: 'quietjun' }]
const str = 'vue3programming'
test('문자열, 배열에 대상이 포함되는가?', () => {
expect(arr).toContain('vue', 'Hello')
expect(arr).not.toContain({ name: 'quietjun' }) // 포함 여부 판단 근거는 toBe
expect(str).toContain('ing')
})
toContainEqual
배열에 포함 여부를 검사할 때 toEqual을 적용하려면 toContainEqual을 이용하면 된다.
test('배열 요소에 대한 검사 시 toEqual 적용', () => {
expect(arr).not.toContain({ name: 'quietjun' }) // 판단 근거는 toBe
expect(arr).toContainEqual({ name: 'quietjun' }) // 판단 근거는 toEqual
})
toHaveProperty
객체가 어떤 속성(또는 그 속성의 값 까지)을 가지고 있는지 점검하기 위해서는 toHaveProperty를 사용한다. 만약 객체의 속성이 객체를 갖을때는 toEqual을 이용해서 검증한다.
test('특정 속성의 포함 여부', () => {
const user = { name: 'quietjun', addr: { home: 'seoul', office: 'busan' } }
expect(str).toHaveProperty('length') // 단순히 속성 존재만 확인
expect(arr[2]).toHaveProperty('name', 'quietjun') // 속성의 값까지 확인
// 객체의 비교는 toEqual
expect(user).toHaveProperty('addr', { home: 'seoul', office: 'busan' })
})
예외 상황 검사
toThrowError
toThrowError는 함수에서 반드시 오류를 발생해야 함을 검증한다. 주의할 점은 expect에서 그냥 함수를 호출하면 안되고 callback 함수를 작성 후 그 안에서 호출해야 한다.
function errorfunc() {
throw new Error('some error')
}
test('실행 결과 반드시 예외가 던져져야 함을 검사: toThrowError', () => {
// 테스트하려는 함수를 콜백 내에서 호출해야 함
// expect(errorfunc()).toThrowError("some error"); // 테스트 실패
expect(() => errorfunc()).toThrowError()
expect(() => {
throw new Error('some error')
}).toThrowError('some error') // 오류 내용 검증
expect(() => {
throw new Error('404 오류 발생')
}).toThrowError(/404/) // 정규 표현식으로 에러 메시지에서 검사
})
검증 과정에서 오류 내용을 검증할 수 있는데 정규 표현식을 이용해서 검색할 수 있는점도 매우 유용하다.
기타 검증
toSatisfy
toSatisfy는 predicate를 이용해서 검증하는 기법으로 함수의 반환 값이 predicate의 파라미터로 전달된다.
test('predicate를 이용해 검증: toSatisfy', () => {
expect(Math.pow(9,2)).toSatisfy((val) => val % 2 == 1)
expect('quietjun').toSatisfy((val) => val.length > 5)
})
toMatch
정규 표현식을 이용해서 문자열을 검증하려면 toMatch를 사용한다.
test('정규표현식을 이용한 패턴 검사: toMatch', () => {
expect('quietjun').toMatch(/[a-z]{5,}/)
})
resolves, rejects
vitest는 promise의 동작 결과를 검증하는 방법도 제시한다. 일단 비동기 동작에 대한 검증이기 때문에 test의 TestFunction은 async 형태로 작성해야 하며 expect를 await로 호출해주어야 한다. expect의 결과를 성공 시 resolves, 실패 시 rejects에 넘겨주고 이후 검증은 기존의 다른 matchers를 사용하면 된다.
function asyncFunc(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
(time%2==0)? resolve("even"):reject("odd");
}, 1000)
})
}
test('promise 동작 결과에 대한 검증', async () => {
await expect(asyncFunc(2)).resolves.toEqual('even')
await expect(asyncFunc(3)).rejects.toEqual('odd')
})
이 외에도 정말 다양한 matchers들이 제공되므로 필요에 따라 찾아보고 사용하자.
'Vue 3.0 > 03.SFC와 Vite' 카테고리의 다른 글
[vue 3] 07. vitest를 이용한 단위 테스팅 4 (0) | 2023.10.15 |
---|---|
[vue 3] 06. vitest를 이용한 단위 테스팅 3 (2) | 2023.10.06 |
[vue 3] 04. vitest를 이용한 단위 테스팅 1 (3) | 2023.10.04 |
[vite] package.json vs package-lock.json (0) | 2022.07.12 |
[vite] package.json의 버전 표시 (0) | 2022.07.12 |
소중한 공감 감사합니다