Могу ли я использовать @depends, чтобы зависеть от теста с помощью @dataProvider?
У меня есть testclass, в котором один тест выполняется несколько раз с помощью @dataProvider
и другого теста, который @depends
по первому методу. Однако, когда я вызывал var_dump
на то, что нужно передать второму тесту, он дает мне твердый NULL
, чего я не ожидал.
Другими словами: что это должно сделать:
<?php
class DevicesTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider registerDataProvider
*/
public function testRegister($device, $supposedResult)
{
//do a bunch of tests
return array($device, $supposedResult);
}
public function registerDataProvider()
{
return array(array("foo", "foo"));
}
/**
* @depends testRegister
*/
public function testSaveDevicePreferences($deviceArr)
{
$this->assertNotEmpty($deviceArr);
}
}
?>
Ответы
Ответ 1
Обычно @dataProvider
используется, если вы хотите выполнить тест несколько раз с разными наборами данных для каждого. Он существует, чтобы избавить вас от написания кода цикла в тесте и позволить отдельным наборам данных проходить или отказываться индивидуально.
Как я уже сказал в своих комментариях, я считаю, что PHPUnit будет использовать либо @depends
либо @dataProvider
, и из вашего примера я предполагаю, что второй выигрывает. Другая возможность заключается в том, что тесты с поставщиками данных не могут использоваться в качестве зависимостей, потому что PHPUnit не знает, какой набор тестовых плюс-данных выбрать.
Поскольку registerDataProvider
возвращает один набор данных, вы можете так же легко вызвать его из самого теста. Это позволит @depends
работать во втором тесте без @dataProvider
. Предполагая, что testRegister
должен изменить $device
и/или $supposedResult
testRegister
, это должно работать:
class DevicesTest extends PHPUnit_Framework_TestCase {
public function testRegister() {
list($device, $supposedResult) = $this->registerDataProvider();
//do a bunch of tests
//register a device in the DB
return array($device, $supposedResult);
}
public function registerDataProvider() {
return array("foo", "foo");
}
/**
* @depends testRegister
*/
public function testSaveDevicePreferences($data) {
list($device, $supposedResult) = $data;
// do stuff dependent on testRegister()
$this->assertEquals($device, $supposedResult);
}
}
Если эти переменные не должны быть изменены с помощью первого теста, вы можете просто вызвать registerDataProvider
из обоих тестов. Обратите внимание, что PHPUnit не будет отделять возвращаемый массив от зависимости от теста до аргументов зависимого теста, как это делает механизм поставщика данных. Это связано с тем, что он не знает, что возвращаемый массив представляет собой несколько аргументов по сравнению с одним аргументом.
Ответ 2
В текущей версии PHPUnit (5.4 на сегодняшний день) это возможно.
Согласно документации:
Когда тест получает входные данные как из метода @dataProvider, так и из одного или нескольких тестов, которые он @depends, аргументы от поставщика данных будут поступать до тех, которые зависят от тестов. Аргументы из зависимых тестов будут одинаковыми для каждого набора данных.
Вот как это выглядело бы практически:
<?php
class DataProviderAndDependsCombinationTest extends AbstractUnittest{
public function dataProviderForSomething()
{
return array(
array(
'someProvidedValue',
'someOtherProvidedValue'
)
);
}
public function testToDependOn()
{
$this->assertTrue(true);
return 'someDependedValue';
}
/**
* @dataProvider dataProviderForSomething
* @depends testToDependOn
*/
public function testSomething($someProvidedValue, $someOtherProvidedValue, $someDependedValue)
{
$this->assertSame('someProvidedValue', $someProvidedValue);
$this->assertSame('someOtherProvidedValue', $someOtherProvidedValue);
$this->assertSame('someDependedValue', $someDependedValue);
}
}
Ответ 3
Я обнаружил, что нет, это невозможно. Однако, слегка адаптировав тестовый класс, я достиг практически того же результата, однако зависимое отношение, похоже, потеряно в том, что если первый тест не прошел, второй с радостью работает:
<?php
class DevicesTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider registerDataProvider
*/
public function testRegister($device, $supposedResult)
{
//do a bunch of tests
//register a device in the DB
return array($device, $supposedResult);
}
public function registerDataProvider()
{
return array(array("foo", "foo"));
}
/**
* @depends testRegister
* @dataProvider registerDataProvider
*/
public function testSaveDevicePreferences($device, $supposedResult)
{
// do stuff dependent on testRegister()
$this->assertEquals($device, $supposedResult);
}
}
?>