A data provider with string keys reads better on failure

A provider returning a plain list produces failures reported as “with data set #3”, and you count rows to find out which one.

/**
 * @dataProvider vatRates
 */
public function testVatIsApplied(string $country, int $net, int $gross): void
{
    $this->assertSame($gross, (new Vat())->gross($net, $country));
}

public function vatRates(): array
{
    return [
        'uk standard'   => ['GB', 1000, 1200],
        'uk zero rated' => ['GB-Z', 1000, 1000],
    ];
}

The provider runs before setUp, which catches people expecting to use a fixture in it — anything needing the container has to be built inside the test. A provider returning a generator is worth it for large sets, since the whole array is otherwise held in memory for the run. --filter matches on the key, which is the second reason to name them.