Kotlin에서의 BDD (Behavior Driven Development)

wisdom·2022년 11월 15일
0

Kotlin

목록 보기
1/1
post-thumbnail

들어가며..

최근 프로젝트 팀원이 추천해준 영상을 보고 BDD 라는 것을 처음 알게 되었다. 해당 영상에서는 kotest와 mockk 테스팅 툴을 사용하여 TDD와 BDD의 차이점을 잘 설명해주고 있다.
최근 Kotlin 언어를 공부하고, Kotlin + Spring 조합으로 개발하는 것에 관심을 가지고 있다보니 꽤 흥미로웠다.

영상 : https://tv.kakao.com/channel/3693125/cliplink/414004682
예제코드 : https://github.com/harry-jk/ifkakao-2020-code

BDD (Behavior Driven Development) 란

  • TDD에서 파생된 개발 방법론
  • 개발자와 비개발자간의 협업 과정을 녹여낸 방법
  • 사용자의 행위를 작성하고 결과를 검증한다.
  • BDD로 테스트 코드를 작성하면, 설계 역시 행위 중심이 되는 도메인 기반 설계가 된다.

TDD 에서 T가 Test 였다면, BDD 에서 B는 Behavior, 즉 행위이다.

일반적으로 테스트 코드를 작성할 때, given-when-then 형식으로 많이 작성하는데 BDD에서는 각각을 주어진 환경, 행위, 기대결과로 서술한다.

  • given : 주어진 환경 (ex. 본인 인증된 사용자가 로그인된 상황에서)
  • when : 행위 (ex. 검수 정보를 입려갛고 검수 등록 버튼을 누르면)
  • then : 기대결과 (ex. 등록 결과가 포함된 검수 진행 화면으로 이동한다)

BDD는 행위에 초점을 맞춰 테스트를 작성하기 때문에 그 자체로 기획서와 동기화가 되며, 자연스럽게 서비스에 대한 이해도 높아지게 된다는 장점이 있다.


TDD와 BDD의 차이

BDD와 TDD는 상호보완적인 관계이다.

BDD는 TDD에서 확인하기 어려운 유저 시나리오의 흐름을 알 수 있고, TDD는 각 모듈의 기능을 검증할 수 있다.

BDD의 테스트케이스로 시나리오 검증을 하고, 해당 시나리오에서 사용되는 각 모듈들은 TDD 테스트케이스로 검증을 해야 기대하는 테스트 커버리지를 가질 수 있다.

 TDD (Test Driven Development)BDD (Behavior Driven Development)
테스트 코드의 목적기능 동작의 검증서비스 유저 시나리오 동작의 검증
테스트 코드의 설계중심제공할 모듈의 기능 중심서비스 사용자 행위 중심
테스트 코드 설계 재료모듈 사양 문서 (개발자가 작성)서비스 기획서 (서비스 기획자가 작성)
적합한 프로젝트모듈/라이브러리 프로젝트서비스 프로젝트
장점설계 단계에서 예외 케이스들을 확인할 수 있다.설계 단계에서 누락된 기획을 확인할 수 있다.

BDD의 장점을 유심히 보자!

BDD의 경우, 기획 시나리오의 빈틈(누락)을 테스트케이스 작성 시에 확인할 수 있다는 장점이 있다. 이는 이후에 기획의 변경으로 인한 대대적인 코드 수정을 예방할 수 있도록 해준다.


kotest

Kotlin을 위한 테스팅 툴로써, BDD 스타일과 TDD 스타일을 모두 지원한다.

BDD : BehaviorSpec, FeatureSpec
TDD : AnnotationSpec, ExpectSpec

BehaviorSpec

Given/When/Then 구조를 지원하는 BDD용 스타일

예시

And 블록

  • 해당 컨텍스트 안에서 하위 분기를 할 수 있다.
  • 즉, 중복된 서술을 하지 않아도 상위에 서술된 동일한 내용을 테스트 결과에 출력할 수 있고, 같은 상위 코드 블록을 사용함으로서 변수도 공유할 수 있다.
class RegisterEmoticonFeature : BehaviorSpec() {
    ...
    init {
        Given("본인 인증된 사용자가 로그인된 상황에서") {
            ...
            When("검수 정보를 입력란에") {
                ...
                And("검수 정보를 입력하고 검수 등록 버튼을 누르면") {
                    ...
                    Then("등록 결과가 포함된 검수 진행 목록 화면으로 이동한다") {
                        ...
                    }
                }

                And("검수 정보를 입력하지 않고 검수 등록 버튼을 누르면") {
                    ...
                    Then("검수 등록 실패 사유가 화면에 표시되어야 한다") {
                        ....
                    }
                }
            }
        }
    }
}

FeatureSpec

Feature/Scenario 구조를 지원하는 BDD용 스타일
시나리오의 행위자를 특정하기 어렵고, 기능에 대해서만 쓰여져있는 기획에서 유용하게 쓸 수 있다.

class EmoticonFeature : FeatureSpec() {
    init {
        ...
        feature("이모티콘 검수 이메일 발송") {
            ...
            scenario("""
                2020-08-05 11:00:00(KST)에 전날 생성된 이모티콘 목록이
                검수자에게 이메일 발송되어야 한다.
            """.trimIndent()) {
                ...
            }
        }
    }
}

AnnotationSpec

JUnit 형태의 Testcase 작성을 하게 해주는 TDD용 스타일

class AccountServiceSpec : AnnotationSpec() {

    @BeforeAll
    fun setupStub() {
		...
    }

    @AfterAll
    fun clearStub() {
		...
    }

    @Test
    fun taskAccountIfExistByToken() {
		...
    }

    @Test
    fun takeNullIfNotExistByToken() {
        ...
    }
}

ExpectSpec

DSL로 Testcase 작성을 하게 해주는 TDD용 스타일

class EmotionServiceSpec : ExpectSpec() {
    ...
    init {
        context("이모티콘 생성을 할 때") {
            ...
            expect("계정과 이모티콘 정보, 이미지가 있으면 이모티콘이 생성된다.") {
                ...
            }
        }
    }
}

+) mockk

kotest와 함께 사용하기 좋은 라이브러리이다.

kotest를 사용하고 있다면 mockk도 함께 사용해보자!

mockk은 다음과 같은 기능을 제공한다

  • mocking : mock을 생성하여 어떠한 행위를 할 것인지 사전 정의
  • verify : 해당하는 행위가 원하는대로 시행되었는지 검증

정리

정리하자면 BDD는 다음과 같은 큰 장점들을 가지고 있다.

  • 기획서를 통한 TestCase 작성으로 작성에 대한 비용 감소
  • TDD보다도 더 넓은 테스트 커버리지 확보 가능
  • 설계 변경에 따른 리스크 최소화
  • 서비스의 이해도 증가
profile
백엔드 개발자

0개의 댓글