Run all tests scripts in parallel

We use K6 to do our functional, performance and load testing. Currently we have 50-60 functional tests which are running daily, and we would love to run them in parallel if there is an efficient way.

There are some discussions around this topic I found here using docker which we are thinking about implementing, if there is no other solution. We will be using k6 to run our functional tests so the total number of cases will keep on increasing. Any ideas or suggestions for us to efficiently run all the tests quickly ?

With 50+ functional tests, having a separate scenario per test might not be the best option… I assume your functional tests just require a single VU each? If so, then you can encode your tests in an array, and then use the __VU (and potentially __ITER) execution context variables to partition the tests between your VUs and execute them in parallel. Something like this:

import { sleep } from 'k6';

const VUs = 6; // adjust this if you want more or less concurrency

var functionalTests = [];

function getTest(i) {
    return function () {
        return 'Test #' + i;
    }
}

for (var i = 0; i < 57; i++) {
    functionalTests.push(getTest(i));
}

const testsPerVU = Math.ceil(functionalTests.length / VUs);

export let options = {
    scenarios: {
        contacts: {
            executor: 'per-vu-iterations',
            vus: VUs,
            iterations: testsPerVU,
            maxDuration: '1h',
        },
    },
};


export default function () {
    var myTestNumber = (__VU - 1) * testsPerVU + __ITER
    if (myTestNumber >= functionalTests.length) {
        return; // last VU might have more iterations than needed
    }

    console.log(`VU ${__VU}, iter ${__ITER}, executed ${functionalTests[myTestNumber]()}`);
    sleep(1);
}

When we implement https://github.com/loadimpact/k6/issues/1320 and have a shared iterator, we’d be able to do something like this even more cleanly, but this should work until then, with just a few empty iterations that don’t run tests.

1 Like

Thank you @ned. I do want to clarify one thing when I said 50-60 functional tests that also means 50-60 separate test files for us. Currently they all run serially using a common default function. Is your answer still going to work in that case ?

You can keep them in separate tests files, so you can run them individually. But you can also have a single file that imports all of these separate files and executes their exported default functions concurrently, like I showed above. k6 has a require() function (that is very different than the one in NodeJS, see details in here, though you can use it with --compatibility-mode=extended as well), so you can have something like:

var functionalTests = [
    require("./functiona-test-001.js").default,
    require("./functiona-test-002.js").default,
    // ...
];

or do it programatically, and use the example I showed above to run all of the tests concurrently.

1 Like

Thank you @ned. All my test files also contains multiple groups so I am getting this error

ERRO[0015] GoError: Using group() in the init context is not supported at github.com/loadimpact/k6/js/common.Bind.func1 (native)

You shouldn’t run their default functions in the init context, only reference them. See:

require("./whatever.js").default

instead of

require("./whatever.js").default()

Thank you @ned. This is a game changer for us. Thank you once again :slight_smile: