subtest_for / foreach function to combine subtest with for loop #294

wants to merge 1 commit into


None yet
2 participants

SineSwiper commented May 3, 2012

This is an untested proof of concept. Wanted to RFC before I finished it up.


schwern commented May 8, 2012

If I understand correctly, this is syntax sugar that puts a for loop around subtest. Could you explain the value in that? Will it make something complicated about looping with subtests easier, more obvious or less prone to bugs? Why should it be applied to subtest in particular and not any other tests?


SineSwiper commented May 8, 2012

Yes and yes. Here's my readability nightmare:

As you can see, I've had to buck traditional indentation to make sure the foreach/subtest pairs don't get tab'd into an infinite right-side black hole. Sure, I could just forgo the subtest subs, but subtests give the test plan a lot more structure. It allows the test output to match the foreach loops.

I think I'm trying to promote an ideal that is unusual, since subtests just aren't used all that often. But, hopefully more people will use it with the right sugar.


schwern commented May 10, 2012

If I saw that in regular code, loops nested five deep, I'd say what you have is too much nesting caused by too long and dense a code block. Having to indent code too far to the right is a good red flag that the code is too complicated. Breaking some of the inner elements into subroutines is the usual solution. That whole .t file is IMO too large and doing too many things.

And there's no reason it isn't the solution here. subtest_for would only address the symptom, code going too far to the right, but you'd still have deeply nested and difficult to understand code.

Or you can use this style:

foreach my $license (sort @licenses) { subtest "license = $license" => sub {

Which is not too far out from something like this:

$obj->method(sub {

Or the style you have is ok:

for my $thing (@things) {
subtest $name => sub {
}; }

But I would avoid this as it gets a bit confusing.

foreach my $bt (1..15) {
subtest $name => sub {
}; }

Or, if all you're using the subtest for is planning, use done_testing and get rid of the plan. If all you're using it for is the naming and lexical isolation, use a block + a note.

note "something something"; {

(all of which would make a great FAQ)


schwern commented Apr 23, 2013

I'm going to close this up as the use case for subtest_for hasn't been demonstrated. Feel free to reopen.

schwern closed this Apr 23, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment