How to run the tests of a typical Perl module
If you'd like to contribute code to a Perl based project - typically a CPAN module - the first thing you need to make sure is that all the tests of the current version work well on your computer.
If you don't do this and after you make some changes you find out that something is not working you won't know if your changes broke that part of the project, or if it was already broken.
Where are the unit tests of the Perl module?
Almost all the Perl modules on CPAN have a t/ directory and in that directory there are files with .t extension. These files are the tests of the typical Perl project.
In some cases you will find more tests in the subdirectories of t/.
In some cases there is an additional directory called xt/ with additional test that should be run by the developers and contributors only.
In other cases, especially in older modules, you'll find a file called test.pl in the root directory of the distribution.
The normal workflow of the Perl module development
There are 4 major packaging systems for Perl. The ones using Module::Build will have a file called Build.PL. In this case the workflow to run the tests is
perl Build.PL perl Build perl Build test
ExtUtils::MakeMaker and Module::Install both use a file called Makefile.PL
In this case the flow is:
perl Makefile.PL make make test
(On MS Windows, it is probably nmake or dmake instead of make.)
Dist::Zilla can be recognized by the dist.ini file in the root directory. It needs less ceremony, you only need to type
dzil test
well, of course after you've installed Dist::Zilla and all the other dependencies.
More than one packaging system
Normally only one of the 3 files: Build.PL, Makefile.PL, or dist.ini should be in the source code repository of every CPAN distribution BUT:
When releasing a distribution Dist::Zilla will create a Makefile.PL file. Some developers add this file to their version control system to make it easier to contribute to their code, even though they probably should not as it is a generated file.
On one hand the argument is that you should never include any file in your source repository that can be generated from the other files of your repository, on the other hand having the already generated Makefile.PL will make it a lot easier for someone to contribute without installing the whole Dist::Zilla toolchain. While the latter approach is more pragmatic and easier for the drive-by contributors, there is a risk that the two files diverge. Either by someone mistakenly editing the Makefile.PL or by not updating the Makefile.PL after the dzil.ini file was updated.
Build.PL can generate a Makefile.PL during the release process. Because for a long time Build.PL could not handle itself alone, many CPAN developers have opted to include this Makefile.PL in the distribution. Unfortunately some of them have also added these to their version control system, even though they probably should not.
So if you see both Build.PL and Makefile.PL then it is probably Build.PL that is the source. The best would be to talk to the author and to either remove Makefile.PL from the version control, or to switch the whole distribution to use either Dist::Zilla or one of the Makefile.PL based tools and remove Build.PL from the repository. Short of doing that, you can look into the Makefile.PL. If it has a comment like this:
# Note: this file was auto-generated by Module::Build::Compat version ...
then you can be quite sure it was indeed generated from the Build.PL file.
Install dependencies
Normally the Build.PL, the Makefile.PL, or the dist.ini file will have a list of all the modules that are required for the module under investigation, to run. Sometime they also have separate section for build-time and/or test-time dependencies. For example many modules will require all kinds of Test::* modules in order to be tested, but they won't need those modules for actually running the code.
Some modules have optional run-time dependencies and some have optional test-time dependencies. The former are usually described in the documentation. An example for that might be a module such as Text::CSV that would work by itself, but if you also have Text::CSV_XS installed then it will use that and be a lot faster.
Other example might be a module that can work with multiple database backend. It might have none of the database engines required by default, but you'd only be able to use it with any database if the driver for that specific database is installed. Separately. DBI the Database independent interface for Perl works that way.
As of optional test-time dependencies. The most common such modules are the ones that test if the code adheres to the Perl::Critic rules specified by the authors.
Running tests with prove
Using the prove command it is easy to run tests both in the t/ and in the xt/ directories:
$ perl Makefile.PL $ make $ prove -b t/ xt/
No skipped test
When you run the test, especially when you also include the xt/ directory you might see that some of the test files, or some tests in specific files are being skipped.
You'll need to check why are they skipped. Some might be always skipped because the tests are broken and the author of the module has decided to temporarily disable the tests. Most of the skipped tests however are skipped because of a missing optional dependency or because they are not relevant to your environment. (e.g. There might be MS Windows-specific tests that will never run on your Linux.) If they are skipped due to a missing dependency, or a lack of some configuration parameter, then install those dependencies and set those configurations so as many of the tests as possible will run on your.
After all they are there to protect you from introducing a bug while making your improvements.
TODO
Once you managed to run all the test and you saw that all of them are passing in your environment you can start making your changes.
Published on 2018-04-17