Post on 24-Jun-2022
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Uso de propiedades y modelos para laspruebas de sistemas distribuidos basados
en la integración de componentesheterogéneos
Miguel A. Francisco1 Laura M. Castro2
1Interoud Innovation S.L. (Spain) – miguel.francisco@interoud.com
2MADS Group – Dept. Computer Science – University of A Coruña (Spain) –lcastro@udc.es
17 de Septiembre 2013, Madrid
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
VoDKATV
Interoud es una compañía gallega (A Coruña) nacida enMarzo de 2011.Desarrollo de software para entornos IPTV/OTT(hospitality, telcos, etc): middleware, STB y back-end.VoDKATV es el prinicipal producto de Interoud.VoDKATV es un middleware IPTV/OTT que ofrece unaexperiencia interactiva al usuario a través de su televisión,PC o dispositivo móvil (smartphones, tablets, dispositivosAndroid, etc)
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Servicios VoDKATV
VoDKATV ofrece una seriede servicios al usuario:
Videoclub.Canales IPTV.PVR (grabación).Navegación por Internet.Juegos.etc.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Pruebas
Software implementado usando diferentes lenguajes deprogramación: Erlang, Java, C, JavaScript, etc.Las pruebas del software permiten validar el correctofuncionamiento de nuestros sistemas.Sin embargo, muchas veces las pruebas son omitidas.Para muchos programadores, las pruebas son:
Un proceso tediosoAlgo para lo que nunca sobra tiempo
Buscar nuevas técnicas de prueba que puedan paliarestos “inconvenientes”.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Pruebas
Participación en proyectos europeos relacionados con laspruebas del software:
ProTest (2007 - 2011): Property-Based TestingProwess (2012 - 2015): Property-Based Testing for WebServices
El rol de Interoud (anteriormente LambdaStream) esproporcionar casos de estudio reales en donde seapliquen y evalúen las técnicas y aproximaciones paraprobar el software.Las nuevas técnicas están basadas en el uso depropiedades ⇒ Property-Based Testing.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Property-Based Testing (PBT)
Tradicionalmente el código fuente se prueba escribiendocasos de prueba manualmente:
Exampleremove(I: Integer, L: List<Integer>):List<Integer>
Se escriben casos de prueba y se comprueba si elresultado es el correcto:
Caso de prueba lists:delete(I, L)I = 5, L = [5] lists:delete(5, [5]) = []
I = 0, L = [1, 2] lists:delete(0, [1, 2]) = [1, 2]... ...
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Property-Based Testing (PBT)
En Property-Based Testing, las pruebas se especificancomo una serie de propiedades que el software debecumplir.Las propiedades describen los requisitos del sistema aprobar.Los casos de prueba no se escriben manualmente, sinoque existen herramientas que generan casos de prueba apartir de las propiedades.
Exampleremove(I: Integer, L: List<Integer>):List<Integer>
La operación remove borra todas las ocurrencias del entero Ide una lista de enteros L:
∀ {I,L} ∈ {int(), list(int())}, I /∈ remove(I,L)
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
QuickCheck
QuickCheck es una herramienta de Property-BasedTesting, implementada en Erlang, que automatiza lageneración, ejecución y evaluación de casos de prueba.
prop_remove()->?FORALL({I, L}, {int(), list(int())},
not lists:member(I, lists:delete(I, L))).
Caso de prueba lists:delete(I, L) PropiedadI = 0, L = [] lists:delete(0, []) = [] true
I = 0, L = [0, 1] lists:delete(0, [0, 1]) = [1] true... ... ...
I = 1, L = [1,6,1] lists:delete(1, [1, 6, 1]) = [6,1] false
Cuando QuickCheck encuentra un error, intenta obtener elcaso mínimo que provoca el mismo error (shrinking):{1,[1,1]}
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
Test Driven Development consiste en repetir iterativamentelas siguientes fases:
1 Añadir una prueba simple.2 Ejecutar las pruebas y comprobar que falla.3 Implementar funcionalidad hasta pasar las pruebas.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
ExampleImplementar una función string que reemplace lasocurrencias de los elementos entre @ por valores concretos.
lstd_template:string("Hola @nombre@",[{"nombre", "Miguel"}]) = "Hola Miguel"
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
El primer paso consiste en implementar una prueba paradicha función (todavía sin implementación).
Example?assertEqual(
"Hola Miguel",lstd_template:string(
"Hola @nombre@", [{"nombre", "Miguel"}])).
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
A continuación ejecutamos la prueba:
Exampletest: string_test (module ’test’)...*failed*::error:undef
in function lstd_template:string/2called as string("Hola @nombre@",
["nombre","Miguel"])in call from test:’-string_test/0-fun-0-’/1in call from test:string_test/0
===================================================Failed: 1. Skipped: 0. Passed: 0.
error
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
Finalmente implementamos la función para que pase laprueba:
Examplestring(String, Subs) ->
"Hola Miguel".
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
Ejecutamos de nuevo la prueba:
ExampleTest passed.
ok
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
Seguimos añadiendo más pruebas:
Example?assertEqual(
"Hola Miguel",lstd_template:string(
"Hola @nombre@", [{"nombre", "Miguel"}])).
?assertEqual("Hola Laura",lstd_template:string(
"Hola @nombre@", [{"nombre", "Laura"}])).
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development
Ejecutamos las pruebas y refinamos la implementación:
Exampletest: string2_test...*failed*::error:{assertEqual_failed,
[{module,test},{line,15},{expression,
"lstd_template : string (\"Hola @nombre@\" ,[ \"nombre\" , \"Laura\" ] )"},
{expected,"Hola Laura"},{value,"Hola Miguel"}]}
in function test:’-string2_test/0-fun-0-’/1===================================================
Failed: 1. Skipped: 0. Passed: 1.error
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development + Property Based Testing
¿Qué casos de prueba usar?Textos vacíos: ""Textos con @Textos con líneas en blanco: \netc.
Hay demasiados casos límites, incluso para módulossencillos.Usando Property Based Testing, los casos de prueba songenerados automáticamente.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development + Property Based Testing
Exampleprop_string_empty_list() ->
?FORALL(S, string(),S =:= lstd_template:string(S, [])).
Caso de pruebaString = Â/e", Subs = []
String = [], Subs = []String = "U", Subs = []
String = "ðqA", Subs = []...
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Test Driven Development + Property Based Testing
transform requirement into property
test implementation against properties modify implementation
analyze failure[test fail]
[ok]
[bug in specification]
[bug in implementation]
[incorrect specification]
[bug in property]
specify requirement
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Arquitectura de VoDKATV: integraciones
Las integraciones entre componentes se realizamayoritariamente a través de servicios web.
Client
<<component>>
Device
<<component>>
Tablet
<<component>>
HED-STB
<<component>>
PC
Admin
<<component>>
Third-party app
<<component>>
AdminGUI
Backend
<<component>>
Asset-Manager HTTP/XMLJava
Erlang
<<component>>
Third-party app
<<component>>
Third-party app
<<component>>
EPG-serverHTTP/JSON
Core
<<component>>
VoDKATV-server
HTTP/JSON
HTTP/XML
<<component>>
Database
JDBC
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
API de integración
Los componentes provee de una API de integración.Uso de Property Based Testing para probar APIs deintegración.En concreto, uso de máquinas de estado QuickCheck paraespecificar cómo debe funcionar el protocolo decomunicación.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
API de integración
Una API de integración está formada por una serie deoperaciones:
API = {op1,op2, ...,opo}
Cada operación opi :recibe una serie de parámetrosdevuelve un resultadotiene una serie de precondiciones que deben ser válidaspara poder ejecutar la operacióntiene una serie de postcondiciones que deben ser válidasdespués de ejecutar la operación
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Servicios web
Cuando la API de integración es un servicio web, cadaoperación es una URI.
Petición:Método: GET, POST, PUT, HEAD, DELETE.Cabeceras (Accept-Language, Cookie, Date, etc).Parámetros.
Respuesta:Cabeceras (Location, Pragma, Set-Cookie, etc).Cuerpo de la respuesta (XML, JSON).
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Servicios web
Por ejemplo:POST http://<server>:<port>/CreateRoom.do
<?xml version="1.0" encoding="UTF-8" ?><room>
<roomId>ROOM_ID</roomId><description>DESCRIPTION</description>
</room>
GET http://<server>:<port>/FindRoomById.do?roomId=ROOM_ID
GET http://<server>:<port>/FindAllRooms.do
GET http://<server>:<port>/DeleteRoom.do?roomId=ROOM_ID
...
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Pruebas de servicios web
<<component>>
SUT
WS
QuickCheck
State
Machine
<<component>>
<<component>>
WS Connector
HTTP
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
La máquina de estados QuickCheck
-behaviour(eqc_statem)....
% Definir la lista de operacionescommand(S) -> oneof(
[{call, ?MODULE, createRoom, [gen_room()]}] ++[{call, ?MODULE, findRoomById, [gen_roomId()]}] ++[{call, ?MODULE, findAllRooms, []}] ++...
precondition(S, {call, ?MODULE, createRoom, Room})->...% Normalmente true
postcondition(S, {call, ?MODULE, createRoom, Room}, R)->% Chequear postcondición para la operación createRoom
createRoom(Room)->% Invocar GET http://<server>:<port>/CreateRoom.do
findRoomById(RoomId)->% Invocar GET http://<server>:<port>/FindRoomById.do
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
La máquina de estados QuickCheck
QuickCheck genera automáticamente secuencias deoperaciones cumpliendo las precondiciones.QuickCheck ejecuta las secuencias de operaciones,comprobando las postcondiciones para cada operación.
GET http://<server>:<port>/FindAllRooms.doPOST http://<server>:<port>/CreateRoom.do
<?xml version="1.0" encoding="UTF-8" ?><room>
<roomId>A</roomId></room>
GET http://<server>:<port>/FindRoomById.do?roomId=AGET http://<server>:<port>/DeleteRoom.do?roomId=BGET http://<server>:<port>/DeleteRoom.do?roomId=GET http://<server>:<port>/FindAllRooms.doGET http://<server>:<port>/FindAllRooms.doGET http://<server>:<port>/FindRoomById.do?roomId=Ax...
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
La máquina de estados QuickCheck
Generación automática de la máquina de estadosQuickCheck a partir de una descripción del servicio web aprobar.
<<component>>
SUT
WS
QuickCheck
State
Machine
<<component>>
<<component>>
WS Connector
<<component>>
Generator
<<component>>
WSDL + OCL
HTTP
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Pruebas de integración
Los componentes software suelen estar estructurados endiferentes módulos.Las interacciones entre los módulos también deben serprobada.
<<component>>
QuickCheck module
<<component>>
Other component
<<component>>
SUT
<<use>>
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Pruebas de integración
Con Property Based Testing es posible generarsecuencias de operaciones que nos permitan comprobarque se están realizando las llamadas correctas en otrosmódulos.La prueba de integración no requiere el uso delcomponente real integrado: se evitan efectos colaterales.
<<component>>
QuickCheck module
<<component>>
Mock component
<<component>>
SUT
<<use>>
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Conclusiones
El uso de Property Based Testing nos permite probar máscasos de prueba escribiendo menos código de pruebas.El uso de Test Driven Development junto con PropertyBased Testing nos permite aumentar la cobertura denuestras pruebas.Uso de QuickCheck como herramienta de Property BasedTesting.Uso de Erlang como lenguaje de especificación depruebas.
Interoud Pruebas de unidad Pruebas de componente Pruebas de integración Conclusiones
Uso de propiedades y modelos para laspruebas de sistemas distribuidos basados
en la integración de componentesheterogéneos
Miguel A. Francisco1 Laura M. Castro2
1Interoud Innovation S.L. (Spain) – miguel.francisco@interoud.com
2MADS Group – Dept. Computer Science – University of A Coruña (Spain) –lcastro@udc.es
17 de Septiembre 2013, Madrid