일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- ReactHooks
- satisfiles
- css
- hook
- go
- tanstackquery
- Spring
- React
- test
- RTK
- 티스토리챌린지
- react-hook-form
- Redux
- JPA
- 웹애플리케이션서버
- Gin
- storybook
- java
- 오블완
- component
- backend
- typescript
- Chakra
- frontend
- javascript
- golang
- JavaSpring
- springboot
- designpatterns
- Today
- Total
bkdragon's log
[TEST] 프론트의 단위 테스트와 BDD 본문
단위테스트는 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트를 말한다. 프론트엔드에선 하나의 컴포넌트를 테스트 하는 것으로 봐도 된다. 컴포넌트의 원하는 요소가 렌더링 되었는지 사용자 상호작용에 알맞게 반응하는 지 등을 테스트 하면 된다. 단위 테스트에서 실제 기능까지 테스트할 필요는 없다.
BDD는 프론트의 단위 테스트(및 통합 테스트)에 사용하기 좋은 패턴이다.
Behavior Driven Development, 행동(시나리오) 주도 개발을 뜻한다. TDD를 기반으로 두며, 시나리오 기반으로 테스트 코드를 작성하며 함수 단위 테스트를 권장하지 않는다. 시나리오는 개발자가 아닌 사람이 봐도 이해할 수 있을 정도의 레벨을 권장한다.
BDD는 Describe - Context - It 패턴을 사용한다. 이 3가지는 각각 다음과 같은 내용을 뜻한다.
- Describe : 설명할 테스트 대상을 명시, 테스트 대상이 되는 클래스, 메서드 이름을 명시한다.
- Context : 테스트 대상이 놓인 상황을 설명, 테스트할 메서드에 입력할 파라미터를 설명한다. ~인 경우, ~ 할 때, ~ 하다면 과 같이 상황 또는 조건을 기술한다.
- It : 테스트 대상의 행동을 설명, 테스트 대상 메서드가 무엇을 리턴하는지 설명한다. ~ 이다, ~한다, ~를 갖는다 와 같은 결과를 기술한다.
BDD 패턴을 사용하면 테스트 코드는 명세서와 같아진다!!
이 부분이 엄청난 강점이라고 생각한다. 사실상 명세서를 옮겨적은 것 같은 형태를 지닌다.
할 일을 보여주는 TodoItem 컴포넌트의 요구사항(명세서)이 다음과 같다.
1. 할 일이 보여야 한다.
2. 체크 박스가 보여야 한다
3. 체크 박스를 클릭하면 할 일에 취소선이 그어져야 한다.
4. 삭제 버튼을 누르면 해당 할 일이 목록에서 사라진다.
이 요구사항을 기반으로 테스트 코드의 틀을 작성하면 다음과 같이 된다.
describe('todoitem', () => {
const sampleTitle = 'sample'
const sampleId = Math.random()
const handleCheckBox = jest.fn()
const renderTodoItem = ({
title,
id,
done
} : ITask) =>
render(
<TodoItem
title={title}
id={id}
done={done}
handleCheckBox={handleCheckBox}
/>
)
it('할 일이 보여야한다.', () => {
})
it('체크 박스가 보여야한다.', () => {
})
context('체크 박스를 클릭하면', () => {
it('handleCheckBox가 호출 되어야 한다..', () => {
})
})
context('done 값이 true면 ', () =>{
it('취소선이 그어져야 한다.', () => {
})
})
contenxt('삭제 버튼을 누르면', () => {
it('handleDelete가 호출되어야 한다.', () =>{
})
})
})
코드 내부의 글만 보면 요구사항을 옮겨적은 것이나 마찬가지이다. 이걸 먼저 작성하게 되면 요구사항을 상기시키며 더 좋은 코드를 작성하는데 도움이 될 것이다.
좋은 코드의 정의는 개발자마다 다르겠지만 방금 언급한 좋은 코드는 테스트를 짜기 좋고 쉽게 통과할 수 있는 코드를 뜻한다.
상상해보자. TodoItem 컴포넌트는 아마도 TodoList 컴포넌트 내부에서 tasks라는 할 일이 들어있는 배열을 map으로 돌면서 나오는 하나의 할 일을 보여주는 것 일거다. TodoItem으로 분리 하지 않고도 충분히 코드를 짤 수 있지만 그렇게 하게 되면 어떤 문제가 발생할까? 바로 done 값에 대한 취소선 테스트를 하기 보다 어려워 질 것이다. 이는 당연하다. done을 props로 받지 않는다면 외부에서 값이 어떤 상태인지 확인 할 수 없다. 실제 기능을 테스트하는 통합 테스트까지 넘어가야지만 취소선이 그어지는지 테스트 할 수 있을 것이다.
BDD를 활용하여 테스트 코드를 짜면서 좋은 컴포넌트 구조에 대해 고민해보자.
'concept' 카테고리의 다른 글
Flux 패턴 (0) | 2023.07.17 |
---|---|
[TEST] MSW와 통합 테스트 (0) | 2023.07.12 |
[Test] Jest, React-testing-library (0) | 2023.07.07 |
[JavaScript] Call Stack, Callback Queue (0) | 2023.06.24 |
react-daum-postcode, antd, react-hook-form 조합하기 (0) | 2023.03.27 |