제목은 "박*영과 함께하는 spock framework pair programming"이라고 쓰고 사실 꼰대질(?!)을 정리한 것이다.
아마도.. TL;DR (too long, don’t read) 가 될 것 같다.
박*영 님은 같은 회사의 개발자이다.
기존에 jUnit으로 되어 있던 테스트 코드들을 Groovy 기반의 Spock 프레임워크를 도입해서 적용하고 있다고 한다.
처음 접하는 사람들이 공통적으로 겪을 수 있다고 생각해서 공유 및 기록 차원에서 끄적여보았다.
2020-01-14 (화) - 꼰대질1
포인트를 대량 적립해주는 서비스(가칭: MassiveAccumulatingService)에 대한 테스트를 만들고 있었다.
조언
1. 테스트의 이름
- 테스트 대상의 이름을 사용하는 것보다는 테스트가 수행하는 것에 대해 적는 것이 좋다고 권유했다.
예)
MassiveAccumulatingService sut
def "accumulate 테스트"() {
}
보다는
def "이미 데이터가 적립되어 있으면 InvalidStateException 예외가 발생한다."() {
// 생략
then:
thrown(InvalidStateException.class)
}
2. 테스트를 통한 테스트 대상(sut; system under test)에 대한에 대한 개선
- 테스트 코드를 만들다 보면 코드의 냄새(smell)가 느껴질 수 있음
- 예를 들면 SOLID의 원칙중 단일 책임의 원칙이 지켜지지 않았을 때 테스트가 지나치게 복잡하고, 같은 동작을 하는 것이 발생
- 테스트 코드는 1. 기능(비즈니스 로직)에 대한 테스트의 효과 뿐만 아니라 2. 리팩토링 도 하는 긍정적인 효과가 있다.
2020-01-16 (목) - 꼰대질2
*Test vs *Spec
인텔리제이에서는 command-shift-t 를 누르면 테스트 코드를 자동으로 만들어준다.
기본으로 Test로 끝나는 형태의 이름을 제안한다.
Spock 진영에서는 Specification의 줄임말인 Spec을 postfix로 쓰는 경우가 많다. (결국은 개취)
인텔리제이 설정 방법 좀 알려주세요~
where: 블럭
Spock의 블럭 중 where: 가 등장했다.
1. @Unroll 의 사용
2. placeholder를 통한 테스트 이름 이용
예)
@Unroll
def "isEntireCancel : 상품금액(#goodsAmt)과 취소금액(#cancelAmt)이면 #isExpectedEntireCancel"() {
given:
def sut = new RoomCancelParams()
sut.goodsAmt = goodsAmt
sut.cancelAmt = cancelAmt
when:
boolean result = sut.isEntireCancel()
then:
result == isExpectedEntireCancel
where:
goodsAmt | cancelAmt | isExpectedEntireCancel
10_000 | 10_000 | true
10_000 | 9_000 | false
}
위의 테스트 코드를 실행하면 아래와 같이 좀더 명시적인 테스트 결과가 목록에 리스트업 될 수 있다.
나의 경우 다른 응용 방법으로는 테스트에 직접적으로 필요하지는 않지만 테스트 이름을 받아서 표시하는 것도 종종 사용한다.
@Unroll
def "getHeader - #description"(String userAgentWhenCreated, String headerName, String userAgentExpected, String description) {
given:
sut = new MockHttpServletRequest(userAgentWhenCreated, "127.0.0.1")
when:
String response = sut.getHeader(headerName)
then:
response == userAgentExpected
where:
userAgentWhenCreated | headerName | userAgentExpected | description
"UA" | "User-Agent" | "UA" | "적용된 값을 잘 가져온다."
"Mozilla/5.0" | "User-Agent" | "Mozilla/5.0" | "다른 적용된 값을 잘 가져온다."
null | "User-Agent" | null | "적용된 값이 없으면 null을 반환한다."
"UA" | "Server" | null | "적용된 값이 있지만 다른 header를 가져오면 null을 반환한다."
}
2020-01-17 리스폰스 & 리스펙트
*영 님이 공유해주신 내용: IntelliJ IDEA에서 기본 테스트 클래스 접두어 바꾸기
기본 Test로 되어 있는데 Spock 테스트 코드는 Specification의 줄임말인 Spec으로 하는 경우가 있다.
테스트 대상이 MassiveAccumulatingService 라면 MassiveAccumulatingServiceSpec 처럼 말이다.
참고: https://stackoverflow.com/questions/35247586/change-default-test-class-name-suffix-in-intellij-idea
*영 님께 리스펙트! (역시 청출어람)
'Programing > 테스트' 카테고리의 다른 글
[test] 404 테스트 (0) | 2020.09.05 |
---|---|
[Java] Enum에 없는 값을 테스트할 때는 어떻게하지? (0) | 2020.01.22 |
[sonarqube] 'sonar.jacoco.reportPath' is deprecated 메시지 없애기 (0) | 2020.01.14 |
[Pokayoke] 휴먼에러를 어떻게 막지? (0) | 2019.12.24 |
[테스트] 테스트 코드의 회의 (0) | 2019.08.21 |