Spock에 대한 좋은 글이 있어서 번역해서 올립니다.

오역이 있거나 다른 의견이 있으면 댓글로 남겨주시면 감사하겠습니다.

원본 URL : https://thejavatar.com/testing-with-spock/


Spock Testing – Spock tutorial

Good practicies: Using descriptive methods inside test

 

 저는 항상 다른 사람들이나 미래의 제가 테스트 코드를 봤을 때, 무엇에 대한 테스트인지 바로 이해할 수 있을 정도로 설명적인 테스트를 만들기 위해 노력해 왔습니다.  그래서 크기가 커지기 쉬운 given 섹션을 가능하면 줄일려고 하고 있습니다. 가능하면, 이 given 섹션에서 모든 할당들을 제거하고, 모든 Stubbing을 멋지게 명명 된 메서드로 래핑하는 것을 목표로 합니다.

 다양한 종류의 쇼 티켓을 구매할 수 있는 시스템을 만든다고 가정 해 보겠습니다 :  공연, 연극 공연우리는 웹 페이지를 통해 사용자가 지정한 쇼 티켓 예약을 담당하는 BookingService가 사용자가 금지 된 작업 중 하나를 수행하면 예외를 throw하는지 여부를 테스트하려고 합니다. 이 경우는 이틀 전에 공연 티켓을 취소하려고 할 때 입니다. 공연 전 최소 3 일 전에 사용자가 공연 티켓을 취소 할 수 있도록 허용했습니다.  그 이외는 오직 관리자만 할 수 있습니다. 이 작업을 수행하는 테스트를 살펴 보겠습니다.



 여기서 놀랄만 한 첫 번째는 테스트와 관련 없어 보이는 많은 메소드에 대한 stub이 있다는 것인데, 예를 들면 user.getId () 또는 order.status () 입니다. 이것은 BookingService를 개발한 사람이 작은 컴포넌트로 나누는 것에 대해 고민하지 않고, 이 클래스에 많은 것을 담당하게 했다는 것 입니다.  conductValidation() 메서드 내에서 유효성 검사를 하고 있는지가 우리의 관심사이지만, 이 메서드( conductValidation() ) 전에 코드가 실행 되기 전에 conductPreValidation ()이 먼저 유효성을 만족해야 합니다. 그래서 우리는 테스트 로직과 관련없는 많은 메소드를 Stub 처리 해야 합니다. 여러분들도 이런 문제를 여러 번 경험했을 거라고 생각합니다.


테스트 결과에 영향을 미치는 모든 라인을 표시해 보겠습니다


 여러분도 알 수 있듯이 stub화 된 메소드들 중 절반 이상이 테스트 결과에 영향을 미치지 않습니다. 테스트 시나리오에서 구현 세부 사항을 숨기고, 동시에 given 섹션을 축소하여, 더 이상 독자의 관심을 끌지 않도록 할 것입니다. 이를 달성하기 위해서는  멋지게 명명 된 메소드에 stubbing 감싸야 합니다.



 저는 여러분이 이것보다 훨씬 더 분명하고 좋은 방법을  찾길 바랍니다. given 섹션은 짧게 함으로써 좀 더 이해가 쉬워졌고, 테스트 결과에 영향을 주는 매개 변수를 노출하는 동시에 코드 실행하기 위해 필요한 코드는 숨기지만, 테스트 로직에는 영향을 미치지 않았습니다. 제 관심사를 일으키는 한 가지는 TicketOrder 생성시에 Show 객체만을 가지므로써 테스트 로직에 영향을 미치지 않게 보인다는 것입니다. 다음 단계에서 이것을 제거 할 것입니다.


Removing disruptive code

 다음 일은 제 테스트에서 가능한 한 노이즈가 되는 코드를 제거하는 것입니다. 모든 할당을 given 섹션에서 제거합시다. 아무런 가치도 없습니다. 또한 테스트 코드 안에 있는 객체 생성을 모두 테스트 밖으로 이동하고 Show 객체와 동일한 메서드로 TicketOrder 객체를 생성합니다.


Improve method naming

 우리의 테스트가 덜 이상하게 보이도록 메소드의 이름을 조금 변경해 보겠습니다. 예를 들어 매개 변수를 사용하여 위의 예와 같이 공백없이 긴 이름을 사용하지 않도록 합니다.


Good practices: Using “and” label

 given, when과 같은 섹션 레이블과는 별도로 and 레이블이 있으며 이전 레이블을 관련 명령문 그룹으로 분리하는 데 사용할 수 있습니다. 현재 프로젝트에서는 잘못된 입력을 걸러내는 클래스에서 종종 사용하고 있습니다.



물론 메소드의 이름은 예제의 이름보다 의미가 있지만, 일반적인 생각을 가지기를 바랍니다. 테스트에서 모든  경우를 만족시키기 위해서 만족하는 케이스(모든 조건이 충족 됨)와 최소한 모든 if 문에서 부정적인 응답(isValidTrade ()가 false를 반환)을 주는 테스크 케이스를 작성합니다. 해피 케이스 테스트는 아래와 같습니다.



 테스트 이름에 모든 조건을 나열하고 싶지 않기 때문에 긍정적 인 유효성 확인을 위해 특정 시나리오에서 필요한 것을 제안하는 비즈니스 정의가 필요합니다. 이제 불만족 조건인 no. 2로 인해 실패해야하는 테스트를 작성해 보겠습니다.  누군가가 isValidBooking () 메소드 내에서 조건을 재정렬하더라도 내 테스트가 제대로 작동하게 할 것이며,  테스트에서 모든 조건을 만족하는 Booking 객체를 준비할 것입니다.  두 번째 조건은 제외하고




 bookingWillBePaidByCash () 메소드가 bookingWillBePaidByCreditCard () 메소드로 변경 되었다.  테스트의 이름에서도 알 수 있듯이 예약을 할인으로 분류하지 못하게 하고 있습니다. 이를 한 걸음 더 나아가기 위해  given 섹션을 두 그룹으로 분리하십시오.



 이제  given 섹션을 테스트중인 객체에 반대되는 두 섹션으로 명시적으로 분리했습니다. 또한 라벨에 설명을 추가하여 어떤 섹션이 어떤 방식으로 테스트 대상 객체에 영향을 주는지 명확하게 나타냅니다.


Good practices: Using maps for method parameters

 아래와 같은  BookingService가 있다고 상상해 봅시다. 특정 영화를 상영하기 위한 티켓이 충분하지 않은 경우, 예외가 던져 지는지 여부를 확인하는 테스트를 만들고 싶습니다.


 우리는 드디어 아래와 같은 테스트 코드를 작성하게 되었습니다.


 이것은 정말 나쁘지는 않지만, 이 기능이 훨씬 더 많은 stubbing등을 필요로 한다고 상상해보십시오. 이 경우 우리는 관련 Stubbing을 의미있는 메서드로 추출하고 싶을 것입니다.



 이 방법은 매개 변수가 서로 다르기 때문에, 이것도 그리 나쁘지 않습니다. 이 방법이 다음과 같이 나타날 수있는 경우가 있습니다.



 이 경우 어떻게 두 번째 매개 변수가 시나리오의 이름이고 세 번째 매개 변수가 감독이라는 것을 누군가가 알 수 있습니까? 숫자 매개 변수가 두 개인 경우, 어떤 number 매개 변수가 예약 할 티켓의 수라고 생각할 수 있습니까? 이러한 경우 저map을 사용하여 보다 이해할 수 있는 형태로 변형하려고 할 것입니다.


Parametrized tests

 또한 Spock은 테스트 구조를 한 번 정의한 다음 다른 입력 값에 대해 동일한 테스트를 실행하는 매개 변수화 된 테스트를 지원합니다. 이 주제에 대해 별도의 기사를 게시 할 예정이므로 당분간 티저를 제공해 드리겠습니다. 더 복잡한 매개 변수화 된 테스트를 여기서 찾을 수 있습니다.


Setting up Spock

 Spock 작업을 시작하려면 프로젝트에 하나의 종속성만 추가하면 됩니다. 웹 콘솔 온라인 응용 프로그램을 통해 Spock으로 실행 할 수도 있습니다. 기억할 것은 모든 Spock 테스트가 Specification 클래스를 상속받아야  한다는 것입니다.


External links


Spock에 대한 좋은 글이 있어서 번역해서 올립니다.

오역이 있거나 다른 의견이 있으면 댓글로 남겨주시면 감사하겠습니다.

원본 URL : https://thejavatar.com/testing-with-spock/


Spock Testing – Spock tutorial

Managing exceptions in tests

 이제는 예제를 통해 테스트 실행 중에 특정 유형의 예외가 발생 여부를 확인하는 방법을 배우겠습니다. 그 메소드는 throw () , notThrown () 그리고 noExceptionThrown () 메소드 입니다. Throw 된 예외에 대한 세부 사항을 확인하고 싶다면, 변수에 thrown () 메소드의 결과를 할당 한 다음에 예외 자체를 확인해야 합니다.

Extras and catches

Spock에서 테스트를 작성할 때, 알고 있어야할 몇가지 사항이 있습니다.

Assingments created outside test methods

모든 테스트 전에 클래스 수준의 할당이 평가됩니다. 이것은 각 테스트 본문에 objectUnderTest를 생성하고 싶지 않을 때 특히 편리합니다. 다른 테스트들의 동작 중에 해당 객체가 상태가 공유 되는것에 대해 걱정없이 클래스 수준에서 해결 할 수 있습니다. ( 즉, 테스트 케이스가 시작할 때마다 objectUnderTest가 재 할당된다는 의미입니다.)


 특별한 이유로  클래스 레벨에서 생성 된 객체의 상태를 공유하고 싶을 경우에는 해당 변수에 @Shared 주석을 추가하면 됩니다.



 Spock은 클래스에 지정된 테스트가 파일에 표시된 순서대로 실행된다는 것을 보증하지 않습니다.  따라서, 위 예제는 1번 테스트가 실행되기 전에 2번 테스트가 먼저 실행되면 테스트가 실패할 수 경우입니다. 클래스 파일에 작성된 순서대로 테스트 실행을 원할 경우 @Stepwise 주석을 추가해야 합니다.


Verifying interaction of a method while changing its behaviour

 가끔은 메소드가 호출되었는지 여부와 그 메소드 동작을 변경하고 싶을 때가 있습니다. 여기서 가장 자연스럽게 하는 방법은 given 섹션에서 메서드의 사용자 정의 동작을 정의하고 then 섹션에서는 메소드가 호출되었는지 확인하는 것입니다.


 위 예제에서 확인할 수 있는 것은 Spock은 메소드의 동작을 두 번이상 재정의하지 못하게 하고 있다는 것 입니다. 테스트가 실행되면 Spock은 먼저 구문을 검증하기 위해서 then 섹션을 검색합니다. size () 메서드 하나를 찾게 되면, size () 메서드가 이미 처리되었기 때문에 given 섹션의 list.size () >> 10 표현식이 무시됩니다. 이 문제를 해결하기 위해서는 두 구문을 하나로 만들고,  검증문을 배치 할 수 있는 유일한 곳인 then 섹션에 구문의 결과를 넣어야합니다.


Overriding previously specified behaviours

 Stub, Mock 또는 Spy에서 이미 재정의한 메소드의 동작을 다시 재정의하는 방법은 비슷합니다. 하지만 이것은 작동하지 않습니다.  다음 문제는 그동안 매번 저를 힘들게 했습니다. 클래스 레벨에서 테스트를 위해 공통의 Stub 객체를 만들고 특정 메소드의 동작을 정의했습니다. 제가 다른 테스트를 만들면서, 이미 만들어 놓은 사용자 정의 Stub을 잊어 버리게 됩니다. 다른 테스트를 만들 때, 메소드 레벨에서 테스트에서 필요로 하는 요건을 만족하는 매우 비슷한 메소드의 동작을 정의합니다.  30 분 안에 저는 Stub화 된 오브젝트가 예상대로 작동하지 않는 이유를 알지 못했습니다. 이번에는 해결 방법이 없으며, 이런 일이 발생할 수 있음을 명심하십시오.


That keyword

Spock은 테스트를 작성하는 방법을 향상시키고, 스토리를 보다 설명적이고 쉽게 읽을 수 있는 방법을 제공하고 있습니다. 이미 추가된 정적 함수를 위한 키워드 that이 있습니다. 이 키워드는 테스트 로직을 변경하지는 않지만, expect 섹션은 수정할 수는 있습니다.


Spock에 대한 좋은 글이 있어서 번역해서 올립니다.

오역이 있거나 다른 의견이 있으면 댓글로 남겨주시면 감사하겠습니다.

원본 URL : https://thejavatar.com/testing-with-spock/


Spock Testing – Spock tutorial

Checking interactions on Mock/Spy

 

 때로는 단위 테스트를 위해 만든 더미 객체의 특정 동작이 필요 없을 수도 있습니다. 오히려 프로그램을 실행하는 동안 특정 인터페이스의 메소드가 호출 되었는지가 더 관심이 있을 수 있습니다. Mock 또는 Spy를 통해 그 목적을 달성 할 수 있습니다. 이 섹션에서는 이 내용에 대해 논의 하겠지만, 여기에 제시된 모든 내용 또한 Spy에서도 사용 할 수 있습니다.

 Mock를 사용할 때 주의해야할 단점이 있습니다. Mock은 인터페이스와 관계를 확인하기 보다는 특정 구현을 테스트 하거나, 상호 작용을 확인하기 위해서 사용합니다. 그럼에도 불구하고, 컴포넌트간 상호 작용을 검사하는 테스트는 대규모 리팩토링을 수행하는 경우에 유용합니다. 우리는 데이터베이스에 데이터를 삽입하기 전에 중요한 유효성 검사를 놓치지 않고 싶습니다.

Creating Mock

Mock을 만들려면, Spock 테스트 코드에서 Mock () 메소드를 호출하면 됩니다.

Checking interactions with Mock object

 이제 Mock 객체를 만들었으니,  when 섹션 내부에서 코드를 실행하는 동안 객체에 어떤 변화가 있었는지 확인할 수 있습니다.


 우리는 then 섹션에서 상호 작용 여부를 확인할 수 있습니다. Stub에서 사용자 정의 동작을 정의한 것과 같이,  Mock과의 상호 작용을 확인하기 위해서는 해당 메서드 호출이 필요로 합니다. 그 전에 예상하고 있는 상호 작용의 제약 조건을 먼저 정의해야 합니다. 여기서는 Mock이 된 객체의 메소드 size ()가 테스트 중에 정확히 한 번만 호출된다고 가정했습니다. 이 테스트 케이스는 제약 조건이 잘못 됐기 때문에,  Spock은 실패 했음을 알려줄 것입니다. ( list.size()를 호출하는 부분이 없기 때문)


Matching invocations in mocks

Stub에서 했던 것과 동일 방법으로 Mock에서도 동작시키고 싶은 특정 메소드를 찾을 수 있습니다.

Specifying a cardinality of an interaction

 예제에서는 메소드가 한 번 호출되었는지에 대해서만 확인 했습니다. 물론 Spock은 훨씬 더 많은 테스트를 할 수 있습니다.

Check the order of execution

상호 작용이 발생하는 순서를 지정할 수도 있습니다. 그 방법은 여러 개의 then 섹션들을 만들어서 할 수 있습니다

이제 when 세션에서 구문을 변경하면 어떻게 되는지 봅시다.

예상대로 Spock은 메소드가 잘못된 순서로 호출되었음을 발견하고 테스트가 실패 합니다.

Spy in Spock

 정확하게 말하면, Stub이나 Mock과 다르게 Spy는 더미 개체가 아닙니다. 오히려 Spy는 일반 개체에 대한 래퍼라고 말하는 것이 맞을 것입니다. 인터페이스의 특정 메소드의 동작을 재정의 할 수 있으며, Mock처럼 Spy화된 메소드와 상호 작용을 확인할 수 있습니다. UserService 인터페이스를 가지고 Spy에 대해 논의 할 것입니다.

Creating Spy

 Spy를 만들기 위해서는 Spock 테스트 코드에서 Spy () 메소드를 호출해야합니다. 앞에서 말했던 것처럼 Spy는 객체를 감싸는 래퍼입니다. 이를 염두해두고, 인터페이스를 사용하여 Spy를 만든 다음, 다른 컴포넌트을 사용하여 Spy를 통해 메소드를 호출하려고 하면, 재정의한 메서드의 반환값으로 Error를 반환 될 것입니다.


인터페이스에서 Spy를 만드는 대신, 클래스를 사용하는 방식으로 Spy를 만들어 보겠습니다. UserServiceImpl이 Transaction 인수를 가지게 되면서, Spy를 생성하는 방법이 Mock과 Stub에 했던 방법과는 다른 형식이 되었습니다.

Verifying interactions in Spy

Mock과 같이 Spy화된 클래스의 메소드와 어떤 상호 작용이 발생했는지 확인할 수 있습니다.


좋습니다. Mock과 다른 점은 무엇입니까? 답은 정말 간단합니다. save () 메소드의 동작을 변경하지 않았다는 것을 알 수 있습니다. 따라서 콘솔을 열면 UserServiceImpl에 정의 된 메시지가 출력 되는 것을 확인 할 수 있습니다.


기본적으로, 특정 클래스의 메소드가 호출되었는지 확인하고 싶거나 여러가지 이유로 원래 구현했던 메소드가 실행하기 위해 Mock을 사용할 수 없을 때, Mock 대신 Spy를 사용해야합니다.

Specifying behaviour in Spy

Mock와 Stub과 같이 특정 메소드가 호출 될 때 수행해야 할 작업을 재정의할 수 있습니다. 다른 두 클래스(Mock, Stub)과는 달리, Spy는 명시적으로 오버라이드 할 메소드를 선택할 수 있고, 다른 메소드의 구현에는 아무런 영향을 미치지 않습니다.


위의 예제에서는 isServiceUp () 메서드가 호출 될 때마다 true 값을 반환하도록 했습니다. 그럼에도 불구하고 다른 메소드는 변경되지 않았으므로 ,일단 호출되면 콘솔에 메시지를 출력합니다. 기본적으로 테스트에서 사용하는 클래스에서 하나 또는 여러 메소드의 구현을 재정의 필요하고, 동시에 다른 메소드의 구현은 그대로 두고 싶다면 Stub 대신 Spy를 사용해야 합니다.


Spock에 대한 좋은 글이 있어서 번역해서 올립니다.

오역이 있거나 다른 의견이 있으면 댓글로 남겨주시면 감사하겠습니다.

원본 URL : https://thejavatar.com/testing-with-spock/


Spock Testing – Spock tutorial

Stubbing method calls

Spock에서는 다른 클래스나 인터페이스의 동작을 재정의할 수 있는 3 종류의 클래스를 제공하고 있습니다. : Stub, Mock, Spy

이 섹션에서는 다른 클래스를 모방만 하는 Mock과 Spy가 아닌, Stub에만 초점을 맞출 것입니다. 그렇지만 동작을 모방하는 문법은 세 클래스 모두 동일하므로 여기에 나오는 내용들 모두 Mock과 Spy에서도 동일하게 동작합니다.

Creating Stub

Stub을 생성하기 위해서는 Spock 테스트 코드 내에서 Stub () 메소드를 호출하면 됩니다.

Specifying the return value

기본적으로 Stub을 사용하여 수행하려는 작업은 Stub화된 클래스의 특정 메서드가 호출 될 때 발생해야 할 작업을 정의하는 것입니다. Stub화된 메소드의 리턴 값을 지정하고 싶으면, 오른쪽 시프트 연산자 >>를 사용하여 리턴 값을 지정하면 됩니다.

Specifying side effects

메소드 호출 결과로 특정 Side Effect를 원할 경우, 오른쪽 시프트 연산자 다음에 클로저( { } )를 넣습니다. 그렇게 하면 메소드가 테스트 중에 호출 될 때마다 클로저 내의 코드가 실행됩니다.

Throwing an exception as the result of method invocation

위에서 사용했던 Side Effect 기법을 사용하여 Exception도 throw 할 수 있습니다.

Specifying different behaviour based on invocation order

 호출 순서에 따라 Stub화 된 메소드의 동작을 다르게 정의 할 수 있습니다. 아래 예제에서 size () 메서드를 처음 호출 할 때는 1을 반환하고, 두 번째 호출에는 2가 반환되고 세 번째에는 3이 반환됩니다.  이때 사용하는 연산자는 오른쪽 시프트 연산자 3개가 붙은 >>>를 사용합니다.

이 문법은 사용자 정의 동작 구문과 혼합하여 사용할 수 있습니다. ( 아래 예제를 무슨 말인지 모르겠습니다.)

Conditional behaviour of stubbed method

  우리는 몇 가지 조건에 기반하여 Stub화된 메소드에 대해 다른 동작을 지정할 수 있습니다. 

 다음 예제에서는 updateRoleAndReturnPreviousOne () 메서드가 Role.ADMIN 매개 변수와 함께 호출 될 때마다 Exception이 throw되고,  다른 경우에는 Role.USER가 반환되는 것입니다. 이번에는 Stub 메소드에 매개 변수가 필요하므로 메소드 호출시 "_"을 매개 변수로 사용하여, updateRoleAndReturnPreviousOne (_)을 사용했습니다. 

 매개 변수를 취하는 메서드는 다음 섹션에서 다룰 예정이지만이 표기법은 기본적으로 다음과 같이 사용 할 수 있습니다. updateRoleAndReturnPreviousOne () 메서드가 하나의 매개 변수로 호출 될 때마다 : 뒤 따라 오는 작업 실행 (오른쪽 시프트 연산자 이후에 있는 클로저({}) ) 또는 값 (오른쪽 시프트 연산자 이후 값)을 반환합니다.

Stubbing methods that take parameters

Basic parameter matching

 위 예제에서 제기된 문제에 대해 좀 더 자세히 알아보겠습니다. 

 위의 예제처럼 특정 메소드를 모방하기 위해서는 코드에서 메소드를 호출하는 방식으로 사용해야 합니다. 

 매개 변수를 취하는 메서드를 모방하고 싶다면 어떻게 해야 할까요? 'stubbing' 호출도 매개 변수를 전달해야 할까요? 아니면 선언을 생략해야할까요? 

 아래 예제를 통해 후자(선언을 생략)를 선택하면 어떻게 되는지 알아 보겠습니다.

 예제에서 볼 수 있듯이, expect 섹션 내에서 발생한 호출이 given 섹션에 정의한 Stub 선언과 일치하지 않음을 알 수 있습니다.  위 예제는 given 섹션에 있는 Stub를 매개 변수가 0 인 get () 메서드가 호출 될 때마다 0을 반환하도록 수정하면 위의 예제은 정상 동작할 것입니다. ( list.get(0) >> 0 )

 이런 문법은 특정 매개 변수로 메소드가 호출 될 때 리턴 되어야 하는 것을 명시적으로 지정할 수 있기 때문에 매우 편리합니다.

Matching complex objects passed as parameters

 우리는 매개변수를 받을 수 있고, Stubbing 선언에서 매개변수 검증을 할 수 있습니다. User 객체를 매개 변수로 사용하는 save () 메서드를 가진 UserService 인터페이스가 있다고 가정 해 보겠습니다. User 클래스에는 name이라는 String 속성이 있습니다.



 UserService에서 save () 메서드가 호출되면 Exception이 throw되도록 하겠습니다. 좀 더 정교하게 만들기 위해 Michael이라는 이름의 사용자가 저장 될 때 Exception이 발생되도록 하겠습니다.

이 예제를 실행하면 stub화된 동작이 save 메소드에 전달 된 User가 실제로 Michael이라는 이름을 가진 경우에만 실행된다는 것을 확인 할 수 있습니다. 클로저 내부의 표현식에 대한 유일한 제한은 부울 값으로만 평가되어야 한다는 것입니다.


Arguments matching wildcards


Stub화된 메소드에 명시적인 값을 매개 변수로 지정하지 않으려면 와일드 카드를 사용하면 됩니다. Spock은 다음과 같은 와일드 카드를 제공합니다 : 



Spock에 대한 좋은 글이 있어서 번역해서 올립니다.

오역이 있거나 다른 의견이 있으면 댓글로 남겨주시면 감사하겠습니다.

그리고 추가로 이해를 돕기 위해 추가적인 설명이 들어간 부분도 있습니다.

원본 URL : https://thejavatar.com/testing-with-spock/


Spock Testing – Spock tutorial

What is Spock?

Spock은 Groovy 문법을 사용하여 이해하기 쉽게 테스트 케이스를 만들 수 있도록 해주는 단위 테스트 프레임워크(unit testing framework)니다. Groovy 기술이지만, Java 테스트도 할 수 있습니다. 무엇보다 가장 중요한 것은 Spock이 테스트 케이스 작성을 즐겁게 만들어 준다는 것입니다. 그리고 저 또한 전적으로 동의합니다.


Why Spock?

저는 TDD의 모든 장점을 알고 있고, 작성한 모든 코드에 대해 테스트를 해왔습니다. Spock을 사용하면서 어떻게 바뀌었을까요?  

  • Spock을 이용하여 테스트 코드를 작성하는 것은 다른 표준 테스트 프레임워크를 사용하는 것보다 시간이 덜 듭니다.(JUn it 과 Mock 프레임워크의 조합)
  • Mocking, Stubbing 그리고 Spying 작업들을 매우 간단한 코드로 할 수 있는 쉬운 문법 덕분에 테스트 코드 로직을 변질시키지 않을 수 있습니다.
  • Spock은 개발자들이 테스트를 BDD 같은 형식으로 구성할 수 있게 함으로써, 테스트를 더욱 명확하게 할 수 있습니다.
  • Groovy를 사용하여 클로저와 맵을 직접 사용할 수 있어서  테스트의 명확성을 더 높일 수 있습니다.

모든 것을 고려해 볼 때, Spock에서 작성된 테스트 케이스는 다른 개발자들에게 좀 더 많은 정보를 수 있고, 보다 더 잘 정리되게 할 수 있어서 이해하기가 쉽습니다.  게다가 멋져 보입니다. 무엇보다 중요한 것은 Spock이 테스트를 매우 즐겁고 보람있는 경험으로 바꾸어 놓은 것입니다.


Simple test in Spock

Spock으로 작성한 간단한 테스트 코드가 아래에 있습니다.


물론 위의 테스트 코드는 잘못되었기 때문에 테스트가 실패합니다. ( list에 "1" 추가하고, "2"를 가져올 수 있다고 생각하고 설계한 테스트 코드이기 때문입니다.) Spock은 무엇이 잘못 되었는지 명확하게 이해할 수 있도록 오류 메시지를 표시해 줍니다. ( 아래 코드를 보면 list에는 [1] 이 있고, 여기서 "0" index에 있는 "1"을 반환하고 있다고 알려주고 있습니다.)

Test structure

Spock에서 테스트 선언이 얼마나 명확한 지 주목하기 바랍니다. 개발자는 메서드에 대한 표준 명명 규칙을 따를 필요없이 두 개의 아포스트로피(" ") 사이에 테스트 이름을 선언 할 수 있습니다. 그렇기 때문에 테스트 코드에 대한 자세한 설명이 들어간 긴 이름으로 선언할 수 있고, 이를 통해 다른 사람들이 테스트 코드의 목적을 더 잘 이해할 수 있게 됩니다.

앞서 언급했듯이 Spock를 통해 BDD 테스트와 비슷한 방식으로 테스트 코드를 배열할 수 있습니다. 각 테스트는 세 부분으로 나눌 수 있습니다.


Given section

"given" Section에서는 우리가 테스트하고 싶은 기능을 컨텍스트에 지정합니다. 여기서는 테스트 중인 기능에 영향을 미치는 시스템 / 컴포넌트의 매개 변수를 지정합니다. Spock 초보자들은 이 섹션을 매우 큰게 작성되는 경향이 있지만, 궁극적으로는 간결하고 설명되기 쉽도로 만드는 방법을  배우게 될 것 입니다.


When Section


"when" Section은 테스트하고 싶은 것을 작성하는 곳입니다.  즉, 테스트 된 객체 / 컴포넌트와의 상호작용하는 것을 확인하는 곳입니다.


Then section

이제, "then" Section에서는 when 섹션에서 실행해서 나왔던 결과를 확인하는 곳입니다. 즉, 메소드의 결과 (black box test) 또는 Mocks와 Spies를 이용하여 내부에서 테스트된 기능(white box test)과 상호 작용한게 무엇인지 검증하는 곳입니다.


Alternative sections

Spock 문서에서 앞에 나왔던 섹션(given, when, then)에 대한 몇 가지 대안으로 setup, expect 등을 사용할 수 있습니다. 후자는 매우 작은 테스트를 만들 수 있는 매우 흥미로운 것입니다.



+ Recent posts