들어가며..
최근 프로젝트 팀원이 추천해준 영상을 보고
BDD
라는 것을 처음 알게 되었다. 해당 영상에서는 kotest와 mockk 테스팅 툴을 사용하여 TDD와 BDD의 차이점을 잘 설명해주고 있다.
최근 Kotlin 언어를 공부하고, Kotlin + Spring 조합으로 개발하는 것에 관심을 가지고 있다보니 꽤 흥미로웠다.영상 : https://tv.kakao.com/channel/3693125/cliplink/414004682
예제코드 : https://github.com/harry-jk/ifkakao-2020-code
TDD 에서 T가 Test 였다면, BDD 에서 B는 Behavior, 즉 행위이다.
일반적으로 테스트 코드를 작성할 때, given-when-then 형식으로 많이 작성하는데 BDD에서는 각각을 주어진 환경, 행위, 기대결과로 서술한다.
BDD는 행위에 초점을 맞춰 테스트를 작성하기 때문에 그 자체로 기획서와 동기화가 되며, 자연스럽게 서비스에 대한 이해도 높아지게 된다는 장점이 있다.
BDD와 TDD는 상호보완적인 관계이다.
BDD는 TDD에서 확인하기 어려운 유저 시나리오의 흐름을 알 수 있고, TDD는 각 모듈의 기능을 검증할 수 있다.
BDD의 테스트케이스로 시나리오 검증을 하고, 해당 시나리오에서 사용되는 각 모듈들은 TDD 테스트케이스로 검증을 해야 기대하는 테스트 커버리지를 가질 수 있다.
TDD (Test Driven Development) | BDD (Behavior Driven Development) | |
---|---|---|
테스트 코드의 목적 | 기능 동작의 검증 | 서비스 유저 시나리오 동작의 검증 |
테스트 코드의 설계중심 | 제공할 모듈의 기능 중심 | 서비스 사용자 행위 중심 |
테스트 코드 설계 재료 | 모듈 사양 문서 (개발자가 작성) | 서비스 기획서 (서비스 기획자가 작성) |
적합한 프로젝트 | 모듈/라이브러리 프로젝트 | 서비스 프로젝트 |
장점 | 설계 단계에서 예외 케이스들을 확인할 수 있다. | 설계 단계에서 누락된 기획을 확인할 수 있다. |
BDD의 장점을 유심히 보자!
BDD의 경우, 기획 시나리오의 빈틈(누락)을 테스트케이스 작성 시에 확인할 수 있다는 장점이 있다. 이는 이후에 기획의 변경으로 인한 대대적인 코드 수정을 예방할 수 있도록 해준다.
Kotlin을 위한 테스팅 툴로써, BDD 스타일과 TDD 스타일을 모두 지원한다.
BDD : BehaviorSpec, FeatureSpec
TDD : AnnotationSpec, ExpectSpec
Given/When/Then 구조를 지원하는 BDD용 스타일
예시
And
블록
class RegisterEmoticonFeature : BehaviorSpec() {
...
init {
Given("본인 인증된 사용자가 로그인된 상황에서") {
...
When("검수 정보를 입력란에") {
...
And("검수 정보를 입력하고 검수 등록 버튼을 누르면") {
...
Then("등록 결과가 포함된 검수 진행 목록 화면으로 이동한다") {
...
}
}
And("검수 정보를 입력하지 않고 검수 등록 버튼을 누르면") {
...
Then("검수 등록 실패 사유가 화면에 표시되어야 한다") {
....
}
}
}
}
}
}
Feature/Scenario 구조를 지원하는 BDD용 스타일
시나리오의 행위자를 특정하기 어렵고, 기능에 대해서만 쓰여져있는 기획에서 유용하게 쓸 수 있다.
class EmoticonFeature : FeatureSpec() {
init {
...
feature("이모티콘 검수 이메일 발송") {
...
scenario("""
2020-08-05 11:00:00(KST)에 전날 생성된 이모티콘 목록이
검수자에게 이메일 발송되어야 한다.
""".trimIndent()) {
...
}
}
}
}
JUnit 형태의 Testcase 작성을 하게 해주는 TDD용 스타일
class AccountServiceSpec : AnnotationSpec() {
@BeforeAll
fun setupStub() {
...
}
@AfterAll
fun clearStub() {
...
}
@Test
fun taskAccountIfExistByToken() {
...
}
@Test
fun takeNullIfNotExistByToken() {
...
}
}
DSL로 Testcase 작성을 하게 해주는 TDD용 스타일
class EmotionServiceSpec : ExpectSpec() {
...
init {
context("이모티콘 생성을 할 때") {
...
expect("계정과 이모티콘 정보, 이미지가 있으면 이모티콘이 생성된다.") {
...
}
}
}
}
kotest와 함께 사용하기 좋은 라이브러리이다.
kotest를 사용하고 있다면 mockk도 함께 사용해보자!
mockk은 다음과 같은 기능을 제공한다
정리하자면 BDD는 다음과 같은 큰 장점들을 가지고 있다.