Perl test coverage when you don’t have a Makefile
Tags: perl, testing, qa, codequality
Published: 2021-04-26 21:34:20

---
title: Perl test coverage when you don’t have a Makefile
published: true
date: 2021-04-26 21:22:49 UTC
tags: Perl,testing,QA,quality
canonical_url: https://phoenixtrap.com/2021/04/26/perl-test-coverage-when-you-dont-have-a-makefile/?utm_source=rss&utm_medium=rss&utm_campaign=perl-test-coverage-when-you-dont-have-a-makefile
series: Live-coding a web app in Perl and Mojolicious
---

[Yesterday’s pair programming session](https://perlmaven.com/course-management-app-in-mojolicious-4) had [Gábor Szabó](https://szabgab.com/) and I thrashing around for a bit trying to figure out how to get [test coverage](https://en.wikipedia.org/wiki/Code_coverage) statistics for the application. The `Devel::Cover` documentation lists [how to run the module several ways](https://metacpan.org/pod/Devel::Cover#SYNOPSIS), but it doesn’t exactly describe how to run [`prove`](https://perldoc.pl/prove) by itself rather than running a `Makefile`’s tests. I worked out how to do it today, and with [the Baughs’](https://troglodyne.net/) [help on Twitter](https://twitter.com/troglodyne/status/1386747085039546370) I worked out a few more methods.

<mark>All examples below use the <code>bash</code> or `zsh` command shells and were tested on macOS Catalina 10.15.7 running `zsh` 5.7.1 and Perl 5.32.1. If you’re using something very different (e.g., Microsoft Windows’ `CMD` or PowerShell), you may have to set environment variables differently.</mark>

## Ad-hoc test coverage

If all you want to do is run one shell command, here it is:

```
$ prove -vlre 'perl -MDevel::Cover -Ilib' t
```

This takes advantage of `prove`’s [`--exec`](https://perldoc.pl/prove#-exec) option (abbreviated as `-e`) to run a different executable for tests. It recursively (`-r`) runs all your tests verbosely (`-v`) from the `t` directory while loading your application’s libraries (`-l`), while the `perl` executable uses ([`-M`](https://perldoc.pl/perlrun#-M%5B-%5Dmodule)) `Devel::Cover` and the `lib` subdirectory. I use a similar technique when [debugging tests](https://phoenixtrap.com/2021/03/09/perl-debugger-superpower/#testing).

```
$ HARNESS_PERL_SWITCHES=-MDevel::Cover prove -vlr t
```

This does almost the same thing as above without running a different executable. It sets `Test::Harness`’ [`HARNESS_PERL_SWITCHES`](https://perldoc.pl/Test::Harness#ENVIRONMENT-VARIABLES-THAT-AFFECT-TEST::HARNESS) environment variable for the duration of the `prove` command. You won’t get the text output of your test coverage at the end, though, and will still have to run `Devel::Cover`’s [`cover`](https://metacpan.org/pod/distribution/Devel-Cover/bin/cover) command to both see the coverage and generate web pages.

## In a dedicated test session, window, or tab

If you have a terminal session, window, or tab dedicated solely to running your tests, set one of the environment variables above for that session:

```
$ export HARNESS_PERL_SWITCHES=-MDevel::Cover
```

Now all of your test scripts will pick up that option. You can add more options by enclosing the environment variable’s value in `'`quotes`'`. For example, you might also want to load [`Devel::NYTProf`](https://metacpan.org/pod/Devel::NYTProf) for code profiling:

```
$ export HARNESS_PERL_SWITCHES='-MDevel::Cover -MDevel::NYTProf'
```

## Why not [`PERL5OPT`](https://perldoc.pl/perlrun#PERL5OPT)?

Setting the `PERL5OPT` environment variable also sets options for the `perl` running `prove`, which means that your test coverage, profiling, etc. will pick up `prove`’s execution as well as your test scripts.

## What about [`yath`](https://metacpan.org/pod/distribution/Test2-Harness/scripts/yath)?

I don’t know for sure; I don’t use the [`Test2`](https://metacpan.org/pod/Test2) suite. But it looks like it has a [`--cover`](https://metacpan.org/pod/App::Yath::Options::Runner#-cover) option for loading and passing option to `Devel::Cover`.