Pregunta

Lo que más me convencido de los beneficios de la unidad de pruebas, y me gustaría empezar a aplicar el concepto a una gran base de código existente escrito en PHP. Menos del 10% de este código es orientado a objetos.

He mirado en varios marcos de pruebas unitarias (PHPUnit, SimpleTest y HPTP). Sin embargo, no he encontrado ejemplos para cualquiera de estos que ponen a prueba el código de procedimiento. ¿Cuál es el mejor marco para mi situación y si existen ejemplos de unidad de prueba PHP utilizando el código de programación orientada a objetos no?

¿Fue útil?

Solución

Puede unidad de prueba PHP procedimental, no hay problema. Y no está definitivamente fuera de suerte si su código se mezcla con HTML.

A nivel de aplicación o la aceptación de pruebas, su PHP procedimiento probablemente depende del valor de los superglobales ($_POST, $_GET, $_COOKIE, etc.) para determinar el comportamiento, y termina mediante la inclusión de un archivo de plantilla y escupiendo la salida.

Para hacer la prueba de nivel de aplicación, sólo puede establecer los valores superglobales; iniciar un búfer de salida (para mantener un montón de html de la inundación de su pantalla); llamar a la página; oponer cosas dentro de la memoria intermedia; y la basura la memoria intermedia al final.   Así, se podría hacer algo como esto:

public function setUp()
{
    if (isset($_POST['foo'])) {
        unset($_POST['foo']);
    }
}

public function testSomeKindOfAcceptanceTest()
{
    $_POST['foo'] = 'bar';
    ob_start();
    include('fileToTest.php');
    $output = ob_get_flush();
    $this->assertContains($someExpectedString, $output);
}

A pesar de enormes "marcos" con mucha incluye, este tipo de pruebas le dirá si tiene características de nivel de aplicación funcionando o no. Esto va a ser muy importante, ya que empezar a mejorar su código, porque incluso si usted está convencido de que el conector de la base de datos todavía funciona y se ve mejor que antes, tendrá que hacer clic en un botón y ver que, sí, todavía se puede conectarse y desconectarse a través de la base de datos.

A niveles más bajos, hay variaciones menores dependiendo de alcance variable y si las funciones funcionan por efectos secundarios (volviendo verdadera o falsa), o devolver el resultado directamente.

se pasan las variables en torno explícitamente, como parámetros o matrices de parámetros entre funciones? O se establecen las variables en muchos lugares diferentes, y pasaron de forma implícita como globales? Si se trata de la (buena) caso explícito, puede unidad de prueba una función de (1), incluyendo el archivo de la celebración de la función, a continuación, (2) la alimentación de los valores de las pruebas de función directa, y (3) la captura de la salida y hacer valer en contra de ella. Si está utilizando variables globales, sólo hay que tener mucho cuidado (como el anterior, en el ejemplo $ _POST) a nulas todas las variables globales cuidadosamente entre las pruebas. También es especialmente útil para mantener pruebas muy pequeñas (5-10 líneas, 1-2 afirma) cuando se trata de una función que empuja y tira un montón de variables globales.

Otra cuestión fundamental es si las funciones de trabajo mediante la devolución de la salida, o alterando los parametros pasaron en, devolviendo verdadero / falso en su lugar. En el primer caso, la prueba es más fácil, pero una vez más, es posible en ambos casos:

// assuming you required the file of interest at the top of the test file
public function testShouldConcatenateTwoStringsAndReturnResult()
{
  $stringOne = 'foo';
  $stringTwo = 'bar';
  $expectedOutput = 'foobar';
  $output = myCustomCatFunction($stringOne, $stringTwo);
  $this->assertEquals($expectedOutput, $output);
}

En el caso grave, donde funciona su código por los efectos secundarios y devuelve verdadero o falso, todavía se puede probar con bastante facilidad:

/* suppose your cat function stupidly 
 * overwrites the first parameter
 * with the result of concatenation, 
 * as an admittedly contrived example 
 */
public function testShouldConcatenateTwoStringsAndReturnTrue()
    {
      $stringOne = 'foo';
      $stringTwo = 'bar';
      $expectedOutput = 'foobar';
      $output = myCustomCatFunction($stringOne, $stringTwo);
      $this->assertTrue($output);
      $this->Equals($expectedOutput, $stringOne);
    }

Espero que esto ayude.

Otros consejos

¿Qué pruebas unitarias hacen bien, y lo que debe utilizarlas para, es cuando se tiene un pedazo de código que le da cierta cantidad de entradas, y que espera obtener un número de salidas de vuelta. La idea de ser, al agregar funcionalidad posterior, puede ejecutar las pruebas y asegurarse de que aún está realizando la antigua funcionalidad de la misma manera.

Por lo tanto, si usted tiene una base de código de procedimiento, se puede lograr esto llamar a sus funciones en los métodos de prueba

require 'my-libraries.php';
class SomeTest extends SomeBaseTestFromSomeFramework {
    public function testSetup() {
        $this->assertTrue(true);
    }

    public function testMyFunction() {
        $output = my_function('foo',3);

        $this->assertEquals('expected output',$output);
    }
}

Este truco con bases de código PHP es, a menudo el código de la biblioteca va a interferir con el funcionamiento de su marco de pruebas, como su código base y los marcos de prueba tendrá una gran cantidad de código relacionado con la creación de un entorno de aplicación en un navegador web ( sesión, las variables globales compartidas, etc.). Prepárese para pasar en algún momento llegar a un punto en el que puede incluir su código de la biblioteca y ejecutar una prueba sencilla de tierra (la función testSetup arriba).

Si el código no tiene funciones, y es sólo una serie de archivos que PHP páginas HTML de salida, eres un poco de suerte. El código no se puede separar en unidades distintas, lo que significa que las pruebas unitarias no va a ser de mucha utilidad para usted. Usted sería mejor gastar su tiempo en el nivel de "pruebas de aceptación" con productos como selenio y Watir. Estos le permitirán automatizado un navegador y, a continuación, comprobar las páginas de contenido para sitios específicos como / en formas.

Se podría tratar de incluir su código no-oop en una clase de prueba utilizando

require_once 'your_non_oop_file.php' # Contains fct_to_test()

Y con PHPUnit a definir su función de prueba:

testfct_to_test() {
   assertEquals( result_expected, fct_to_test(), 'Fail with fct_to_test' );
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top