지금은 API 테스트를 진행하라고 하면 rest-assured를 사용하기 때문에 다른 도구 사용할 일이 없지만

그래도 api testing 도구라고 하면 제일 많이 사용되는 도구가 뭐냐고 하면 SoapUI라고 말할 것 같다. 

이전에 SoapUI를 업무에 잠시 활용했을 때 나름 정리해두었던 내용을 여기에 다시 게시한다.

기본적인 사용법은 여기저기에 더 잘 정리되어 있으니, 생략하고.. tip 위주로..


Property 제어

  • 프로퍼티는 동적으로 변경되는 값, 자주 변경되어야 하는 값을 처리할 때 사용하고, 가급적 프로젝트 레벨(혹은 Suite레벨)로 관리하자.
    • 예) Endpoint URL, Username, MDN 등
  • 프로퍼티 제어는 Groovy Script를 활용하거나 Property Transfer 등을 활용한다

Assertion


(1) XPath Assertion
  • xml형식의 response message 중 단순 string추출이 아닌 특정한 형식의 값을 추출해낼 수 있는 방법으로 xpath 를 사용한다.
  • xml syntax 참고 : http://www.w3schools.com/xpath/xpath_syntax.asp
  • SoapUI에서는 xpath문법을 그대로 사용하면 동작하지 않는다. 아래 예제를 참고하여 작성하기 바란다.
    • xml response의 namespace값을 꼭 사용해야 한다.

    • expression부분에 하기와 같이 작성한다. 하기 예제는 response message중 첫번째로 보이는 spotCode의 value값을 가져온다.

      declare namespace ns1="http://www.naver.com"; 
      //ns1:spotCode[1]
(2) Regular Expression Assertion
  • Contains/NotContains 의 Assertion에 RegularExpression을 사용하여 적용할 수 있다. 이를 사용하면, 특정 string값이 아닌 원하는 형태의 문장을 비교할 수 있다.
  • Regular Expression 연습하기 좋은 사이트 url : http://www.regerx.com
  • SoapUI에서는 Regular Expression 문법을 그대로 사용하면 동작하지 않는다. 아래 예제를 참고하여 작성하기 바란다.
    •  response message가 json형식일때를 예로 들어, code값이 4만에서 5만번 사이의 숫자가 포함되는 조건을 추가하기 원한다면,

    • Contains/Not Contains Assertion에 use token as Regular Expression 체크박스를 체크하고, Content박스에 하기의 예와 같이 입력한다.

      (?s).*"code": "[4,5]\d{4}".*

(3) Script Assertion

Groovy Script

  • Javascript를 수행해야 하거나, Property를 제어하고자 할 때 많이 사용한다. 
  • Property 수행예제, javascript 실행 예제, cookie 예제를 하나씩 정리한다.

(1) Property 수행 예제

    • 참고 : https://www.soapui.org/scripting-properties/tips-tricks.html#0-1-how-to-get-and-set-properties-from-groovy
    • // get properties from testCase, testSuite and project
      def testCaseProperty = testRunner.testCase.getPropertyValue( "MyProp" )
      def testSuiteProperty = testRunner.testCase.testSuite.getPropertyValue( "MyProp" )
      def projectProperty = testRunner.testCase.testSuite.project.getPropertyValue( "MyProp" )
      def globalProperty = com.eviware.soapui.SoapUI.globalProperties.getPropertyValue( "MyProp" )
       
      // setting values is equally straigh forward
      testRunner.testCase.setPropertyValue( "MyProp", someValue )
      testRunner.testCase.testSuite.setPropertyValue( "MyProp", someValue )
      testRunner.testCase.testSuite.project.setPropertyValue( "MyProp", someValue )
      com.eviware.soapui.SoapUI.globalProperties.setPropertyValue( "MyProp", someValue )

(2) JavaScript 실행 예제

  • import javax.script.*
       
    // 기본으로 제공되는 JS엔진 사용
    ScriptEngineManager factory = new ScriptEngineManager();
    ScriptEngine engine = factory.getEngineByName("JavaScript")
    Invocable invocable = (Invocable) engine;     // JS 안의 메소드를 호출하는 인터페이스
      
    // JS loginName 을 파라미터로 넣어 호출하기 위한 함수를 만들어준다.
    def rsaFile = new URL("https://www.domain.com/encrypt.js").getText();
    rsaFile += """
    function fireEncrypt(str){
        return rsa.encrypt(str);
    };
    """;
    // 넣지 않으면 navigator가 없어 에러가 남.
    engine.put("navigator", "");
    engine.eval(rsaFile);
    def loginName = testRunner.testCase.testSuite.project.getPropertyValue("loginName");    // testSuite 에 설정한 property 를 읽어옴
    def encryptedLoginName = invocable.invokeFunction("fireEncrypt", loginName);
     
    testRunner.testCase.testSuite.project.setPropertyValue("encryptedLoginName",encryptedLoginName);      // testSuite 에 property 를 설정

(3) Cookie 설정 예제

  • import com.eviware.soapui.model.iface.SubmitContext
    import org.apache.http.client.protocol.ClientContext
    import org.apache.http.impl.cookie.BasicClientCookie
       
    // 현재 Case 가 실행되는 Context 를 받아와 여기에 저장한다. 그래서 이 Step 만 따로 실행하기는 안됨
    def httpContext = context.getProperties().getProperties().get(SubmitContext.HTTP_STATE_PROPERTY)
      
    def cookieStore = httpContext.getAttribute(ClientContext.COOKIE_STORE)
    def cookies = cookieStore.getCookies()
       
    // 쿠키에 세팅할 값.
    def sampleCookie = new BasicClientCookie("sample","sampleData");
    pcidCookie.setDomain(".naver.com")
      
    cookieStore.addCookie(sampleCookie)

Reporting


Jenkins 연동하기

1. 준비하기

  • jenkins에 아래와 같은 plugin이 설치되어 있어야 한다.

    • junit attachments plugin

    • junit plugin

    • git plugin

    • svn plugin
  • jenkins가 구동되는 장비에 soapUI가 설치되어 있어야 한다.

2. 수행하기

(0) Jenkins에서 프로젝트(new jobs) 생성 후..

(1) 소스(script) 코드 관리 부분 설정

    소스(soapui script)를 버전관리시스템(리파지토리, 현재 bitbucket)에서 가져오도록 설정

(2) Build 부분 설정

  • execute shell을 선택

    • command입력박스에 아래와 같이 입력 (SoapUI 의 TestRunner 수행을 위한 CommandLine 명령어를 넣어준다)

export JAVA_HOME=/app/jdk1.7.0_80; SOAPUI_HOME=/home/SoapUI-5.2.1; export SOAPUI_HOME; export PATH=$JAVA_HOME/bin:$PATH; export WORKSPACE=$WORKSPACE/MyWorkspace; rm -rf $WORKSPACE/report/JReport/*.xml; $SOAPUI_HOME/bin/testrunner.sh -a -j -I -f$WORKSPACE/report/JReport -PEndpoint=www.naver.com $WORKSPACE/test_api_project.xml

  • workspace는 soapui스크립트가 존재하는 곳을 지정하는 것이 좋음. 
  • -f 옵션은 결과파일 위치 지정, -P옵션은 스크립트 수행에 필요한 파라미터입력
  • 수행 전 기존 결과파일은 삭제하는 것이 좋음. 

(3)  빌드후 조치 부분 설정

  •  publish junit test result report 선택

    • Test report XMLs :  MyWorkspace/report/JReport/*.xml

    • Additional test report features 체크박스 체크.


Open API란?

  • 다양한 서비스와 컨텐츠 그리고 데이터를 좀 더 쉽게 이용할 수 있도록 공개한 인터페이스 (application pragramming interface)
  • 내부를 몰라도 Open API를 통해 해당 서비스의 기능 및 데이터를 쉽게 이용할 수 있다. 

Rest ?

  • 기존의 soap, wsdl 기반의 웹서비스를 대체하는 방식
  • CURD를 위해 Http method 를 사용
  • stateless 임 -> 세션, 쿠키값 등을 유지하지 않음
  • 디렉토리 구조와 같은 URI를 통해 리소스 접근하고, XML/Json 데이터 구조를 통해 데이터를 전송함
  • 구성
    • HTTP URI (Resource) + HTTP Method + Message (json)
  • Method
    • GET (Read) / POST (Create) / PUT (Update) / DELETE (Delete)
  • HTTP 응답코드
    • 2xx - 성공
      • 200 OK
    • 3xx - Redirection 
      • 304 Not Modified
    • 4xx - Client Error
      • 400 Bad Request
      • 401 Unauthorized
      • 403 Forbidden
      • 404 Not Found
    • 5xx - Server Error
      • 500 Internal Server Error
      • 503 Service Unavailable
      • 504 Gateway Timeout

테스트 접근 방법

  • open api의 사용자 관점에서 접근하되, sql query라고 생각하고 접근한다.
  • api 스펙 등 문서 기반으로 접근한다.
  • 전략
    • method type별 테스트 
      • GET : 조회 결과가 있을때, 없을때 
      • POST : 중복 생성이 불가한 경우를 고려한 중복 등록 시도
      • PUT : 존재하지 않는 데이터에 대한 수정 시도, 중복이 불가한 PK값으로 수정 시도
      • DELETE : 존재하지 않는 데이터 삭제 시도 등.
    • 응답코드 확인 테스트
      • 문서에 존재하는 응답코드 별로, 응답코드를 발생시키는 테스트 수행
      • 예) 필수 파라미터 누락, 존재하지 않는 데이터 조회 등
    • 파라미터에 대한 입력 예외 케이스 
      • String type의 경우 : 빈문자, 공백문자, 앞뒤 공백문자, 특수문자, 긴 문자열 등
      • 숫자의 경우 : 문자, int 범위를 넘어서는 숫자, 음수, 0 등
      • 날짜/시간 등 : 시간 연도 구분을 넘어가는 숫자 등 (25시간, 13월 등)
      • 정의된 코드 값 : 정의되지 않은 값, 대소문자 구분 등
      • 범위형 변수 : 시작과 끝, 시작과 끝을 벗어난 값 등
    • 비즈니스 흐름기반, 혹은 사용자 시나리오 기반 테스트 수행
      • api 하나로 기능을 확인할 수 없어, 여러 api를 호출해야 기능 하나를 확인할 수 있는 경우
      • 사용자 권한에 따라 다르게 동작해야 하는 경우
      • 여러 조건에 따라 다르게 동작해야 하는 경우 등.
    • 보안 테스트 수행
      • Parameter fuzzing
      • SQL Injections
      • Username harvesting
      • Cross-site scripting
      • External entities
      • Schema invalid XML
      • Large XML document
      • Malformed XML


성능테스트 진행시 서버 자원 상태에 대해 모니터링이 필요한데, 

이에 대한 기본적인 내용을 정리해봤다. 

참고 : (도서) 실무로 배우는 시스템 성능 최적화 : 시스템 동작 분석부터 성능 개선까지 (권문수)


기본 방향

CPU
  • CPU 자원은 부족한가?
  • 실행큐에 얼마나 쌓였는가?
  • CPU 사용 유형 중 System이나 IO wait의 사용률이 높은가?
  • 프로세스별 CPU 사용률 분포는 균등한가?
메모리
  • 메모리가 부족한가? (swap이 발생하고 있는가?)
  • 서버 전체 또는 개별 프로세스 단위로 메모리 사용량이 지속적으로 증가하는가?
  • 파일 캐시 영역으로 사용하는 메모리량은 얼마인가?
디스크
  • 디스크의 서비스 시간은 디스크 대기시간을 포함해서 얼마인가?
  • 특정 디스크로 입출력이 집중됐는가?
  • 파일시스템 중 공간이 부족한 곳은 있는가?
  • 디스크 스프라이트가 잘 구성돼 있는가?
  • 스토리지 채널 병목이 있는가?
네트워크
  • 네트워크 데이터 전송량은 얼마인가?
  • 네트워크 재전송량이 많은가
  • RTT (Round-Trip time) 시간이 높은가?
  • 일반적으로 CPU > 메모리 > 디스크 > 네트워크 순으로 부족 여부를 확인한다.
  • 자원 모니터링은 5초나 10초 간격으로 한다.
  • 자원 사용률 분석은 그래프를 통해 분석하는 것이 효과적이다.
  • 자원 사용률은 프로세스와 연관시켜 분석하는 것이 좋다.

주요 모니터링 도구

netstat

  • 네트워크 connection 상태, 라우팅테이블, 인터페이스 통계 정보 등을 출력
  • 사용 예
    • netstat -anp : 열려있는 모든 포트 출력
    • netstat -anp | grep LISTEN : listen 되는 모든 포트 출력
  • 옵션
    • -a : 모든 listening, nonlistening 상태 소켓들을 출력
    • -n : ip 주소 형태로 표시
    • -p : 소켓 소유하고 있는 pid와 프로그램 이름을 출력
    • -t : TCP 소켓 리스트 출력
    • -u : UDP 소켓 리스트 출력
    • -c : 1 초 단위로 연속해서 출력
    • -r : 라우팅 테이블 정보 출력

vmstat

  • 프로세스/메모리/입출력/시스템/CPU 활동상황에 대한 정보 확인
  • vmstat <delay> <count>
  • vmstat 모니터링
    • 프로세스 관련 항목

      • r : CPU 접근 대기 중인 실행 가능 프로세스의 수
      • b : 인터럽트 불가능한 sleep 상태에 있는 프로세스의 수
    • memory 관련 항목
      • swpd : 사용된 가상 메모리 용량
      • free : 여유 메모리 용량
      • buff : 버퍼에 사용된 메모리 용량
      • cache : 페이지 캐시에 사용된 메모리 용량
    • swap 관련 항목
      • si ( swap in ) : 디스크에서 스왑된 메모리 용량
      • so ( swap out ) : 물리적 메모리가 부족할 경우 디스크로부터 사용되는 메모리 양. swap out이 지속된다면 메모리 부족을 의심할 수 있음.
    • io 관련 항목
      • bi : block device에서 받은 블록 수 (blocks/s)
      • bo : block device에서 보낸 블록 수
    • system 관련 항목
      • in : 초당 발생한 interrupts 수
      • cs : 초당 발생한 context switches 수
    • cpu 관련 항목
      • us : cpu 가 사용자 수준 코드를 실행한 시간
      • sy : cpu 가 시스템 수준 코드를 실행한 시간 
      • id : cpu가 아무런 작업을 수행하지 않은 시간
      • wa : 입출력 대기
      • st : 가상화를 사용할 경우 가상머신 cpu의 계산으로 대기된 시간
  • vmstat 옵션
    • -a : buff와 cache대신 active/inactive로 출력
    • -n : 주기적으로 헤더를 출력하지 않도록 지정
    • -S : 출력되는 데이터 단위 지정 (k, K, m, M 지정 가능 = 1000, 1024, 1000000, 1048576으로 나눈값 출력)

top

  • linux kernel을 통해 관리되는 프로세스의 태스크 리스크들의 정보 (메모리, cpu, 상태정보) 등을 확인할 수 있는 명령어
  • 사용법
    • top
    • top -d 1
  • 옵션
    • -d : delay
    • -n : interactions
    • -p : pid

sar

  • top와 마찬가지로 cpu/memory/hdd 사용량 통계치 등을 모니터링할 수 있지만, sar는 history 및 최종 통계치를 볼 수 있다.
  • sar 명령을 사용하려면 sysstat package가 설치 되어 있어야 한다.
    • yum install sysstat
  • sar <option> <interval> <count>
  • 옵션
    • -u : cpu activity
    • -r : memory activity
    • -d : disk i/o activity
    • -A : report overall system performance

free

  • 현재 시점의 메모리 상태를 쉽게 확인할 수 있음.
  • free <-b|-k|-m|-g><option>
  • 옵션
    • b/k/m/g : 메모리양을 바이트/킬로바이트(기본값)/메가바이트/기가바이트로 표시한다.
    • -t : 총계가 포함된 줄을 출력
    • -o : 버퍼에 조정된 줄의 출력을 비활성화 한다.
    • -s : delay 초마다 계속해서 출력하도록 한다.

ps

  • 현재 수행되고 있는 프로세스 확인하는 명령어
  • ps -ef | grep httpd (특정 프로세스 확인)
  • ps -ef | wc -l (현재 기동중인 프로세스 총 수 확인)

CPU Monitoring

  • 안정적인 운영을 위한 CPU 사용율 기준
    • CPU 사용률 : CPU 70% 이하
    • CPU 실행큐 : CPU core 당 평균 3개 이하
  • 전체 CPU 기준으로 성능 평가를 할 때는 이중화 구성 등에 따른 부분 장애시에 대한 변화량/사용량을 맞춰서 판단할 필요가 있다. 
  • CPU 사용량 상세 분석
    • System : 커널모드 시스템 콜 호출에 사용된 CPU 사용량.
      • 시스템 콜이라 함은 프로세스 제어, 장치 관리, 파일과 네트워크 관리, 입출력 처리, 시스템 정보와 시간 관리 등에 관련된 함수
      • 일반적으로 전체 사용량 대비 30% 미만인데, system cpu가 높게 나타난다면 어떤 유형의 시스템 콜인지 분석할 필요가 있다 
      • 시스템 콜 모니터링 도구  : truss / pstack / jstack
    • User : 일반 함수를 실행하는데 사용된 CPU 사용량. WAS나 DB 서버 경우 User CPU를 사용한다.
    • IO Wait : 프로세스나 스레드가 CPU를 할당받아 사용할 수 있는 상태가 됐으나, 입출력이 완료되기를 기다리고 있어 CPU를 사용할 수 없는 상태의 사용량
      • 일반적으로 전체 사용량 대비 20% 미만인데, 높게 나타난다면 입출력이 과다하게 발생하는 것은 아닌지 디스크 사용률 등을 확인하면 된다.
      • io wait 모니터링 도구 : netstat / iostat / sar
    • Idle : 사용하지 않는 CPU 여유율
  • 기타 모니터링 방법
    • CPU core 수 확인 방법 (리눅스 기준) : cat /proc/cpuinfo
    • 커널 처리 비트 확인 방법 (리눅스 기준) : getconf WORD_BIT
    • CPU를 많이 사용하는 스레드 식별하는 방법 : top -H , ps -eLf | grep pid
    • 프로세스의 누적 CPU 사용량 확인하는 방법 : ps -ef

Memory Monitoring

  • 메모리 사용패턴이 100% 라고 해도 부족하지 않으면 성능저하가 발생하지 않는다. 
    • 운영체제 측면에서는 페이징스페이스에 대한 스왑 발생 여부로 판단.
    • 자바기반 솔루션 (was 등) 등은 설정한 힙메모리 이상을 사용하지 않기 때문에 운영체제 메모리 부족이 발생할 가능성은 적다.
  • 메모리 관련 용어
    • pagingspace : 메인메모리가 부족할 때 사용하는 디스크 공간, swap space라고도 부름.
      • 운영체제가 메인 메모리 크기 이상의 메모리를 사용할 수 있도록 해주는 역할.
      • 성능 관점에서보면 디스크에 프로세스 메모리를 쓰고 읽는 스와핑 작업으로 인해 큰 성능 저하가 발생한다.
      • pagingspace 크기 확인 방법 : cat /proc/swaps
    • paging : 
    • swapping : 메모리에서 페이지 혹은 세그먼트 단위 데이터를 교환하는 것. 컴퓨터가 메모리보다 큰 프로그램을 실행하거나 메모리보다 큰 데이터 파일을 다룰 수 있게 함.
    • page fault : 페이징 방식의 가상 메모리에서 CPU가 사용하려는 페이지가 메인 메모리에 없는 경우. 
    • page in : 가상 메모리에서 page fault가 발생했을때 디스크에 있는 프로그램이나 데이터를 메모리로 로드하는 것.
    • page out : 가상 메모리에서 page fault가 발생했을 때 메모리가 부족하면 기존 메모리를 디스크로 기록하는 것.
    • page scan rate : 운영체제는 일정량의 여유 페이지를 확보해서 필요한 경우 즉시 제공하기 위해 page scan이라는 검색을 통해 해제함으로써 여분으로 확보할 페이지를 찾는다. 
  • 안정적인 운영을 위한 메모리 판단 기준
    • 메모리 사용률 : 100% 이하
    • 지속적으로 프로세스 스와핑이 발생하지 않는지 확인
  • 일반적인 메모리 사용률 산출
    • 전체 메모리 total : used + free + buffers + cached
    • 실제 free 메모리 : free + buffers + cached
    • 실제 메모리 사용량 : total - (free+buffers+cached)
  • 메모리 총량 확인 방법 : cat /proc/meminfo
  • 프로세스 메모리 사용량 확인 방법 : ps -euf
  • 파일 캐시 확인 명령 : /proc/sys/vm/buffermem, free -m, vmstat -v

Disk I/O 

  • 시스템상 디스크 영향도 확인
    • 자원 영향도 : CPU 사용률에서 io wait 가 비정상적으로 높은지?
    • 디스크 영향도 : 디스크 대기시간과 서비스 시간이 높은지?
    • 어플리케이션 영향도
      • pstack/jstack 으로 스택을 반복 수집했을 때 서비스 중인 스레드 가운데 파일 입출력 관련 작업 중인 스레드의 비중이 높은지
      • lsof/pfiles로 확인한 로그 파일이나 데이터 파일의 크기가 큰지?
      • truss/tusc로 모니터링 했을 때 발생하는 입출력의 양이 많은지?
  • 디스크 입출력 모니터링 방법
    • sar -d <second> <count>
    • iostat <option> <second> <count>
  • 파일시스템 여유율 확인 방법
    • df -k

APM Solution

참고)

Java Heap Memory 

  • JVM 메모리 구조 및 GarbageCollator
    • 메소드 영역

      • 자바 프로그램을 구성하고 있는 메소드와 클래스 변수(static으로 선언된 변수) 저장하기 위한 공간이다.

      • JVM 복수개의 스레드가 메소드를 정상적으로 사용하기 위한 동기화 기법을 제공

    • 힙 영역

      • 프로그램 상에서 데이터를 저장하기 위해 동적으로(실행시간에)할당하여   있는 메모리 영역

      •  new 연산자를 통하여 개체를 동적으로 생성시

      • 메소드 영역과 같이 모든 프로그램에 의해 공유되는 공간 -> 동기화 기법 이용

      • GC(GarbageCollection)으로 관 되는 영역

        • Permanent Space : Class 대한 Meta 정보를 저장하는 공간

        • New Generation

          • Eden : new 생성된 모든 객체

          • Survivor1(From) : Minor GC 의해서 Eden, Survivor 2영역의 객체  활성화  객체만 이동하여 위치, Old Space 이동되기 전의 객체만 위치

          • Survivor2(To) : Minor GC 의해서 Eden, Survivor 1영역의 객체  활성화된 객체만 이동하여 위치, Old Space 이동되기 전의 객체만 위치

          • Old Generation : Survivor 1, Survivor 2 영역에서 이동해온 객체만 위치, Full GC 대상이 되는 객체가 위치

    • 스택영역(Stack area)
      • 메소드가 호출되어 실행될  멤소드의 매개변수메소드 내에 선언된 메소드 지역변수반호나  변수 등을 저장하기 위한 공간
      • 메소드 호출시 필요로 되는 변수들을 스택에 저장하고메소드 실행이 끝나면 스택을 반환하게 된다.
    • 네이티브 메소드 스택
      • 프로그램이 natie 메소드를 호출시 native 메소드의 매개변수, 지역변수 등을 저장하기 위해 사용하는 공간 native 메소드는 자바 언어가 아닌 기존의 다른 언어에서 제공되는 메소드를 의미

  • java heap memory 누수
    • 원인
      • 사용자 세션이나 캐시 데이터의 증가로 인한 메모리 증가
      • 로직 오류로 참조 레퍼런스가 끊어져야 되는데 그렇지 못해 GC대상에서 누락
      • 대용량 조회나 처리 등에서 발생
    • 확인 방법
      • Full GC 이후 old 영역 메모리 사용량이 지속적으로 증가하는지 여부로 판단.
  • java heap memory  monitoring
    • jstat
    • jconsol
    • gc logging
  • gc logging 옵션
    • -Xloggc:<path to file><filename>
    • -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
    • -verbose:gc 
  • java heap dump 
    • jmap -dump:format=b,file=12345_dump.hprof 12345 (pid가 12345일때)
    • kill -3 or Ctrl + Break 
    • java -Xrunhprof:heap=all,cpu=samples,thread=y,cutoff=0,format=a,doe=n,com.TestRun
    • jvm option
      • -XX:+HeapDumpOnOutOfMemoryError
      • -XX:+HeapDumpPath=/logs/app/dump 
      • -XX:+HeapDumpOnCtrlBreak

 

'QA > Perfomance' 카테고리의 다른 글

성능 테스트시 주로 사용하는 Shell 명령어 사용법  (0) 2018.03.05

appium으로 사내 서비스 자동화를 진행하다가, junit report나 surefire report 포맷이 별로라서, 좀 더 새로운 html report를 찾다가 발견한 extent report.


좀 더 이쁘장하고, 결과에 따라 필터링도 된다. 

다만, junit 결과를 자동으로 report로 변환하는게 아니라서, 테스트 이후 결과에 따른 로그를 직접 넣어야 된다. 


selenium이나 appium 자동화에 사용하는 사례도 구글링하면 좀 나오는거 보니, 쓸만한 것 같아 적용하기로 했고, 

실제 ui 자동화랑 api 자동화 업무에 해당 리포트를 사용하고 있다. 


우선, maven 설정을 추가하고,

<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>3.1.2</version>
</dependency>


  • 테스트 시작 시점에는 createReport
  • 테스트케이스 시작시점에는 createTest 
  • 테스트 종료시점에 pass/fail/skip 의 결과를 extent report에 작성-> test.log(STATUS.PASS...)


우선 report 생성할때, 설정 내용을 반영하도록 해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static ExtentReports createReport() throws Exception {
    if(extent != nullreturn extent;
 
    String reportFile= new File("target/result.html").getAbsolutePath();
 
    htmlReporter = new ExtentHtmlReporter(reportFile);
    htmlReporter.setAppendExisting(true);
    htmlReporter.config().setChartVisibilityOnOpen(true);
    htmlReporter.config().setDocumentTitle("타이틀적용");
    htmlReporter.config().setEncoding("UTF-8");
    htmlReporter.config().setReportName("리포트제목");
 
    extent = new ExtentReports();
    extent.setSystemInfo("OS""Windows 7");
    extent.attachReporter(htmlReporter);
 
    return extent;
}
cs


테스트 시작시

1
2
3
4
5
@BeforeClass
public static void setUp() throws Exception {
    enableLoggingOfRequestAndResponseIfValidationFails();
    extent = createReport();
}
cs


케이스 실행 시작 시점

1
2
3
4
@Before
public void beforeMethod() throws Exception {
    test = extent.createTest(methodName);
}
cs

케이스 종료 시점

1
2
3
4
@After
public void afterMethod() throws Exception {
    extent.flush();
}
cs

테스트 결과에 따라 리포트 로그를 남겨야 하기에 TestWatcher를 활용.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Rule
public TestWatcher testWatcher = new TestWatcher() {
 
    @Override
    protected void failed(Throwable e, Description description) {
        test.log(Status.FAIL, e.toString());
    }
 
    @Override
    protected void succeeded(Description description) {
        test.log(Status.PASS, "SUCCESS");
    }
 
     @Override
    protected void skipped(AssumptionViolatedException e, Description description) {
        test.log(Status.SKIP, SKIP_MSG);
    }
 
}
cs


대충 이정도 구성해놓으면, 각 테스트케이스 @Test 단위에서는 기존과 같이 자동화 코드를 작성하면 된다.


덧붙여 좀 더 추가해서 신경쓸 부분이 있다면, 

  • test.assignCategory(SuiteName); 등을 추가해서, 카테고리별로 구분해서 보게 할 수 있다.
  • 혹시 retry 를 사용하고 있다면, retry시에는 createTest를 추가할 필요가 없다.
  • report에 screenshot을 추가하고 싶다면, test.log(...).addScreenCaptureFromPath() 를 사용하면 된다.
  • jenkins에 연동할때에는 CSS가 적용될 수 있도록 jenkins에 CSS 관련 설정을 해야 한다.


더 좋거나 쉬운 리포트 라이브러리가 있으면 찾아보겠지만, extent report만으로도 현재까지는 만족.





'QA > Test Automation' 카테고리의 다른 글

SoapUI를 이용한 API 테스트 방법 정리  (0) 2018.01.28
API 테스트 방법  (0) 2018.01.27
Jenkins와 Sonar 연동하기  (0) 2012.07.19
Ant 로 Sonar 수행하기.  (0) 2011.04.12
Sonar 소개  (0) 2011.02.14

하도 오래전에 Jenkins와 Sonar를 연동해봤었는데,

요번에 BMS 프로젝트 진행하면서 Sonar한번 설치할래니 기억이 가물가물..;;


그래서 다시 이곳에 정리하기로 했다. 우선 Jenkins와 Sonar가 설치되어 있다는 가정하에 내용을 정리하겠다.


  1. Jenkins에 Sonar Plugin을 설치해야 한다. 
    • Jenkins 관리 > 플러그인 관리
  2. Maven 관련 설정을 한다. Sonar 자체가 Maven기반으로 동작하기 때문에 Maven설정은 필수다.
    • Jenkins 관리 > Configuration (시스템 설정) > Maven
  3. Sonar 관련 설정을 한다.
    • Jenkins 관리 > Configuration (시스템 설정) > Sonar
  4. Build Job을 생성하고 Build 관련 설정을 한다. 
    1. Build Job > 설정 > Build 관련 설정
      • root pom.xml 을 설정하고, goal에서는 -DskipTests=true를 꼭 넣어준다. sonar에서 test를 수행하기 때문에 저 옵션을 넣지 않으면 test가 두번 수행된다.
    2. Build Job > 설정 > Post-build Actions > Sonar 관련 설정
      • Add post-build action에서 Sonar를 선택하고, Sonar관련 설정을 한다.
      • -Dsonar.projectVersion옵션을 사용하면 Sonar에 version 정보를 전달할수 있다. 옵션을 사용하지 않으면 pom.xml의 <version> 정보가 sonar로 넘어간다. 
  5. Jenkins에서 Build를 수행한다. 연동 완료!


'QA > Test Automation' 카테고리의 다른 글

API 테스트 방법  (0) 2018.01.27
자동화에 extent report 적용하기  (0) 2018.01.22
Ant 로 Sonar 수행하기.  (0) 2011.04.12
Sonar 소개  (0) 2011.02.14
CI(Continuous Integration) 서버 구성안  (0) 2011.02.14

JIRA와 TestLink를 연동하는 방법을 아래에 기술한다.

JIRA 설정
1. Administration > Global Settings 하위의 General Configuration > Options 에서 Accept remote API calls 를 ON으로 설정한다.
2. JIRA RPC Plugin 을 설치한다.

TestLink 설정
1. config.inc.php 와 Custom_config.inc.php 파일에 $g_interface_bugs = 'JIRASOAP'; 로 설정
2. jirasoap.cfg.php 파일을 아래와 같이 수정
/** The Username being used by JIRA logon */
define('BUG_TRACK_USERNAME', 'jirauser');
 
/** The Password being used by JIRA logon*/
define('BUG_TRACK_PASSWORD', 'jirapassword');
 
/** link of the web server for JIRA*/
define('BUG_TRACK_HREF',"http://192.168.1.22:8080/");
 
* The values here are relative to the BUG_TRACK_HREF property *
 
/** path of JIRA WSDL */
define('BUG_TRACK_SOAP_HREF', "rpc/soap/jirasoapservice-v2?wsdl");
/** link of the web server for jira ticket*/
define('BUG_TRACK_SHOW_BUG_HREF', "browse/");
/** link of the web server for creating new jira ticket*/
define('BUG_TRACK_ENTER_BUG_HREF',"secure/CreateIssue.jspa");


  1. Acid 3 Test http://acid3.acidtests.org/
  2. W3C HTML4 Test Suite http://www.w3.org/MarkUp/Test/HTML401/current/
  3. W3C HTML5 Test Suite http://w3c-test.org/html/tests/harness/harness.htm
  4. HTML 5 Test http://html5test.com
  5. DOM Conformance Test Suite http://www.w3.org/DOM/Test/
  6. W3C XML Test Suite http://www.w3.org/DOM/Test
  7. JIL 1.2.2 Tests
  8. Sputnik Sputnik Sputnik ? JavaScript Conformance http://sputnik.googlelabs.com/
  9. JavaScript tests & Compatibility tables http://robertnyman.com/javascript/
  10. Native JSON TestNative http://robertnyman.com/javascript/javascript-native-json.html
  11. ECMAScript 3 Conformance Test Suite http://kangax.github.com/sputniktests-webrunner/
  12. CSS 2.1 Conformance Test Suite http://test.csswg.org/suites/css2.1/20110323/
  13. CSSCSS 3 Color Conformance Test Suite http://www.w3.org/Style/CSS/Test/CSS3/Color/current/
  14. Quirksmode background Test http://www.quirksmode.org/css/background.html
  15. W3C CSS3 Media Queries Test http://www.w3.org/Style/CSS/Test/MediaQueries/20100726/
  16. W3C CSS3 Selectors Test http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/
  17. CSS3 Selectors Test http://www.css3.info/selectors-test
  18. W3C XHR Test Suite http://tc.labs.opera.com/apis/XMLHttpRequest/
  19. W3C SVG Test Suite http://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overview
  20. DOM Level 1http://dorothybrowser.com/test/android/conformance/dom/level1/core/alltests.html?implementation%3Diframe%26skipincompatibletests%3Dtrue%26contenttype%3Dtext/html
  21. DOM Level 2 Corehttp://dorothybrowser.com/test/android/conformance/dom/level2/core/alltests.html?implementation=iframe&skipIncompatibleTests=true&autoRun=true&contentType=text/html
  22. DOM Level 2 HTMLhttp://dorothybrowser.com/test/android/conformance/dom/level2/html/alltests.html?implementation=iframe&skipIncompatibleTests=true&autoRun=true&contentType=text/html
  23. W3C XHR Test Suite http://tc.labs.opera.com/apis/XMLHttpRequest/testrunner.htm
  24. SVG 1.1 Tiny Test Suitehttp://www.w3.org/Graphics/SVG/Test/20061213/htmlObjectHarness/tiny-index.html

참고할 만한 링크자료

고급 Bash Scripting Guide : http://wiki.kldp.org/HOWTO/html/Adv-Bash-Scr-HOWTO/index.html
Shell Programming 강좌 : http://wiki.kldp.org/KoreanDoc/Shell_Programming-KLDP


http://www.tpc.org/tpce/
물론 위 링크에서 EGen을 다운 받아서 수행하면 될 것 같지만, 여러가지 문제점이 많이 발생하는 관계로, Lauchpad Percona-tools project에서 tpcemysql 을 다운 받는다.

이는 물론 TPC-E like한 것 뿐이라서 동일하지는 않지만, 같은 database구조로 같은 query를 날리는 것 같다.

우선 linux에서 bzr 이 설치 되어 있는지 확인하고, 안되어 있으면 설치한다.
# yum install bzr

이 후 bzr 을 이용해 Lauchpad Percona-tools project에서 tpcemysql을 다운 받는다.
# bzr branch lp:~percona-dev/perconatools/tpcemysql

mysqltpce를 수행하기에 앞서서 unixODBC, unixODBC-devel package와 make를 위해 gcc-c++ package가 설치되어 있어야 하므로, 기설치여부를 확인하고 설치한다.
# yum install unixODBC, unixODBC-devel, gcc-c++

다운받은 tpcemysql의 prj 디렉토리로 이동하면 Makefile이 존재한다. 그 곳에서 make를 수행한다.
# cd tpcemysql/prj
# make

make를 수행하기 전에 혹시 64bit 머신이라면 Makefile의 옵션을 수정해본다.(아직 이 옵션에 대한 의미가 확실치 않음)
  # Defines for Linux (MySQL C API Wrapper)
  CXX=g++
! CCFLAGS=-g -O2 -Wall -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -I/usr/include/mysql -DMYSQL_ODBC -DODBC_WRAPPER -DUSE_PREPARE
  LDFLAGS=-g -O2 -Wall
  LIBS=-lpthread -lmysqlclient_r
--- 23,29 ----
  # Defines for Linux (MySQL C API Wrapper)
  CXX=g++
! CCFLAGS=-g -O2 -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -I/usr/include/mysql -DMYSQL_ODBC -DODBC_WRAPPER -DUSE_PREPARE
  LDFLAGS=-g -O2 -Wall
  LIBS=-lpthread -lmysqlclient_r

make가 성공적으로  완료되면 tpcemysql의 bin디렉토리에 3개의 파일이 생성되어 있을 것이다.
* EGenLoader, EGenSimpleTest, EGenValidate

tpcemysql 홈디렉토리에서 아래와 같이 수행한다. (꼭 홈디렉토리에서.. 아니라면 flat_in, flat_out옵션을 따로 주어야 함)
# ./bin/EGenLoader -c 1000 -t 1000 -w 3

사실 이정도로 옵션을 주고 데이터를 생성하는 것은 TPC-E specification 에 비해서 너무 작다. 하지만, EGenLoader의 default값으로 수행하면 하루 죙일.. 걸리는 것 같다. 동작을 확인하기 위해서 우선 작은 값으로 수행하는 것을 알아두자.

그 다음, tpcemysql/script/mysql 디렉토리로 이동하여 해당 query들을 수행하자. 수행하기전, database와 user를 생성해 두는 것은 잊지 말자.
# mysql -u root -p
# create database tpce;
# grant all privileges on tpce.* to 'tpce'@'localhost' identified by 'tpce';
# flush privileges;

# cd tpcemysql/script/mysql
# mysql -u tpce -p tpce < 1_creat_table.sql
# mysql -u tpce -p tpce < 2_load_data.sql
# mysql -u tpce -p tpce < 3_create_fk.sql
# mysql -u tpce -p tpce < 4_create_index.sql
# mysql -u tpce -p tpce < 5_create_sequence.sql

query까지 수행하였다면, 이젠 EGenSimpleTest를 이용해서 테스트 하기만 하면 된다.
# ./bin/EGenSimpleTest -S localhost -D tpce -d 30 -t 180 -r 60 -u 8


참고 URL :
http://d.hatena.ne.jp/sh2/20100510
http://www.tpc.org/tpce/
http://www.mysqlperformanceblog.com/?s=tpc+e

'System > MySQL' 카테고리의 다른 글

mysql 기본 명령어 정리  (0) 2011.03.30
빌드는 maven으로 하고, sonar 구동 및 전체 수행은 ant 로 수행시키는 build.xml 예제.

사내 build에 적용해야 하는데, 아직 미 완성.
좀 더 프로세스를 구체화 시킨 후 적용할 예정이다.

<?xml version="1.0" encoding="UTF-8"?>
<project name="Sonar Ant Project" default="build" basedir="." xmlns:artifact="antlib:org.apache.maven.artifact.ant">
 <property environment="env"/>
 <path id="maven-ant-tasks.classpath" path="${basedir}/lib/maven-ant-tasks-2.1.1.jar"/>
 <typedef resource="org/apache/maven/artifact/ant/antlib.xml"
             uri="antlib:org.apache.maven.artifact.ant"
             classpathref="maven-ant-tasks.classpath" />
 <taskdef resource="net/sf/antcontrib/antlib.xml">
   <classpath>
     <pathelement location="${basedir}/lib/ant-contrib-1.0b3.jar" />
   </classpath>
 </taskdef>
 <taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml">
    <classpath path="lib/sonar-ant-task-1.0.jar" />
 </taskdef>
 <target name="build" depends="mvn,sonar"/>
 <target name="mvn">
   <property name="maven.home" value="${env.M2_HOME}"/>
   <echo message="M2_HOME = ${maven.home}"/>
   <artifact:mvn pom="pom.xml" mavenHome="${maven.home}" fork="true" failonerror="true">
     <arg value="clean"/>
     <arg value="install"/>
     <arg value="-Dmaven.test.skip=true"/>
    </artifact:mvn>
 </target>
 <target name="sonar">
   <tstamp>
     <format property="build.time" pattern="yyyy-MM-dd.hh:mm" locale="en"/>
   </tstamp>
  <!--
  <property file="build.number" />
  <echo message="build.number = ${build.number}"/>
  <buildnumber file="build.number" />
  -->
  <!-- The workDir directory is used by Sonar to store temporary files -->
  <sonar:sonar workDir="." key="org.example:example" version="${build.time}" xmlns:sonar="antlib:org.sonar.ant">
    <sources>
      <path location="${basedir}/common/src/main/java"/>
      <path location="${basedir}/model/src/main/java"/>
      <path location="${basedir}/dao-api/src/main/java"/>
      <path location="${basedir}/dao-hibernate/src/main/java"/>
      <path location="${basedir}/agent/src/main/java"/>
      <path location="${basedir}/manager/src/main/java"/>
    </sources>
    <tests>
      <path location="${basedir}/common/src/test/java"/>
      <path location="${basedir}/model/src/test/java"/>
      <path location="${basedir}/dao-api/src/test/java"/>
      <path location="${basedir}/dao-hibernate/src/test/java"/>
      <path location="${basedir}/agent/src/test/java"/>
      <path location="${basedir}/manager/src/test/java"/>
    </tests>
   <!--
    1. binaries: binaries directories, which contain for example the compiled Java bytecode (optional)
    2. libraries: path to libraries (optional). These libraries are for example used by the Java Findbugs plugin
    <binaries>
      <path location="..." />
    </binaries>
    <libraries>
      <path location="..." />
    </libraries>
   -->
   <!-- list of properties (optional) -->
   <property key="sonar.projectName" value="Sonar Ant Project" />
   <property key="sonar.dynamicAnalysis" value="true" />
   <property key="sonar.jdbc.url" value="jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8" />
   <property key="sonar.jdbc.driverClassName" value="com.mysql.jdbc.Driver" />
   <property key="sonar.jdbc.username" value="sonar" />
   <property key="sonar.jdbc.password" value="sonar" />
   <property key="sonar.host.url" value="http://192.168.20.34:9000" />
   <property key="sonar.java.source" value="1.6" />
   <property key="sonar.java.target" value="1.6" />
  </sonar:sonar>
 </target>
</project>
sonar를 ant로 구동시키면, modules(sub-projects)가 지원되지 않는 점 때문인지, tree map이 package이름으로 번잡하게 나오고, tangle index 정보가 나오지 않는다. 안타깝다;

+ Recent posts