Closed farafiri closed 9 years ago
@farafiri, can you please explain what exactly is the difference between the @dataProvider
annotation feature and what you just described – besides the fact that you don't define a real method that actually provides the data?
None. It's only syntactic sugar. Easer to write and read. Jumping around methods to find out what cases are tested is disturbing.
@farafiri I guess one of the bright sides of having provider methods is that you can reuse them – not sure if that's a good practice, though.
You are right, but in most cases you don't need reusability, in most cases you need readability.
In case when programmer realise that he made bad choice using @testWith because he needs reusability/mock as parameter/whatever switching into @dataProvier is very easy and safe operation.
@sebastianbergmann thoughts? I kind of like it.
+1 from me :) Just make sure that internally the data provider infrastructure is reused.
@farafiri do you mind if I build on bf1c416 and open a PR with a complete implementation?
It would be great. Thank you.
Hello,
I came here to propose such feature. That nice it is already done.
A few thoughts (according to: https://github.com/sebastianbergmann/phpunit/pull/1728). @sebastianbergmann @giorgiosironi Please express your opinions about them.
1) Why do not use old good @dataProvider
annotation instead of adding new one @testWith
? In my opinion distinguish between function and data set shouldn't be complicated.
2) Simplify syntax (more space for large data list, faster to write, easier to read)
@dataProvider
0, 1, 1
1, 2, 3
20, 22, 42
3) Support complex types (inspared by https://code.google.com/p/zohhak/). Requirements: parse test method signature to find complex types, parse class file to find desired function which will create complex type. Search could support @return
phpdoc.
Example 1
/**
* @dataProvider
* "EUR", "FR",
* "GBP", "UK"
* "USD", "US"
*/
public function testCountryUsesCurrency(Currency $currency, Country $country)
{
$this->assertTrue($country->isDefaultCurrency($currency));
}
/**
* @return Currency
*/
public function createCurrency($currency)
{
return new Currency($currency);
}
/**
* @return Country
*/
public function createCountry($country)
{
return new Country($country);
}
Example 2
/**
* @dataProvider
* [49.95, "EUR"], "ACCEPTED", 49.95, "EUR"
* [39.95, "GBP"], "REFUSED", 0, "GBP"
*/
public function testCapturePayment(
Namespace_Order $order, Zend_Soap_Client $gateway,
$expectedAmount, $expectedCurrency
) {
$payment = new Payment($gateway, $order);
$transaction = $payment->capture();
$this->assertEquals($expectedAmount, $transaction->getAmount());
$this->assertEquals($expectedCurrency, $transaction->getCurrency());
}
/**
* @return Zend_Soap_Client
*/
public function createStubPaymentGateway($status)
{
$stub = $this->getMockBuilder('Zend_Soap_Client')->getMock();
$stub->method('getResult')->willReturn($status);
return $stub;
}
/**
* @return Namespace_Order
*/
public function createOrder($amount, $currency)
{
return new Namespace_Order($amount, $country);
}
@sebastianbergmann @giorgiosironi @whatthejeff bump
1) Separation of concerns
2) I don't see the point
3) Too much work (not to implement it but at runtime)
It would be great to have @testWith (like JUnit) feature:
I know that I can use @dataProvider but it overcomplicated and require to much code for most tasks.