perl-testing
Perl testing patterns using Test2::V0, Test::More, prove runner, mocking, coverage with Devel::Cover, and TDD methodology. Use when writing Perl tests with Test2::V0 or Test::More, or measuring coverage.
By affaan-m · 2,797 installs
npx skills add affaan-m/ecc --skill perl-testing
Source repository · Upstream listing
Perl Testing Patterns
Comprehensive testing strategies for Perl applications using Test2::V0, Test::More, prove, and TDD methodology.
When to Activate
Writing new Perl code (follow TDD: red, green, refactor)
Designing test suites for Perl modules or applications
Reviewing Perl test coverage
Setting up Perl testing infrastructure
Migrating tests from Test::More to Test2::V0
Debugging failing Perl tests
TDD Workflow
Always follow the RED GREEN REFACTOR cycle.
Test::More Fundamentals
The standard Perl testing module — widely used, ships with core.
Basic Assertions
SKIP and TODO
Test2::V0 Modern Framework
Test2::V0 is the modern replacement for Test::More — richer assertions, better diagnostics, and extensible.
Why Test2?
Superior deep comparison with hash/array builders
Better diagnostic output on failures
Subtests with cleaner scoping
Extensible via Test2::Tools:: plugins
Backward compatible with Test::More tests
Deep Comparison with Builders
Subtests
Exception Testing with Test2
Test Organization and prove
Directory Structure
prove Commands
.proverc Configuration
Fixtures and Setup/Teardown
Subtest Isolation
Shared Test Helpers
Place reusable helpers in t/lib/TestHelper.pm and load with use lib 't/lib' . Export factory functions like create test db() , create temp dir() , and fixture path() via Exporter .
Mocking
Test::MockModule
For lightweight mock objects, use Test::MockObject to create injectable test doubles with mock() and verify calls with called ok() .
Coverage with Devel::Cover
Running Coverage
Integration Testing
Use in memory SQLite for database tests, mock HTTP::Tiny for API tests.
Best Practices
DO
Follow TDD : Write tests before implementation (red green refactor)
Use Test2::V0 : Modern assertions, better diagnostics
Use subtests : Group related assertions, isolate state
Mock external dependencies : Network, database, file system
Use prove l : Always include lib/ in @INC
Name tests clearly : 'user login with invalid password fails'
Test edge cases : Empty strings, undef, zero, boundary values
Aim for 80%+ coverage : Focus on business logic paths
Keep tests fast : Mock I/O, use in memory databases
DON'T
Don't test implementation : Test behavior and output, not internals
Don't share state between subtests : Each subtest should be independent
Don't skip done testing : Ensures all planned tests ran
Don't over mock : Mock boundaries only, not the code under test
Don't use Test::More for new projects : Prefer Test2::V0
Don't ignore test failures : All tests must pass before merge
Don't test CPAN modules : Trust libraries to work correctly
Don't write brittle tests : Avoid over specific string matching
Quick Reference
Task Command / Pattern
Run all tests prove lr t/
Run one test verbose prove lv t/unit/user.t
Parallel test run prove lr j8 t/
Coverage report cover test && cover report html
Test equality is($got, $expected, 'label')
Deep comparison is($got, hash { field k = 'v'; etc() }, 'label')
Test exception like(dies { ... }, qr/msg/, 'label')
Test no exception ok(lives { ... }, 'label')
Mock a method Test::MockModule new('Pkg') mock(m = sub { ... })
Skip tests SKIP: { skip 'reason', $count unless $cond; ... }
TODO tests TODO: { local $TODO = 'reason'; ... }
Common Pitfalls
Forgetting done testing
Missing l Flag
Over Mocking
Mock the dependency , not the code under test. If your test only verifies that a mock returns what you told it to, it tests nothing.
Test Pollution
Use my variables inside subtests — never our — to prevent state leaking between tests.
Remember : Tests are your safety net. Keep them fast, focused, and independent. Use Test2::V0 for new projects, prove for running, and Devel::Cover for accountability.