rawr / phpunit-data-provider
PhpUnit 数据提供程序的轻量级构建器
Requires
- php: >=7.1.0
Requires (Dev)
- phpunit/phpunit: ^9.5.4 || ^8.0 || ^7.5
This package is auto-updated.
Last update: 2024-08-24 13:13:58 UTC
README
PhpUnit @dataProvider 的助手
为 PhpUnit 提供便捷的 require-dev
测试工具。它允许使用 zip()
、join()
、cross()
、pairs()
、slice()
、map()
等方法管理数据提供程序。
安装
PHP 7.1 及以上版本的安装
composer require --dev rawr/phpunit-data-provider
概述
DataProvider
可以用来构建、组合和编辑用于 PhpUnit 的数据提供程序,由 @sebastianbergmann 提供。
DataProvider::list()
DataProvider::list()
提供元素列表。每次测试调用时只有一个参数。
/** * @test * @dataProvider colors */ public function test(string $color): void { // your test here } public function colors(): DataProvider { return DataProvider::list('blue', 'yellow', 'red'); }
此外,DataProvider::list()
根据值对行进行命名。
DataProvider::join()
垂直连接数据提供程序。
💡 当两个数据提供程序在其他测试中使用时,并且新测试应该使用这两个数据提供程序时,这很有用。
/** * @test * @dataProvider colors */ public function test(string $color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::join($this->blueColors(), $this->yellowColors(), $this->redColors()); } public function blueColors(): DataProvider { return DataProvider::tuples( ['blue', 'sky'], ['deep blue', 'ocean'] ); } public function yellowColors(): iterable { yield 'sun' => ['yellow', 'sun']; } public function redColors(): array { return [ 'apple' => ['red', 'apple'] ]; }
注意
- 只有具有相同数量参数的行的数据提供程序才能连接。可以使用
DataProvider.drop()
来剪裁溢出的列,或者使用DataProvider::zip()
来拓宽具有较少行的数据提供程序。
DataProvider::zip()
水平连接数据提供程序。
💡 对于保持数据提供程序简洁简单很有用。
/** * @test * @dataProvider colors */ public function test($blueColor, $blueThing, $adjective, Factory $factory): void { // your test here } public function colors(): DataProvider { return DataProvider::zip($this->blueThings(), $this->adjectives(), $this->factories()); } public function blueThings(): DataProvider { return DataProvider::tuples( ['blue', 'ink'], ['light blue', 'shirt'], ['deep blue', 'ocean'] ); } public function adjectives(): iterable { return DataProvider::list('liquid', 'comfortable', 'majestic'); } public function factories(): iterable { yield [new InkFactory()]; yield [new ShirtFactory()]; yield [new OceanFactory()]; }
注意
- 只有具有相同数量行的数据提供程序才能压缩。可以使用
DataProvider.slice()
来剪裁溢出的行,或者使用DataProvider::join()
来延长较短的提供程序。
DataProvider::cross()
创建给定数据提供程序的方阵。
💡 对于测试所有参数组合很有用。
/** * @test * @dataProvider colorsAndThings */ public function test(string $color, string $shade): void { // your test here } public function colorsAndThings(): DataProvider { return DataProvider::cross($this->colors(), $this->things()); } public function colors(): array { return [ ['blue'], ['yellow'], ['red'] ]; } public function things(): iterable { return DataProvider::list('sky', 'sun', 'apple'); }
DataProvider::pairs()
调用测试时使用两个参数。每个参数都与所有其他参数配对。所有行都根据参数命名。
示例显示了测试图像格式配对
/** * @test * @dataProvider formats */ public function shouldConvertFile(string $from, string $to): void { // your test here } public function formats(): array { return DataProviders::distinctPairs('png', 'jpg', 'bmp'); }
DataProvider::of()
从由 PhpUnit 接受的原始数组中实例化 DataProvider
。
public function example(): DataProvider { return DataProvider::of($this->rawArray()); } public function rawArrayDataProvider(): array { return [ 'key' => ['argument 1', 'argument 2'] ]; }
注意
- 也接受
iterable
、\Generator
和其他由 PhpUnit 接受的类型。
DataProvider::tuples()
为每个测试提供多个参数。 DataProvider::tuples()
根据值对每行进行命名。
/** * @test * @dataProvider colors */ public function test(string $color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::tuples( ['blue', 'sky'], ['yellow', 'sun'], ['red', 'apple'] ); }
DataProvider::dictionary()
为测试指定单个参数。使用 DataProvider::dictionary()
根据提供的数组键为每行命名。
/** * @test * @dataProvider colors */ public function test(string $color): void { // your test here } public function colors(): DataProvider { return DataProvider::dictionary([ 'custom name 1' => 'blue', 'custom name 2' => 'yellow', 'custom name 3' => 'red' ]); }
在大多数情况下,使用 DataProvider::list()
或 DataProvider::tuples()
来根据参数命名行。当参数不具自解释性时,方法 DataProvider::dictionary()
很有用。
public function ports(): DataProvider { return DataProvider::dictionary([ 'http' => 80, 'https' => 443, 'ftp' => 21 ]); }
DataProvider.map()
将 DataProvider
中每行的值转换为任何其他值集。
💡 用于将提供者内容和其表单分开。
/** * @test * @dataProvider folderIterators */ public function test(\Iterator $iterator, string $name): void { // your test here } public function folderIterators(): DataProvider { return $this->folders()->map(function (string $name, string $path): array { return [ new \DirectoryIterator($path), $name ]; }); } public function folders(): DataProvider { return DataProvider::tuples( ['temporary', '/tmp'], ['user directory', '/home'], ['system resources', '/usr/bin']); }
注意
DataProvider
中的名称将被保留。
DataProvider.slice()
从 DataProvider
中删除开头或结尾的行。
💡 用于将 DataProvider
适应为压缩或限制提供的值。
/** * @test * @dataProvider limitedColors */ public function test(string $color, string $thing): void { // your test here } public function limitedColors(): DataProvider { return $this->colors()->slice(0, 2); } public function colors(): DataProvider { return DataProvider::tuples( ['blue', 'sky'], ['yellow', 'sun'], ['red', 'apple'] ); }
DataProvider.entries()
为每个测试提供两个参数,从键值对中获取。 DataProvider::entries()
根据键值对命名每行。
/** * @test * @dataProvider colors */ public function test(string $color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::entries( 'blue' => 'sky', 'yellow' => 'sun', 'red' => 'apple', ); }
文档
功能
-
创建新的数据提供者
-
组合现有提供者
-
编辑现有提供者
DataProvider.map()
、DataProvider.slice()
、DataProvider.drop()
。这些方法不会修改DataProvider
实例,而是返回一个新实例。
特性
- 清除命名
- 每个
DataProvider
构建器根据值设置适当的 名称。
- 每个
- 重复键
- 重复键会得到适当的处理和格式化,在编辑时不会丢失任何行。
- 延迟评估
- 迭代器仅在调用时进行评估。参数迭代器只会调用一次,即使
DataProvider
被多次调用。
- 迭代器仅在调用时进行评估。参数迭代器只会调用一次,即使
DataProvider
接受许多 提供者类型。
名称
DataProvider
根据值为每行设置适当的名称。
/** * @test * @dataProvider colors */ public function test(string $color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::tuples( ['blue', 'sky'], ['yellow', 'sun'], ['red', 'apple'] ); }
示例用法
DataProvider::cross()
返回一个 DataProvider
实例,该实例是输入数据提供者的方阵。
/** * @test * @dataProvider services */ public function shouldLogin(string $service, string $method, int $port): void { // your test here } public function services(): DataProvider { return DataProvider::cross( [ ['github.com'], ['bitbucket.com'], ['gitlab.com'], ['sourceforge.net'] ], [ ['http', 80], ['https', 443], ['ssh', 22] ]); }
这相当于有一个由 12 个条目组成的常规数据提供者,类似于
public function services(): array { return [ ['github.com', 'http', 80], ['github.com', 'https', 443], ['github.com', 'ssh', 22], ['bitbucket.com', 'http', 80], ['bitbucket.com', 'https', 443], ['bitbucket.com', 'ssh', 22], ['gitlab.com', 'http', 80], ['gitlab.com', 'https', 443], ['gitlab.com', 'ssh', 22], ['sourceforge.net', 'http', 80], ['sourceforge.net', 'https', 443], ['sourceforge.net', 'ssh', 22], ]; }
DataProvider::cross()
接受不同类型的数据提供者:array
、\Iterator
、\IteratorAggregate
、\Traversable
、\Generator
、iterable
和 DataProvider
。
这意味着 DataProvider
可以组合在一起。
public function services(): DataProvider { return DataProvider::cross( DataProvider::list('github.com', 'bitbucket.com', 'gitlab.com', 'sourceforge.net'), DataProvider::tuples(['http', 80], ['https', 443], ['ssh', 22])); }
高级用法
DataProvider
可以与其他 DataProvider
以及常规的 PhpUnit 数据提供者结合使用。
/** * @test * @dataProvider urls */ public function test0(string $url): void { // your test here } /** * @test * @dataProvider services */ public function test1(string $url, string $name, string $method, int $port): void { // your test here } /** * @test * @dataProvider allServices */ public function test2(string $url, string $name, string $method, int $port): void { // your test here } public function urls(): DataProvider { return DataProvider::list('github.com', 'bitbucket.com', 'gitlab.com', 'sourceforge.net'); } public function rawArrayProvider(): array { return [ ['GitHub'], ['BitBucket'], ['GitLab'], ['SourceForge'] ]; } public function services(): DataProvider { return DataProvider::cross( DataProvider::zip($this->urls(), $this->rawArrayProvider()), DataProvider::tuples( ['http', 80], ['https', 443], ['ssh', 22])); } public function allServices(): DataProvider { return DataProvider::join( $this->services(), $this->localServices() ); } public function localServices(): array { return [ 'my local service' => ['localhost', 'local', 'http', '80'] ]; }
接受类型
DataProvider
接受任何类型的数据提供者
- 所有由 PhpUnit 允许的类型:
array
、iterable
、\Traversable
、\Iterator
、\IteratorAggregate
、\Generator
DataProvider
本身,允许数据提供者可以组合在一起
注意
DataProvider::join()
的注意事项
DataProvider::join()
保留了每个数据提供者的名称,并垂直地合并它们。标题中的重复项被保留并适当地呈现。DataProvider::join()
接受任何类型的数据提供者。DataProvider::join()
在概念上类似于在原始数组提供者上调用\array_merge()
,但是\array_merge()
会覆盖重复键,而DataProvider::join()
会保留重复键,并适当地命名它们。DataProvider::join()
变量参数...iterable
可以用于合并多个数据提供者DataProvider::join()
只能合并每行具有相同数量参数的数据提供者,否则将抛出IrregularDataProviderException
。DataProvider::join()
接受DataProvider
或iterable
,这些类型由 PhpUnit 接受。如果传递了不合适的数据提供者,将抛出MalformedDataProviderException
。
DataProvider::zip()
的注意事项
DataProvider::zip()
保留了每个数据提供者的名称,并水平地合并它们。DataProvider::zip()
接受任何类型的数据提供者。DataProvider::zip()
函数支持可变参数...iterable
,可以连接多个数据提供者。DataProvider::zip()
只能连接具有相同行数的数据提供者,否则会抛出IrregularDataProviderException
异常。此外,每个特定的数据提供者必须在每一行中具有相同数量的参数。DataProvider::zip()
接受DataProvider
或由 PhpUnit 接受的其他iterable
。如果传递了不适当的数据提供者,则会抛出MalformedDataProviderException
异常。
关于 DataProvider::pairs()
的说明
DataProvider::pairs()
产生重复的 pairs(例如'png', 'png'
),而DataProvider::distinctPairs()
只生成不同参数的 pairs。
关于 DataProvider::tuples()
的说明
DataProvider::tuples()
与DataProvider::of()
类似,但::of()
接受一个显式的名称,而DataProvider::tuples()
根据行中的值来命名行。
从先前版本迁移
要使用版本 3.0.0
,从 2.4.0
或更早版本迁移
- 库命名空间从
\TRegx\DataProvider\
更改为\TRegx\PhpUnit\DataProviders\
。 - 将
\TRegx\DataProvider\DataProviders::cross()
更改为\TRegx\PhpUnit\DataProviders\DataProvider::cross()
。 - 将
\TRegx\DataProvider\CrossDataProviders::cross()
更改为\TRegx\PhpUnit\DataProviders\DataProvider::cross()
。 - 将数据提供者的返回类型从
array
更改为iterable
或\TRegx\PhpUnit\DataProviders\DataProvider
。 - 已删除
\TRegx\DataProvider\CrossDataProviders::builder()
,请使用\TRegx\PhpUnit\DataProviders\DataProvider::cross()
代替。