There are several ways to get the behavior you want.
One way is to tell it that you won't run tests, per that command-line option
use warnings;
use strict;
use feature 'say';
use Test::More;
my $run_tests = shift;
if ($run_tests) {
Test::More->builder->no_plan;
}
else {
Test::More->builder->output('/dev/null');
Test::More->builder->skip_all('Not testing');
}
#...
if ($run_tests) {
note("one test");
test_x();
}
sub test_x { ok( 1, "1 is ok" ) }
The message for skipping won't be seen as the output is redirected to /dev/null, as desired, but is provided as an example (and there must be something there).
I use methods from the backend Test::Builder module (Test::More->builder returns its object) to set a plan/skip, even as there is a plan function in Test::More itself.
This is for consistency, since for output we do need Test::Builder, and as further examples of Test::Builder, where one can find many more tools in cases where that may be needed. The Test::More is built upon this moduel and I suggest a good perusal of it.
An alternative to declaring no_plan is to use done_testing at the very end of the program, conditioned on $run_tests (but not in END block, see docs).
Another way is to place all tests in SKIP blocks, used for conditional testing
use warnings;
use strict;
use feature 'say';
use Test::More qw(no_plan);
my $run_tests = shift;
SKIP: {
skip_test() if not $run_test;
note("one test");
test_x();
}
sub test_x { ok( 1, "1 is ok" ) }
sub skip_test {
Test::More->builder->output('/dev/null');
skip "Not testing";
}
where output is again sent to /dev/null, as desired in the question.
We can also use Test::Builder methods directly, either skip
use warnings;
use strict;
use feature 'say';
use Test::More qw(no_plan);
my $run_tests = shift;
if ($run_tests) {
note("one test");
test_x();
}
else { skip_test() }
sub test_x { ok( 1, "1 is ok" ) }
sub skip_test {
Test::More->builder->output('/dev/null');
Test::More->builder->skip;
}
or perhaps reset, for different circumstances or context
use warnings;
use strict;
use feature 'say';
use Test::More qw(no_plan);
my $run_tests = shift;
if ($run_tests) {
note("one test");
test_x();
}
else { Test::More->builder->reset }
# At the very end of the program (not in END block though)
done_testing if $run_tests;
sub test_x { ok( 1, "1 is ok" ) }
where we're now best off using done_testing in the end.
All of these print nothing and have exit code 0 when the program is invoked without any arguments, or run tests and print messages when invoked with a "true" argument.† All of them were tested with more (than 1) testing blocks, omitted here for brevity.
The need to deal with some details above comes up because the testing framework is intended to be used in dedicated programs, not for testing pieces in a running program. And while it is possible to use it this way as well some things get more complicated.
See Test2, or perhaps its suite Test2::Suite, for a newer alternative.
† That is, "true" for Perl when passed to the program, so not 0 or empty string "''"