SlideShare ist ein Scribd-Unternehmen logo
1 von 38
Downloaden Sie, um offline zu lesen
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
Solo tengo algo que decir...
2 / 37
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
Aumenta la cantidad de código a escribir *
Hace que el 'build' sea más lento
etc, etc...
7 / 37
¿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
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=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
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
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
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
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
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
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 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
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
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 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
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
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
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
¿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
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
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
¿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 difícil
Si no estudias y te aplicas... tabla
¡pero no hay de otra!
Salvo vivir en la incertidumbre...
35 / 37
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
¡Happy Testing!
Agustín Ramos
@MachinesAreUs
37 / 37
Pairwise and property based testing

Weitere ähnliche Inhalte

Was ist angesagt?

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc X
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en AndroidDroidcon Spain
 
Estructuras de control try catch
Estructuras de control try catchEstructuras de control try catch
Estructuras de control try catchjbersosa
 
Las excepciones standar
Las excepciones standarLas excepciones standar
Las excepciones standarjbersosa
 
Uso de Excepciones en JAVA
Uso de Excepciones en JAVAUso de Excepciones en JAVA
Uso de Excepciones en JAVAinnovalabcun
 
Workshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsWorkshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsVisual Engineering
 
Mas sobre excepciones
Mas sobre excepcionesMas sobre excepciones
Mas sobre excepcionesjbersosa
 
Programación Reactiva con RxJava
Programación Reactiva con RxJavaProgramación Reactiva con RxJava
Programación Reactiva con RxJavaParadigma Digital
 
Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013dayaorte
 
3 java sesin 3 pps
3 java sesin 3 pps3 java sesin 3 pps
3 java sesin 3 ppsajplbe
 
SCJP, Clase 4: Operadores
SCJP, Clase 4: OperadoresSCJP, Clase 4: Operadores
SCJP, Clase 4: Operadoresflekoso
 
SMA1011_BUBAL_Tipos de comportamiento
SMA1011_BUBAL_Tipos de comportamientoSMA1011_BUBAL_Tipos de comportamiento
SMA1011_BUBAL_Tipos de comportamientoxoanGz
 
SCJP, Clase 5: Control de Flujo
SCJP, Clase 5: Control de FlujoSCJP, Clase 5: Control de Flujo
SCJP, Clase 5: Control de Flujoflekoso
 
Tipos De Comportamiento
Tipos De ComportamientoTipos De Comportamiento
Tipos De ComportamientoSegaAlex
 
Mecanismos de exclusion mutua y algoritmos
Mecanismos de exclusion mutua y algoritmosMecanismos de exclusion mutua y algoritmos
Mecanismos de exclusion mutua y algoritmosAbimael hernandez
 

Was ist angesagt? (19)

Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unit
 
Programación Reactiva en Android
Programación Reactiva en AndroidProgramación Reactiva en Android
Programación Reactiva en Android
 
Estructuras de control try catch
Estructuras de control try catchEstructuras de control try catch
Estructuras de control try catch
 
Sincronizacion
SincronizacionSincronizacion
Sincronizacion
 
Las excepciones standar
Las excepciones standarLas excepciones standar
Las excepciones standar
 
Uso de Excepciones en JAVA
Uso de Excepciones en JAVAUso de Excepciones en JAVA
Uso de Excepciones en JAVA
 
Workshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operatorsWorkshop iOS 4: Closures, generics & operators
Workshop iOS 4: Closures, generics & operators
 
Mas sobre excepciones
Mas sobre excepcionesMas sobre excepciones
Mas sobre excepciones
 
Programación Reactiva con RxJava
Programación Reactiva con RxJavaProgramación Reactiva con RxJava
Programación Reactiva con RxJava
 
Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013
 
5.manejo de excepciones
5.manejo de excepciones5.manejo de excepciones
5.manejo de excepciones
 
3 java sesin 3 pps
3 java sesin 3 pps3 java sesin 3 pps
3 java sesin 3 pps
 
SCJP, Clase 4: Operadores
SCJP, Clase 4: OperadoresSCJP, Clase 4: Operadores
SCJP, Clase 4: Operadores
 
Chap 15bpin
Chap 15bpinChap 15bpin
Chap 15bpin
 
SMA1011_BUBAL_Tipos de comportamiento
SMA1011_BUBAL_Tipos de comportamientoSMA1011_BUBAL_Tipos de comportamiento
SMA1011_BUBAL_Tipos de comportamiento
 
SCJP, Clase 5: Control de Flujo
SCJP, Clase 5: Control de FlujoSCJP, Clase 5: Control de Flujo
SCJP, Clase 5: Control de Flujo
 
Tipos De Comportamiento
Tipos De ComportamientoTipos De Comportamiento
Tipos De Comportamiento
 
Mecanismos de exclusion mutua y algoritmos
Mecanismos de exclusion mutua y algoritmosMecanismos de exclusion mutua y algoritmos
Mecanismos de exclusion mutua y algoritmos
 
Javaintroduccion 2010
Javaintroduccion 2010Javaintroduccion 2010
Javaintroduccion 2010
 

Ähnlich wie Pairwise and property based testing

Junit y Jmock
Junit y JmockJunit y Jmock
Junit y Jmockkaolong
 
¿En qué la estamos regando en pruebas de software?
¿En qué la estamos regando en pruebas de software?¿En qué la estamos regando en pruebas de software?
¿En qué la estamos regando en pruebas de software?Agustin Ramos
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - TrovitJordi Gerona
 
U7.resumen.ANALISIS DE LOS ALGORITMOS
U7.resumen.ANALISIS DE LOS ALGORITMOSU7.resumen.ANALISIS DE LOS ALGORITMOS
U7.resumen.ANALISIS DE LOS ALGORITMOSLuiS YmAY
 
Tema 9 pruebas unitarias por gio
Tema 9   pruebas unitarias por gioTema 9   pruebas unitarias por gio
Tema 9 pruebas unitarias por gioRobert Wolf
 
Actividad 14_ Diseño de Algoritmos Paralelos.pdf
Actividad 14_ Diseño de Algoritmos Paralelos.pdfActividad 14_ Diseño de Algoritmos Paralelos.pdf
Actividad 14_ Diseño de Algoritmos Paralelos.pdfalejandrogomezescoto
 
Manuales ...
Manuales ...Manuales ...
Manuales ...elidetjc
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUGJordi Gerona
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAVíctor Bolinches
 
Testing efectivo con pytest
Testing efectivo con pytestTesting efectivo con pytest
Testing efectivo con pytestHector Canto
 
métodos procedimimientos estructuras de control java
métodos procedimimientos estructuras de control javamétodos procedimimientos estructuras de control java
métodos procedimimientos estructuras de control javaHenry Upla
 
Ingenieria de sw Junit
Ingenieria de sw JunitIngenieria de sw Junit
Ingenieria de sw Junitpattyand89
 
Sentencia if else
Sentencia if elseSentencia if else
Sentencia if elseUVM
 
Clase5 controldeflujo
Clase5 controldeflujoClase5 controldeflujo
Clase5 controldeflujojorg_marq
 

Ähnlich wie Pairwise and property based testing (20)

Junit y Jmock
Junit y JmockJunit y Jmock
Junit y Jmock
 
¿En qué la estamos regando en pruebas de software?
¿En qué la estamos regando en pruebas de software?¿En qué la estamos regando en pruebas de software?
¿En qué la estamos regando en pruebas de software?
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - Trovit
 
U7.resumen.ANALISIS DE LOS ALGORITMOS
U7.resumen.ANALISIS DE LOS ALGORITMOSU7.resumen.ANALISIS DE LOS ALGORITMOS
U7.resumen.ANALISIS DE LOS ALGORITMOS
 
Tema 9 pruebas unitarias por gio
Tema 9   pruebas unitarias por gioTema 9   pruebas unitarias por gio
Tema 9 pruebas unitarias por gio
 
Actividad 14_ Diseño de Algoritmos Paralelos.pdf
Actividad 14_ Diseño de Algoritmos Paralelos.pdfActividad 14_ Diseño de Algoritmos Paralelos.pdf
Actividad 14_ Diseño de Algoritmos Paralelos.pdf
 
Manuales ...
Manuales ...Manuales ...
Manuales ...
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUG
 
Qunit CookBook español
Qunit CookBook españolQunit CookBook español
Qunit CookBook español
 
2ª unidad de algoritmo
2ª unidad de algoritmo2ª unidad de algoritmo
2ª unidad de algoritmo
 
Concurrencia en Java
Concurrencia en Java Concurrencia en Java
Concurrencia en Java
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
 
Testing efectivo con pytest
Testing efectivo con pytestTesting efectivo con pytest
Testing efectivo con pytest
 
Java básico
Java  básicoJava  básico
Java básico
 
Ejercicios3
Ejercicios3Ejercicios3
Ejercicios3
 
Javascript
JavascriptJavascript
Javascript
 
métodos procedimimientos estructuras de control java
métodos procedimimientos estructuras de control javamétodos procedimimientos estructuras de control java
métodos procedimimientos estructuras de control java
 
Ingenieria de sw Junit
Ingenieria de sw JunitIngenieria de sw Junit
Ingenieria de sw Junit
 
Sentencia if else
Sentencia if elseSentencia if else
Sentencia if else
 
Clase5 controldeflujo
Clase5 controldeflujoClase5 controldeflujo
Clase5 controldeflujo
 

Mehr von Agustin Ramos

Exploring Elixir Codebases with Archeometer
Exploring Elixir Codebases with ArcheometerExploring Elixir Codebases with Archeometer
Exploring Elixir Codebases with ArcheometerAgustin Ramos
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017Agustin Ramos
 
Programación funcional con haskell
Programación funcional con haskellProgramación funcional con haskell
Programación funcional con haskellAgustin Ramos
 
Técnicas basadas en matriz de estructura de diseño
Técnicas basadas en matriz de estructura de diseñoTécnicas basadas en matriz de estructura de diseño
Técnicas basadas en matriz de estructura de diseñoAgustin Ramos
 
Acercándose a la entrega continua
Acercándose a la entrega continuaAcercándose a la entrega continua
Acercándose a la entrega continuaAgustin Ramos
 
Modelos de paralelismo y concurrencia
Modelos de paralelismo y concurrenciaModelos de paralelismo y concurrencia
Modelos de paralelismo y concurrenciaAgustin Ramos
 
Arquitecturas que crecen y arquitecturas que no
Arquitecturas que crecen y arquitecturas que noArquitecturas que crecen y arquitecturas que no
Arquitecturas que crecen y arquitecturas que noAgustin Ramos
 
Arqueología de software
Arqueología de softwareArqueología de software
Arqueología de softwareAgustin Ramos
 
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)Agustin Ramos
 
BDD - Desarrollo dirigido por comportamiento
BDD - Desarrollo dirigido por comportamientoBDD - Desarrollo dirigido por comportamiento
BDD - Desarrollo dirigido por comportamientoAgustin Ramos
 
La nueva imagen del gurú - El maestro artesano dentro del ingeniero
La nueva imagen del gurú - El maestro artesano dentro del ingenieroLa nueva imagen del gurú - El maestro artesano dentro del ingeniero
La nueva imagen del gurú - El maestro artesano dentro del ingenieroAgustin Ramos
 
Modularización efectiva - domando a la hidra
Modularización efectiva - domando a la hidraModularización efectiva - domando a la hidra
Modularización efectiva - domando a la hidraAgustin Ramos
 

Mehr von Agustin Ramos (13)

Exploring Elixir Codebases with Archeometer
Exploring Elixir Codebases with ArcheometerExploring Elixir Codebases with Archeometer
Exploring Elixir Codebases with Archeometer
 
From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017From Elixir to Akka (and back) - ElixirConf Mx 2017
From Elixir to Akka (and back) - ElixirConf Mx 2017
 
Programación funcional con haskell
Programación funcional con haskellProgramación funcional con haskell
Programación funcional con haskell
 
Técnicas basadas en matriz de estructura de diseño
Técnicas basadas en matriz de estructura de diseñoTécnicas basadas en matriz de estructura de diseño
Técnicas basadas en matriz de estructura de diseño
 
Acercándose a la entrega continua
Acercándose a la entrega continuaAcercándose a la entrega continua
Acercándose a la entrega continua
 
Modelos de paralelismo y concurrencia
Modelos de paralelismo y concurrenciaModelos de paralelismo y concurrencia
Modelos de paralelismo y concurrencia
 
Arquitecturas que crecen y arquitecturas que no
Arquitecturas que crecen y arquitecturas que noArquitecturas que crecen y arquitecturas que no
Arquitecturas que crecen y arquitecturas que no
 
Arqueología de software
Arqueología de softwareArqueología de software
Arqueología de software
 
Hola OSGi
Hola OSGiHola OSGi
Hola OSGi
 
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)
Desarrollo Dirigido por Comportamiento (con Cucumber y Groovy)
 
BDD - Desarrollo dirigido por comportamiento
BDD - Desarrollo dirigido por comportamientoBDD - Desarrollo dirigido por comportamiento
BDD - Desarrollo dirigido por comportamiento
 
La nueva imagen del gurú - El maestro artesano dentro del ingeniero
La nueva imagen del gurú - El maestro artesano dentro del ingenieroLa nueva imagen del gurú - El maestro artesano dentro del ingeniero
La nueva imagen del gurú - El maestro artesano dentro del ingeniero
 
Modularización efectiva - domando a la hidra
Modularización efectiva - domando a la hidraModularización efectiva - domando a la hidra
Modularización efectiva - domando a la hidra
 

Pairwise and property based testing