Codeception: dataProvider enhancement

Created on 19 Feb 2018  Â·  7Comments  Â·  Source: Codeception/Codeception

PhpUnit has useful option - named data in dataprovider.
Example:
https://phpunit.de/manual/current/en/textui.html#textui.examples.filter-shortcuts

Is it possible to run tests with particular data from dataprovider with codeception?
It's needed to make parallel run tests with dataprovider.

Most helpful comment

It would be also great to print name of dataset in console output.

All 7 comments

I made some changes to support running tests with particular data set index from dataset.
Example:
codecept run tests/acceptance/FirstCest.php:frontpageWorks#0
codecept run tests/acceptance/FirstCest.php:frontpageWorks#1

So, it will be possible to split tests by groups with dataproviders.
There is another one PR for this issue:
https://github.com/Codeception/phpunit-wrapper/pull/3

It would be also great to print name of dataset in console output.

@fffilimonov I believe that using #0 is for unamed dataproviders, what should we do with named dataproviders? Just replace the 0 witht he name ?

@KacerCZ values are printed in console output.
@marabesi we are using named dataproviders and run tests by index (it's enough for us).
There is some problem with name of dataset - codeception replace it with "example".
https://github.com/Codeception/Codeception/blob/1d4bb38d1a5ac852ddb8a35f7aa88c18180176df/src/Codeception/Test/Loader/Cest.php#L90
So dataset name not passed to phpunit (it's always "example").
If you need it - you can submit PR

It would be also great to print name of dataset in console output.

@KacerCZ I found a solution that worked for me to name the console output. Here's what the output originally looked like:

public function objectTypeProvider() {
    return [
        ['item'],
        ['term'],
        ['user'],
    ];
}

/**
* @dataProvider objectTypeProvider
*/
public function test_someTest($objectType) {
    // ...
}

Output:

✔ ComponentTest: some test | #0
✔ ComponentTest: some test | #1
✔ ComponentTest: some test | #2

The output was more useful when the data provider function used an associative array with a name:

public function objectTypeProvider() {
    return [
        'item' => ['item'],
        'term' => ['term'],
        'user' => ['user'],
    ];
}

/**
* @dataProvider objectTypeProvider
*/
public function test_someTest($objectType) {
    // ...
}

Output:

✔ ComponentTest: some test | "item"
✔ ComponentTest: some test | "term"
✔ ComponentTest: some test | "user"

@alecgeatches Can it be that this so-called named dataset approach (cf. https://phpunit.readthedocs.io/en/8.0/writing-tests-for-phpunit.html#writing-tests-for-phpunit-data-providers-examples-datatest1-php) is only supported by non-acceptance tests?

I think the "name" of the dataset is $k in https://github.com/Codeception/Codeception/blob/367de4ffde960d8be98d710e4a9f849cfd17e28f/src/Codeception/Test/Loader/Cest.php#L81-L95 , but is lost (not used any further)?
Update/Correction: No, I think this is wrong (or not so easy) -- I mixed up @dataProvider and @example :-(

Let's say support for named datasets in @dataProvider AND @example would be really great to have...

A possible workaround is returning instances of classes with overridden __toString() method in @dataProvider, e.g.:

class ParameterizedCest {

  /**
   * @dataProvider provider4
   *
   * @param \Codeception\Example $example
   */
  public function testTaxRate4(\Codeception\Example $example) {
    /** @var Provider4TestCase $testCase */
    $testCase = $example[0];
    Assert::assertEquals(20, $testCase->getData()[0]);
  }

  /**
   * Returns array of array entries with: int $taxRate, bool $nettoPrice, bool $asCompany, string $ustId, string $countryCode, int $postCode
   */
  protected function provider4() {
    return [
      [
        (new Provider4TestCase('PrivateUserInAustria'))->setData([ 20, false, false, "", 'AT', 4120 ])
      ],
      [
        (new Provider4TestCase('BusinessUserInAustria'))->setData([ 20, false, true, 'ATU56712338', 'AT', 4120 ])
      ]
    ];
  }

}

class Provider4TestCase {

  private $name;
  private $data;

  public function __construct(string $name) {
    $this->name = $name;
  }

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

  public function setData(array $data) {
    $this->data = $data;
    return $this;
  }

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

Screenshot from PhpStorm:

grafik

  • (Note: Testcode was not in ParameterizedCest)
Was this page helpful?
0 / 5 - 0 ratings