성능 테스트 도구 알아보기: Silk Performer (3) 스크립트 작성

Updated:

이번 글에서는 Silk Performer를 사용하여 실제 스크립트를 작성하는 과정에 대해, 작성 단계별로 살펴보도록 하겠습니다.

1. New Project

성능 테스트 대상 프로젝트의 정보를 입력하는 기능입니다.

Silk Performer Workbench를 클릭하여 실행한 후 나타나는 초기 화면에서, 상단 메뉴들 중 ‘New Project’(File>New Project)를 선택합니다. 이때, 중앙에 ‘Workflow - Outline Project’란 팝업창이 뜨는데, 화면내의 기능은 왼쪽의 1) 애플리케이션 유형을 선택하는 메뉴와, 오른쪽의 2) 프로젝트 정보를 기입하는 입력창으로 나뉘어 구성되어 있습니다.

Silk Performer

1) 애플리케이션 유형

기본적으로 Web business transaction(HTML/HTTP)가 선택되어 있으며, 이 유형은 Web Protocol Level Script를 기록하는데 사용됩니다. Web 이외에도 다양한 애플리케이션 별 통신 프로토콜을 지원하고 있으므로, 대상 애플리케이션에 맞게 Silk Performer가 지원하는 프로토콜을 선택하시면 됩니다.

2) 프로젝트 정보

여기서는, 간단히 성능 테스트를 수행하고자 하는 대상 프로젝트 이름과 설명을 기입합니다. 1개의 프로젝트에는 성능 테스트 수행시 사용할 여러개의 스크립트가 만들어지고 관리됩니다.(ex. Tech Blog Project - 1. 로그인, 2.메인화면 3. 키워드 검색 4. 공지글 등록 스크립트 등)

2. Model Script

스크립트 작성 수행을 위한 브라우저와 대상 URL 정보를 입력하는 기능입니다.

위의 작업이 완료된 후 팝업창 오른측 하단의 Next 버튼을 클릭하면, 아래와 같이 ‘Workflow - Model Script’ 팝업창 화면으로 이동하게 됩니다. 여기서는 실제 레코딩 작업을 수행할 1) 웹 브라우저의 종류를 선택하고, 2) 성능 테스트 대상 애플리케이션의 URL를 기입합니다. 브라우저는 Internet Explorer가 기본으로 설정되어 있으며, 다른 브라우저(ex. Chrome, Firefox 등)를 선택할 수도 있습니다.

Silk Performer

참고로, Micro Focus에서는 성능 스크립트 작성 연습을 위해 InsuranceWeb sample Web application을 제공하고 있습니다. 주소는 http://demo.borland.com/InsuranceWebExtJS/이며, 사용자 아이디 및 비밀번호는 초기화면 우측 중간에 기재되어 있습니다.

Silk Performer

사용할 브라우저와 대상 URL 기입이 완료되면, 중간에 위치한 Record using browser를 클릭함으로, 스크립트 작성을 시작합니다.

3. Silk Performer Recorder

실제적인 스크립트 레코딩을 진행하는 기능입니다.

1) Start Recording

스크립트 작성이 시작되면, 아래 화면과 같이 오른쪽 상단에 Silk Performer Recorder dialog가 최소화된 형태로 열리면서 레코딩이 시작되며, URL에 기입한 주소에 따라 웹 브라우저가 함께 열리면서 클라이언트 애플리케이션이 시작됩니다.

웹 브라우저 화면에서 로그인, 메뉴 클릭 후 이동 등의 실제 동작이 수행될 때마다, 레코딩 작업이 수행되면서 Silk Performer Recorder 왼쪽 하단의 Events의 숫자가 올라가는 것을 확인하실 수 있습니다.

Silk Performer

2) Start Timer/Stop Timer

성능 테스트 수행 중 상세 구간별 응답시간(ex. 로그인, 메인화면, 검색 등)을 측정하기 위해서는, Timer 기능을 사용하여 대상 구간을 표시해 주어야 합니다.

Silk Performer

예를들어, ‘로그인’의 응답시간 측정을 위해서는 다음과 같이 레코딩 작업을 진행합니다.

  • 측정대상 웹 브라우저의 로그인 화면에서 ID/PWD 기입
  • Silk Performer Recorder의 ‘Start Timer’ 버튼 클릭
  • Start Timer 팝업창에 ‘Timer 이름’ 기입(ex. 01_01_Login)
  • 웹 브라우저의 실제 ‘Login’ 버튼 클릭하여 동작 실행
  • 메인화면으로의 이동 완료 확인 후 ‘Stop Timer’ 버튼 클릭
  • Stop Timer 팝업창에서 종료할 Timer 이름 선택 후 OK 버튼 클릭

Silk Performer

3) Stop Recording

스크립트 작성을 종료하기 위해서는 Silk Performer Recorder 우측 상단의 닫기(X)버튼을 클릭한 후 .bdf 파일의 이름을 작성하고 저장하면, 스크립트 파일이 생성됩니다. 스크립트 작성이 종료되면 클라이언트 애플리케이션이 띄워져 있는 웹 브라우저도 함께 닫아줍니다.

Silk Performer

4. Capture File

레코딩이 완료된 후, 스크립트 생성을 위한 설정작업을 수행하는 기능입니다.

앞의 글에서 설명드린대로, 스크립트 작업이 완료되면 바로 스크립트 화면으로 이동하는 것이 아니라, 스크립트 생성에 대한 설정 작업을 수행한 후 Generate Script 기능을 수행할 수 있도록 Capture File 화면으로 이동됩니다.

1) Configure Script Generation Setting

Capture File 화면의 우측을 보시면 Options 하단에 ‘Configure Script Generation Setting’이라는 기능이 있습니다. 이 버튼을 클릭하면 Profile 팝업창이 뜨게 되는데, 레코딩된 값들에 대한 설정을 수행하는 여러가지 기능들이 있습니다. 설정에 대해서는 주요한 기능 몇가지만 짚고 넘어가도록 하겠습니다.

  • Profile 팝업창 > Record > Script > General Tab

예를 들어, 왼쪽 상단의 Record 박스 내의 Script를 클릭하면, 여기서는 레코딩 단계에서 자동으로 기록되는 Think Time의 포함 여부, 스크립트에 작성되는 최대라인의 길이(참고. 500이 최대한도), TrueLog Section의 자동생성 여부 등을 설정해 주는 기능들이 있습니다.

Silk Performer

  • Profile 팝업창 > Record > Web(Protocol Level)

왼쪽 Record 박스 하단의 여러 버튼들 중, Web(Protocol Level)을 클릭하여 들어가보면, 우측에 나타나는 여러 Tab들 중에 ‘Recording’이 있습니다. 여기서는 스크립트 작성시 기록된 Transaction에 대해 ‘Page-Level Web API’로 스크립트를 High Level 관점에서 생성할 것인지, 아니면 ‘Low-level Web API’로 단일 HTTP requests별로 모든 Network Interactions을 스크립트에 모두 기록할 것인지 등을 선택할 수 있습니다. Silk Performer

  • Domain Filter Settings

Profile의 팝업창을 빠져나와서, 다시 Capture File의 메인 화면으로 돌아가 보면, 화면 왼쪽의 기능들 중 ‘Domain Filter Settings’라는 기능이 있습니다. 스크립트를 작성하다보면, 대상 애플리케이션 외에도 소셜 미디어 또는 통계 플러그인과 같은 웹사이트에 포함된 타사 애플리케이션 구성요소 또한 레코딩 시 잡히게 되는데, 이러한 내역들이 리스트로 나타나게 됩니다.

그대로 남겨놓게 되면, 성능 테스트 수행 시 불필요하게 외부의 타 시스템에 과부하가 갈 수도 있고, 응답시간 측정 구간 내에 포함된 경우 측정에도 영향을 줄 수 있으므로, 해당 부분은 체크해제 한 후 측정하고자 하는 대상 도메인만 체크해 줍니다.

Silk Performer

  • Path and Query Filter Settings

마지막으로, 필터 기능을 이용해서 불필요한 웹 요청(ex. API calls) 이나, CSS, JS, PNG, GIF 등과 같은 파일등의 호출을 스크립트에서 제외할 수 있습니다. 스크립트에서 제외할 필터값 입력이 완료되면, 오른쪽 상단의 ‘Generate Script’ 버튼을 클릭함으로 정의된 패턴이 반영된 스크립트가 생성됩니다.

Silk Performer

5. Scripts

생성된 스크립트 내용을 확인하고 수정하는 기능입니다.

드디어, 단순한 것 같으면서도 은근히 복잡한 작업들을 거친 스크립트의 결과가 아래 화면과 같이 나타납니다.

Silk Performer

Micro Focus의 데모 페이지(http://demo.borland.com/InsuranceWebExtJS/)를 통해, 로그인(01_01_Login)과 로그아웃(01_02_Logout)의 레코딩 작업을 수행한 후, 설정값 변경 없이 바로 Generate Script를 수행하게 되면 아래와 같이 스크립트가 작성됩니다.


// ----------------------------------------------------------------------
// Generated 2020-12-22 from 'Insu_1222.spcap'
// by Silk Performer Recorder v20.5.0.8539
// ----------------------------------------------------------------------
//  * Rule "Excluding browser-specific domains"
// Excluding proprietary TCP/IP traffic
// Excluding UDP traffic
// Rule set "ASP.NET ViewState"
//  * Rule "Parse and Replace __VIEWSTATE"
//  * Rule "Parse and Replace __EVENTVALIDATION"
// ----------------------------------------------------------------------

@codepage(949)

benchmark SilkPerformerRecorder

use "WebAPI.bdh"

dcluser
  user
    VUser
  transactions
    TInit           : begin;
    TMain           : 1;

var

dclrand

dcltrans
  transaction TInit
  begin
    WebSetBrowser(WEB_BROWSER_MSIE11);
    WebModifyHttpHeader("Accept-Language", "en-US,en;q=0.7,ko;q=0.3");
    //WebSetUserBehavior(WEB_USERBEHAVIOR_FIRST_TIME);
    //WebSetDocumentCache(true, WEB_CACHE_CHECK_SESSION);
  end TInit;

  transaction TMain
  var
  begin
    TrueLogSection("Start Recording");
 
    SetEncoding("UTF-8");
 
    WebPageAddUrl("images/h_back2.jpg");
    WebPageAddUrl("images/ltc1.gif");
    WebPageAddUrl("images/lbc1.gif");
    WebPageAddUrl("images/rtc1.gif");
    WebPageAddUrl("images/rbc1.gif");
    WebPageAddUrl("images/header.png");
    WebPageAddUrl("images/pimp1.gif");
    WebPageAddUrl("images/ltc.gif");
    WebPageAddUrl("images/lbc.gif");
    WebPageAddUrl("images/rtc.gif");
    WebPageAddUrl("images/rbc.gif");
    WebPageAddUrl("images/pimp2.gif");
    WebPageAddUrl("images/pimp3.gif");
    WebPageUrl("http://demo.borland.com/InsuranceWebExtJS/", "InsuranceWeb: Home");
 
    ThinkTime(33.9);
    MeasureStart("01_01_Login");
 
    TrueLogSection("Click", "", "Screenshot_93920369");
 
    WebPageAddUrl("images/h_back2.jpg");
    WebPageAddUrl("images/rtc1.gif");
    WebPageAddUrl("images/header.png");
    WebPageAddUrl("images/pimp1.gif");
    WebPageAddUrl("images/ltc.gif");
    WebPageAddUrl("images/rbc1.gif");
    WebPageAddUrl("images/lbc.gif");
    WebPageAddUrl("images/rbc.gif");
    WebPageAddUrl("images/pimp2.gif");
    WebPageAddUrl("images/pimp3.gif");
    WebPageAddUrl("images/ltc1.gif");
    WebPageAddUrl("images/lbc1.gif");
    WebPageAddUrl("images/rtc.gif");
    WebPageSubmit("login-form", LOGIN_FORM001, "InsuranceWeb: Home (#1)"); // Form 2
    MeasureStop("01_01_Login");
 
    ThinkTime(19.7);
    MeasureStart("01_02_Logout");
 
    TrueLogSection("Click", "", "Screenshot_93940102");
 
    WebPageAddUrl("images/h_back2.jpg");
    WebPageAddUrl("images/pimp1.gif");
    WebPageAddUrl("images/rtc1.gif");
    WebPageAddUrl("images/rbc1.gif");
    WebPageAddUrl("images/lbc.gif");
    WebPageAddUrl("images/rbc.gif");
    WebPageAddUrl("images/ltc.gif");
    WebPageAddUrl("images/pimp2.gif");
    WebPageAddUrl("images/ltc1.gif");
    WebPageAddUrl("images/lbc1.gif");
    WebPageAddUrl("images/rtc.gif");
    WebPageAddUrl("images/header.png");
    WebPageAddUrl("images/pimp3.gif");
    WebPageSubmit("logout-form", LOGOUT_FORM002, "InsuranceWeb: Home (#2)"); // Form 2
    MeasureStop("01_02_Logout");
 
  end TMain;

dclform
  LOGIN_FORM001:
    "login-form"                := "" <USE_HTML_VAL> , // hidden, unchanged, value: "login-form"
    "login-form:email"          := "john.smith@gmail.com", // changed
    "login-form:password"       := Decrypt3DES("BK2kMA74+JIT"), // changed
    "javax.faces.ViewState"     := "" <USE_HTML_VAL> , // hidden, unchanged, value: "j_id1:j_id2"
    "login-form:login.x"        := "40", // added
    "login-form:login.y"        := "7"; // added

  LOGOUT_FORM002:
    "logout-form"               := "" <USE_HTML_VAL> , // hidden, unchanged, value: "logout-form"
    "javax.faces.ViewState"     := "" <USE_HTML_VAL> , // hidden, unchanged, value: "j_id1:j_id3"
    "logout-form:logout.x"      := "27", // added
    "logout-form:logout.y"      := "14"; // added

자동으로 작성된 스크립트 내용들 중 몇가지 부분에 대해 간단히 살펴보겠습니다.

1) Startup and Shutdown Transactions

우선 Transactions의 구성은 스크립트의 기본 생성시 TInit과 TMain으로 구분되어 있으며, 아래의 예문에는 TShutdown이 추가되어 있습니다. TMain, TShutdown 등의 이름 자체는 원하는 명칭으로 변경하여 사용할 수 도 있습니다.

dcluser
  user
    User1
  transactions
    TInit     : begin;
    TMain     : 1;
    TShutdown : end;
  • TInit

    TInit과 같이 ‘begin’으로 선언된 부분은 모든 트랜잭션들을 초기화하는 것으로, 테스트 스크립트의 시작 부분에서 사용자(Virtual User)당 한 번만 실행됩니다.

  • TMain

    TMain은 기록된 모든 API Function 등을 포함하고 있는 곳으로, ‘1’과 같이 숫자로 표시되어 있는 부분은 부하가 지속되는 동안 반복적으로 실행되는 구간입니다. (참고. 이 숫자가 1보다 큰 값을 사용할 때는, 여러 트랜잭션들간의 가중치를 적용하는 데 사용할 수 있습니다.) TMain 부분은 한개 이상의 트랜잭션을 포함하여 설정할 수 도 있습니다.

  • TShutdown

    TShutdown과 같이 ‘end’로 선언된 부분은 테스트 스크립트가 종료될 때 사용자당 한번만 실행되는 종료 트랜잭션입니다.

예를 들어, 스크립트가 아래와 같은 형태로 구성되어 시뮬레이션이 수행된다면, 진행되는 순서는 다음과 같습니다.

  • ‘begin’으로 선언된 TInit Transaction은 전체 시뮬레이션이 시작되는 초기에 최초 1번 실행됩니다.

  • 다음으로, 숫자 ‘1’로 선언된 Login, Search, Close의 3개 Transaction들은 순차적으로 각각 1번씩 수행되는 것을 반복하며(Login → Search → Close → Login → …) 시뮬레이션이 진행되는 시간동안 계속해서 반복됩니다.

  • 마지막으로, ‘end’로 선언된 Logout Transaction은 시뮬레이션이 종료될때 1번 실행됩니다.

dcluser
  user
    User1
  transactions
    TInit     : begin;
    Login     : 1;
    Search    : 1;
    Close     : 1;
    Logout    : end;

2) MeasureStart and Stop

앞에서 스크립트 작성에 대해 언급할 때, 특정 구간에 대한(ex. login) 응답시간 측정을 위해서는 Start Timer와 Stop Timer를 이용해 이름을 정의한다고 설명하였습니다. 해당 작업의 반영 결과는, 아래 스크립트 예시와 같이 MeasureStart와 MeasureStop으로 구간을 정의하여 레코딩이 반영된 것을 보실 수 있습니다.

참고로, 스크립트 내에 자동으로 ThinkTime이 들어가 있는 것을 볼 수 있는데, 이 부분은 앞서 살펴본 Record Setting에서 ‘Include ThinkTime’을 체크 해제하면 스크립트에 포함되지 않습니다.

  transaction TMain
  var
  begin
 
  //스크립트 생략

    WebPageUrl("http://demo.borland.com/InsuranceWebExtJS/", "InsuranceWeb: Home");
 
    ThinkTime(33.9);
    MeasureStart("01_01_Login");
 
  //스크립트 생략

    WebPageSubmit("login-form", LOGIN_FORM001, "InsuranceWeb: Home (#1)"); // Form 2
    MeasureStop("01_01_Login");
 
  end TMain;

※ ‘Think Time’에 대한 개념이 궁금하신 분들은, Tech Blog의 홍성진 수석님의 글들 중 “Introduce to Performance test(1/5)”을 참조하시기 바랍니다.

3) DCLFORM

스크립트 내용에서 마지막으로 살펴볼 것은, 로그인 계정 등과 같은 입력값에 대한 처리 부분입니다. 앞서 스크립트 작성 시, 우리는 User ID(ex. john.smith@gmail.com)와 Password(ex. john)를 기입하였는데, 그 부분은 스크립트의 어느 부분에 표시가 되어 있을까요?

    MeasureStart("01_01_Login");
 
  //스크립트 생략

    WebPageSubmit("login-form", LOGIN_FORM001, "InsuranceWeb: Home (#1)"); // Form 2
    MeasureStop("01_01_Login");
 
  end TMain;

dclform
  LOGIN_FORM001:
    "login-form"                := "" <USE_HTML_VAL> , // hidden, unchanged, value: "login-form"
    "login-form:email"          := "john.smith@gmail.com", // changed
    "login-form:password"       := "john", // changed
   
   // 스크립트 생략

위의 스크립트 예시에서 보여지는 것과 같이, 해당 부분은 TMain이 끝나는 하단부에 위치한 dclform이라는 Section에서, email과 password에 대해 우리가 입력한 정보가 레코딩되어 있음을 알 수 있습니다. dclform은 스크립트의 트랜잭션에서 웹서버와 데이터를 교환하는데 사용되는 웹양식이 정의되는 부분입니다.

6. Try Script

스크립트 모델링을 통해 완성된 스크립트가 오류없이 정상 동작하는지 확인하는 기능입니다.

Silk Performer

상단의 Workflow Bar 메뉴들 중에서 Try Script 버튼을 클릭한 후 나타나는 팝업에서 오른쪽 하단의 Run 버튼을 클릭하면, 1Vuser에 대해 스크립트 수행을 시작합니다.

Silk Performer

1) Try Script Summary

실행이 완료되고 나면, 아래 화면과 같이 수행 결과에 대한 요약 화면이 나타납니다.

Insurance Co. 페이지의 로그인 및 로그아웃 스크립트에 대해 1명의 User와 1개의 Agent를 이용하여 수행한 결과, Transaction Error 및 Fail은 발생하지 않았으며, 2개의 Transaction 모두 성공적으로 수행했다는 요약 결과를 보여줍니다.

Silk Performer

2) Silk TrueLog Explorer

Try Script를 실행할 때, 동시에 또 하나의 창이 뜨면서 동작하는 것을 확인할 수 있는데, 이것의 이름은 TrueLog Explorer이며 실제 수행 결과에 대한 시각적인 분석을 지원해줍니다.

아래에서와 같이 왼쪽의 트리구조에서 우리가 정의한 Login 구간을 클릭해보면, 오른쪽에 로그인이 정상적으로 수행될 때 나타나는 웹페이지(ex. Logged in as John Smith) 정보들을 통해, 로그인 스크립트가 실제로 오류없이 잘 작성되었음을 가시적으로 쉽게 확인할 수 있습니다.

Silk Performer

이외에도, TrueLog Explorer를 통해 수행할 수 있는 작업들은 아래와 같이 다양하며, Micro Focus에서 제공하는 도움말에서 상세 설명을 확인할 수 있습니다.

  • Find replay errors quickly and easily
  • Customize session handling
  • Parameterize input data
  • Add verifications to test scripts
  • Analyze TrueLog On Error
  • Visualize and customize database operations
  • Visualize and customize XML
  • Visualize and customize Citrix
  • Visualize and customize terminal emulation
  • Analyze TCP/IP and UDP test results
  • Analyze GUI-level test results

7. Customization of output-input correlations

이번 글에서는 Silk Performer에서 프로젝트를 정의하는 것에서부터, 웹브라우저 레코딩 및 Capture File을 통해 스크립트를 생성하고, 생성된 스크립트가 정상적으로 값을 주고 받는지 Try Script 기능을 통해 확인하며, 수행 결과에 대해 TrueLog Explorer를 통해 실제 화면으로 확인해보는 작업까지에 대한 내용을 다루어 보았습니다.

물론, 실제적인 성능 테스트를 위해서는 스크립트 단계에서 추가적인 작업들(ex. Customize session handling, Parameterize input data 등)이 필요한 경우가 많습니다.

예를들어, 500명의 가상사용자(Virtual Users)별로 고유의 ID와 Password를 각각 부여한다든지, 검색창에 입력하는 검색어를 1,000개로 다양하게 구성하여 호출하도록 처리한다든지, 스크립트 반복시마다 동적으로 변화하는 Session ID 값을 변수처리해준다든지 하는 작업들입니다.

해당 내용을 이번 글 아래에 계속 이어 쓰기에는 내용이 너무 길고 가독성이 떨어질 수 있어서, 별도의 글로 구분하여 다루도록 하겠습니다.

참조.

  1. https://www.microfocus.com/documentation/silk-performer/205/en/silkperformer-205-webhelp-en/SILKPERF-2953CAE0-SILKPERFORMER.html
  2. https://www.slideshare.net/SunTechnlogies/silk-performer-presentation-v1
  3. http://www.sqaforums.com/forums/archive/index.php/f-11.html
  4. http://demo.borland.com/InsuranceWebExtJS/