¿Hay alguna manera de hacer que las pruebas dentro de un TestCase
se ejecuten en un orden determinado? Por ejemplo, quiero separar el ciclo de vida de un objeto de la creación para usarlo en la destrucción, pero necesito asegurarme de que el objeto esté configurado antes de ejecutar las otras pruebas.Ejecute pruebas de PHPUnit en cierto orden
Respuesta
Quizás haya un problema de diseño en sus pruebas.
Por lo general, cada prueba no debe depender de ninguna otra prueba, por lo que pueden ejecutarse en cualquier orden.
Cada prueba necesita crear instancias y destruir todo lo que necesita para ejecutarse, ese sería el enfoque perfecto, nunca debe compartir objetos y estados entre pruebas.
¿Puede ser más específico acerca de por qué necesita el mismo objeto para las pruebas de N?
Esto no me parece correcto. El objetivo de una prueba unitaria es probar una unidad completa. El objetivo de tener una unidad es agrupar cosas que dependen unas de otras. Los exámenes de escritura que evalúan métodos individuales sin el contexto de la clase son similares a abogar por la programación de procedimientos sobre oo porque usted está defendiendo que las funciones individuales no deben depender de los mismos datos. – doliver
No estoy de acuerdo con su punto de vista. El resultado de una prueba de creación de instancias es un objeto válido que puede ser utilizado por otras pruebas en su conjunto de pruebas. No es necesario crear una instancia de un nuevo objeto para cada prueba, especialmente si el constructor es complicado. – pedromanoel
Si el constructor es complicado, estás haciendo algo mal, probablemente tu clase está haciendo demasiado. Por favor, lea sobre "SOLIDO", más específico sobre el "Patrón de Responsabilidad Individual (SRP)", también debe "falsificar" las dependencias en sus pruebas usando simulaciones, por favor lea también "burlas, falsificaciones y talones". –
Realmente existe un problema con las pruebas si necesitan ejecutarse en un orden determinado. Cada prueba debe ser totalmente independiente de las demás: le ayuda con la localización de defectos y le permite obtener resultados repetibles (y por lo tanto, depurables).
Consulte this site para obtener toda una serie de ideas/información sobre cómo factorizar sus pruebas de manera que pueda evitar este tipo de problemas.
PHPUnit admite dependencias de prueba a través de @depends. – mjs
Si desea que sus pruebas compartan varios objetos y configuraciones de ayudantes, puede usar setUp()
, tearDown()
para agregar a la propiedad sharedFixture
.
¿Aún puede 'assertEquals()', etc. en 'setUp()'? ¿Esa es una mala práctica? – jchook
PHPUnit admite dependencias de prueba a través de la anotación @depends.
Aquí se muestra un ejemplo de la documentación donde se llevará a cabo pruebas en un orden que satisface las dependencias, con cada prueba depende de pasar un argumento a la siguiente:
class StackTest extends PHPUnit_Framework_TestCase
{
public function testEmpty()
{
$stack = array();
$this->assertEmpty($stack);
return $stack;
}
/**
* @depends testEmpty
*/
public function testPush(array $stack)
{
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertNotEmpty($stack);
return $stack;
}
/**
* @depends testPush
*/
public function testPop(array $stack)
{
$this->assertEquals('foo', array_pop($stack));
$this->assertEmpty($stack);
}
}
Sin embargo, es importante tener en cuenta que las pruebas con las dependencias no resueltas se ejecutarán no (deseable, ya que esto llama la atención rápidamente a la prueba que falla). Por lo tanto, es importante prestar mucha atención cuando se usan dependencias.
Para PHPUnit, esto significa que la función de prueba se omitirá si la prueba anterior no se ejecutó. Eso no crea un orden de prueba. – Dereckson
Solo para expandir en @Dereckson, la anotación '@ depends' hará que se omita una prueba si aún no se ha ejecutado la prueba que depende de _either_ o falló cuando se ejecutó. –
No resuelve el problema con la orden de prueba –
PHPUnit permite el uso de la anotación '@depends' que especifica casos de prueba dependientes y permite pasar argumentos entre casos de prueba dependientes.
En mi opinión, tome el siguiente escenario donde necesito probar la creación y la destrucción de un recurso en particular.
Inicialmente tenía dos métodos, a. testCreateResource y b. testDestroyResource
a. testCreateResource
<?php
$app->createResource('resource');
$this->assertTrue($app->hasResource('resource'));
?>
b. testDestroyResource
<?php
$app->destroyResource('resource');
$this->assertFalse($app->hasResource('resource'));
?>
creo que esto es una mala idea, ya que depende de testDestroyResource testCreateResource. Y una mejor práctica sería hacer
a. testCreateResource
<?php
$app->createResource('resource');
$this->assertTrue($app->hasResource('resource'));
$app->deleteResource('resource');
?>
b.testDestroyResource
<?php
$app->createResource('resource');
$app->destroyResource('resource');
$this->assertFalse($app->hasResource('resource'));
?>
-1 En su segundo enfoque, destroyResource también depende de createResource, pero no está establecido explícitamente como tal. Si createResource falla, UTesting Framework señalará erróneamente que destroyResource no funciona – Tivie
solución alternativa: (!) Uso estática funciones en sus pruebas para crear elementos reutilizables. Por ejemplo (utilizo IDE selenio para pruebas de discos y PHPUnit-selenio (github) para ejecutar la prueba dentro del navegador)
class LoginTest extends SeleniumClearTestCase
{
public function testAdminLogin()
{
self::adminLogin($this);
}
public function testLogout()
{
self::adminLogin($this);
self::logout($this);
}
public static function adminLogin($t)
{
self::login($t, '[email protected]', 'pAs$w0rd');
$t->assertEquals('John Smith', $t->getText('css=span.hidden-xs'));
}
// @source LoginTest.se
public static function login($t, $login, $pass)
{
$t->open('/');
$t->click("xpath=(//a[contains(text(),'Log In')])[2]");
$t->waitForPageToLoad('30000');
$t->type('name=email', $login);
$t->type('name=password', $pass);
$t->click("//button[@type='submit']");
$t->waitForPageToLoad('30000');
}
// @source LogoutTest.se
public static function logout($t)
{
$t->click('css=span.hidden-xs');
$t->click('link=Logout');
$t->waitForPageToLoad('30000');
$t->assertEquals('PANEL', $t->getText("xpath=(//a[contains(text(),'Panel')])[2]"));
}
}
Ok, y ahora, puedo utilizar estos elementos reutilizables en otra prueba :) Por ejemplo:
class ChangeBlogTitleTest extends SeleniumClearTestCase
{
public function testAddBlogTitle()
{
self::addBlogTitle($this,'I like my boobies');
self::cleanAddBlogTitle();
}
public static function addBlogTitle($t,$title) {
LoginTest::adminLogin($t);
$t->click('link=ChangeTitle');
...
$t->type('name=blog-title', $title);
LoginTest::logout($t);
LoginTest::login($t, '[email protected]','hilton');
$t->screenshot(); // take some photos :)
$t->assertEquals($title, $t->getText('...'));
}
public static function cleanAddBlogTitle() {
$lastTitle = BlogTitlesHistory::orderBy('id')->first();
$lastTitle->delete();
}
- de esta manera, se puede construir la jerarquía de ustedes pruebas.
- Puede conservar la propiedad de que cada caso de prueba está totalmente separado de otro (si limpia DB después de cada prueba).
- Y lo más importante, si por ejemplo, el camino del cambio de inicio de sesión en el futuro, es suficiente modificar la clase LoginTest, y no encentras necesitará parte de inicio de sesión correcto en otras pruebas (que debería funcionar después de la actualización LoginTest) :)
Cuando ejecuto la prueba, el script se limpia hasta el comienzo. Arriba uso mi clase SeleniumClearTestCase
(hago una captura de pantalla() y otras funciones agradables allí) es la extensión de MigrationToSelenium2
(desde github, para portar pruebas grabadas en firefox usando seleniumIDE + complemento de ff "Selenium IDE: Formateadores PHP") que es extensión de mi clase LaravelTestCase (es una copia de Illuminate \ Foundation \ Testing \ TestCase pero no extiende PHPUnit_Framework_TestCase) que tiene laravel de instalación para tener acceso elocuente cuando queremos limpiar DB al final de la prueba) que es la extensión de PHPUnit_Extensions_Selenium2TestCase. Para configurar laravel elocuent también tengo en la función SeleniumClearTestCase createApplication (que se llama en setUp
, y tomo esta función de laral test/TestCase)
Aquí hay más detalles para ejecutar la prueba registrada en Selenium IDE en Laravel 5.2 y phpUnit: http://stackoverflow.com/questions/33845828/set-up- tests-with-phpunit-and-selenium/37890854 # 37890854 –
La respuesta correcta para esto es un archivo de configuración adecuado para las pruebas. Yo tenía el mismo problema y lo arreglaron mediante la creación de banco de pruebas con los archivos de prueba necesarios ordenar:
phpunit.xml:
<phpunit
colors="true"
bootstrap="./tests/bootstrap.php"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
strict="true"
stopOnError="false"
stopOnFailure="false"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
>
<testsuites>
<testsuite name="Your tests">
<file>file1</file> //this will be run before file2
<file>file2</file> //this depends on file1
</testsuite>
</testsuites>
</phpunit>
Creo que esta es la única solución confiable – emfi
- 1. ¿Puedo hacer que NUnit ejecute pruebas en orden aleatorio?
- 2. eco en las pruebas de phpunit
- 3. Depure algunas pruebas de PhpUnit en Eclipse
- 4. si contiene cierto texto, luego ejecute jquery
- 5. "Interfaz web" para pruebas PHPUnit?
- 6. ¿Cómo saltarse las pruebas en PHPunit?
- 7. Generar informe PHPUnit (Pruebas fallidas y pasadas)
- 8. ¿Cómo ejecuto todas mis pruebas PHPUnit?
- 9. Cómo realizar pruebas unitarias Excepciones con PHPUnit?
- 10. en PHPUnit cómo forzar que tearDownAfterClass() se ejecute en caso de excepciones inesperadas
- 11. Orden de ejecución de pruebas en TestNG
- 12. Cómo determinar si las pruebas PHPUnit se están ejecutando?
- 13. Obtención de datos en un cierto orden utilizando mySql
- 14. ASP.NET MVC (4) - propiedades de BIND en un cierto orden
- 15. PHPUnit - reutilización de objetos simulados para múltiples conjuntos de pruebas
- 16. Obtener QUnit para ejecutar pruebas en orden
- 17. ¿Cómo ejecutar un conjunto de pruebas de phpunit xml específico?
- 18. ¿Disposición del directorio para las pruebas de PHPUnit?
- 19. Crear dinámicamente pruebas PHPUnit a partir del archivo de datos
- 20. Ejecute todas las pruebas abiertas en Visual Studio
- 21. ¿Puedo hacer que @OnApplicationStart no se ejecute en las pruebas?
- 22. Pruebas de prueba de unidad orden
- 23. Zend Framework (PHPUnit) Pruebas won'r plazo (PHPUnit: command not found/'PHPUnit_Framework_TestCase' Clase no encontrada)
- 24. PHPUnit: reintenta automáticamente las pruebas fallidas X veces?
- 25. ¿Cómo configurar las pruebas de unidad pesada de base de datos en Symfony2 usando PHPUnit?
- 26. cambio de orden de pruebas unitarias en Python
- 27. ¿Cómo hacer que TeamCity ejecute pruebas usando MSTest?
- 28. PHPUnit: manejo
- 29. ¿Cómo puedo ejecutar pruebas de Mocha asíncronas (NodeJS) en orden?
- 30. ¿Cómo puedo obtener phpunit para ejecutar pruebas de todos los archivos en una carpeta?
Puede añadir @Depends como se describe en una respuesta más abajo, y el uso de la configuración() y desmontaje() es también una buena idea, pero las pruebas solo se ejecutan de arriba a abajo ... – Andrew
Un caso de uso adicional que no parece haberse cubierto: Quizás todas las pruebas sean atómicas, pero algunas pruebas son LENTAS. Quiero que las pruebas rápidas se ejecuten lo antes posible para que puedan fallar rápido, y las pruebas lentas que se ejecuten muertas al final, después de que ya haya visto otros problemas y pueda acceder a ellos de inmediato. – Kzqai