Skip to content

Commit

Permalink
Discourage use_ok() and emphasize require_ok().
Browse files Browse the repository at this point in the history
Rather than write a whole bunch of docs about why use_ok() is evil and
clutter things up for new developers, require_ok() has been emphesized.

* The main docs have been moved to require_ok()
* require_ok() comes first
* use_ok() is gone from the SYNOPSIS
* Various misuses of use_ok() are mentioned
* The "Module Tests" blurb doesn't give bad advice

For #288
  • Loading branch information
schwern committed Apr 26, 2012
1 parent 7e32d0e commit ab98acb
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 58 deletions.
4 changes: 4 additions & 0 deletions Changes
Expand Up @@ -8,6 +8,10 @@
* use_ok() was calling class->import without quoting which could
cause problems if "class" is also a function.

Doc Fixes
* use_ok() has been discouraged and de-emphasized as a general
replacement for `use` in tests. [github #288]

Incompatible Changes With Previous Alphas
* use_ok() will no longer apply lexical pragams. The incompatibilities
and extra complexity is not worth the marginal use.
Expand Down
145 changes: 87 additions & 58 deletions lib/Test/More.pm
Expand Up @@ -49,7 +49,6 @@ Test::More - yet another framework for writing test scripts
# or
use Test::More; # see done_testing()
BEGIN { use_ok( 'Some::Module' ); }
require_ok( 'Some::Module' );
# Various ways to say "ok"
Expand Down Expand Up @@ -782,21 +781,101 @@ sub fail (;$) {
=head2 Module tests
You usually want to test if the module you're testing loads ok, rather
than just vomiting if its load fails. For such purposes we have
C<use_ok> and C<require_ok>.
Sometimes you want to test if a module, or a list of modules, can
successfully load. For example, you'll often want a first test which
simply loads all the modules in the distribution to make sure they
work before going on to do more complicated testing.
For such purposes we have C<use_ok> and C<require_ok>.
=over 4
=item B<require_ok>
require_ok($module);
require_ok($file);
Tries to C<require> the given $module or $file. If it loads
successfully, the test will pass. Otherwise it fails and displays the
load error.
C<require_ok> will guess whether the input is a module name or a
filename.
No exception will be thrown if the load fails.
# require Some::Module
require_ok "Some::Module";
# require "Some/File.pl";
require_ok "Some/File.pl";
# stop testing if any of your modules will not load
for my $module (@module) {
require_ok $module or BAIL_OUT "Can't load $module";
}
=cut

sub require_ok ($) {
my($module) = shift;
my $tb = Test::More->builder;

my $pack = caller;

# Try to determine if we've been given a module name or file.
# Module names must be barewords, files not.
$module = qq['$module'] unless _is_module_name($module);

my $code = <<REQUIRE;
package $pack;
require $module;
1;
REQUIRE

my( $eval_result, $eval_error ) = _eval($code);
my $ok = $tb->ok( $eval_result, "require $module;" );

unless($ok) {
chomp $eval_error;
$tb->diag(<<DIAGNOSTIC);
Tried to require '$module'.
Error: $eval_error
DIAGNOSTIC

}

return $ok;
}

sub _is_module_name {
my $module = shift;

# Module names start with a letter.
# End with an alphanumeric.
# The rest is an alphanumeric or ::
$module =~ s/\b::\b//g;

return $module =~ /^[a-zA-Z]\w*$/ ? 1 : 0;
}


=item B<use_ok>
BEGIN { use_ok($module); }
BEGIN { use_ok($module, @imports); }
These simply use the given $module and test to make sure the load
happened ok. It's recommended that you run use_ok() inside a BEGIN
block so its functions are exported at compile-time and prototypes are
properly honored.
Like C<require_ok>, but it will C<use> the $module in question and
only loads modules, not files.
If you just want to test a module can be loaded, use C<require_ok>.
If you just want to load a module in a test, we recommend simply using
C<use> directly. It will cause the test to stop.
It's recommended that you run use_ok() inside a BEGIN block so its
functions are exported at compile-time and prototypes are properly
honored.
If @imports are given, they are passed through to the use. So this:
Expand Down Expand Up @@ -897,56 +976,6 @@ sub _eval {
return( $eval_result, $eval_error );
}

=item B<require_ok>
require_ok($module);
require_ok($file);
Like use_ok(), except it requires the $module or $file.
=cut

sub require_ok ($) {
my($module) = shift;
my $tb = Test::More->builder;

my $pack = caller;

# Try to determine if we've been given a module name or file.
# Module names must be barewords, files not.
$module = qq['$module'] unless _is_module_name($module);

my $code = <<REQUIRE;
package $pack;
require $module;
1;
REQUIRE

my( $eval_result, $eval_error ) = _eval($code);
my $ok = $tb->ok( $eval_result, "require $module;" );

unless($ok) {
chomp $eval_error;
$tb->diag(<<DIAGNOSTIC);
Tried to require '$module'.
Error: $eval_error
DIAGNOSTIC

}

return $ok;
}

sub _is_module_name {
my $module = shift;

# Module names start with a letter.
# End with an alphanumeric.
# The rest is an alphanumeric or ::
$module =~ s/\b::\b//g;

return $module =~ /^[a-zA-Z]\w*$/ ? 1 : 0;
}

=back
Expand Down

0 comments on commit ab98acb

Please sign in to comment.