Testing Perl: To plan or not to plan
Tags: perl, testing, qa, codequality
Published: 2021-05-11 14:09:27

---
title: Testing Perl: To plan or not to plan
published: true
date: 2021-05-11 14:00:00 UTC
tags: Perl,testing,QA,quality
canonical_url: https://phoenixtrap.com/2021/05/11/testing-perl-to-plan-or-not-to-plan/?utm_source=rss&utm_medium=rss&utm_campaign=testing-perl-to-plan-or-not-to-plan
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnw5g5zm32m78euj0wy6.jpeg
---

Let’s assume for the moment that you’re writing a Perl module or application. You’d like to maintain some level of software quality (or [kwalitee](https://qa.perl.org/phalanx/kwalitee.html)), so you’re writing a suite of test scripts. Whether you’re writing them first (good for you for practicing [test-driven development](https://en.wikipedia.org/wiki/Test-driven_development)!) or the application code is already there, you’ll probably be reaching for [Test::Simple](https://metacpan.org/pod/Test::Simple), [Test::More](https://metacpan.org/pod/Test::More), or one of the [Test2::Suite](https://metacpan.org/pod/Test2::Suite) bundles. With the latter two **you’re immediately confronted with a choice:** do you count up the number of tests into a plan, or do you forsake that in favor of leaving a `done_testing()` call at the end of your test script(s)?

There are good arguments for both approaches. When you first start, you probably have no idea how many tests your scripts will contain. After all, a test script can be a useful tool for designing a module’s interface by writing example code that will use it. Your exploratory code would be written as if the module or application was already done, testing it in the way you’d like it to work. **Not declaring a plan makes perfect sense in this case;** just put `done_testing()` at the end and get back to defining your tests.

You don’t have that option when using Test::Simple, of course—it’s so basic it only has one function (`ok()`), and you have to pre-declare how many tests you plan to run when `use`ing the module, like so:

```perl
use Test::Simple tests => 23;
```

Test::More also [supports this form of plan](https://metacpan.org/pod/Test::More#I-love-it-when-a-plan-comes-together), or you can opt to use its `plan` function to state the number of tests in your script or `subtest`. With Test2 you have to use `plan`. Either way, **the plan acts as a sort of meta-test,** making sure that you executed exactly what you intended: no more, no less. While there are situations where it’s not possible to predict how many times a given set of tests should run, I would highly suggest that in all other cases you should “clean up” your tests and declare a plan. Later on, if you add or remove tests you’ll immediately be aware that something has changed and it’s time to tally up a new plan.

**What about other Perl testing frameworks?** They can use plans, too. Here are two examples:

- [Test::Class](https://metacpan.org/pod/Test::Class) declares its plans as part of the method’s [Test attribute](https://metacpan.org/pod/Test::Class#Test), and uses helper methods called `fail_if_returned_early` and `fail_if_returned_late` to indicate that an unfollowed plan should trigger failure.
- [Test::Class::Moose](https://metacpan.org/pod/Test::Class::Moose) says [“no plans needed”](https://metacpan.org/pod/Test::Class::Moose#Plans) but also supports declaring plans either in an attribute or via a method call.

Thoughts? Does declaring a test plan make writing tests too inflexible? Does not having a plan encourage bad behavior? Tell me what you think in the comments below.