본문 바로가기
dev/spring

REST Assured로 API 테스트하기

by igooo 2024. 6. 3.
728x90

개요

REST Assured는 Java 언어에서 Ruby, Groovy와 같은 동적 언어처럼 Rest 서비스를 테스트하고 검증하는 것은 쉽게 사용할 수 있게 해준다.

 

특징

  • Given When Then 패턴으로 가독성 높은 테스트를 작성한다.
  • Json, XML, Plain Test 응답값 검증이 쉽다.
  • Spring, Kotlin. Scala Support

 

Example

{
	"lotto": {
		"lottoId":5,
		"winning-numbers": [2,45,34,23, 7,5,3],
		"winners": [
			{
				"winnerId": 23,
				"numbers": [2,45,34, 23, 3, 5]
			},
			{
				"winnerId": 54,
				"numbers": [52,3,12,11, 18, 22]
			}
		]            
	}
}

@Test
void lotto_resource_returns_200_with_expected_id_and winners() {
	when().
		get("/lotto/{id}", 5).
	then().
		statusCode(200).
		body("lotto.lottoId", equalTo(5),
			"lotto.winners.winnerId", hasItems (23, 54));
}

 

Getting Started

Dependency

# Rest Assured
testImplementation 'io.rest-assured:rest-assured:5.4.0'

# Json Path
testImplementation 'io.rest-assured:json-path:5.4.0'

# Json Schema Validataion
testImplementation 'io.rest-assured:json-schema-validator:5.4.0'

# XmlPath
testImplementation 'io.rest-assured:xml-path:5.4.0'

# Spring Mock Mvc
testImplementation 'io.rest-assured:spring-mock-mvc:5.4.0'

# Spring Web Test client
testImplementation 'io.rest-assured:spring-web-test-client:5.4.0'

 

Static imports

import static io.restassured. RestAssured.*;
import static io.restassured.matcher. RestAssuredMatchers.*;
import static org. hamcrest. Matchers

참고 : https://github.com/rest-assured/rest-assured/wiki/GettingStarted

 

Json Path

Operator Description
The root element to query. This starts all path expressions.
@ The current node being processed by a filter predicate.
* Wildcard. Available anywhere a name or numeric are required.
.. Deep scan. Available anywhere a name is required.
. Dot-notated child
['<name>' (, '<name>')] Bracket-notated child or children
[<number> (, <number>)] Array index or indexes
[start:end]  Array slice operator
[?(<expression>)] Filter expression. Expression must evaluate to a boolean value.

 

Usage

Syntax

# new syntax
given().
	param("x", "y").
when().
	get("/lotto").
then().
	statusCode(400).
    body ("lotto.lottold", equalTo(6));

# legay syntax
given().
	param("×", "y").
expect().
	statusCode(400).
	body("lotto.lottoId", equalTo(6)).
when().
	get("/lotto");

 

Logging

Request Logging

given().log().all(). .. // Log all request specification details including parameters, headers and body
given().log().params(). .. // Log only the parameters of the request
given().log().body(). .. // Log only the request body 
given().log().headers(). .. // Log only the request headers
given().log().cookies(). .. // Log only the request cookies 
given().log().method(). .. // Log only the request method 
given().log().path (). .. // Log only the request path

 

Response Logging

then().log().all() // status, header, cookie, body
then().log().body() // 상태 코드와 관계없이 로깅
then().log().ifEnror() // 오류가 발생하면 로깅
then().log().statusLine() // Only log the status line 
then().log().headers() // Only log the response headers 
then().log().cookies() // Only log the response cookies 
then().log().ifStatusCodeIsEqualTo(302). .. // Only log if the status code is equals to 302

 

 

Example

// 목록 조회 후 개별 조회
var petId = given().log().all()
.When()
	. get("/pets")
.then().log().all()
	.statusCode(200)
	.body("status", equalTo("OK"))
.extract()
	.path("pets[0].id");

given ().log().all()
.when ()
	.get("pets/{id}*, petId)
.then().log().all()
	.statusCode(200)
    .body("status", equalTo("OK"))
    .body("pets[0].id", equalTo(petId));

 

// Specfication Re-use
var builder = new ResponseSpecBuilder();
builder.expectStatusCode(200);
builder.expectBody("status", equalTo("Success"));
var responsespec = builder.build() ;

// 전체 목록 조회
van petId = given().log().all()
.when ()
	.get("pets")
.then().log().all()
	.spec(responseSpec)
extract()
	.path("pets[0].id");

given().log().all()
.when()
	get("pets/{id}", patId)
.then().log().all()
	.spec(responseSpec)
	.body("pets[0].id", equalTo(petId));

 

참고