본문 바로가기
[개발] Test

Spock Framework

by Devsong26 2024. 8. 11.

Spock은 Java 및 Groovy 애플리케이션을 위한 테스트 프레임워크로, BDD(Behavior-Driven Development) 스타일의 테스트 작성과 강력한 기능을 제공합니다. Spock은 테스트 코드를 간결하고 가독성 있게 작성할 수 있도록 돕고, Groovy의 메타프로그래밍 기능을 활용하여 매우 직관적이고 표현력이 높은 테스트 코드를 작성할 수 있게 해줍니다.

Spock의 주요 특징

  • BDD 스타일:
    • Spock은 BDD 스타일을 따르며, given, when, then, expect 같은 키워드를 사용하여 테스트의 의도를 명확히 표현할 수 있습니다. 이를 통해 테스트가 스펙(specification)처럼 읽히도록 작성할 수 있습니다.
    • 예시:
class ExampleSpec extends Specification {
    def "maximum of two numbers"() {
        expect:
        Math.max(a, b) == c

        where:
        a | b || c
        1 | 3 || 3
        7 | 4 || 7
        0 | 0 || 0
    }
}

 

  •  Groovy와의 통합:
    • Spock은 Groovy 언어의 특성과 기능을 최대한 활용합니다. 이로 인해, Groovy의 유연성과 간결한 문법을 바탕으로 테스트 코드를 더욱 간단하고 효율적으로 작성할 수 있습니다.
    • 데이터 드리븐 테스트(Parameterized tests)를 쉽게 작성할 수 있도록 where 블록을 사용하여 다양한 입력값을 테이블 형식으로 정의할 수 있습니다.
  • 기본 제공 Mocking 및 Stubbing:
    • Spock은 객체의 Mocking 및 Stubbing 기능을 기본으로 제공합니다. 이를 통해 외부 의존성을 간단히 대체하거나 테스트할 수 있습니다.
    • 예시:
def "test with mock"() {
    given:
    def service = Mock(MyService)
    service.doSomething() >> "mocked result"

    expect:
    service.doSomething() == "mocked result"
}

 

  •  강력한 확장 기능:
    • Spock은 확장 가능한 구조를 가지고 있어, 커스텀 확장 기능을 쉽게 추가할 수 있습니다. 이를 통해 특수한 요구 사항을 충족하는 맞춤형 테스트 환경을 구성할 수 있습니다.
  • JUnit 통합:
    • Spock은 JUnit과의 호환성을 제공하므로, 기존 JUnit 기반의 테스트 프레임워크와 함께 사용할 수 있습니다. 또한, JUnit 테스트 러너를 사용하여 Spock 테스트를 실행할 수 있습니다.

Spock 사용 방법

  • 프로젝트 설정:
    • Maven 또는 Gradle을 사용하여 Spock을 프로젝트에 추가할 수 있습니다.
    • 예를 들어, Gradle에서는 다음과 같이 설정할 수 있습니다:
dependencies {
    testImplementation 'org.spockframework:spock-spring:2.3-groovy-3.0'
}

 

  •  테스트 클래스 작성:
    • Spock 테스트는 Specification 클래스를 상속하여 작성됩니다.
    • Groovy 또는 Java를 사용하여 테스트 클래스를 작성할 수 있으며, Groovy의 유연성을 최대한 활용하는 것이 일반적입니다.
  • 테스트 실행:
    • Gradle, Maven, 또는 IDE에서 Spock 테스트를 실행할 수 있습니다. JUnit 기반의 테스트 러너가 Spock 테스트를 실행할 수 있기 때문에, 기존 JUnit 설정과 함께 사용할 수 있습니다.

Spock의 장점과 단점

장점:

  • 가독성: BDD 스타일의 문법을 통해 테스트 코드가 매우 직관적이고 가독성이 높습니다.
  • 데이터 드리븐 테스트: where 블록을 사용해 다양한 입력값에 대한 테스트를 간결하게 작성할 수 있습니다.
  • 통합성: JUnit과의 호환성 덕분에 기존 Java 테스트 프레임워크와 쉽게 통합할 수 있습니다.
  • Groovy의 장점 활용: Groovy의 동적 특성과 간결함을 통해 테스트 작성이 간편해집니다.

단점:

  • 학습 곡선: Groovy에 익숙하지 않은 개발자에게는 Spock의 문법이 다소 생소할 수 있습니다.
  • 성능: Groovy 기반이므로 순수 Java 기반 테스트 프레임워크에 비해 성능이 떨어질 수 있습니다.

Spock은 특히 복잡한 비즈니스 로직을 테스트하는 데 강력한 도구이며, Groovy와의 결합을 통해 테스트 코드를 더욱 효율적이고 표현력 있게 만들 수 있습니다. BDD 스타일의 테스트가 필요하거나 Groovy를 사용하는 프로젝트에서 Spock은 매우 유용한 선택이 될 수 있습니다.

 


 

실습

의존성 라이브러리를 gradle.build 파일에 추가합니다.

 

plugin {
	...
	id 'groovy'
    ...
}


dependencies {
	...	
    // spock, spring boot에서 버전관리 해주지 않음
	testImplementation 'org.spockframework:spock-spring:2.3-groovy-3.0'    
    ...
}

 

 

테스트 디렉터리 하위에 groovy 디렉터리를 추가합니다.

 

 

단위 테스트는 Specification을 상속받아서 작성해야 합니다.

 

class TTest extends Specification {

    def "length of a string should be correct"() {
        expect: "Check the length of the string"
        "Hello, Groovy!".length() == 13
    }

    def "addition should return the correct result"() {
        expect: "Check if the addition is correct"
        3 + 7 == 10
    }

    def "list should contain the expected elements"() {
        given: "A list with some elements"
        def list = [1, 2, 3, 4, 5]

        expect: "The list should contain 3"
        list.contains(3)
    }
}

 

1번 테스트는 틀린 케이스이므로 실행하면 아래와 같이 spock에서 지적을 해줍니다.