2012-05-22 6 views
8

Tengo una clase de prueba en la que una prueba se ejecuta varias veces a través de un @dataProvider y otra prueba que @depends en el primer método. Sin embargo, cuando llamé al var_dump sobre lo que debería pasarse a la segunda prueba, me da un sólido NULL, que no esperaba.¿Puedo usar @depends para depender de una prueba usando @dataProvider?

En otras palabras: ¿qué debería hacer esto:

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

Respuesta

5

Normalmente @dataProvider se utiliza cuando desea ejecutar una prueba varias veces con diferentes conjuntos de datos para cada uno. Existe para salvarte de escribir código de bucle en la prueba y para permitir que diferentes conjuntos de datos pasen o fallen individualmente.

Como ya he dicho en mis comentarios, creo que PHPUnit usará ya sea @dependso@dataProvider, y de su ejemplo mi suposición es que el segundo gana. Otra posibilidad es que las pruebas con proveedores de datos no se puedan usar como dependencias porque PHPUnit no sabe qué test-plus-dataset elegir.

Dado que registerDataProvider devuelve un único conjunto de datos, puede llamarlo tan fácilmente desde la propia prueba. Esto permitiría que @depends trabaje en la segunda prueba sin el @dataProvider. Suponiendo que testRegister necesita modificar $device y/o $supposedResult, esto debería funcionar:

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

Si estas variables no necesitan ser modificados por la primera prueba, sólo tiene que llamar registerDataProvider de ambas pruebas. Tenga en cuenta que PHPUnit no separará una matriz devuelta de un dependiente y una prueba en argumentos para la prueba dependiente como lo hace el mecanismo del proveedor de datos. Esto se debe a que no sabe que la matriz que se devuelve es de múltiples argumentos versus un solo argumento.

+0

Consulte https://github.com/sebastianbergmann/phpunit/issues/183#issuecomment-816066 para obtener una explicación sobre este comportamiento – pedromanoel

+0

La información de '@ dataProvider' es lo primero, que proviene de los datos '@ depends'. Así es como funciona para mí. –

-1

descubrí que no, esto no es posible. Sin embargo, adaptando ligeramente la testclass, he logrado básicamente el mismo resultado, sin embargo, la relación de dependencia parece estar perdido en que si no pasa la primera prueba, la segunda felizmente se ejecuta:

<?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); 
    } 
} 
?> 
+0

Sería curioso cómo se comporta cuando el método proveedor de datos devuelve una matriz con más de una serie de parámetros. El método de prueba debe invocarse una vez por conjunto de parámetros, pero las dependencias de prueba están diseñadas para depender de una sola invocación de método de prueba. –

+0

Se comporta de una manera correcta, sin embargo, cuando edité, la segunda prueba no se omite si falla la primera prueba. Además, la segunda prueba depende de que algunas cosas estén presentes en la base de datos, que están puestas allí por la primera prueba.El hecho de que estén allí significa que la primera prueba se ejecuta antes que la segunda. – Zsub

+0

Las pruebas se ejecutan en el orden en que se declaran. PHPUnit no los reordena según el gráfico de dependencia. Dado que la segunda prueba utiliza el mismo proveedor de datos, recibe sus datos de ese método en lugar de la prueba de la que depende. Mi apuesta es que PHPUnit busca '@ dataProvider' antes de' @ depends' y por lo tanto puede eliminar la dependencia sin ningún efecto. –

9

En la versión actual de PHPUnit (5.4 a partir de hoy), es posible.

Según la documentation:

Cuando una prueba recibe la entrada tanto de un método @dataProvider y de una o más pruebas que @Depends en, los argumentos del proveedor de datos vendrá antes que los de dependido -las pruebas Los argumentos de las pruebas dependientes serán los mismos para cada conjunto de datos.

Esto es cómo se vería prácticamente:

<?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); 
    } 
} 
+0

Exactamente. Esto debe ser aceptado para el estado actual. –

+0

Sin embargo, no era realmente lo que preguntaba la pregunta. OP tiene '@ dataProvider' en la prueba de la que se depende, no en la prueba que depende de otra (como la que tiene aquí). – Luke

Cuestiones relacionadas