writing unit tests with spock framework
Spock 프레임 워크로 단위 테스트 작성 : 테스트 픽스처, 어설 션 및보고
이것에 Spock에 대한 완전한 초보자 가이드 , 간략한 Spock 프레임 워크 및 Groovy 프로그래밍 소개 이전 튜토리얼에서 제공되었습니다.
이 자습서에서는 시작하는 데 필요한 모든 세부 정보 / 단계를 안내합니다. 단위 테스트 스팍에서.
간단하게하기 위해 덧셈, 뺄셈, 곱셈, 나눗셈 등과 같은 다양한 방법을 가진 간단한 계산기 응용 프로그램을 테스트 할 것입니다.이 응용 프로그램은 모두 정수 매개 변수를 받아들이고 정수 출력을 반환합니다.
학습 내용 :
Spock 비디오 자습서를 사용한 단위 테스트
시작하기
다른 단위 테스트 프레임 워크와 마찬가지로 Spock도 테스트중인 애플리케이션에 대한 시나리오 / 테스트 사례를 작성하는 데 사용할 수 있습니다. Spock 프레임 워크의 다양한 기능을 다음과 같은 기존 / 알려진 프레임 워크와 비교하고 대조하려고합니다. JUnit .
'def'키워드
먼저 Groovy의 'def'키워드를 간단히 이해해 보겠습니다. def 키워드는 type-def를 정의하는 데 사용되며 함수 및 필드 / 변수를 선언하는 데 사용할 수 있습니다.
'def'는 일반적으로 필드 유형이나 메서드의 반환 유형을 제한하지 않으려는 경우에 사용됩니다. 그루비 클래스에서 def 키워드의 몇 가지 예와 모든 유효한 사용법을 살펴 보겠습니다.
소프트웨어 라이프 사이클의 검증 단계는 무엇을 수행합니까?
// def as variable types def inputNum = 100 def inputStr = 'hello world!!' def app = new CalculatorApp() // def as return type of function def 'test function'() { // function body here }
Spock 사양의 수명주기
실행될 때 Spock 사양은 정의 된 모든 테스트를 찾아 하나씩 실행합니다. 그러나 Spock에서 제공하는 다른 기능 / 특징은 거의 없습니다.
아래에서 몇 가지 기능에 대해 설명하겠습니다.
사양의 일부로 입력 / 변수 정의
모두 동일한 입력 값을 사용하는 여러 테스트를 고려하십시오. 한 가지 방법은 각 테스트의 입력 값을 개별적으로 초기화하는 것입니다. 그렇지 않으면 사양 수준에서 필드를 직접 정의하고 각 테스트 전에 필드가 초기화되어 실행중인 테스트에 사용할 수 있는지 확인할 수 있습니다.
계산기 애플리케이션 클래스의 예를 살펴 보겠습니다. .
사양에있는 모든 테스트에 대해 초기 값을 사용할 수 있도록 사양 수준에서 입력 데이터를 정의합니다.
class CalculatorAppSpec extends Specification { def input1 = 50 def input2 = 10 def result = 0 def app = new CalculatorApp() def 'addition with valid inputs return expected result'() { when: result = app.add(input1, input2) then: result == 60 } def 'multiplication with valid inputs return expected result'() { when: result = app.multiply(input1, input2) then: result == 500 } def 'division with valid inputs return expected result'() { when: result = app.divide(input1, input2) then: result == 5 } def 'subsctraction with valid inputs return expected result'() { when: result = app.substract(input1, input2) then: result == 40 } }
이 코드 샘플에서는 input1, input2, 테스트중인 애플리케이션 및 사양 수준의 결과를 정의했음을 알 수 있습니다. 이것이 보장하는 것은 사양 파일에서 테스트가 실행될 때마다 초기화 된 필드가 해당 테스트로 전달된다는 것입니다. 이것은 실제로 입력 값으로 매번 테스트를 설정할 필요가 없습니다.
시험 설비
대부분의 단위 테스트 프레임 워크와 마찬가지로 Spock은 테스트 실행의 특정 수명주기 이벤트에서 특수 논리 / 작업을 실행하기위한 설정 및 정리 방법도 제공합니다.
setupSpec 및 cleanupSpec
이러한 메서드는 각 사양 실행에 대해 한 번 호출되며 테스트 실행 전후에 각각 호출됩니다. @와 비슷합니다. BeforeClass 및 @ 방과후 JUnit의 주석.
설정 및 정리
이러한 메서드는 사양의 각 테스트 실행 전후에 호출됩니다.
이러한 후크는 테스트 실행 전후에 실행하려는 모든 로직 / 코드에 적합한 위치입니다. 예를 들어 , 정리시 테스트 중에 사용 된 데이터베이스 연결 (있는 경우)을 닫는 코드를 작성할 수 있습니다.
@와 비교할 수 있습니다. BeforeTest 및 @ AfterTest JUnit의 주석.
계산기 애플리케이션 테스트에서 이러한 픽스처의 예를 보겠습니다.
def setupSpec() { println('###in setup spec!') } def cleanupSpec() { println('###in cleanup spec!') } def setup() { println('>>>in test setup!') } def cleanup() { println('>>>in test cleanup!') }
위의 테스트 픽스처 코드가 4 개의 테스트를 포함하는 사양에 추가되면 출력은 다음과 같습니다.
###in setup spec! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! >>>in test setup! >>>in test cleanup! ###in cleanup spec!
스팍 어설 션
Spock의 주장은 power assert라고 불립니다 (그리고 나중에 Spock에 의해 도입 된 후 groovy에 의해 채택되었습니다). Spock 어설 션은 어설 션 실패시 많은 진단 예외를 제공합니다.
Windows 10 용 무료 DVD 리퍼
자세한 정보가 아닌 고장 진단을 살펴보면 무엇이 잘못되었는지 쉽게 찾을 수 있습니다. AssertionErrors JUnit 및 기타 프레임 워크에서.
이것을 예제로 이해하고 JUnit과 대조 해보자
문자열이 같은지 확인하고 어설 션 실패시 어떤 진단이 생성되는지 확인하는 간단한 테스트로 작업합니다.
스팍 테스트
def 'check case-insensitive equality of 2 strings'() { given: 'two input strings' String str1 = 'hello' String str2 = 'HELLO world' when: 'strings are lowercased' str1 = str1.toLowerCase() str2 = str2.toLowerCase() then: 'equal strings should return success' str1 == str2 }
JUnit 테스트
@Test public void compareStrings_withValidInput_shouldReturnSuccess() { // Arrange String str1 = 'hello'; String str2 = 'HELLO world'; // Act str1 = str1.toLowerCase(); str2 = str2.toLowerCase(); // Assert Assert.assertEquals(str1,str2); }
Spock 출력
Condition not satisfied: str1 == str2 | | | hello| hello world false 6 differences (45% similarity) hello(------) hello( world) Expected :hello world Actual :hello
JUnit 출력
org.junit.ComparisonFailure: Expected :hello Actual :hello world
위에서 추론 할 수 있듯이 Spock이 제공하는 진단 정보는 JUnit과 같은 다른 프레임 워크와 비교할 때 더 자세하고 사용자 친화적입니다.
어설 션 팁 및 요령
한 번에 여러 요소를 주장하기 – Spock은 주장에 대한 다양한 속기를 제공하며 그 중 하나는 목록에서 요소를 주장 할 수있는 '*'표기법입니다.
예를 들어 이해해 보겠습니다.
cityName 및 인구를 필드로 갖는 CityInfo 클래스를 고려하십시오. 주어진 목록에있는 도시의 이름을 확인하는 Spock 테스트를 작성합니다.
public class CityInfo { public CityInfo(String cityName, int population) { this.cityName = cityName; this.population = population; } public String cityName; public int population; }
이제 테스트를 보겠습니다.
def 'Assert multiple elements of list' () { given: def cityList = new LinkedList() cityList.add(new CityInfo('Mumbai', 120)) cityList.add(new CityInfo('Delhi', 80)) cityList.add(new CityInfo('Chennai', 100)) expect: cityList*.cityName == ('Mumbai', 'Delhi', 'Chennai') }
위의 단언 속기에서 볼 수 있듯이 '*'키워드를 사용하여 전체 목록의 유효성을 검사 할 수 있습니다.
또한 실패가 어떻게 생겼는지 살펴 보겠습니다. 위의 주장에서 한 도시의 이름을 제거하겠습니다.
Condition not satisfied: cityList*.cityName == ('Delhi', 'Chennai') | | | | | false | (Mumbai, Delhi, Chennai) (app.CityInfo@31368b99, app.CityInfo@1725dc0f, app.CityInfo@3911c2a7)
어설 션 실패의 진단 정보가 풍부하고 이해하기 쉽다는 것을 알 수 있습니다.
클로저 매개 변수 활용 – every ().
목록이나 컬렉션의 모든 요소에 대한 어설 션을 추가하기 위해 every ()라는 클로저 매개 변수를 어떻게 활용할 수 있는지 살펴 보겠습니다. 같은 예에서 주어진 입력이 50보다 큰 경우 각 도시의 인구를 검증하는 어설 션을 추가해 보겠습니다.
def 'Assert multiple elements of list' () { given: def cityList = new LinkedList() cityList.add(new CityInfo('Mumbai', 120)) cityList.add(new CityInfo('Delhi', 80)) cityList.add(new CityInfo('Chennai', 100)) expect: cityList*.cityName == ('Mumbai', 'Delhi', 'Chennai') and: cityList.population.every() { it > 50 } }
throw 된 예외 확인
'then'블록에서 예외가 발생하도록 주장 할 수 있습니다 (즉, 블록도 필요할 때를 의미합니다). 예외 세부 사항은 throw 된 예외를 필드에 할당하고 throw 된 예외의 필수 속성을 어설 션하여 진단 할 수 있습니다.
동일한 CityInfo 클래스를 사용하고 예외를 발생시키는 메서드를 정의하고 이에 대한 테스트를 작성해 보겠습니다.
public class CityInfo { public CityInfo(String cityName, int population) { this.cityName = cityName; this.population = population; } public String cityName; public int population; public CityInfo() { } public int getCleanlinessScore() { throw new RuntimeException('method not implemented'); } }
이제 테스트를 살펴 보겠습니다.
def 'cleanliness score throws runtime exception with message - method not implemented'() { given: CityInfo app = new CityInfo(); when: app.cleanlinessScore() then: def e = thrown(RuntimeException) e.message == 'method not implemented' }
보고
아름답고 상세한 HTML 기반 보고서를 생성하기 위해 빌드 파일에 추가 할 수있는 라이브러리가 있으며 이제 빌드 중에 (또는 직접 실행에 의해) 테스트가 실행될 때마다 자세한 HTML 기반 보고서가 생성됩니다. 출력 폴더.
테스트 보고서를 생성하려면 다음 라이브러리를 build.gradle 파일에 추가하십시오 (Maven pom.xml 파일의 경우도 유사).
testCompile 'com.athaydes:spock-reports:1.6.1' testCompile 'org.slf4j:slf4j-api:1.7.13' testCompile 'org.slf4j:slf4j-simple:1.7.13'
이제 프로젝트를 빌드하고 'test'폴더에있는 모든 테스트를 실행하거나 ' gradle 깨끗한 테스트 ”.
열 수 있습니다 index.html 실행 가능한 모든 Spock 사양에 대한 요약 보고서를 가져옵니다.
Windows 10 용 무료 방화벽 소프트웨어
특정 사양에 대한 자세한 보고서를 보려면 위 목록에서 사양을 클릭하면 실패 및 성공에 대한 자세한 보고서를 볼 수 있습니다.
결론
이 자습서에서는 Spock Framework를 사용한 단위 테스트의 기본 사항을 다뤘습니다. 우리는 주장을 작성하는 다양한 방법과 속기, 그리고 주장 실패에 대해 Spock 프레임 워크에서 생성 된 풍부한 진단 정보의 종류를 보았습니다.
또한 실행 된 테스트에 대한 동일한 세부 진단을 포함하는 Spock 테스트에 대해 조용하고 예쁜 HTML 기반 보고서를 생성하는 방법도 살펴 보았습니다.
다가오는 튜토리얼에서는 Spock으로 매개 변수화 된 테스트를 작성하는 방법에 대해 자세히 설명합니다 !!