회사에서 테스트를 작성하면서 객체 구조가 복잡해서 테스트 준비과정이 어려워 기존에 적용되어 있던 Junit 외에 추가로 Spock을 도입하게 되었습니다.
Spock은 groovy 문법으로 유연하고 가독성 높은 테스트를 작성할 수 있는 테스트 프레임워크인데요.
적용 과정과 몇가지 팁을 공유합니다.
Spring Boot 프로젝트에 Spock 적용
1. build.gradle에 의존성 추가
...
ext {
...
spockVersion = "2.3-groovy-4.0"
}
depedencies {
...
testImplementation "org.spockframework:spock-core:${spockVersion}"
testImplementation "org.spockframework:spock-spring:${spockVersion}"
...
}
2. test 폴더에 groovy 폴더 추가
java와 동일한 폴더에 spock 테스트를 만들었을 때 런타임 이슈 발생했었습니다.
잘 해결하면 같은 폴더에서 할수도 있겠지만 별도 폴더로 Junit 테스트와 별도 관리했을 때 장점도 있겠다 싶어 별도 폴더로 두었습니다.
src
- main
- test
- groovy
- java
3. 테스트 생성
package com.example.product
import spock.lang.Specification
class FooTest extends Specification {
def "doSomthing은 true를 반화한다"() {
given:
def foo = new Foo()
when:
def result = foo.doSomething()
then:
result == true
}
}
Spock 테스트 팁
1. given, when, then 에도 설명 추가하기
아래와 같이 given, when, then에서 설명을 추가하여 가독성을 높일 수 있습니다.
def "doSomthing은 true를 반화한다"() {
given: "Foo 객체 준비"
def foo = new Foo()
foo.a = 'apple'
foo.b = 'banana'
when: "doSomething을 호출한다"
def result = foo.doSomething()
then: "true를 반환한다"
result == true
}
2. and를 활용해 그룹화하기
준비구절과 검증 구절이 길어질 때가 있는데요. and를 활용해서 그룹화 할 수 있습니다.
def "doSomthing은 true를 반화한다"() {
given: "Foo 객체 준비"
def foo = new Foo()
and: "Bar 객체 준비"
def bar = new Bar()
3. where의 데이터 테이블을 활용해서 설명 높이기
데이터 테이블을 활용하면 테스트 설명문과 각 영역에서 쉽게 변수를 활용할 수 있습니다.
input 파라미터들과 구분하기 위해 expected 앞에는 |가 아닌 ||로 구분하는 것이 국룰이라고 하니 코드 작성 시 참고 해주세요:)
def "#foo와 #bar가 주어비면 #expected이다"() {
when:
def result = doSomething(foo, bar);
then:
result == expected
where:
foo | bar || expected
1 | 2 || true
}
4. 반복문 안에서 검증하지 않기
팁이라기 보다는 주의사항인데요.
반복문 안에서 검증하는 경우 실패하더라도 테스트 결과에 반영되지 않습니다.
그래서 every로 처리하는 등의 다른 방법을 사용해야 합니다.
then: "foo 전체가 bar를 포함하는지 확인"
// (O)
foos.every(f -> f.conatins("bar"))
// (X)
for(def f : foos) {
f.conatins("bar") == true
}
5. 객체 생성은 기본 생성자로 하고 이후 필드 설정
Spock을 사용하면서 가장 불편했던 것이 컴파일 시점이 아니라 런타임에 타입 체크를 해주는 것입니다.
잘못된 생선자를 호출해도 런타임이 되어야만 알 수 있습니다.
유연함이 장점이기도 하지만 단점으로 작용하는 것인데요.
생성자를 선택할 때도 가능하다면 기본 생성자로 생성 후 필드를 별도로 설정해주는 것이 좋습니다.
이 외 메서드 호출 등에서도 언어적인 특성을 고려해서 테스트를 작성하는 것이 좋습니다.
'제안&정리' 카테고리의 다른 글
| [Java] 스레드 풀 설정 - corePoolSize, maxPoolSize, queueCapacity (2) | 2023.10.15 |
|---|---|
| [SQL] join에서 on vs where (0) | 2023.10.08 |
| [Spring] 동일 클래스의 Async 호출하기 (0) | 2023.07.09 |
| [JAVA] IntelliJ로 class -> record 변환 (0) | 2023.06.25 |
| 2023 AWS Summit Seoul Session Review (Day1) (0) | 2023.05.05 |