Advanced CLI Usage

Learn some advanced patterns when using the stormforge CLI.

All examples and patterns shown in this guide are about the CLI only and are not usable in the web frontend.

Building a Test Case with ECMAScript Modules

You can use the CLI to create a test case that imports other JavaScript code from your local machine using ECMAScript modules. The CLI uses esbuild for compiling the various JavaScript files into a single bundle.

To enable this functionality, the main file of your test case must use the file extension .mjs (also called entrypoint). You can import JavaScript code from other .js or .mjs files.

// file: testcase.mjs
definition.setTarget("http://testapp.loadtest.party");

definition.setArrivalPhases([
  {
    duration: 5 * 60,
    rate: 1.0,
  },
]);

definition.setTestOptions({
  cluster: { sizing: "preflight", },
});

import helloWorldScenario from "./exported_modules.js";
definition.session("hello world", helloWorldScenario);
// file: exported_modules.js
function helloWorldScenario(session) {
  session.get("/hello");
}

export default helloWorldScenario;

This example will be automatically processed (because of the .mjs file extension), for example when using the create test-case command:

stormforge create test-case my-modular-testcase --from-file testcase.mjs

Caveats:

  • If the entrypoint ends in .mjs, bundling is automatically enabled.
  • All CLI commands accepting test case definitions, support bundling.
  • The compilation processes uses dead code elimination. So you might not find all defined code in your compiled output.

Defining Values

In addition to ECMAScript modules, the CLI also supports passing values via the command line (via --define) to make change test cases before being uploaded. We use esbuild’s define feature here:

This feature provides a way to replace global identifiers with constant expressions.

To pass a value from the CLI, use --define name=value (e.g. --define users=123 or --define env=\"prod\"). The name must be an expression from your test case that you want to adjust and value a valid JavaScript value.

To default values, we recommend wrapping them in an object that gets defaulted:

// --define works on global identifiers only! To make "defines" in this case
// a global identifier, it MUST NOT be defined via `var`, `let` or `const`.
defines = {}
const config = {
    env: defines.ENV || "staging",
}

In this example, config.env is set to "staging" by default (because defines.ENV is undefined). By using define (e.g. --define 'defines.ENV="prod"') config.env is set to "prod". Note the quotes are necessary as the replacement is verbatim and must be valid JavaScript term - depending on your shell, escaping might be required too.

stormforge edit test-case my-modular-testcase --from-file testcase.mjs --define 'defines.ENV="prod"'

To use multiple defines, pass multiple --define flags.

A few caveats:

  • You can use --define only if you also provide the test case file
  • To use strings as defines, you may need to quote your values twice to escape them, otherwise your shell eats them (see above)
  • If you want defaulting in case no --define is used, you have to define a global identifier first as shown above

Find out more

You can also checkout our GitHub Actions Guide or GitLab Guide for an example of using the stormforge CLI in a CI/CD context.

Last modified July 4, 2023