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


+ Recent posts