2012-06-30 6 views
5

Existen varias herramientas para generar datos de muestra para una expresión regular determinada. Algunos incluyen:Generación de datos de muestra de expresiones regulares para verificar cadenas de entrada mediante el enfoque en casos de límites definidos en expresiones regulares

Sin embargo, si bien pueden ser suficientes para sembrar un conjunto de datos, que no ayuda mucho probar el código que depende de la propia expresión regular, como la validación .

Supongamos que tiene un generador de código que genera un modelo con una propiedad. El usuario especifica una expresión regular para validar la propiedad. Supongamos ahora que el generador de códigos está intentando generar pruebas para garantizar que la validación tenga éxito y falle adecuadamente. Parece razonable que la herramienta se centre en los casos límite dentro de la expresión regular para evitar la generación de datos innecesarios.

Por ejemplo, considere una expresión regular ^([a-z]{3,6})$ entonces los casos de contorno incluyen:

  • cualquier cadena que consiste solamente en [az] una longitud igual a 2 (fallo)
  • cualquier cadena que consiste solamente en [az] una longitud igual a 3 (éxito)
  • cualquier cadena que consiste solamente en [az] una longitud igual a 4 (éxito)
  • cualquier cadena que consiste solamente en [az] una longitud igual a 5 (éxito)
  • una cadena ny que consiste solamente en [az] una longitud igual a 6 (éxito)
  • cualquier cadena que consiste solamente en [az] una longitud igual a 7 (fallo)
  • cualquier cadena no consiste en [az] (fallo)
  • cualquier cadena que no empiezan con [az], pero termina con [az] (fallo)
  • cualquier cadena que comienza con [az], pero no termina con [az] (fallo)

La razón centrada en el límite casos es que cualquier cadena que conste solo de [az] con una longitud mayor que 6 verifica el límite superior de la longitud de cadena definida en la expresión regular. Entonces probar una cadena de longitud 7, 8, 9 es realmente solo probar la misma condición (límite).

Esta fue una expresión regular arbitraria elegida por su simplicidad, pero cualquier expresión regular razonable puede actuar como una entrada.

Existe un marco/herramientas que el generador de códigos puede usar para generar cadenas de entrada para casos de prueba de las diferentes capas de los sistemas que se generan. Los casos de prueba entran en su propio cuando el sistema ya no se genera y se modifica más adelante en el ciclo de desarrollo.

+0

¿Cuál es el punto de esto? ¿Estás probando si tu libégea lib está funcionando correctamente? ¿O está escribiendo alguna validación alternativa (sin regex) y la expresión regular original es la única especificación de lo que es válido o no? – Qtax

+0

El objetivo principal es generar pruebas que verifiquen la lógica de validación generada por el generador de código. Entonces, cuando el generador de códigos ya no se usa y el desarrollador cambia la lógica de validación, una prueba puede fallar, lo que indica que puede haber una regresión. Las pruebas no suponen que se utiliza una expresión regular para la validación. – bloudraak

+0

La expresión regular también se puede usar en diferentes capas del sistema, como javascript discreto en el navegador, aplicación de escritorio (WPF), PowerShell Cmdlets, ASP.NET MVC Models y servicios WCF. El generador de códigos genera pruebas que verifican que cada uno realiza la validación antes de enviar los datos al sistema remoto. – bloudraak

Respuesta

1

Si entiendo su pregunta correctamente, quiere generar entradas para el sistema basadas en la expresión regular de validación para que pueda automatizar las pruebas de la unidad.

Sin embargo, ¿esto no acaba con el propósito de las pruebas unitarias? Si alguien cambia la expresión regular, ¿no le gustaría que fallara la validación?

En cualquier caso, la respuesta simple es que generar una cadena de una expresión regular es casi imposible. Si pudiera hacerse, sería extremadamente complejo.Por ejemplo, considere esta expresión regular:

(?<=\G\d{0,3})(?>[a-z]+)(?<=(?<foo>foo)|)(?(foo)(?!)) 

Es muy simple para mí pensar en una cadena que se correspondería con (y/o generar coincidencias):

abc123def456ghi789jkl123foo456pqr789stu123vwx456yz

El los partidos serían:

  • "abc"
  • "def"
  • "ghi"
  • "jkl"

Pero, ¿cómo habría que generar una cadena de la expresión? No hay un punto de partida claro: se necesita inteligencia extrema (para una computadora) más una pizca de creatividad para encontrar una solución. Algo simple para un humano, pero muy, muy difícil para una computadora. Incluso si se pudiera llegar a un algoritmo informático que generaría una cadena coincidente, que fácilmente podría ser algo como esto:

un

Esto generaría un partido, pero lo hace un mal trabajo de ejercitar la expresión regular El \d{0,3} nunca es realmente probado y \G solo se usa para coincidir con el comienzo de la entrada (en lugar del final de la última coincidencia). (?<=(?<foo>foo)) nunca se prueba (y si lo fuera, daría como resultado una falta de coincidencia).

También sería fácil de generar una cadena que no coincide:

Pero, de nuevo, esto no es realmente poner la expresión regular a prueba.

No conozco la teoría de la computación lo suficiente como para demostrarlo, pero creo que esto cae en el P v NP class of problems. Es relativamente fácil generar una expresión regular para que coincida con una colección de cadenas complejas, pero es difícil generar una colección de cadenas complejas para que coincida con una expresión regular.

+0

En cuanto a las pruebas unitarias, nadie dice que todo debe escribirse manualmente. A menudo uso PEX para generar pruebas unitarias para complementar las que escribí. Asegura una lógica que nunca pensé que estaba cubierta, destaca los efectos secundarios como excepciones no deseadas y, como resultado, mejora la confiabilidad de mi código. Lo mismo ocurre con las expresiones regulares ... – bloudraak

+0

@WernerStrydom - Ok, puedo aceptar eso. – JDB

Cuestiones relacionadas