testing php applications

Pest Datasets

Pest datasets run one test shape against several examples. They are the Pest equivalent of table-driven checks and work well for validation rules, calculations, and boundary conditions.

Name Boundary Cases

A dataset should expose the meaning of each row. Thresholds, empty values, malformed values, and representative normal values deserve names that make a failure understandable.

Share Only Stable Data

Datasets can be local to a file or shared more broadly. Keep shared datasets purposeful; a giant global bag of fixtures makes ownership unclear.

PHP example
<?php

declare(strict_types=1);

function discount(int $totalPence): int
{
    return $totalPence >= 10_000 ? intdiv($totalPence, 10) : 0;
}

test('calculates discount', function (int $totalPence, int $expected): void {
    expect(discount($totalPence))->toBe($expected);
})->with([
    'below threshold' => [9_999, 0],
    'at threshold' => [10_000, 1_000],
    'above threshold' => [15_000, 1_500],
]);

Common Mistakes

  • Unnamed values that make failures cryptic.
  • Mixing unrelated behaviours.
  • Sharing datasets globally without a real reuse need.
  • Using large datasets instead of targeted examples.

What To Practise

  • Build named Pest datasets.
  • Cover rule boundaries.
  • Keep shared test data understandable.

Practice

Practice: Create A Password-Length Dataset

Define named examples for a registration rule requiring at least 12 characters.

Requirements

  • Include empty, 11-character, 12-character, and longer examples.
  • Name each case.
  • Store input and expected acceptance together.
  • Keep the dataset focused on length only.
Show solution

The dataset identifies the exact boundary.

PHP example
<?php

declare(strict_types=1);

$passwords = [
    'empty' => ['', false],
    'eleven characters' => ['abcdefghijk', false],
    'twelve characters' => ['abcdefghijkl', true],
    'longer password' => ['correct horse battery staple', true],
];

foreach ($passwords as $name => [$password, $accepted]) {
    echo $name . ': ' . ($accepted ? 'accepted' : 'rejected') . PHP_EOL;
}

// Prints:
// empty: rejected
// eleven characters: rejected
// twelve characters: accepted
// longer password: accepted

A Pest test can receive each dataset row and apply one expectation to the validation rule.