By implementing k6 interfaces, you can close various gaps in your testing setup:
- New network protocols
- Improved performance
- Features not supported by k6 core
To run this tutorial, you'll need the following applications installed:
You also need to install xk6:
First, set up a directory to work in:
Register the module to use these from k6 test scripts.note
k6 extensions must have the k6/x/ prefix, and the short name must be unique among all extensions built in the same k6 binary.
Save the file as something like compare.go. The final code looks like this:compare.go
To build a k6 binary with this extension, run this command:
When building from source code, xk6-compare is the Go module name passed to go mod init. Usually, this would be a URL similar to github.com/grafana/xk6-compare.
Now, use the extension in a test script!
Make a file with a name like test.js then add this code:test.js
Run the test with ./k6 run test.js.
It should output the following:
Suppose your extension needs access to internal k6 objects to, for example, inspect the state of the test during execution. We will need to make slightly more complicated changes to the above example.
- lib.State, the VU state with values like the VU ID and iteration number
- a global context.Context containing objects like the lib.ExecutionState
Additionally, there should be a root module implementation of the modules.Module interface to serve as a factory of Compare instances for each VU.
The compare factory can have memory implications
The significance depends on the size of your module.
Here's what that would look like:
Notice that we implemented the Module API and now modules.Register the root module rather than our Compare object!
At this time, we've provided access to the modules.VU from the Compare type; however, we aren't taking advantage of the methods provided. Here is a contrived example of how we can utilize the runtime state:
Create a test script to utilize the new getInternalState() function as in the following:
Executing the script as ./k6 run test-state.js --vus 2 --iterations 5 will produce output similar to the following:
For a more extensive usage example of this API, look at the k6/execution module.
- The code in the default function (or another function specified by exec) will be executed many times during a test run and possibly in parallel by thousands of VUs. Any operation of your extension should therefore be performant and thread-safe.
- Any heavy initialization should be done in the init context, if possible, and not as part of the default function execution.
- Use the registry's NewMetric method to create custom metrics; to emit them, use metrics.PushIfNotDone().
Questions? Feel free to join the discussion on extensions in the k6 Community Forum.
Next, create an Output extension to publish test metrics to a destination not already supported by k6.