본문 바로가기
Software Test/Contract Test by Postman

[Postman 사용법] 3. 응답 검증 (Test Scripts)

by kellis 2020. 8. 19.

요청에 대한 응답이 예상한 응답과 동일한지 검증하기 위해 Test scripts를 작성합니다.

 

이 장에서는 Test scripts를 작성하는 방법 및 예제를 살펴보겠습니다.

 

1.  포스트맨의 Scripts란?
2. Pre-request scripts란?
3. Test scripts란?
4. Script Example
5. 분기 및 반복

 

1.  포스트맨의 Scripts란?

포스트맨은 Node.js 기반의 런타임을 포함하고 있어, Request와 Collection에 동적으로 동작을 추가할 수 있습니다. 이를 통해 동적 매개변수를 사용하거나 요청 간에 데이터를 전달하는 것이 가능합니다. 이런 동적 작업을 수행하는 2가지 이벤트 흐름에 대해 자바스크립트 코드를 작성할 수 있습니다. 

  • Pre-request Script : 요청이 서버로 보내지기 전에 실행
  • Tests Script : 응답이 반환된 후 실행

 

Pre-request script와 Tests script는 collection, folder 그리고 collection 내의 request 각각에 대해 작성이 가능하며, 그러므로 실행 순서가 존재합니다. 

스크립트는 컬렉션의 모든 요청에 대해 항상 컬렉션 → 폴더 → 요청의 계층 구조에 따라 실행되며, 이는 Pre-request script와 test script에 모두 적용됩니다.

그렇다면 실제로 그렇게 동작하는지 콘솔에 로그를 출력하는 script를 작성하여 확인해 보도록 하겠습니다. 

요청은 아래와 같이 Request Builder에서 작성이 가능합니다. 

컬렉션과 폴더의 경우에는 펼침(...)버튼 > Edit 버튼을 통해 스크립트 수정이 가능합니다. 

스크립트는 모두 자바스크립트로 작성되며, 이를 실행하려면 Collection을 Run 해야 합니다. 

Runner를 실행하는 방법에는 위와 같이 두 가지 방법이 존재합니다.

  • Runner 버튼 클릭
  • 사이드바의 Collection 오른삼각형(▶)을 클릭 → Collection Runner 창의 Run 버튼

여기에서는 어떤 컬렉션을 실행할 지, 어떤 실행 옵션을 줄 것인지 지정할 수 있습니다. 만약 최근에 실행한 테스트가 존재한다면 우측의 Recent Runs에 나타나므로 곧바로 재실행하는 것도 가능합니다. 

각각의 옵션은 아래와 같습니다.

  • Environment : 환경 변수 추가
  • Iterations : 전체 테스트를 몇 번 수행할 것인가
  • Delay : 각 요청 사이에 지연 시간(millisecond 단위)을 줄 것인가
  • Log Responses : 응답을 기록하는 범위를 제한할 것인가
  • Data : 데이터 파일을 추가하겠는가
  • Keep variable values : 컬렉션 러너에서 사용된 환경변수의 값이, 러너가 끝난 후에 요청 빌더의 환경변수에 적용되기를 바라는가

 

세팅이 끝났다면, Run을 하기에 앞서 포스트맨 콘솔을 열겠습니다. 

포스트맨 앱 하단의 버튼을 누르면 포스트맨을 위한 콘솔이 열립니다. 콘솔을 연 이후부터 실행되는 테스트에 대해서 로그가 출력되며, 닫으면 모두 전부 삭제됩니다.

언급했던 것과 동일한 순서로 로그가 출력되는 것을 확인할 수 있습니다. (명확한 테스트를 위해 Script Request 2를 하나 더 추가하였습니다)

 

2. Pre-request scripts란?

 

요청이 전송되기 전에 실행되는 스크립트로, Request 헤더에 timestamp를 포함시키거나, URL 매개변수에 임의의 영숫자 문자열을 추가하고자 할 때 사용할 수 있습니다. 

예를 들어 Request 헤더에 Timestamp를 포함시키고자 한다면, 아래와 같이 작성할 수 있습니다. 

요청보다 먼저 실행되기 때문에, Request Header에서 현재 존재하지 않는 timestampHeader 변수를 사용하여도, 요청이 보내질 때에는 생성되어 값을 문자열로 치환하여 전달합니다. 

테스트를 실행하면 요청헤더에 timestamp가 들어가 있는 것을 확인할 수 있습니다. 

앞서 언급하였듯이 컬렉션이나 폴더에도 Pre-request script를 작성할 수 있습니다. 이는 모든 요청 전에 공통적으로 실행되는 코드를 기재하기 위한 것으로, 동일한 코드를 모든 요청에 작성할 필요가 없도록 하기 위함입니다.

 

3. Test scripts란?

 

test scripts는 요청에 대한 응답을 받은 후에 실행되는 코드로, pre-request script와 달리 pm.response 객체에 대한 액세스가 허용됩니다. 따라서 응답에 대한 테스트 스크립트를 작성하여 해당 요청에 대한 결과가 의도한 대로 왔는지 검증할 수 있습니다. 상태 코드가 올바르게 왔는지, 응답의 내용이 제대로 왔는지, 원하는 변수가 사용 중인지 등 테스트하고자 하는 만큼 테스트 코드를 추가할 수 있습니다. 

tests에 테스트에 대한 코드가 존재하면 하단 Test Results에 결과가 표시됩니다.  직관적으로 코드를 작성할 수 있기 때문에, 어떤 예시들이 있는지만 숙지한다면 작성하는 것은 그다지 어렵지 않습니다.  예시에 대한 부분은 아래에서 자세히 다루도록 하겠습니다.

위 이미지의 우측의 SNIPPETS은 많이 사용하는 스크립트 예시에 대한 짧은 스니펫으로, 이를 이용하는 것도 나쁘지 않습니다. 

 

test script는 앱의 실행 환경과 별도로 샌드 박스 환경에서 실행됩니다. 따라서 밑에서 다루게 될 예시 코드 외에도 몇 가지 사용할 수 코드들이 있는데, 이에 대한 내용은 샌드박스 설명서와 샌드박스 API에서 살펴보시기 바랍니다. 

 

마찬가지로 컬렉션과 폴더에도 테스트 스크립트를 작성할 수 있으며, 이 경우 테스트 스크립트는 모든 요청 각 각에 대해서 응답이 돌아온 후 실행되게 됩니다. 마찬가지로 중복 코드를 줄여 줍니다. 

 

4. Script Example

 

자주 쓰이는 스크립트에 대한 예시를 다루어보겠습니다. 

 

먼저 환경변수와 관련된 스크립트입니다. 환경변수에 대한 내용은 다음 장에서 자세히 다룰 것이며 이 장에서는 코드만 먼저 소개하겠습니다. 

 

< 환경변수 설정 >

pm.environment.set("key","value") 

 

< 중첩된 객체를 환경 변수로 설정하기 >

var array = [1, 2, 3, 4];
pm.environment.set("array", JSON.stringify(array, null, 2));
  
var obj = {a: [1, 2, 3, 4], b: { c: val'} };
pm.environment.set("obj", JSON.stringify(obj)); 

 

< 환경변수 얻기 >

pm.environment.get("key"); 

 

< 값이 문자열화된 객체인 경우 환경 변수 얻기 >

var array = JSON.parse(pm.environment.get("array"));
var obj = JSON.parse(pm.environment.get("obj")); 

 

< 환경 변수 삭제 >

pm.environment.unset("key"); 

 

 

전역 변수 역시 다음 장에서 자세히 다루도록 하겠습니다. 

 

< 전역 변수 설정 >

pm.globals.set("key", "value");

 

< 전역 변수 얻기 >

pm.globals.get("key"); 

 

< 전역 변수 삭제 >

pm.globals.unset("key"); 

 

 

아래 함수는 전역변수와 활성화된 environment에서 변수를 검색하여 가져옵니다. 마찬가지로 다음장에서 자세히 다루겠습니다. 

 

< 변수 가져오기 >

pm.variables.get("key");

 

 

그럼 다음으로 응답에 대한 검증을 위한 스크립트를 살펴보겠습니다. 

 

< response body에 문자열이 들어있는가 >

pm.test("Body matches string", function(){
    pm.expect(pm.response.text()).to.include("string you want to search");
}); 

 

test의 첫 번째 매개변수로 들어가는 문자열은, 이 테스트가 어떤 것을 테스트하기 위함인지 명시하기 위한 것임으로 간결하고 명확하게 쓰는 것을 권장합니다. 테스트의 결과 시트에서 이 문자열과 pass, fail 여부만 출력되기 때문에 어떤 것에 대한 테스트가 성공했는지 실패했는지 알 수 있도록 기재하는 것이 중요합니다. 

 

< response body가 문자열과 같은가 >

pm.test("Body is correct", function(){
    pm.response.to.have.body("response body");
});

 

< JSON 값 확인 >

pm.test("json value test", function(){
    var jsonData = pm.response.json();
    pm.expect(jsonData.value).to.eql(100);
}); 

 

< content-type이 헤더에 있는가 >

pm.test("Content-Type is present", function(){
    pm.response.to.have.header("Content-Type");
});

 

< 응답 시간이 200ms 미만인가 >

pm.test("Response time is less than 200ms",function(){
    pm.expect(pm.response.responseTime).to.be.below(200);
}); 

 

< status code는 200(ok) >

pm.test("Status code is 200 - OK",function(){
    pm.response.to.have.status(200);
});

 

< status code 이름이 문자열이며 일치하는가 >

pm.test("Status code name has String",function(){
    pm.response.to.have.status("Created");
});

 

< POST 요청이 성공했는가 >

pm.test("Successful POST request",function(){
    pm.expectI(pm.response.code).to.be.oneOf([201,202]);
});

 

 

이런 기본적인 테스트 방법 외에도 몇 가지 향상된 기능을 사용할 수 있습니다. 

 

< JSON 데이터에 Tiny Validator 사용하기 >

var schema = {
    "items": {
                "type":"boolean"
             }
};
var data1 = [true, false];
var data2 = [true, 123];
  
pm.test("Schema is valid", function(){
    pm.expect(tv4.validate(data1, schema)).to.be.true;
    pm.expect(tv4.validate(data2, schema)).to.be.true;
});

Tiny Validator는 JSON Schema 검증기로, 자세한 내용은 Tiny Validator에서 확인하실 수 있습니다. 

 

 

< base64로 인코딩된 데이터 디코드 >

var intermediate,
    base64Content,  //인코딩 데이터가 있다고 가정
    rawContent = base64Content.slice('data:application/octet-stream;base64,'.length);
  
intermediate = CryptoJS.enc.Base64.parse(base64content);
  
pm.test('Contents are valid', function(){
    pm.expect(CryptoJS.enc.Utf8.stringify(intermediate)).to.be.true;
}); 

 

< 비동기 요청 보내기 >

pm.sendRequest('https://postman-echo.com/get', function(){
    console.log(response.json());
}); 

 

< XML 본문을 JSON 객체로 변환 >

var jsonObject = xml2Json(responseBody); 

 

5. 분기 및 반복

 

컬렉션을 실행할 때, API 요청을 분기하거나 반복하는 것도 스크립트를 통해 구현 가능합니다. postman.setNextRequest("request_name") 메서드를 사용하면 됩니다. test scripts에서 다음에 실행될 요청을 직접적으로 명시하는 것으로, 이 코드가 스크립트 내에 존재하지 않는다면 각 각의 요청들은 순서대로 실행됩니다.  요청명을 기재하지 않고, null을 입력하게 되면 현재 플로우를 더 이 상 실행하지 않고 중지시킬 수도 있습니다. 

 

< Next Request >

postman.setNextRequest("request_name")

 

< 워크 플로우 실행 중지 >

postman.setNextRequest(null)

 

이 메서드에서 다음에 실행될 요청의 이름이나 ID를 지정하면, Collection Runner가 나머지를 알아서 처리해줍니다. 당연하겠지만 test scripts뿐만 아니라 pre-request script에서도 사용 가능하며, 만약 이 코드가 여러 줄 작성되어 있는 경우에는 가장 마지막에 기재된 값으로 실행됩니다.

 

제어 흐름에 대한 더 자세한 내용은 Work Flow 작성에서 확인하실 수 있습니다. 

댓글