Pairwise & Property-Based Testing
Agustín Ramos
@MachinesAreUs
1 / 37
Así que ya te decidiste a hacer pruebas
automatizadas...
Unitarias
De integración
De aceptación / funcionales
De desempeño...
Yarrrr so cool!
3 / 37
Ya te vi
4 / 37
Algún día...
5 / 37
Tú...
6 / 37
¿Qué dificultades te has encontrado al
implementar pruebas?
Toma su tiempo
Requiere el uso de varios frameworks y técnicas...
¿Y qué pasa si no automatizas pruebas?
Para probar una función/método:
Tengo que levantar toda la aplicación/ambiente
Teng...
El problema del testing
9 / 37
Ejemplo 1
¿Cuántos diferentes casos de prueba se necesitan para probar ésta interfaz?
10 / 37
Ejemplo 2
¿Cuántos casos de prueba se necesitan para probar ésta función?
functionpartition(items,left,right){
varpivot=it...
Ejemplo 2
¿Cuántos tipos de prueba se necesitan para probar ésta función?
functionpartition(items,left,right){
varpivot=it...
Ejemplo 2
¿Cuántos tipos de prueba se necesitan para probar ésta función?
Valores en rangos esperados
Valores no esperados...
Ejemplo 2
¿Cuántos rutas de ejecución tiene ésta función?
functionpartition(items,left,right){
varpivot=items[Math.floor((...
Complejidad Ciclomática
Métrica.
Thomas J. McCabe, 1976
Mide el número de rutas de ejecución linealmente independientes de...
Ejemplo 2
¿Cuántos rutas de ejecución tiene ésta función?
functionpartition(items,left,right){
varpivot=items[Math.floor((...
Ojo:
¿Por qué escribir código si no estás seguro
que se debe ejecutar?
17 / 37
Corolario:
Entre menos código escribas y más sencillo
sea, es más fácil saber que funciona
18 / 37
El problema
es la explosión combinatorial
19 / 37
El PExC
20 / 37
... y hay quienes además, quieren seguir
haciéndolo a mano.
21 / 37
Pairwise Testing
22 / 37
Pairwise Testing
Idea central:
Es una técnica de generación de casos de prueba que se basa en la
observación de que la may...
Ejemplo
Tienes que probar un componente web que debe correr en distintos
navegadores (Chrome y Firefox), distintos sistema...
Pairwise testing vs Exhaustive testing
Pairwise Testing in the Real World
25 / 37
Property Based Testing
26 / 37
Property Based Testing
Es una técnica complementaria a unit testing.
La idea es especificar un conjunto de propiedades que...
Quick Check - Ejemplo 1
Vamos a verificar si una función que implementa el reverso de una cadena
cumple ciertas propiedade...
Quick Check - Ejemplo 2
La siguiente máquina de estados acepta todas las cadenas cuyo número de 0
es par.
La función 'deci...
Quick Check - Ejemplo 2
Propiedad 1: decidedebe regresar solo Trueo False.
ghci>quickCheck(s->decides`elem`[True,False])
+...
¿Y Java apá ?
Mira mijo...
Hay varios frameworks
Ninguno me gusta
Pero da un vistazo a
Junit Theories
Quickcheck
Y si eres...
JUnit Theories 1/2
@Theory
publicvoidmultiplyIsInverseOfDivideWithInlineDataPoints(
@Between(first=-100,last=100)intamount...
JUnit Theories 2/2
@Retention(RetentionPolicy.RUNTIME)
@ParametersSuppliedBy(BetweenSupplier.class)
public@interfaceBetwee...
¿Otros lenguajes?
¡Claro!
Google for it!!!
34 / 37
Resúmen
Hacer pruebas es difícil
Si no las haces... tabla
Si no las automatizas... tabla
Hacer buenas pruebas es aún más d...
Más información
Property Based Testing (video by @jessitron)
Pairwise testing (community website)
Combinatorial Software T...
¡Happy Testing!
Agustín Ramos
@MachinesAreUs
37 / 37
Pairwise and property based testing
Próxima SlideShare
Cargando en…5
×

Pairwise and property based testing

305 visualizaciones

Publicado el

Talk given at SGCE 2015:
http://sg.com.mx/sgce/2015/agenda

Source code:
https://github.com/MachinesAreUs/sgce2015_combinatorial_testing

0 comentarios
0 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Sin descargas
Visualizaciones
Visualizaciones totales
305
En SlideShare
0
De insertados
0
Número de insertados
19
Acciones
Compartido
0
Descargas
0
Comentarios
0
Recomendaciones
0
Insertados 0
No insertados

No hay notas en la diapositiva.

Pairwise and property based testing

  1. 1. Pairwise & Property-Based Testing Agustín Ramos @MachinesAreUs 1 / 37
  2. 2. Así que ya te decidiste a hacer pruebas automatizadas... Unitarias De integración De aceptación / funcionales De desempeño Solo tengo algo que decir... 2 / 37
  3. 3. Yarrrr so cool! 3 / 37
  4. 4. Ya te vi 4 / 37
  5. 5. Algún día... 5 / 37
  6. 6. Tú... 6 / 37
  7. 7. ¿Qué dificultades te has encontrado al implementar pruebas? Toma su tiempo Requiere el uso de varios frameworks y técnicas Aumenta la cantidad de código a escribir * Hace que el 'build' sea más lento etc, etc... 7 / 37
  8. 8. ¿Y qué pasa si no automatizas pruebas? Para probar una función/método: Tengo que levantar toda la aplicación/ambiente Tengo que seguir el flujo que me lleva a la llamada a mi función/método Depende de las configuraciones de mi máquina Ahora imagina... lo mismo para todas las funciones del sistema 8 / 37
  9. 9. El problema del testing 9 / 37
  10. 10. Ejemplo 1 ¿Cuántos diferentes casos de prueba se necesitan para probar ésta interfaz? 10 / 37
  11. 11. Ejemplo 2 ¿Cuántos casos de prueba se necesitan para probar ésta función? functionpartition(items,left,right){ varpivot=items[Math.floor((right+left)/2)], i =left, j =right; while(i<=j){ while(items[i]<pivot){i++;} while(items[j]>pivot){j—;} if(i<=j){ swap(items,i,j); i++; j--; } } returni; } Javascript Quicksort 11 / 37
  12. 12. Ejemplo 2 ¿Cuántos tipos de prueba se necesitan para probar ésta función? functionpartition(items,left,right){ varpivot=items[Math.floor((right+left)/2)], i =left, j =right; while(i<=j){ while(items[i]<pivot){i++;} while(items[j]>pivot){j—;} if(i<=j){ swap(items,i,j); i++; j--; } } returni; } 12 / 37
  13. 13. Ejemplo 2 ¿Cuántos tipos de prueba se necesitan para probar ésta función? Valores en rangos esperados Valores no esperados (Indices fuera de rango, nulos) Condiciones de frontera (arreglo vacío, arreglo de tamaño máximo) Valores que ejerciten las distintas rutas de ejecución 13 / 37
  14. 14. Ejemplo 2 ¿Cuántos rutas de ejecución tiene ésta función? functionpartition(items,left,right){ varpivot=items[Math.floor((right+left)/2)], i =left, j =right; while(i<=j){ while(items[i]<pivot){i++;} while(items[j]>pivot){j—;} if(i<=j){ swap(items,i,j); i++; j--; } } returni; } 14 / 37
  15. 15. Complejidad Ciclomática Métrica. Thomas J. McCabe, 1976 Mide el número de rutas de ejecución linealmente independientes dentro de un programa. Aproximador 2^N - 1 N es el número de bifurcaciones en el código (bloques if, where, for, etc.) 15 / 37
  16. 16. Ejemplo 2 ¿Cuántos rutas de ejecución tiene ésta función? functionpartition(items,left,right){ varpivot=items[Math.floor((right+left)/2)], i =left, j =right; * while(i<=j){ * while(items[i]<pivot){i++;} * while(items[j]>pivot){j—;} * if(i<=j){ swap(items,i,j); i++; j--; } } returni; } 2^4 = 16 Necesitas 16 distintos casos de prueba, solo para saber que pasaste por todas las rutas de ejecución posibles 16 / 37
  17. 17. Ojo: ¿Por qué escribir código si no estás seguro que se debe ejecutar? 17 / 37
  18. 18. Corolario: Entre menos código escribas y más sencillo sea, es más fácil saber que funciona 18 / 37
  19. 19. El problema es la explosión combinatorial 19 / 37
  20. 20. El PExC 20 / 37
  21. 21. ... y hay quienes además, quieren seguir haciéndolo a mano. 21 / 37
  22. 22. Pairwise Testing 22 / 37
  23. 23. Pairwise Testing Idea central: Es una técnica de generación de casos de prueba que se basa en la observación de que la mayoría de los defectos (~90%) son causados por interacciones de a lo más dos factores de prueba. Con ésta técnica se generan todas las posibles combinaciones de dos valores distintos para cada factor de prueba y por tanto, las suites de pruebas son mucho más pequeñas que las generadas de manera exhaustiva y aún así son muy efectivas para encontrar defectos. 23 / 37
  24. 24. Ejemplo Tienes que probar un componente web que debe correr en distintos navegadores (Chrome y Firefox), distintos sistemas operativos (OSX, Linux, Windows) y con diferentes capacidades de memoria de video (500Mb y 1Gb). ¿Cuántas posibles configuraciones tienes que probar? Con pairwise testing son 6 Browser OS Video Memory Chrome Windows 500Mb Chrome Linux 1Gb Chrome OSX 1Gb Firefox Windows 1Gb Firefox Linux 500Mb Firefox OSX 500Mb 24 / 37
  25. 25. Pairwise testing vs Exhaustive testing Pairwise Testing in the Real World 25 / 37
  26. 26. Property Based Testing 26 / 37
  27. 27. Property Based Testing Es una técnica complementaria a unit testing. La idea es especificar un conjunto de propiedades que siempre se deben cumplir (invariantes). El framework (QuickCheck) genera un conjunto de ejemplos 'aleatorios' contra los cuales probar si la propiedad se cumple o no. Si encuentra un ejemplo que invalida la propiedad, trata de reducirlo a su mínima expresión. 27 / 37
  28. 28. Quick Check - Ejemplo 1 Vamos a verificar si una función que implementa el reverso de una cadena cumple ciertas propiedades. Propiedad 1: El reverso del reverso de una cadena, es la misma cadena. ghci>quickCheck(s->reverse(reverses)==s) +++OK,passed100tests. Propiedad 2: El reverso de una cadena, tiene la misma longitud que la cadena original. ghci>quickCheck(s->length(reverses)==lengths) +++OK,passed100tests. Propiedad 3: El reverso de una cadena palíndroma, es la misma cadena. ghci>quickCheck(s->isPalindromes==>reverses==s) +++OK,passed100tests. 28 / 37
  29. 29. Quick Check - Ejemplo 2 La siguiente máquina de estados acepta todas las cadenas cuyo número de 0 es par. La función 'decide' decide si el autómata acepta la cadena o no. Ejemplos: decide"00100"==True decide"00110"==False 29 / 37
  30. 30. Quick Check - Ejemplo 2 Propiedad 1: decidedebe regresar solo Trueo False. ghci>quickCheck(s->decides`elem`[True,False]) +++OK,passed100tests. Propiedad 2: decidesólo acepta cadenas con un númpero par de 0's. ghci>quickCheck(s->isEvenZeross==decides) +++OK,passed100tests. Y... ¿si quiero probar 10,000 casos? ghci>letdeepCheckp=quickCheckWith(stdArgs{maxSuccess=10000})p ghci>deepCheck(s->isEvenZeroess==decides) +++OK,passed10000tests. 30 / 37
  31. 31. ¿Y Java apá ? Mira mijo... Hay varios frameworks Ninguno me gusta Pero da un vistazo a Junit Theories Quickcheck Y si eres más atrevido, prueba ScalaCheck 31 / 37
  32. 32. JUnit Theories 1/2 @Theory publicvoidmultiplyIsInverseOfDivideWithInlineDataPoints( @Between(first=-100,last=100)intamount, @Between(first=-100,last=100)intm) { assumeThat(m,not(0)); assertThat(newDollar(amount).times(m).divideBy(m).getAmount(),is(amount)); } 32 / 37
  33. 33. JUnit Theories 2/2 @Retention(RetentionPolicy.RUNTIME) @ParametersSuppliedBy(BetweenSupplier.class) public@interfaceBetween{ intfirst(); intlast(); } publicstaticclassBetweenSupplierextendsParameterSupplier{ @Override publicListgetValues(Objecttest,ParameterSignaturesig){ Betweenannotation=(Between)sig.getSupplierAnnotation(); ArrayListlist=newArrayList(); for(inti=annotation.first();i<=annotation.last();i++) list.add(i); returnlist; } } 33 / 37
  34. 34. ¿Otros lenguajes? ¡Claro! Google for it!!! 34 / 37
  35. 35. Resúmen Hacer pruebas es difícil Si no las haces... tabla Si no las automatizas... tabla Hacer buenas pruebas es aún más difícil Si no estudias y te aplicas... tabla ¡pero no hay de otra! Salvo vivir en la incertidumbre... 35 / 37
  36. 36. Más información Property Based Testing (video by @jessitron) Pairwise testing (community website) Combinatorial Software Testing (article) Better than unit tests (article) Practical Combinatorial Testing (NIST Report) 36 / 37
  37. 37. ¡Happy Testing! Agustín Ramos @MachinesAreUs 37 / 37

×