The hierarchical group information at the end of a test should be ordered in some way.
As this user in the community forum complained, and I've confirmed, the information for the hierarchical groups k6 emits at the end of the test run doesn't seem sorted in any way.
Testing old k6 version, this seems to have worked in k6 up to version v0.21.1, which ordered groups ~alphabetically~, and way broken by k6 v0.22.0...
Run the following script multiple times:
import { group, check } from "k6";
function test(i) { group(`test ${i}`, () => { subTest(i); }); }
function subTest(i) { group(`subtest ${i}`, () => { check(1, { "check": () => true == true }) }); }
export default function () { for (let i = 1; i <= 10; i++) { test(i); } }
I have also noticed that custom metrics have a seemingly random order in the CLI output.
I believe the custom metrics used to be displayed in the order they have been created/executed.
@sniku, I'm not sure we ever showed metrics in the order they occurred in the script, but we probably should... I see that it seems like we're sorting them alphabetically now, which is not ideal, but as far as I can see has been the case since at least k6 v0.19.0 and maybe earlier. For example, running the following script with k6 v0.26.0:
import { Counter } from "k6/metrics";
import { group, check, sleep } from "k6";
let counter1 = Counter("bbb");
let counter2 = Counter("ccc");
let counter3 = Counter("aaa");
export let options = {
vus: 10,
duration: "2s",
}
const checks = {
"1) is below 0.5": (v) => v < 0.5,
"2) is equal to 0.5": (v) => v == 0.5,
"3) is above 0.5": (v) => v > 0.5,
};
export default function () {
group("group 1", function () {
counter1.add(__ITER);
check(Math.random(), checks);
});
group("group 2", function () {
counter2.add(__ITER);
check(Math.random(), checks);
});
group("group 3", function () {
counter3.add(__ITER);
check(Math.random(), checks);
});
sleep(0.5);
}
may result in something like this:
โ group 2
โ 1) is below 0.5
โณ 55% โ โ 22 / โ 18
โ 2) is equal to 0.5
โณ 0% โ โ 0 / โ 40
โ 3) is above 0.5
โณ 45% โ โ 18 / โ 22
โ group 3
โ 2) is equal to 0.5
โณ 0% โ โ 0 / โ 40
โ 3) is above 0.5
โณ 52% โ โ 21 / โ 19
โ 1) is below 0.5
โณ 47% โ โ 19 / โ 21
โ group 1
โ 1) is below 0.5
โณ 40% โ โ 16 / โ 24
โ 2) is equal to 0.5
โณ 0% โ โ 0 / โ 40
โ 3) is above 0.5
โณ 60% โ โ 24 / โ 16
aaa..................: 60 29.99754/s
bbb..................: 60 29.99754/s
ccc..................: 60 29.99754/s
checks...............: 33.33% โ 120 โ 240
data_received........: 0 B 0 B/s
data_sent............: 0 B 0 B/s
group_duration.......: avg=52.93ยตs min=20.2ยตs med=36.83ยตs max=375.24ยตs p(90)=109.49ยตs p(95)=131.02ยตs
iteration_duration...: avg=500.59ms min=500.11ms med=500.47ms max=501.81ms p(90)=501.26ms p(95)=501.36ms
iterations...........: 30 14.99877/s
vus..................: 10 min=10 max=10
vus_max..............: 10 min=10 max=10
:man_facepalming: ...
I guess the most immediate and biggest reason for the disorderly listing of groups and checks in the summary is that iteration order of maps is not guaranteed in any way in Go, and we save the groups and the checks as string maps: https://github.com/loadimpact/k6/blob/74f11a6b6703282c282c2baf42ccaa8fa3a23d31/lib/models.go#L110-L112
Would it be possible to have the groups ordered in the order they are executed in the script, with the first at the top? I'm not sure alphabetical would be intuitive...
@safebear, probably yes. At the moment, to me, displaying the groups in chronological order seems to be the most logical and to offer the best UX. That said, if we sort the group names alphabetically, you can always turn that in a chronological order by just naming your first group 01 First group name, the second 02 whatever and so on...
Ideally, though, I'd like for us to have both options (and maybe more) through the planned templating functionality for the end-of-test summary (https://github.com/loadimpact/k6/issues/1319#issuecomment-579462738). It's just a matter of carefully and efficiently storing the groups and checks information in a way that doesn't loose the chronological order, and then providing some simple helper functions in the template that allows for different sort orders... :crossed_fingers: :sweat_smile:
I would like to throw in some support for chronological order. This is what I was expecting to see, kind of like the result tree in JMeter. I was surprised when they weren't in order, and had to add some console.log statements to verify things were not occurring in an unexpected order. I think chronological order (order of execution) would make the best default.
@na-- Can we consider using an ordered map for storing the groups and checks? wk8/go-ordered-map seems sensible to import. This would allow us to print the groups in the order they were defined in, as well as alphabetical if needed.
I think we can make our own version:
container/list supposedly for faster Delete operations ... which might be true, but we don't need that or half of it's other methods As I mentioned in https://github.com/loadimpact/k6/issues/1316#issuecomment-583425182, we should first have template support for the end-of-test summary and then tackle this. That way we can order the groups however we want (by time, by name, etc.), as well as make any number of other adjustments that someone might want. It would still likely require that we change the data structure from a map to some sort of an ordered data structure (though a slice seems better than an ordered map), but
Hurray for this feature :tada:
