Cannot run single test with data provider in PHPUnit

Asked
Active3 hr before
Viewed126 times

7 Answers

singlecannot
90%

2 Nice example! Note that the dataset number also might a string (named dataproviders using array keys in the datasets) so \d+ might not catch everything. But phpunit --filter "/::test.+( with data set #.+)?$/" or something is a very cool way to run all tests with data providers ;) – edorian Aug 31 '12 at 12:55 ,It's not really pretty and having another syntax for this within PHPUnit is definitely preferable but for now it might solve your problem and once someone sends a PR it will be nicer to use ;), 1 @TomášVotruba I wanned to be able to run a single test and make my tests clear but not too verbose. You can find more sample by searching "phpunit data provider yield". – Aurel Jul 16 '19 at 8:50 , Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers

The regex to handle tests with or without data sets is

phpunit --filter "/::<method>( with data set .*)?$/" <class>
      <file>

For example

phpunit--filter "/::testAdd( with data set .*)?$/"
DataTest DataProviderTest.php

Since a test method won't have a space in the name unless it has a data set, you could really shrink this to

phpunit--filter "/::testAdd( .*)?$/"
DataTest DataProviderTest.php
load more v
88%

I have a test which is using a data provider. It runs as expected when running the whole file, however the individual test filter does not account for data providers.,After a little searching around, it looks like the filter needs to account for tests with data providers, which explains why it doesn't work:,Output when running run_single_phpunit_test:,Also came across this problem. Created a pull request to solve this. #37

use Tests\ TestCase;

class ExampleTest extends TestCase {
   function exampleDataProvider() {
      return [
         ['foo'],
      ];
   }

   /**
    * @test
    * @dataProvider exampleDataProvider
    */
   function example_test($foo) {
      $this - > assertSame('foo', $foo);
   }
}
load more v
72%

You link it to the test method with a @dataProvider annotation followed by the method name.,You can even return instances from the data provider:,Instead of having large arrays in the data provider, you can use yield for each data set:,Instead of duplicating the test method and just changing the inputs, you can use Data Providers:

Let's say you are implementing your own trim function and you need to test it with lots of tests like the following one:

< ? php

public
function testTrimTrimsLeadingSpace() : void {
   $input = ' Hello World';
   $expectedResult = 'Hello World';

   self::assertSame($expectedResult, trim($input));
}
load more v
65%

Now our data provider will allow us to test all four validation rules with a single test. Just as in the previous example, the provider datasets cause the test_form_validation test to be run four times, once per dataset.,Data Providers allow us to define tests once and run them multiple times with different datasets. Using a data provider requires three steps:,The clientFormValidationProvider defines three datasets. In this case, the value of each dataset corresponds to the name value of the input under test. These three datasets will cause the required_inputs_are_required test to be run three times, once for each input.,Let's look at some real-world uses of data providers to better understand how they can help tidy up our tests.

  1. Define a public method that returns an array of datasets to be used
  2. Annotate the data provider in the docblock of your test
  3. Pass the dataset as an argument to the test method.
/**
 * @test
 * @dataProvider myTestProvider
 */
public
function we_are_testing_something_good_here($dataProvider) {
   //
}

public myTestProvider() {
   return [
      ['set 1'],
      ['set 2'],
      ['set 3'],
   ];
}
load more v
75%

A test method can accept arbitrary arguments. These arguments are to be provided by one or more data provider methods (additionProvider() in Example 2.5). The data provider method to be used is specified using the @dataProvider annotation.,The tests are public methods that are named test*.,A consumer is a test method that depends on one or more producers and their return values.,When a test receives input from both a @dataProvider method and from one or more tests it @depends on, the arguments from the data provider will come before the ones from depended-upon tests. The arguments from depended-upon tests will be the same for each data set. See Example 2.9

< ? php declare(strict_types = 1);
use PHPUnit\ Framework\ TestCase;

final class StackTest extends TestCase {
   public
   function testPushAndPop(): void {
      $stack = [];
      $this - > assertSame(0, count($stack));

      array_push($stack, 'foo');
      $this - > assertSame('foo', $stack[count($stack) - 1]);
      $this - > assertSame(1, count($stack));

      $this - > assertSame('foo', array_pop($stack));
      $this - > assertSame(0, count($stack));
   }
}
load more v
40%

A dedicated integration test database,The test framework database configuration,PHPUnit offers several ways to only execute a subset of tests. For example, it is common to only execute a single test suite from the phpunit.xml configuration.,By default, for every integration test run, the test framework installs a fresh Magento test database.

1
2
CREATE DATABASE magento_integration_tests;
GRANT ALL ON magento_integration_tests.*TO 'magento2_test_user'
@ 'localhost'
IDENTIFIED BY 'ftYx4pm6^x9.&^hB';
1
2
CREATE DATABASE magento_integration_tests;
GRANT ALL ON magento_integration_tests.*TO 'magento2_test_user'
@ 'localhost'
IDENTIFIED BY 'ftYx4pm6^x9.&^hB';
load more v
22%

When the above test runs, the result shown below is produced,When the above test is executed, the results below are obtained.,can be provided by one or more methods known as data provider methods. The data provider method to be used are specified using the @dataProvider annotation.,The PHPUnit test above illustrating named datasets produces the following results when executed.

The example below illustrates how a data provider method returns an array of arrays.

< ? php
use PHPUnit\ Framework\ TestCase;

class DataTest extends TestCase {
   /**
    * @dataProvider additionProvider
    */
   public
   function testAdd($a, $b, $expected) {
      $this - > assertSame($expected, $a + $b);
   }

   public
   function additionProvider() {
      return [
         [0, 0, 0],
         [0, 1, 1],
         [1, 0, 1],
         [1, 1, 3]
      ];
   }
} ?
>

When the above test runs, the result shown below is produced

$ phpunit DataTest
PHPUnit | version | .0 by Sebastian Bergmann and contributors.

   ...F

Time: 0 seconds, Memory: 5.75 Mb

There was 1 failure:

   1) DataTest::testAdd with data set #3 (1, 1, 3)
Failed asserting that 2 is identical to 3.

/home/sb/DataTest.php:9

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

The example below illustrates a data provider with named datasets

< ? php
use PHPUnit\ Framework\ TestCase;

class DataTest extends TestCase {
   /**
    * @dataProvider additionProvider
    */
   public
   function testAdd($a, $b, $expected) {
      $this - > assertSame($expected, $a + $b);
   }

   public
   function additionProvider() {
      return [
         'adding zeros' => [0, 0, 0],
         'zero plus one' => [0, 1, 1],
         'one plus zero' => [1, 0, 1],
         'one plus one' => [1, 1, 3]
      ];
   }
} ?
>

The PHPUnit test above illustrating named datasets produces the following results when executed.

$ phpunit DataTest
PHPUnit | version | .0 by Sebastian Bergmann and contributors.

   ...F

Time: 0 seconds, Memory: 5.75 Mb

There was 1 failure:

   1) DataTest::testAdd with data set "one plus one"(1, 1, 3)
Failed asserting that 2 is identical to 3.

   /
   home / sb / DataTest.php: 9

FAILURES!
   Tests: 4, Assertions: 4, Failures: 1.

As mentioned earlier, a data provider can either return an array of an array or an object implementing the iterator interface. The example below, illustrates a data provider, returning an iterator object.

< ? php
use PHPUnit\ Framework\ TestCase;

require 'CsvFileIterator.php';

class DataTest extends TestCase {
   /**
    * @dataProvider additionProvider
    */
   public
   function testAdd($a, $b, $expected) {
      $this - > assertSame($expected, $a + $b);
   }

   public
   function additionProvider() {
      return new CsvFileIterator.php('data.csv');
   }
} ?
>

The above date provider returning an iterator object, produces the following results on test.

$ phpunit DataTest
PHPUnit | version | .0 by Sebastian Bergmann and contributors.

   ...F

Time: 0 seconds, Memory: 5.75 Mb

There was 1 failure:

   1) DataTest::testAdd with data set #3 ('1', '1', '3')
Failed asserting that 2 is identical to 3.

/home/sb/DataTest.php:11

FAILURES!
Tests: 4, Assertions: 4, Failures: 1.

The CsvFileIterator which was required and tested in the above is defined below:

< ? php
use PHPUnit\ Framework\ TestCase;

class CsvFileIterator implements Iterator {
   protected $file;
   protected $key = 0;
   protected $current;

   public
   function __construct($file) {
      $this - > file = fopen($file, 'r');
   }

   public
   function __destruct() {
      fclose($this - > file);
   }

   public
   function rewind() {
      rewind($this - > file);
      $this - > current = fgetcsv($this - > file);
      $this - > key = 0;
   }

   public
   function valid() {
      return !feof($this - > file);
   }
   public
   function key() {
      return $this - > key;
   }

   public
   function current() {
      return $this - > current;
   }

   public
   function next() {
      $this - > current = fgetcsv($this - > file);
      $this - > key++;
   }
} ?
>

The arguments from depended-upon tests will also be the same for each data set. The example below illustrates a test with a @dataProvider and @depends.

< ? php
use PHPUnit\ Framework\ TestCase;

class DependencyAndDataProviderComboTest extends TestCase {
   public
   function provider() {
      return [
         ['provider1'],
         ['provider2']
      ];
   }

   public
   function testProducerFirst() {
      $this - > assertTrue(true);
      return 'first';
   }

   public
   function testProducerSecond() {
      $this - > assertTrue(true);
      return 'second';
   }

   /**
    * @depends testProducerFirst
    * @depends testProducerSecond
    * @dataProvider provider
    */
   public
   function testConsumer() {
      $this - > assertSame(
         ['provider1', 'first', 'second'],
         func_get_args()
      );
   }
} ?
>

When the above test is executed, the results below are obtained.

Multiple data providers can also be used in a single test, the example below illustrates the use of multiple data providers in a single test.

< ? php
use PHPUnit\ Framework\ TestCase;

class DataTest extends TestCase {
   /**
    * @dataProvider additionWithNonNegativeNumbersProvider
    * @dataProvider additionWithNegativeNumbersProvider
    */
   public
   function testAdd($a, $b, $expected) {
      $this - > assertSame($expected, $a + $b);
   }

   public
   function additionWithNonNegativeNumbersProvider() {
      return [
         [0, 1, 1],
         [1, 0, 1],
         [1, 1, 3]
      ];
   }

   public
   function additionWithNegativeNumbersProvider() {
      return [
         [-1, 1, 0],
         [-1, -1, -2],
         [1, -1, 0]
      ];
   }
} ?
>

The above test illustrating the use of multiple dependencies gives the following output.

$ phpunit DataTest
PHPUnit | version | .0 by Sebastian Bergmann and contributors.

   ..F...6 / 6(100 % )

Time: 0 seconds, Memory: 5.75 Mb

There was 1 failure:

   1) DataTest::testAdd with data set #3 (1, 1, 3)
Failed asserting that 2 is identical to 3.

/home/sb/DataTest.php:12

FAILURES!
Tests: 6, Assertions: 6, Failures: 1.
load more v

Other "single-cannot" queries related to "Cannot run single test with data provider in PHPUnit"