2010-08-07 14 views
12

Puede ser una pregunta tonta, pero ¿realiza pruebas unitarias para la salida HTML de sus funciones/scripts PHP?Pruebas unitarias para salida HTML?

Intento mantener mi HTML y mi PHP separados - es decir, HTML incluye marcadores de posición y funciones para ciertos elementos recurrentes (datos tabulares/cualquier tipo de salida en bucle) - pero no estoy seguro de cómo verificar esto .

¿Hay una manera estándar para ir por esas cosas, o es sobre todo una cuestión de usar pruebas regulares de la unidad de funciones que crean el contenido insertado, y luego asegurarse de que es correcta en el navegador/W3C Validador?

Gracias.

Editar: supongo que un corolario de esto sería: son estos tipos de pruebas de unidad, incluso vale la pena tener? Si mantiene su contenido y estructura adecuadamente separados, entonces realmente solo estaría probando un puñado de inclusiones en escenarios muy limitados (presumiblemente, de todos modos). ¿Realmente vale la pena hacerlo en páginas completas de manualidades para solo tener un archivo para comparar?

Respuesta

3

Puede usar PHPUnit. Tiene pruebas de salida.

http://www.phpunit.de/manual/3.0/en/testcase-extensions.html

+0

Esto plantea una pregunta similar: ¿Es realmente vale la pena semi-artesanal, páginas completas de este tipo sólo para tener un archivo de comparar a para algunas pruebas unitarias? ¿No sería visible cuando se rompa? – Kristina

+1

@Kristina Si está probando partes enormes y monolíticas de su programa, le falta el objetivo de [pruebas unitarias] (http://bit.ly/dezkGz) – NullUserException

+0

Se pueden verificar las funciones y métodos individuales que componen la página, pero ¿Estás diciendo que no debería probar el método que los llama/presenta la página? – Kristina

4

Las pruebas para la salida HTML se consideraría una prueba de cobertura. Inicialmente, cuando comencé a usar PHP estaba creando estas pruebas, pero con el tiempo descubrí que estas pruebas no eran realmente tan útiles.

Si hay algo que sé, es que la presentación va a cambiar un lote desde el desarrollo inicial hasta la implementación.

Si lo piensas bien, un bucle for realmente no es lógico sino que es una función de transformación isométrica, y si sigues Separation of Concerns, entonces estás pasando los datos al bucle for mediante un método de algún tipo. Recomendaría probar que el bucle for obtiene los datos correctos, pero no la salida del bucle for.

Si usted se encuentra repitiendo en la generación de las tablas a continuación, por todos los medios inicio de unidad de los ensayos de los plantillas de mesa. Pero una vez más, descubrirá que esas plantillas verán muchos cambios.

En este punto, debería considerar separar la iteración de la salida HTML para ayudarlo a aislarse de estas preocupaciones en sus pruebas.

Una forma de hacer esto es usar una función de mapeo, tomará una función de lista y transformación y realizará la función en cada elemento de la lista, luego regresará la lista transformada.

lo general, cuando la creación de tablas, termino con dos bucles en la creación de una fila.

  1. Iterar todas las filas.
  2. Mientras está en (1) repite los elementos en la fila.

Bastante feo a la prueba de la unidad, pero con los cierres puede crear generadores de funciones que sería realmente fácil [esto se dice con un grano de sal] para implementar.

0

Entrando en esta pregunta yo mismo. Creo que un enfoque podría ser usar algo como phpQuery para hacer que tus pruebas sean menos frágiles.En lugar de probar la salida exacta, pruebe que debería haber una etiqueta h3 ~ en algún lugar ~ en la salida. Si se ve envuelto en un div más tarde porque un diseñador necesita virar en un fondo adicional, o debido a alguna solución de error flotante ie6, entonces su prueba todavía funciona.

No es muy puro, pero aún es una herramienta potencialmente muy útil.

1

me encontré con el marco SimpleTest a ser muy útil, por lo general lo uso para la integración y las pruebas PHPUnit para unidad de pruebas. Me ahorran una gran cantidad de formuladores enviados manualmente, lo que haría de lo contrario una y otra vez.

Se convirtió en mi hábito de seguir estos puntos, al hacer este tipo de pruebas de interacción con otros:

  1. tratar de no repetir las pruebas que ya se realizan con unidad de pruebas reales. Si, por ejemplo, tiene una función de validación probada por unidad para las direcciones de correo electrónico, no tiene sentido enviar todo tipo de direcciones de correo electrónico no válidas. Solo verifique una vez si se le redirige con un mensaje de error.
  2. No compare el HTML resultante con un resultado de referencia completo, tendrá que actualizar sus pruebas con cada rediseño de sus páginas. En su lugar, revise solo las partes cruciales con $webTestCase->assertText('...'); o $webTestCase->assertPattern('/.../');.

Con algunas pequeñas funciones auxiliares, puede obtener una gran solidez. La siguiente función abrirá una página y verificará si la página se abrió correctamente sin advertencias. Dado que no existe un compilador de PHP que pueda emitir advertencias en el momento del diseño, al menos puede asegurarse de que su código no produzca errores ni advertencias.

public static function openPageWithNoWarnings($webTestCase, $page, $landingPage = null) 
{ 
    // check that page can be opened successfully 
    $webTestCase->assertTrue($webTestCase->get($page)); 

    // check that there are no PHP warnings 
    $webTestCase->assertNoPattern('/(warning:|error:)/i', 'PHP error or warning on page!'); 

    // check if landed on expected page (maybe a redirect) 
    if (!empty($landingPage)) 
    { 
    $url = $webTestCase->getUrl(); 
    $file = basename(parse_url($url, PHP_URL_PATH)); 
    $webTestCase->assertEqual($page, $file, 
     sprintf('Expected page "%s", got page "%s".', page, $file)); 
    } 
} 

Tales pruebas no le dará gran parte del trabajo, se puede empezar con pruebas muy ligeros, pero le dará al instante retroalimentación si algo falla, con sólo un clic del ratón.

+0

¡Perfecto! SimpleTest es de hecho mejor en esto que phpunit. :) – winkbrace

0

En algunos casos (como CakePHP Helpers), el propósito de una clase o función es generar HTML consistente para usted. En tales casos, es importante probar que las propiedades esperadas de la unidad generada de HTML son correctas para entradas dadas. La pregunta es definitivamente válida en ese contexto.

PHPUnit proporciona una función assertTag() para este propósito.

Sin embargo, para hacer eco de los demás; es importante destacar que las pruebas de la unidad deben realizarse en los componentes más pequeños posibles de su proyecto, y no en páginas web renderizadas completas. Hay otras herramientas (Selenium por ejemplo) que están diseñadas para garantizar que esos componentes individuales sean integrados juntos correctamente.

0

Una manera muy simple de hacer esto es con el buffer de salida.

por ejemplo

ob_start(); 
function_which_produces_some_output(); 
$this->assertEquals(ob_get_clean(), '<p>Expected Output Here</p>'); 
7

Con base en mi experiencia en HTML pruebas, que ahora sigue estas tres reglas básicas:

1. No prueba de salida HTML en contra de una plantilla correcta. Modificará el HTML generado con demasiada frecuencia, y terminará perdiendo el tiempo manteniendo sus pruebas.

2. Compruebe la existencia de datos importantes en HTML generado. Si está generando HTML (a diferencia del HTML estático que escribió una vez), pruebe el HTML generado para datos importantes. Por ejemplo: si está generando una tabla basada en una matriz bidimensional, verifique que los valores en la matriz se encuentren en algún lugar del HTML generado. No se moleste en validar el resultado completo, ya que esto violaría el # 1.

3. Validar si la salida es HTML correcto. Valide todos los resultados para HTML correcto a fin de evitar errores estúpidos, como falta de etiquetas finales. He escrito una biblioteca para esto, que se puede usar de manera totalmente gratuita.

Esta biblioteca PHP le permitirá validar si una cadena es válida HTML5. La biblioteca usa Validator.nu. Compatible con PHPUnit o cualquier otro marco de prueba.

Download and documentation here.

Fácil de usar, ejemplo:

$validator=new HTML5Validate(); 

// Validate (returns TRUE or FALSE) 
$result=$validator->Assert('<p>Hello World</p>'); 

// Get explanation of what's wrong (if validation failed) 
print $validator->message;