k6 테스트 알아보기

민정·2025년 2월 6일

Grafana K6 공식 문서를 읽고 정리한 글이다.


k6 기초

k6 시작하기

  • k6는 JavaScript, TypeScript를 지원한다.
    • JavaScript 기반이지 Node.js 기반이 아니다. 따라서 npm 모듈과 호환되지 않을 수 있다.
  • vscode, intellij에서 자동 완성 및 기타 기능을 활성화하는 확장이 있다.
  • k6 설치하기를 참고해 설치 가능하다.

기본 구조

  • 기본 함수
    • 테스트 로직
  • import
    • k6 모듈
    • JavaScript 라이브러리
  • options(선택)
  • 수명 주기 작업(선택)
// import
import http from 'k6/http';
import { sleep } from 'k6';

// options
export const options = {
  iterations: 10,
};

// default function
export default function () {
  http.get('https://test-api.k6.io');
  sleep(1);
}

k6 실행하기

$ k6 run [테스트 파일]

위 명령어로 단순하게 실행 가능하다.

$ k6 run --vus 10 --duration 30s [테스트 파일]

가상 사용자 수(vus), 실행 시간(duration) 등의 옵션을 실행 명령어에서 설정할 수 있다.

export const options = {
  vus: 10,
  duration: '30s',
};

옵션은 CLI 플래그에서 설정하지 않고 테스트 스크립트에서 설정 가능한 것도 있으며, CLI 플래그로만 설정 가능한 것도 있다. 이는 아래의 Options 항목을 참고하자.

결과 출력하기

테스트가 마무리되면, 아래와 같은 테스트 결과 요약이 자동으로 출력된다.테스트 결과에서는 check의 실행 결과가 가장 상단에 나타난다. 이는 아래의 Check 항목을 확인하자.

테스트 결과에서는 여러 지표를 다음과 같은 통계 값으로 알려준다.

  • 평균(avg), 중앙(med)
  • 최소(min), 최대(max)
  • 90%(p90), 95%(p95)

테스트 결과에서 나타나는 k6 내장 지표는 다음과 같다.

  • standard

    지표설명
    checks성공적인 검사 비율
    data_received수신된 데이터의 양
    data_sent전송된 데이터의 양
    iteration_duration하나의 함수를 실행하는 시간
    iterations함수를 실행하는 총 횟수
    vus활성 가상 사용자 수
    vus_max가능한 최대 가상 사용자 수
  • http

    지표설명
    http_req_blocked요청 시작 전 차단된 시간(네트워크 연결, 서버 응답 지연 등)
    http_req_connectingTCP 연결을 설정하는 데 걸린 시간
    http_req_duration요청에 대한 총 시간(http_req_sending + http_req_waiting + http_req_receiving)
    http_req_failed요청 실패 비율
    http_req_receiving응답 데이터를 받는 데 소요된 시간
    http_req_sending데이터를 전송하는 데 소요된 시간
    http_req_waiting응답을 기다리는 데 소요된 시간
    http_reqsk6가 생성한 총 HTTP 요청 수

k6 테스트 함수 만들기

http 메소드

import http from 'k6/http';

export default function () {
  const url = 'http://test.k6.io/login';
  const body = JSON.stringify({
    email: 'aaa',
    password: 'bbb',
  });

  const params = {
    headers: {
      'Content-Type': 'application/json',
    },
  };

  http.get(url);
  http.post(url, body, params);
}
  • http 메소드를 사용할 수 있다.
    • del, put, patch 등의 메소드도 제공한다.
    • 매개변수로는 url, body, params를 필요로 한다.

{
  "type": "Point",
  "metric": "http_req_duration",
  "data": {
    "time": "2017-06-02T23:10:29.52444541+02:00",
    "value": 586.831127,
    "tags": { // http 요청에 자동 적용되는 태그
      "expected_response": "true",
      "group": "",
      "method": "GET",
      "name": "http://test.k6.io",
      "scenario": "default",
      "status": "200",
      "url": "http://test.k6.io"
    }
  }
}
  • k6는 http 요청에 자동으로 태그를 적용한다.
    • 위의 json 파일과 같은 형태로 자동으로 태그가 적용된다.
    • 적용된 태그를 바탕으로 결과를 필터링하고 분석할 수 있다.

check

check를 통해 응답 결과를 검사할 수 있다. check는 실패한다고 해서 테스트가 중단되거나 실패 상태가 되지 않는다. 테스트 중단, 실패를 원한다면 check 대신 아래의 임계값(thresholds)을 사용하자.

import { check } from 'k6';
import http from 'k6/http';

export default function () {
  const res = http.get('http://test.k6.io/');
  check(res, {
    'is status 200': (r) => r.status === 200,
  });
}

여기서 check 이름은 'is status 200'이다. 검사 마지막에 check 이름을 바탕으로 다음과 같이 결과가 표시된다.

$ k6 run checks.js

   ✓ is status 200

  checks.........................: 100.00% ✓ 10

import { check } from 'k6';
import http from 'k6/http';

export default function () {
  const res = http.get('http://test.k6.io/');
  check(res, {
    'is status 200': (r) => r.status === 200,
    'body size is 11,105 bytes': (r) => r.body.length == 11105,
  });
}

check로 응답에 대한 검사를 진행할 수 있다. 단일 check 문 내에 하나 이상의 검사가 포함될 수 있다.

임계값

테스트 지표가 설정한 임계값 조건을 충족하지 못하면 테스트가 중단, 실패하도록 설정할 수 있다.
임계값은 options의 thresholds를 통해 아래와 같이 설정할 수 있다.

export const options = {
  thresholds: {
    http_req_duration: ['p(90) < 400', 'p(95) < 800', 'p(99.9) < 2000'],
  },
};

단일 지표에 대해 여러 임계값을 설정할 수 있다.

export const options = {
  thresholds: {
    metric_name: [
      {
        threshold: 'p(99) < 10',
        abortOnFail: true,
        delayAbortEval: '10s',
        /*...*/
      },
    ],
  },
};
  • abortOnFail : true일 경우, 임계값 조건을 충족하지 못하면 테스트가 종료된다.
  • delayAbortEval: 테스트가 시작되고 설정한 시간만큼 경과한 후 임계값 조건을 충족하지 못할 때 테스트가 종료된다.

위의 코드는 metric_name이라는 특정 지표가 테스트가 시작된 지 10초 후에 p(99) < 10 조건을 충족하지 못하면 테스트가 종료된다.

Options

옵션은 CLI 플래그, 환경변수, 스크립트, 기본 구성 파일 등 다양한 위치에서 설정 가능하다. 우선순위는 CLI 플래그 > 환경변수 > 스크립트 > 기본 구성 파일 순이다.

옵션의 작성 방법에 대해 참고하자. 아래에서는 자주 사용하는 옵션에 대해서만 작성했다.

  • 파일 출력: 테스트 결과를 파일에 출력한다.

    $ k6 run --console-output [출력 파일] [테스트 파일]

  • 테스트 결과 시간 단위: 테스트 결과에 사용할 시간 단위를 설정한다. 시간 단위로는 s, ms, us를 사용할 수 있다.
    설정하지 않으면 k6가 알아서 적절한 단위를 선택해 표현한다.

    export const options = {
     summaryTimeUnit: 'ms',
    };

  • 테스트 결과 통계값: 테스트 결과에 나타날 통계값을 선택한다. 사용 가능한 값은 다음과 같다.

    • avg, med, min, max
    • 임의의 백분위 값: p(90), p(99.9) 등
      export const options = {
       summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.99)', 'count'],
      };


  • 로그 출력: 로그를 파일에 출력할 수 있다.

    $ k6 run --log-output=stdout script.js

  • 로그를 출력할 파일의 경로 지정이 필요한 경우 file 키워드를 함께 사용한다.

    $ k6 run --log-output=file=./k6.log script.js

  • 로그 포맷: json 또는 raw를 사용해 지정 가능하다.

    $ k6 run --log-format raw test.js

  • HTTP 디버그: 모든 HTTP 요청과 응답을 기록한다. 기본적으로 body는 기록하지 않으나, full을 사용하는 경우 body도 기록한다.

    export const options = {
     httpDebug: 'full',
    };



  • 가상 사용자: 가상 사용자 수를 설정한다. iterations 또는 duration 옵션과 함께 사용된다.

    export const options = {
     vus: 10,
     duration: '1h',
    };

  • 지속 시간 설정: 테스트 시간을 설정한다. vus와 함께 가상 사용자 + 시간을 설정할 수 있다.

    export const options = {
     vus: 100,
     duration: '3m',
    };

  • 반복: default 함수의 총 반복 횟수를 지정한다. duration 대신 사용할 수 있다.
    반복은 공평하게 분배되지 않는다. 가상 사용자 중 속도가 빠른 사용자가 다른 사용자보다 더 많은 반복을 진행할 수 있다.

    export const options = {
     vus: 5,
     iterations: 10,
    };

  • 램프 업/다운: 일정 기간동안 램프 업/다운할 VU 수를 지정한다.

    export const options = {
     stages: [
       { duration: '3m', target: 10 }, // 3분간 1 -> 10명으로 VU 램프업
       { duration: '5m', target: 10 }, // 5분간 10명 유지
       { duration: '10m', target: 35 }, // 10분간 10 -> 35명으로 VU 램프업
       { duration: '3m', target: 0 }, // 3분간 35 -> 0명으로 VU 램프 다운
     ],
    };

  • 임계값: 지표에 대해 설정할 수 있는 임계값. 위의 임계값 설명을 확인하자.

    export const options = {
     thresholds: {
       'http_req_duration': ['avg<100', 'p(95)<200'],
       'http_req_connecting{cdnAsset:true}': ['p(95)<100'],
     },
    };

Lifecycle

k6 테스트도 수명 주기가 존재한다. 수명 주기는 다음과 같은 단계로 진행된다.

  • init: 파일 로드, 모듈 가져오기 등의 작업을 수행한다.
  • setup(선택): 테스트 환경 설정, 데이터 생성 등의 작업을 수행한다.
  • VU code(≒default function): 테스트 기능이 실행된다.
  • teardown(선택): 데이터 후처리, 테스트 환경 닫기 등의 작업을 수행한다.
// 1. init code

export function setup() {
  // 2. setup code
}

export default function (data) {
  // 3. VU code
}

export function teardown(data) {
  // 4. teardown code
}

  • init 단계
    • 생애주기 밖의 코드는 모두 init 단계의 코드이다.
    • init 단계는 생애주기 중 가장 먼저, 단 한 번만 실행된다.
    • init 단계에서는 http 요청을 보낼 수 없다.
// init 단계 예제 코드
// 모듈 가져오기
import http from 'k6/http';
import { Trend } from 'k6/metrics';

// options 구성하기
export const options = {
  vus: 10,
  duration: '30s',
};

// 전역 변수 설정
const customTrend = new Trend('oneCustomMetric');

// 커스텀 함수 생성
function myCustomFunction() {
  // ...
}

  • VU code 단계

    • VU code의 default 함수는 테스트 동안 계속 반복적으로 실행된다.
    • VU code 단계에서는 init 단계의 작업(로컬 파일 가져오기, 모듈 불러오기)을 실행할 수 없다.
  • setup, teardown 단계

    • 생애 주기 중 단 한 번만 실행된다.
      • setup은 init 이후, VU 전에 호출된다.
      • teardown은 VU 후 호출된다.
    • init과 달리 http 요청을 보낼 수 있다.

내장 모듈

  • JavaScript API 목록에서 내장 모듈을 확인할 수 있다.
  • 주로 사용하는 모듈은 다음과 같다.
    • k6: check , sleep
    • k6/http: get , post , put 등 http 메소드

시나리오

시나리오를 사용하면 다음과 같은 이점이 있다.

  • 동일한 스크립트에서 여러 시나리오 선언 가능
  • 시나리오의 독립적, 병렬적 수행 가능
  • 세부적 결과 분석

시나리오는 다음과 같이 구성할 수 있다.

export const options = {
  scenarios: { // scenarios 키 사용
    example_scenario: {
      executor: 'shared-iterations',
      startTime: '10s', // 테스트 시작 시점
      gracefulStop: '5s',
      env: { EXAMPLEVAR: 'testing' }, // 환경 변수
      tags: { example_tag: 'testing' }, // 태그
      vus: 10, // 가상 사용자 수
      iterations: 200, // 반복 수
      maxDuration: '10s', // 최대 반복 시간
    },
    another_scenario: {
      /*...*/
    },
  },
};
  • executor

    • 반복 횟수
      • shared-iterations VU 간 반복 수 공유
      • per-vu-iterations 각 VU가 정확한 수의 반복 실행
    • VU 수 → 지정 시간 동안 가능한 많은 반복 실행
      • constant-VUs 고정된 수의 VU
      • ramping-vus 단계에 따라 VU 수 증가
    • 반복률
      • constant-arrival-rate 일정한 속도로 반복
      • ramping-arrival-rate 단계에 따라 반복 속도 증가
  • gracefulStop

    • 테스트가 강제 중단되는 경우, 현재 진행 중인 작업이 정상적으로 완료될 수 있도록 잠시 대기하는 시간을 의미한다.

테스트 결과

  • handleSummary 메소드를 통해 테스트 종료 결과를 마음대로 변형할 수 있다.
profile
시스템 + 리눅스 + 클라우드

0개의 댓글