菜单
开源

高级示例

您可以在一个脚本中使用多个场景,这些场景可以按顺序或并行运行。组合场景的一些方法包括以下几点

  • 设置不同的启动时间以按顺序运行工作负载
  • 为每个场景添加标签和环境变量
  • 设置场景特定的阈值。
  • 使用多个场景运行不同的测试逻辑,这样 VU 就不会只运行默认函数。

组合场景

使用 startTime 属性,您可以配置脚本以使某些场景晚于其他场景启动。要按顺序运行场景,可以将 startTime 与执行器特定的 duration 选项结合使用。(对于具有固定 duration 的执行器,例如 arrival-rate 执行器,这样做最容易)。

此脚本包含两个按顺序运行的场景:contactsnews

  1. 测试开始时,k6 启动 contacts 场景。50 个 VU 在 30 秒内尝试运行尽可能多的迭代。
  2. 30 秒后,k6 启动 news 场景。每个 VU 在一分钟内尝试运行 100 次迭代。

除了 startTimedurationmaxDuration 外,请注意每个场景不同的测试逻辑。

JavaScript
import http from 'k6/http';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: 'constant-vus',
      exec: 'contacts',
      vus: 5,
      duration: '5s',
    },
    news: {
      executor: 'per-vu-iterations',
      exec: 'news',
      vus: 5,
      iterations: 10,
      startTime: '10s',
      maxDuration: '20s',
    },
  },
};

export function contacts() {
  http.get('https://test.k6.io/contacts.php', {
    tags: { my_custom_tag: 'contacts' },
  });
}

export function news() {
  http.get('https://test.k6.io/news.php', { tags: { my_custom_tag: 'news' } });
}

为每个场景使用不同的环境变量和标签。

前面的示例为单个 HTTP 请求指标设置了标签。但是,您也可以为每个场景设置标签,这也会将其应用于其他可标记对象。

JavaScript
import http from 'k6/http';
import { fail } from 'k6';

export const options = {
  discardResponseBodies: true,
  scenarios: {
    contacts: {
      executor: 'constant-vus',
      exec: 'contacts',
      vus: 50,
      duration: '30s',
      tags: { my_custom_tag: 'contacts' },
      env: { MYVAR: 'contacts' },
    },
    news: {
      executor: 'per-vu-iterations',
      exec: 'news',
      vus: 50,
      iterations: 100,
      startTime: '30s',
      maxDuration: '1m',
      tags: { my_custom_tag: 'news' },
      env: { MYVAR: 'news' },
    },
  },
};

export function contacts() {
  if (__ENV.MYVAR != 'contacts') fail();
  http.get('https://test.k6.io/contacts.php');
}

export function news() {
  if (__ENV.MYVAR != 'news') fail();
  http.get('https://test.k6.io/news.php');
}

注意

默认情况下,k6 会为每个场景中的所有指标应用一个 scenario 标签,其值是场景名称。您可以将这些标签与阈值结合使用,或使用它们来简化结果过滤。

要禁用场景标签,请使用 --system-tags 选项。

使用不同的阈值运行多个场景函数

您还可以为不同的场景函数设置不同的阈值。为此,请执行以下操作

  1. 设置场景特定的标签
  2. 为这些标签设置阈值。

此测试包含 3 个场景,每个场景都有不同的 exec 函数、标签、环境变量和阈值

JavaScript
import http from 'k6/http';
import { sleep } from 'k6';

export const options = {
  scenarios: {
    my_web_test: {
      // some arbitrary scenario name
      executor: 'constant-vus',
      vus: 50,
      duration: '5m',
      gracefulStop: '0s', // do not wait for iterations to finish in the end
      tags: { test_type: 'website' }, // extra tags for the metrics generated by this scenario
      exec: 'webtest', // the function this scenario will execute
    },
    my_api_test_1: {
      executor: 'constant-arrival-rate',
      rate: 90,
      timeUnit: '1m', // 90 iterations per minute, i.e. 1.5 RPS
      duration: '5m',
      preAllocatedVUs: 10, // the size of the VU (i.e. worker) pool for this scenario
      tags: { test_type: 'api' }, // different extra metric tags for this scenario
      env: { MY_CROC_ID: '1' }, // and we can specify extra environment variables as well!
      exec: 'apitest', // this scenario is executing different code than the one above!
    },
    my_api_test_2: {
      executor: 'ramping-arrival-rate',
      startTime: '30s', // the ramping API test starts a little later
      startRate: 50,
      timeUnit: '1s', // we start at 50 iterations per second
      stages: [
        { target: 200, duration: '30s' }, // go from 50 to 200 iters/s in the first 30 seconds
        { target: 200, duration: '3m30s' }, // hold at 200 iters/s for 3.5 minutes
        { target: 0, duration: '30s' }, // ramp down back to 0 iters/s over the last 30 second
      ],
      preAllocatedVUs: 50, // how large the initial pool of VUs would be
      maxVUs: 100, // if the preAllocatedVUs are not enough, we can initialize more
      tags: { test_type: 'api' }, // different extra metric tags for this scenario
      env: { MY_CROC_ID: '2' }, // same function, different environment variables
      exec: 'apitest', // same function as the scenario above, but with different env vars
    },
  },
  discardResponseBodies: true,
  thresholds: {
    // we can set different thresholds for the different scenarios because
    // of the extra metric tags we set!
    'http_req_duration{test_type:api}': ['p(95)<250', 'p(99)<350'],
    'http_req_duration{test_type:website}': ['p(99)<500'],
    // we can reference the scenario names as well
    'http_req_duration{scenario:my_api_test_2}': ['p(99)<300'],
  },
};

export function webtest() {
  http.get('https://test.k6.io/contacts.php');
  sleep(Math.random() * 2);
}

export function apitest() {
  http.get(`https://quickpizza.grafana.com/api/json?crocId=${__ENV.MY_CROC_ID}`);
  // no need for sleep() here, the iteration pacing will be controlled by the
  // arrival-rate executors above!
}

通过环境变量运行特定场景

k6 默认运行测试脚本中列出的所有场景。但是,通过一些小的代码更改和使用环境变量,您可以通过命令行告诉 k6 仅运行特定场景。

以下示例展示了一个测试脚本,该脚本使用 SCENARIO 环境变量(如果存在)来选择要执行的场景

JavaScript
import http from 'k6/http';

const scenarios = {
  my_web_test: {
    executor: 'per-vu-iterations',
    vus: 1,
    iterations: 1,
    maxDuration: '30s',
  },
  my_api_test: {
    executor: 'per-vu-iterations',
    vus: 1,
    iterations: 1,
    maxDuration: '30s',
  },
};

const { SCENARIO } = __ENV;
export const options = {
  // if a scenario is passed via a CLI env variable, then run that scenario. Otherwise, run
  // using the pre-configured scenarios above.
  scenarios: SCENARIO ? { [SCENARIO]: scenarios[SCENARIO] } : scenarios,
  discardResponseBodies: true,
  thresholds: {
    http_req_duration: ['p(95)<250', 'p(99)<350'],
  },
};

export default function () {
  const response = http.get('https://quickpizza.grafana.com');
}

然后,您可以通过运行以下命令,从命令行运行测试脚本并仅执行 my_web_test 场景

bash
SCENARIO=my_web_test k6 run script.js
windows
set "SCENARIO=my_web_test" && k6 run script.js
powershell
$env:SCENARIO="my_web_test"; k6 run script.js