Last active
November 19, 2019 01:51
-
-
Save jkeroes/797d1a6e11f2397fb6e86d51da5d9f57 to your computer and use it in GitHub Desktop.
Perl testing.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Testing | |
## SYNOPSIS | |
use Ndn::Test::Bundle -target => 'Ndn::Foo'; # Sets $CLASS to 'Ndn::Foo' | |
database dreamhost { | |
table foo { | |
row { col1 => 1, col2 => 2 }; | |
row { col1 => 3, col2 => 4 }; | |
} | |
table bar { | |
row { this => 'that' }; | |
} | |
} | |
describe things { | |
tests a { | |
ok ... | |
}; | |
tests b { | |
ok ... | |
}; | |
}; | |
done_testing; | |
## Fixtures | |
Running a unit test will automatically provision a sandboxed database and | |
create all the tables defined in Ndn::*. These tables will be empty. There | |
are a few different ways to insert data: | |
### database/table/row | |
any columns left unmentioned will be filled with mysql's notion of default values. | |
database people { | |
table person { | |
row { username => 'jdoe', first => 'John', last => 'Doe', status => 'dh2' }; | |
row { ... }; | |
} | |
} | |
### load_fixtures | |
load_fixtures people => ( | |
person => [ | |
{ username => 'jdoe', first => 'John', last => 'Doe', status => 'dh2' }, | |
{ ... }, | |
] | |
); | |
### using Ndn | |
my $Person = Ndn::People::Person->new( | |
{ username => 'jdoe', first => 'John', last => 'Doe', status => 'dh2' }, | |
); | |
$Person->Save; | |
## Mocking time | |
use Test::MockTime qw(set_fixed_time); | |
$ENV{TZ} = 'Z'; | |
set_fixed_time('2000-01-01T00:00:00Z'); | |
## Coverage | |
Figuring out if you've tested all the things. | |
ndnperl current | |
cd ndn | |
cover -delete | |
# perl -Iperl -d:Cover perl/t/unit/path/to/file.t | |
# perl -Iperl -MDevel::Cover perl/t/unit/path/to/file.t | |
HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr **/Bronto.t **/BrontoEmail/basic.t | |
cover | |
## Profiler | |
HARNESS_PERL_SWITCHES=-MDevel::NYTProf prove -lr **/Bronto.t **/BrontoEmail/basic.t | |
## Test2 | |
### Env vars | |
T2_WORKFLOW=$test_name yath ... # test single test/describe block. | |
T2_WORKFLOW_ASYNC=9 yath ... # run in 9 forks. | |
prove, perl, or yath all work the same way. | |
### Mock | |
my $mock = mock 'Some::Class' => ( | |
add => [ | |
new_method_name => sub { ... }, | |
], | |
override => [ | |
replacement_method_name => sub { ... }, | |
], | |
); | |
### Output | |
note() - write to STDOUT; hidden under prove; shown with prove -v | |
diag() - write to STDERR; visible under prove and prove -v | |
### Exceptions | |
##### perldoc Test2::Tools::Exceptions | |
ok(lives { ... }, "did not die") or note($@); | |
like( | |
dies { die 'xxx' }, | |
qr/xxx/, | |
"Got exception" | |
); | |
##### perldoc Test2::Tools::Warnings | |
ok ( warns { warn 'xxx' }); | |
like( | |
warning { warn 'xxx' }, # works with carp, too. | |
qr/xxx/, | |
"Got warning" | |
); | |
like( | |
warnings { warn 'xxx' }, | |
["Warning A", "Warning B"] | |
"Got warning" | |
); | |
### Comparisons | |
#### perldoc Test2::Tools::Compare | |
Test only some of the things in a hash: | |
is( | |
$hashref, | |
hash { | |
field this => 'value'; | |
field that => hash { | |
field ...; | |
}, | |
end; | |
}, | |
"it matches!" | |
); | |
is( | |
$arrayref, | |
array { | |
item 'foo'; | |
item 'bar'; | |
end(); | |
} | |
) | |
bag { } is like array { } but unordered. | |
subset { } is like array { } but ordered. | |
### case | |
describe is_corp { | |
my ($name, $company, $is_corp); | |
case both { $name = 1; $company = 1; $is_corp = 1 } | |
case just_name { $name = 1; $company = 0; $is_corp = 0 } | |
case just_company { $name = 0; $company = 1; $is_corp = 1 } | |
case neither { $name = 0; $company = 0; $is_corp = 0 } | |
tests old { | |
ok ($is_corp, ($name ? 0 : $company ? 1 : 0)); | |
} | |
tests new { | |
ok ($is_corp, ($company ? 1 : 0)); | |
} | |
} | |
### skip and todo | |
These can be added to any test block, ie describe, tests, subtest, etc. | |
Skips this block when $when is true: | |
describe block_name { skip => $when } { | |
tests unit_name { pass() }; | |
}; | |
A TODO will run the test block but consider any failures to be okay. | |
The $reason should explain why it's okay for these tests to be in a | |
failing state. | |
describe block_name { todo => $reason } { | |
tests unit_name { fail() }; | |
}; | |
### skip unless... | |
Requires that a certain environment variable be set: | |
use Test2::Require::EnvVar 'LIVE_API_TESTING'; | |
Requires that a certain module be present: | |
use Test2::Require::Module 'Some::Module'; | |
Requires that v5.555 or better of Other::Module be installed. | |
use Test2::Require::Module 'Other::Module' => '5.555'; | |
## Old perl testing | |
For testing code on controllers. The Jenkins machines, serf5353 and snafu, have | |
the controllers' set of modules as well as some extra test modules. They're just | |
special that way. | |
serf5353 runs the Jenkins ndn-syntax-check-env job for envperl. | |
snafu runs the Jenkins ndn-syntax-check job for oldperl. | |
These modules are known to exist of serf5353 and snafu. | |
use Test::More; # subtest "..." => sub { ... }; is(); ok(); | |
use Test::Fatal; # like(exception { dies() }, qr/.../, "..."); # available on serf5353 only. | |
use Test::Warn; # warning_like(), warning_ok() | |
use Test::Deep; # cmp_deeply(), bag(), subset(), superhashof(), | |
use Test::Exception; # works on snafu but crappier than Test::Fatal. | |
use Mock::Quick; | |
qtakeover $class => ( | |
$subname => sub { ... }, | |
); | |
use Capture::Tiny; | |
my ($stdout, $stderr, $exit) = capture { ... }; | |
my Capture::Tiny qw/capture_stdout capture_stderr/; | |
my $stdout = capture_stdout { ... }; | |
my $stderr = capture_stderr { ... }; | |
cmp_deeply( | |
$hash, | |
superhashof( | |
this => ignore(), | |
that => ignore(), | |
other => 'foo', | |
), | |
"explained" | |
); | |
cmp_deeply( | |
$ary, | |
superbagof( # order does not matter. | |
'foo', | |
'bar', | |
) | |
); | |
SKIP: { | |
skip $why, $how_many unless $boolean; | |
ok ... | |
... | |
}; | |
TODO: { ... } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment