rawr / phpunit-data-provider

PhpUnit 数据提供程序的轻量级构建器

3.3.0 2023-11-18 16:20 UTC

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() 等方法管理数据提供程序。

Build Status Coverage Status Dependencies License Composer lock

PHP Version PHP Version PHP Version PHP Version PHP Version PHP Version PHP Version

PRs Welcome

  1. 安装
  2. 概述
  3. 文档
  4. 迁移

安装

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');
}

list.png

此外,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']
  ];
}

join.png

注意

  • 只有具有相同数量参数的行的数据提供程序才能连接。可以使用 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()];
}

zip.png

注意

  • 只有具有相同数量行的数据提供程序才能压缩。可以使用 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');
}

cross.png

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');
}

pairs.png

DataProvider::of()

从由 PhpUnit 接受的原始数组中实例化 DataProvider

public function example(): DataProvider {
  return DataProvider::of($this->rawArray());
}

public function rawArrayDataProvider(): array {
  return [
    'key' => ['argument 1', 'argument 2']
  ];
}

of.png

注意

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']
  );
}

tuples.png

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'
  ]);
}

dictionary.png

在大多数情况下,使用 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']);
}

map.png

注意

  • 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',
  );
}

entries.png

文档

功能

特性

  • 清除命名
    • 每个 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']
  );
}

names names

示例用法

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\GeneratoriterableDataProvider

这意味着 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 接受任何类型的数据提供者

注意

DataProvider::join() 的注意事项

  • DataProvider::join() 保留了每个数据提供者的名称,并垂直地合并它们。标题中的重复项被保留并适当地呈现。
  • DataProvider::join() 接受任何类型的数据提供者。
  • DataProvider::join() 在概念上类似于在原始数组提供者上调用 \array_merge(),但是 \array_merge() 会覆盖重复键,而 DataProvider::join() 会保留重复键,并适当地命名它们。
  • DataProvider::join() 变量参数 ...iterable 可以用于合并多个数据提供者
  • DataProvider::join() 只能合并每行具有相同数量参数的数据提供者,否则将抛出 IrregularDataProviderException
  • DataProvider::join() 接受 DataProvideriterable,这些类型由 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() 代替。