Search
🧪

BDD 테스트 작성 기법

1) Describe는 어떻게 작성하는가?

테스트 대상 메소드를 명시한다
@Nested @DisplayName("update 메소드는") class Describe_update { // 생략 }
Java
복사

2) Context는 어떻게 작성하는가?

테스트 대상 메소드(Describe)가 사용될 수 있는 상황에 대해 명시한다
상황에 대한 명시를 강조하기 위해 'when', 'with' or 'without'으로 시작한다
@Nested @DisplayName("update 메소드는") class Describe_update { @Nested @DisplayName("만약 기본 생성된 Task를 수정한다면") class Context_with_default_task { // 생략 } @Nested @DisplayName("만약 존재하지 않는 Task를 수정한다면") class Context_without_existing_task { // 생략 } }
Java
복사

3) It은 어떻게 작성하는가?

명시성을 높이기 위해 짧게 작성한다(40자 이내 권장)
만약 너무 길어진다면 관련 상황과 조건을 Context로 분리한다
it 'has 422 status code if an unexpected params will be added' do // to when not valid it should respond with 422
Plain Text
복사

4) 하나의 테스트에는 하나의 assertion만 존재해야하는 이유는?

독립적인 환경에서 각각의 테스트케이스를 실행하여 테스트의 신뢰성을 보장 받기 위함
테스트 실패 시, 빠르게 원인을 파악하기 위함
예외적으로, 테스트 환경 구성에 많은 자원이 소모되는 테스트(DB 통합, Web Mock 등)의 경우 동일한 테스트 환경을 여러번 setup하는 것은 매우 큰 비용을 초래하므로 하나의 테스트 케이스에 여러개의 assertion을 담을 수 있음

5) 모든 가능한 테스트케이스를 구상할 수 있는 방법은?

Valid, Invalid, Edge 케이스로 나눠서 구상할 필요가 있음
describe '#destroy' do context 'when resource is found' do it 'responds with 200' it 'shows the resource' end context 'when resource is not found' do it 'responds with 404' end context 'when resource is not owned' do it 'responds with 404' end end
Plain Text
복사

6) 테스트 코드와 구현 코드의 결합도를 낮추기 위한 방법은?

Context 단위에서 중복되는 부분을 추상 클래스를 정의하는 방법과 It 단위에서 중복되는 부분을 subject 클래스로 정의하는 방법이 있다.
→ 구현 코드 수정에 따라 테스트 코드에 수정사항을 반영할 때, 별개로 정의된 부분만 수정하면 됨으로 테스트 유지보수성이 향상된다

7) Mock 객체는 왜 꼭 필요한 경우에만 제한적으로 사용해야 하나?

Mock 객체는 실제 객체와 달리 사용자의 정의 아래서만 동작하므로 테스트의 범위가 제한적이다.
Mock 객체를 제대로 정의하기 위해서는 많은 비용이 소모되므로 가성비가 떨어진다.
외부 API나 개발자가 직접 조작할 수 없는 객체 대상으로만 Mock 객체를 정의하여 테스트하는 방향이 가성비가 좋다

Reference