본문 바로가기
프로그래밍/테스트

[Spock] Spock Framework 이용하기 - Where

by 사바라다 2020. 9. 4.

[Spock] Spock Framework 이용하기 - 개론편
[Spock] Spock Framework 이용하기 - 실습편
[Spock] Spock Framework 이용하기 - Mock
[Spock] Spock Framework 이용하기 - Where

안녕하세요. 오늘은 Spock Framework의 4번째 시간입니다. 오늘 Spock Framework의 Where에 대해서 배워보도록 하겠습니다. Spock의 Where을 잘 사용할 수 있게 되면 데이터가 다르고 로직이 동일한 테스트에 대해 발생하는 중복 코드를 많이 제거할 수 있습니다.

Introduction

Math.max가 정상적으로 동작하는 지 검증하는 테스트 메서드를 작성해보도록 하겠습니다. 아래와 같이 2개의 파라미터 중 더 큰값이 정상적으로 나오는지 보기위해 오른쪽에 큰값, 왼쪽에 큰값, 그리고 동일한 값을 넣어 검증합니다.

class MathSpec extends Specification {
  def "maximum of two numbers"() {
    expect:
    // exercise math method for a few different inputs
    Math.max(1, 3) == 3
    Math.max(7, 4) == 7
    Math.max(0, 0) == 0
  }
}

아무런 문제 없이 잘 동작합니다. 하지만 이런 방식의 검증방법은 소위 말하는 노가다 방법입니다. 왜냐하면 각 검증을 위해서 변하는 것은 내부의 파라미터뿐이지만 각 메서드를 한번씩 다시 사용해가며 검증해야합니다. spock에서는 이러한 파라미터 검증에 대해서 간편하게 접근할 수 있는 방법을 제공합니다. 바로 where 이며 Spock에서는 이를 data-driven testing이라고 명명합니다.

Data Table

파라미터 값을 고정하여 사용하는 경우 Data Table을 이용하면 쉽습니다. 위의 예제를 Data Table을 이용하여 변경해 보도록 하겠습니다. 이전 위의 예제와는 확연하게 다르게 간편해 진 것을 확인할 수 있습니다. 먼저 Data Table로 사용하고자 하는 변수를 파라미터로 입력하며 where:에 해당 테이블을 |를 이용해서 만듭니다. 이렇게 한 후 row를 추가하면 해당 파라미터로의 테스트가 진행됩니다.

class MathSpec extends Specification {
  def "maximum of two numbers"(int a, int b, int c) {
    expect:
    Math.max(a, b) == c

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

방금 본 Data Table을 이용한 예제에 실패케이스를 넣어보겠습니다. 1 | 2 | 1을 케이스로 넣오보고 돌렸을때는 아래와 같이 verification 메시지가 출력됩니다. 우리는 Data Table을 추가했을 뿐인데 실제로 해당 메서드에 파라미터를 넣은 것과 동일한 검증을 진행하였다는 것을 알 수 있습니다.

Condition not satisfied:

Math.max(a, b) == c
|    |   |  |  |  |
|    2   1  2  |  1
|              false
class java.lang.Math

Data Table은 적어도 2개 컬럼 이상이 필요합니다. 하나의 파라미터를 테스트하고 싶으신 분들은 아래와 같이 입력하시면 됩니다.

where:
a | _
1 | _
7 | _
0 | _

Syntactic Variations

위의 where 코드는 좀 더 조정이 가능합니다. 사실 메서드 파라미터를 (int a, int b, int c)와 같이 넣지 않고 생략이 가능합니다. 그리고 | 대신 ||도 사용할 수 있습니다. 특별히 달라지는 것은 아니고 req와 res의 차이를 두기위해 사용하면 좋을 것으로 보여지며 그렇게 문서에 권장하고 있습니다.

class MathSpec 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
  }
}

Unroll Annotation

@Unroll 어노테이션을 붙이면 where:의 결과가 각각 독립적으로 출력됩니다.

class MathSpec extends Specification {
  @Unroll
  def "maximum of two numbers"() {
    expect:
    Math.max(a, b) == c

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

where, @Unroll 적용 

Data Pipes

Data Table 뿐만 아니라 Data Pipes라는 방법도 존재합니다. 이 방법은 아래와 같이 where:를 기술합니다.

where:
a << [1, 7, 0]
b << [3, 4, 0]
c << [3, 7, 0]

주의할점

where의 각각의 테스트는 독립적입니다. 따라서 멤버변수가 공유되지 않습니다. 멤버변수를 공유하기 위해서는 static 변수로 만들던가 아니면 @Shared 어노테이션을 변수만이 가능합니다.

마무리

오늘은 이렇게 Spock Framework의 where:Block에 대해서 알아보는 시간을 가졌습니다.

이것으로 4번째 Spock Framework에 대한 시간은 마무리 되었습니다. 또한 Spock Framework의 사용법 포스팅을 마무리 하려고합니다.

다음번에도 도움이 되는 다른 포스팅으로 찾아뵙도록 하겠습니다.

감사합니다.

참조

spockframework Data Driven Testing

댓글