성능 테스트 기법 (4) Manual Correlation

Updated:

1. Client-Server 통신에서의 Dynamic Values 처리

성능 테스트 Script를 작성하는 단계에서, Client와 Server간 통신에서 주고받는 Dynamic Values(ex. 세션 아이디, 인증 토큰, 날짜값 등, Server에서 생성하여 전송받는 동적인 고유의 값)들을 처리하는 방법에 대해서는, 지난번 글인 “성능 테스트 기법 (2) Customize Session Handling”에서 자동화 도구의 ‘Automatic Correlation 기능’을 이용한 처리 방법에 대해 이미 살펴본 바 있습니다.

하지만, 실제적으로 다양한 Project 현장에서 Script를 작성하다보면, 복잡한 애플리케이션의 경우에는, 자동화 도구가 제공하는 Correlation 기능만으로 처리해 주어야 할 ‘모든’ 동적인 값들을 찾는 것이 생각보다는 쉽지 않음을 종종 접하게 됩니다.(전체 성능 테스트 일정 중 Script 작성 기간을 3일 이상으로 충분히 잡는 이유도, 이러한 문제 발견과 해결에 많은 생각보다 많은 노력과 시간이 소요되고 있기 때문입니다.)

자동화 도구가 제공하는 Automatic Correlation 기능은 ‘규칙에 기반한 접근방법(Rule-based Approach)’으로 작동하기 때문에, 사전에 정의된 규칙의 범위를 벗어나 있는 애플리케이션의 Dynamic Value들은 식별되지 않을 수 있습니다. 이 경우, 동적으로 변하는 값들을 성능 테스트 담당자가 직접 식별하고, Script에서 해당 값들이 처리될 수 있도록 변환해 주어야만, Server가 Script의 반복적인 요청을 지속적으로 인식할 수 있게 되어, 성능 테스트가 정상적으로 수행 될 수 있게 됩니다.

실제 Script 작성사례를 설명하기에 앞서, Client와 Server간 통신에서 작성된 Script가 반복적인 수행이 불가능하게 되는 상황에 대해서, 아래에서 그림과 함께 그 원인을 살펴보도록 하겠습니다.

1) Client와 Server간 통신과정: Script Recording 단계

우선 Client에서 Server로 세션 ID 요청을 보내면, Server에서는 고유한 동적값을 생성하여 Client에게 전송하게 됩니다.(참고로, 아래의 그림에서는 Client가 세션 ID인 “ABC”를 받고 있는데, 이 값은 동적이어서 Server가 각각의 요청에 대한 응답을 전송할때마다 값이 바뀌게 됩니다.)

다음 요청에서, Client는 이 세션 ID를 Server로 보내게 되고, Server는 세션 ID를 인식한 후 다음 응답을 보내게 됩니다. 성능 테스트 자동화 도구는 이 과정을 Script로 기록하게 됩니다.

Script Recording Source: Correlation in LoadRunner with Web_Reg_Save_Param Example - www.guru99.com

2) Client와 Server간 통신과정: Script Replay 단계

위와 같은 상황에서 성능 테스트 도구의 Recording 기능을 통해 작성된 Script를 실행(Replay)해 보면, 바로 FAIL되는 결과를 확인하게 됩니다. 그 원인은, 아래 그림에서와 같이 Recording시 할당받은 세션 ID(ex. ABC)를 변경없이 Script 작성 시점에 저장된 고정값을 그대로 재사용하였기 때문입니다.

Server 입장에서는 자신이 새로 할당한 세션 ID(ex. DEF)와는 다른 값을 받게 되므로, 결과적으로 인식할 수 없게 되어 Script에서 수행한 Transaction에서 Fail이 발생하게 된 것입니다.

Script Replay Source: Correlation in LoadRunner with Web_Reg_Save_Param Example - www.guru99.com

이러한 문제를 해결하기 위해서는, Script에서 Sever로부터 전송받는 동적인 값을 Parameter로 처리하여 저장하게 한 후, 해당값을 가지고 바로 세션이 시작될 수 있도록 Script에 추가로 반영해주는 Correlation 작업이 필요하게 됩니다. Automatic Correlation 방법은 이미 지난 글에서 설명하였으므로, 여기서는 나머지 Manual Correlation에 대해서만 추가로 다루도록 하겠습니다.

2. Manual correlation: Silk Performer와 Chrome 개발자 도구 활용

이제부터는, Silk Performer를 가지고 수행한 실제 Project의 Script 사례를 통해, 어떻게 세션값을 확인하고 Script에 반영해 주는지에 대해 단계별로 설명해 보도록 하겠습니다.

우선, 대상 애플리케이션의 ‘로그인 업무’를 대상으로 Script를 작성합니다.

transaction TMain
  var
  begin

   SetEncoding("UTF-8");

   WebUrlBeginPage("Sample Portal Login Page");
   WebUrl("http://sk.abc.com/signin");
   WebUrlEndPage(); // Sample Portal Login Page

 MeasureStart("01_login");
 
    WebFormPost("http://sk.abc.com/portal/signin", 
      PORTAL_SIGNIN003, 0.10);
 
    WebUrlBeginPage("main");
    WebCookieSet(
      "x-auth-token=eyJhbGciOiJIUzI"; domain=.sk.abc.com; path=/; expires"
      "=Sat, 22 Feb 2031 05:01:54 GMT", 
      "http://sk.abc.com/main");
    WebUrl("http://sk.abc.com/main");
    WebUrlEndPage(); // main
 
    WebUrlBeginPage("userinfo");
    WebUrl("http://sk.abc.com/portal/userinfo");
    WebUrlEndPage(); // userinfo

[중략] 

Script가 완료된 후, Try Script를 실행해 보니 403 Error가 발생하고 있습니다.

silk

참고. HTTP 403 403 Forbidden은 서버가 허용하지 않는 웹 페이지나 미디어를 사용자가 요청할 때 웹 서버가 반환하는 HTTP 상태 코드이다. 다시 말해, 클라이언트가 서버에 도달할 수 있어도 서버가 페이지 접근 허용을 거부했다는 것을 뜻한다.

Source: https://ko.wikipedia.org/wiki/HTTP_403

Silk TrueLog Explorer를 통해 확인해 보니, ID와 Password를 기입하고 로그인버튼을 누르고 난 이후부터 메인화면이 뜨기까지의 과정에서 아래와 같이 오류가 발생한 것으로 확인됩니다.

silk

1) Chrome 개발자 도구 사용

Client와 Server간 발생하는 Request 및 Response를 좀 더 자세히 관찰하기 위해, Chrome 브라우저에서 F12를 눌러 개발자 도구를 열어놓은 상태에서, Script 대상 애플리케이션의 로그인을 위한 초기 화면을 호출합니다. 이때, 로그가 유지될 수 있도록 우측 상단의 Preserve log를 체크한 상태로 진행합니다.

f12

2) 브라우저에서 로그인 작업 수행 및 로그 확인

Script 대상 웹페이지의 로그인 화면에서 ID와 Password를 입력하고 로그인 버튼을 클릭하면, 해당 업무의 수행 과정에 대한 로그가 우측 화면에 표시되어 나타나는 것을 확인할 수 있습니다.

f12

3) Header값 확인

로그인이 수행되어 메인 화면으로의 이동까지 완료되면, 오른쪽 화면에서 “Network” Tab을 선택하고, 왼쪽 Name 항목에 나타난 내역들 중 로그인 관련 페이지(이번 예시에서는 ‘signin’페이지)를 클릭한 후, 우측 하단의 “Headers” Tab 상태에서 관련 로그 내용들을 확인해 봅니다.

우선, Cookie 항목에 “JSESSIONID”와 “X-auth-token”값이 들어있음을 확인할 수 있습니다.

f12

4) Cookie값 확인

우측 하단의 “Cookies” Tab을 눌러보면, 보다 정리된 상태로 위에서 확인한 것과 동일하게 우리가 Parameter 처리해 주어야 할 “JSESSIONID”와 “X-auth-token” 값이 있음을 확인할 수 있습니다.

f12

5) Silk Performer에서 In Header Tab 확인

Silk Performer에서 대상 애플리케이션의 로그인 업무에 대한 Script를 작성하고 나서, Silk TrueLog Explorer 왼쪽 트리메뉴에서 해당 로그인 페이지(ex. signin)를 클릭한 후, 우측 하단 In Header Tab을 통해 로그를 확인해 보면, Server에서 보내온 “JSESSIONID”값이 있음을 확인할 수 있습니다.

우선 해당 값에 대한 Parameter 처리를 진행해 보도록 하겠습니다.

silk

6) JSESSIONID의 Parameter 처리

Parameter를 처리하는 방법은, “JSESSIONID”의 실제 값(ex. EF525~) 부분을 마우스로 드래그 한 후 오른쪽 버튼을 클릭하면, 하단에 “Parse Selected Text into a Variable..”이라는 메뉴가 나타나는데 여기를 클릭해 줍니다.

silk

7) Insert Parsing Function

이때, ‘Insert Parsing Function’ 팝업 창이 뜨는데, Parameter 처리할 “JSESSIONID”의 이름을 기입(ex. Param_JSESSIONID)해 준 후, OK 버튼을 눌러주면 Script에 반영이 됩니다.

silk

8) Session ID값 Prameter 처리 내용의 Script 반영 확인

Script를 확인해 보면, 아래와 같이 “WebParseDataBoundEx” Function을 이용한 JSESSIONID에 대한 Parameter 처리가, 최초 로그인 페이지의 URL 윗쪽에 반영되어 있음을 확인하실 수 있습니다.

    WebParseDataBoundEx(Param_JSESSIONID, STRING_COMPLETE, ToEncoding("JSESSIONID="), 1, ToEncoding(";"),
      WEB_FLAG_IGNORE_WHITE_SPACE | WEB_FLAG_CASE_SENSITIVE | WEB_FLAG_HEADER_ONLY, 1);
    WebUrlBeginPage("Sample Portal Login Page");
    
    WebUrl("http://sk.abc.com/signin");

9) In Body Tab에서 X-auth-token 확인

다음으로, 해당 로그인 페이지의 “X-auth-token” 값은 어디서 받고 있는지 TrueLog Explorer에서 제공되는 로그를 통해 확인해 보니, In Body Tab에서 해당 값이 있음을 확인하였습니다.

“X-auth-token” 값에 대해서도 Parameter 처리를 해주어야 하는데, 이번 경우에는 (지난 글에서 다룬) Silk Performer의 ‘Customize Session Handling’ 기능을 활용하여 Parameter 처리를 해주었습니다.

silk

10) Token값 Prameter 처리 내용의 Script 반영 확인

위의 과정을 통해, “X-auth-token” 값의 Parameter 처리 내용이 아래와 같이 (ID와 Password의 로그인 정보를 Server에 전송하는 단계의) Script 위에 반영된 것을 확인하실 수 있습니다.

MeasureStart("TC00_login");
 
WebParseDataBoundEx(Param_token, STRING_COMPLETE, ToEncoding(""), 0, ToEncoding(""),
      WEB_FLAG_IGNORE_WHITE_SPACE | WEB_FLAG_CASE_SENSITIVE, 1);

WebFormPost("http://sk.abc.com/portal/signin", 
  PORTAL_SIGNIN003, 0.10); 

11) Cookie값의 Parameter 반영 수행

Server로부터 전송받는 “JSESSIONID”값과 “x-auth-token”값에 대한 Parameter 처리가 완료되었기 때문에, 이 값들을 동적으로 Script에 반영해 주기 위한 다음 작업을 수행합니다.

기존 Script에 고정값으로 기록되어 있던 Cookie값은 주석처리(//)하고, “WebCookieSet” Function을 이용하여 아래와 같이 Parameter가 반영된 새로운 Cookie값을 각각 추가해 줍니다.(아래 예시에서는, 기존 Script의 WebCookieSet 부분을 복사하여, 고정값 부분만 Parameter값(ex. “+Param_token+”)으로 바꾸어 주었습니다.)


  WebUrlBeginPage("main");

  WebCookieSet(
     "JSESSIONID="+Param_JSESSIONID+"; domain=.sk.abc.com; path=/; expires"
     "=Sat, 22 Feb 2031 04:25:59 GMT", 
     "http://sk.abc.com/main");

  WebCookieSet(
      "x-auth-token="+Param_token+"; domain=.sk.abc.com; path=/; expires"
      "=Sat, 22 Feb 2031 04:25:59 GMT", 
      "http://sk.abc.com/main");

// WebCookieSet(
//    "x-auth-token=eyJhbGciOiJIUzI; domain=.sk.abc.com; path=/; expires"
//    "=Sat, 22 Feb 2031 04:25:59 GMT", 
//    "http://sk.abc.com/main");

 WebUrl("http://sk.abc.com/main");

12) Try Script

지금까지의 과정을 정리해 보면, 우리는 Cookie값에서 “JSESSIONID”와 “X-auth-token”의 고정 값이 들어있어 Script Fail이 발생하고 있음을 사전에 확인하였고, Server로부터 해당값들이 변경되어 전송될때마다 받아서 Script에 반영될 수 있도록 Parameter 처리를 해 주었습니다.

이제, 해당 작업으로 인해 Script가 실제로 동적인 값들을 잘 처리해 주는지, Try Script를 실행을 통해 확인해 보겠습니다.

silk

그런데, (예상과 달리) Script를 실행한 결과를 확인해 보니, 하단의 Output 화면에서 여전히 ‘403 Error’가 발생하고 있음을 확인할 수 있습니다. 무엇이 문제였을까요?

13) Header값 재확인

다시한번 Chrome 개발자 도구 화면으로 돌아가서, 우측 하단의 “Headers” Tab을 클릭한 후 살펴보니, 우리가 처음에 Cookie값에만 집중했었는데, 자세히 보면 하단에 별도로 ‘X-AUTH-TOKEN’이 있음을 확인하실 수 있습니다.(현실적으로, Script 과정은 이러한 Fail 결과 확인, 원인 분석 및 Script 반영 과정의 반복인 경우가 많습니다.)

F12

14) WebHeaderAdd Function

이제, Try Script 수행 시 오류가 났던 Script 부분에 대해, “WebHeaderAdd” Function을 이용해 X-AUTH-TOKEN 값을 추가해 주면, 아래와 같이 정리될 수 있습니다.


 WebUrlBeginPage("main");

  WebCookieSet(
     "JSESSIONID="+Param_JSESSIONID+"; domain=.sk.abc.com; path=/; expires"
     "=Sat, 22 Feb 2031 04:25:59 GMT", 
     "http://sk.abc.com/main");

  WebCookieSet(
      "x-auth-token="+Param_token+"; domain=.sk.abc.com; path=/; expires"
      "=Sat, 22 Feb 2031 04:25:59 GMT", 
      "http://sk.abc.com/main");
    
  WebHeaderAdd("X-AUTH-TOKEN", Param_token);
      
  WebUrl("http://sk.abc.com/main");

WebUrlEndPage(); // main

참고로, Silk Performer에서 제공하는 “WebHeaderAdd” Function의 예시는 다음과 같습니다.

Syntax

WebHeaderAdd( in sName  : string,
              in sValue : string ): boolean;

Example

dcltrans
  transaction TWebOwnAuthHeader
  var
    sUserPass    : string(200);
    nUserPassLen : number;
  begin
    // Build your own authentication header
    WebBase64Encode(sUserPass, 200, nUserPassLen,
                    "smith:paranoia{}[]~^",
    Strlen("smith:paranoia{}[]~^"));
    sUserPass := "Basic " + sUserPass;
    WebHeaderAdd("Authorization", sUserPass);
    WebUrl("http://standardhost/", 0.0);
  end TWebOwnAuthHeader;

Source: Silk Performer Help

15) Try Script

Script 수정이 완료된 후 다시한번 Try Script를 실행해 보면, 이제는 (우리의 바램대로) Script가 오류 발생 없이 정상적으로 동작하는 것을 확인하실 수 있습니다.

F12

3. 마무리 글

이번 글에서는, Chrome 브라우저의 ‘개발자 도구’를 이용하여 Manual Correlation을 수행하는 방법을 예시와 함께 설명 드렸습니다.

만약, 성능 테스트 담당자 스스로 확인이 어려운 경우(또는 Script 작성 시간이 촉박한 경우)에는, Project에서 해당 기능을 개발한 ‘개발자 인터뷰’를 통해 Dynamic Values에 대해 직접 확인하면서 Script에 반영하는 작업이 추가적으로 필요할 수 있습니다.

물론, 가장 좋은 업무 환경은 경험이 많은 성능테스트 전문가와 함께 2인 1조로 함께 지원하면서, 동일 스크립트에 대해 함께 작성하면서 고민해보고, 발생하는 문제들을 하나하나 해결해가는 과정을 통해 점진적으로 성장해가는 방향이 가장 이상적이라고 생각합니다.^^

[끝]