Kotest와 BDD, 테스트 코드 작성하기 전 읽어두면 좋을 자료들

effiRin·2023년 6월 14일
0

Kotest

목록 보기
1/1
post-thumbnail
post-custom-banner

해당 글은
BDD(Behavior Driven Development) 방식의 테스트 스타일과,
Kotest 프레임워크의 BehaviorSpec을 사용하는 것으로 가정하고
작성하는 것을 미리 알려드립니다.



Cucumber의 BDD 작성 가이드

일단 BDD 방식으로 테스트 코드를 짜겠다고 마음 먹었는데
테스트 문장은 어떻게 구성해야 맞는 걸까? 고민하다가 아래 글을 참고하게 되었다.

참고로 Cucumber는 BDD 방식의 테스트 프레임워크이다.
테스트 프레임워크는 다르지만 어쨌든 테스트 방법은 같으니까 참고해도 좋을 것 같다.

  • 3인칭 한 명의 시점으로 작성하라
    • 1인칭(나), 2인칭(그/그녀) 등 1,2인칭 시점을 쓰면 상황적 제한이 생길 수 있다. 3인칭 시점으로 보편화하여 적는 것이 포인트
    • 시나리오는 나를 포함하여 소프트웨어를 사용하는 ‘사용자’를 설명하기 때문에 개인적으로 User(유저)라는 단어를 선호한다.
  • Step 내에서 접속사를 쓰지말아라.
    • 스탭 자체 내에서 ‘그리고, 그러면, 하지만’ 등의 접속사는 피한다.
    • 접속사가 들어간다는 것은 한 가지 이상의 행동이나 확인이 필요하다는 뜻으로, 다른 스텝으로 쓰거나 다른 시나리오로 써야한다.
  • GIVEN(조건)은 과거형 또는 현재형으로 쓴다.
    • 조건 스텝은 시나리오 전제조건을 조성하는 스텝이다.
    • 이 스텝은 과거형으로 적어서 전제조건이 확립된 것으로 작성하며
    • 각 시나리오 최대한 단 한 개의 조건 스텝만 작성하도록 한다.
  • WHEN(만일, 만약)은 현재형으로 쓴다.
    • 이 스텝은 시나리오 내에서 이루어지는 ‘행동’이나 ‘변화’를 포함한다.
    • 그러므로 이 스텝은 현재형으로 작성하여 간결화한다.
    • 예) 유저가 로그인 버튼을 클릭하고, (유저가) 화면을 위로 스크롤하면, user enters an email
  • THEN(그러면)은 현재완료형으로 쓴다.
    • 그러면 스텝은, 만약 스텝이 행해졌을 시 예상하는 완료 상태에 대해 설명하기 때문에 완료형으로 적는다.
    • 예) 유저는 성공적으로 로그인이 된다. 리스트의 가장 마지막 아이템을 화면에 보이게 된다. button is enabld, image is displayed
  • AND(그리고) & BUT(하지만, 단) 은 바로 이전 스텝의 시제를 따라간다.
    WHEN의 AND나 BUT이면 현재형으로, THEN의 AND나 BUT이면 완료형으로 적는다.

출처 : 🥒 Cucumber 이해하고 잘 쓰는 방법



kotest 그리고 TDD와 BDD

kotest 프레임워크는 정했는데 TDD와 BDD 사이를 방황하고 있다면?
아래 자료를 참고하면 아주 좋을 것 같다.

kotest가 있다면 TDD 묻고 BDD로 가!
-> 해당 영상의 요약정리글 : Kotlin에서의 BDD (Behavior Driven Development)
-> 해당 영상의 예제 코드 : https://github.com/harry-jk/ifkakao-2020-code


  • 이 자료에서 핵심 내용은 다음과 같다.
    1. 먼저, 테스트할 코드부터 Testable하게(테스트하기 쉽게) 짜야한다.
    2. BDD와 TDD는 상호보완적 관계다. 둘이 적절히 섞어서 쓰자.

  • Testable - 테스트하기 쉽게 만들어진 코드
    • 테스트를 쉽게 하기 위해서는 테스트할 모듈의 역할이 명확해야 되는데 이러기 위해서는 모듈의 역할을 단순화는 작업이 필요합니다.
    • 테스터블한 곳에 작성은 모듈 크기를 줄이는 설계를 유도하고 모듈 또는 계층간의 커플링도 적게 만들어 유지보수와 확장이 가능하게 하는 장점이 있습니다.
  • BDD와 TDD는 상호보완적인 관계이다.
    • BDD는 TDD에서 확인하기 어려운 유저 시나리오의 흐름을 알 수 있고, TDD는 각 모듈의 기능을 검증할 수 있다.
    • kotest는 BDD 스타일과 TDD 스타일 모두 지원한다.
      • BDD : BehaviorSpec, FeatureSpec
        • BehaviorSpec - Given/When/Then 구조를 지원하는 BDD용 스타일
        • FeatureSpec - Feature/Scenario 구조를 지원하는 BDD용 스타일
          시나리오의 행위자를 특정하기 어렵고, 기능에 대해서만 쓰여져있는 기획에서 유용하게 사용
      • TDD : AnnotationSpec, ExpectSpec
        • AnnotaionSpec - JUnit 형태의 Testcase 작성을 하게 해주는 TDD용 스타일
        • ExpectSpec - DSL로 Testcase 작성을 하게 해주는 TDD용 스타일


kotest Assertion 알아보기

이제 본격적으로 kotest를 작성하려는데..
assertion은 뭐가 있지? 해서 찾아본 자료.


Kotest 해보기



Kotest의 LifeCycle Hook

Kotest에선 BDD를 지원하는 BehaviorSpec, DescribeSpec이 존재한다.
이때 위 두 스펙은 중첩 테스트인데, 중첩 테스트의 경우 테스트 수명 주기를 이해하는 것이 매우 중요하다.


사실 이 부분은 개인적으로 굉장히 헤맸던 부분이다.

테스트를 시작하기 전, 특정 설정을 하고 싶어서 (예 : 테스트 계정 로그인 설정 등)
JUnit의 BeforeTest, AfterTest과 같이 Hook 역할을 하는 함수들을 찾아보았다.
그래서 찾은 BeforeSpec, BeforeContainer, BeforeEach 등...
-> 공식 문서 : Lifecycle hooks | Kotest

그런데 Kotest의 nestedSpec(BehaviorSpec, DescribeSpec)에서 이 메소드들을 사용한다면...
Given, when, then 중 어디서 얼마나 반복되어 실행되는지가 굉장히 헷갈린다.


그래서 나처럼 한참 헤매고 삽질하기 전에 미리 봐두면 좋을 자료...

고품격 Kotlin 개발: 테스트 코드를 우아하게 작성하는 방법 #우아콘2022 #Day2_음식그이상의것을문앞으로



  • 해당 영상에서 테스트 수명 주기에 대한 내용을 요약하면 아래와 같다.

➡️ 테스트 영역 전체가 Spec이며, beforeSpec 혹은 AfterSpec으로 리슨을 할 수 있다.



➡️ given, when, then만 두고 봤을 때 이들을 묶어 container라고 부르고,
beforeContainer, afterContainer라는 메소드로 수명주기를 관리할 수 있다.



➡️ then은 beforeEach, afterEach라는 메소드로 수명주기를 관리할 수 있다.

이렇게 수명주기에 대해서 알고 나면 어느 시점에 트랜잭션을 롤백 해야 될지,
어느 시점에 mockk 객체를 초기화 해야 될지 등에 대한 경계를 확실히 알 수 있다.



profile
모종삽에서 포크레인까지
post-custom-banner

0개의 댓글