Full text
Generaci´on Autom´atica de Or´aculos de Prueba para APIs RESTful* Juan C. Alonso, Sergio Segura, and Antonio Ruiz-Cort´es Unidad de Excelencia Smart Computer Systems Research and Engineering (SCORE) Intituto de Investigaci´on en Ingenier´ıa Inform´atica (I3US) Universidad de Sevilla, Espa˜na {javalenzuela, sergiosegura, aruiz}@us.es Resumen Las APIs web basadas en el estilo arquitect´onico REST (conocidas como APIs RESTful) se han convertido en el est´andar de-facto para la integraci´on web. Dada su popularidad y difusi´on, en los ´ultimos a˜nos han proliferado gran cantidad de herramientas para la generaci´on autom´atica de casos de prueba para este tipo de APIs. Sin embargo, todas las herramientas est´an limitadas por el tipo de errores que son capaces de detectar: fallos inesperados (i.e., respuestas con c´odigo 5XX) y errores de conformidad con la especificaci´on. En este art´ıculo, describimos nuestro trabajo en progreso para la generaci´on autom´atica de or´aculos de prueba para APIs RESTful. El objetivo es poder detectar errores de forma autom´atica mediante el aprendizaje de invariantes potenciales a partir de un conjunto de llamadas y respuestas a la API. Una evaluaci´on inicial muestra la efectividad de nuestra propuesta para detectar cientos de or´aculos en sistemas reales, detectando errores replicables en las APIs de GitHub y OMDb. Keywords: API RESTful ·Pruebas autom´aticas ·Problema del or´aculo 1. Introducci´on Las APIs RESTful, basadas en el estilo arquitect´onico REST (REpresentational State Transfer), se han convertido en el elemento central de la integraci´on web, permitiendo la interacci´on entre distintas aplicaciones mediante el intercambio de mensajes en formato JSON o XML usando HTTP. En la actualidad, existen una gran cantidad de frameworks destinados a la generaci´on autom´atica de pruebas para APIs RESTful a partir de una especificaci´on OAS del sistema [4], el est´andar actual para describir la funcionalidad de una API. Esta especificaci´on contiene informaci´on sobre las operaciones de una API, los par´ametros *Este proyecto ha sido parcialmente financiado por la Comisi´on Europea (FEDER), la Junta de Andaluc´ıa bajo los proyectos APOLO (US-1264651) y EKIPMENT-PLUS (P18-FR-2895), el Gobierno de Espa˜na (FEDER/Ministerio de Ciencia e Innovaci´on – Agencia Estatal de Investigaci´on) bajo el proyecto HORATIO (RTI2018-101204- B-C21) y la red de excelencia SEBASENet 2.0 (RED2018-102472-T).
2 Alonso et al. que recibe y los tipos de respuesta que puede devolver. La mayor´ıa de estas propuestas solo pueden detectar errores muy espec´ıficos, como errores de conformidad con la especificaci´on (por ejemplo, que un campo de la respuesta de tipo num´erico sea un string) o respuestas que devuelven un error del servidor. Determinar si la respuesta devuelta por una API es correcta o no constituye un desaf´ıo, ya que en la mayor´ıa de las ocasiones no es posible conocer su salida esperada, esto es lo que se conoce como el problema del or´aculo [1]. Es posible definir or´aculos propios del comportamiento esperado de una API, pero estos son espec´ıficos del dominio de la API y requieren de trabajo manual. Por ejemplo, si realizamos una b´usqueda de canciones en la API de Spotify estableciendo un n´umero m´aximo de resultados, el array de canciones de respuesta debe tener un tama˜no igual o menor al valor del n´umero m´aximo de resultados. Un invariante es una propiedad que se cumple en un punto o en una serie de puntos de la ejecuci´on de un programa, como pueden ser sus entradas y sus salidas en el contexto de pruebas de caja negra. Actualmente existen diversos sistemas para la detecci´on autom´atica de invariantes potenciales, siendo Daikon [2] uno de los m´as populares. Daikon detecta la existencia de invariantes potenciales mediante la instrumentalizaci´on del programa que se est´a ejecutando, dicha instrumentalizaci´on se lleva a cabo mediante un instrumenter que convierte la estructura del programa a un formato que pueda ser procesable por Daikon. Existen instrumenters de Daikon para diversos formatos y lenguajes de programaci´on, entre los que se encuentran Java, Perl, C++ y archivos csv. Daikon es una implementaci´on de detecci´on autom´atica de invariantes potenciales, una t´ecnica de machine learning que puede ser aplicada sobre distintos tipos de datos. En concreto, Daikon observa las propiedades de un programa en varias ejecuciones y devuelve aquellas propiedades (invariantes potenciales) que se han cumplido en todas las ejecuciones. En este art´ıculo, proponemos un m´etodo para la generaci´on autom´atica de or´aculos de prueba para APIs RESTful a partir de un conjunto de llamadas v´alidas, modelando la generaci´on autom´atica de or´aculos como un problema de detecci´on de invariantes potenciales. Para ello, hemos creado un instrumenter que permite expresar la especificaci´on OAS de una API y un conjunto de casos de prueba como entradas para Daikon. Una evaluaci´on preliminar con 8 operaciones de 6 APIs industriales muestra la capacidad de nuestra propuesta para la generaci´on autom´atica de or´aculos, obteniendo una precisi´on total del 65.1 % y detectando errores e inconsistencias en sistemas reales como GitHub y OMDb. 2. Propuesta En esta secci´on presentamos el m´etodo propuesto para la generaci´on autom´atica de or´aculos en el contexto de APIs RESTful a partir de una especificaci´on OAS y un conjunto de pruebas, donde cada prueba contiene los valores de los par´ametros usados y el cuerpo de la respuesta devuelta por la API. En primer lugar, el instrumenter de Daikon desarrollado recibe estos dos ficheros para generar un archivo decls (describe el formato del programa, en este caso las entradas y salidas) y un archivo dtrace (valores asignados a cada campo del
Generaci´on Autom´atica de Or´aculos de Prueba para APIs RESTful 3 archivo decls en cada prueba), que son empleados como entradas para una ver- si´on modificada de Daikon que devuelve un conjunto de invariantes potenciales que se han cumplido en todas las pruebas usadas como input y que pueden ser utilizados como or´aculos. En concreto, hemos modificado Daikon a˜nadiendo un total de 22 invariantes nuevos propios del dominio de las APIs RESTful y suprimiendo 26 invariantes que no revelar´ıan informaci´on relevante sobre el funcionamiento de la API y probablemente resultar´ıan en la aparici´on de falsos positivos. Por ejemplo, hemos suprimido, entre otros, los invariantes que realizan comparaciones aritm´eticas entre las longitudes de las propiedades de tipo string, e.g., length(return.countryCode)<length(return.href). En total, esta versi´on de Daikon soporta un total de 139 invariantes, que pueden clasificarse dentro de varias categor´ıas: Relaciones aritm´eticas: Indican comparaciones del valor de las propiedades de tipo num´erico. Por ejemplo, al realizar una b´usqueda de ´albumes en Spotify, el n´umero de track de una canci´on debe ser mayor o igual que 1 (return.track number >= 1). Propiedades de arrays: Indican que un array cumple con determinadas caracter´ısticas. Por ejemplo, al buscar hoteles por id en Amadeus, el id de cada hotel devuelto debe encontrarse dentro del array de ids que se utiliza como par´ametro de entrada (return.hotelId in input.hotelIds[]). Asimismo, el tama˜no de la propiedad de tipo array que contiene los resultados (data) debe ser menor o igual que el tama˜no de la lista de ids que se ha usado como par´ametro (size(input.hotelIds[]) >= size(return.data[])). Valores espec´ıficos: Indican que una propiedad siempre tiene un valor o conjunto de valores fijos. Por ejemplo, en la API de GitHub, un repositorio puede ser p´ublico o privado (return.visibility one of {"private", "public"}). Formatos espec´ıficos: Indican que un campo de tipo string siempre sigue un formato concreto, como URLs, fechas o emails. Por ejemplo, el campo Poster de OMDb siempre debe ser de tipo URL (return.Poster is Url). 3. Evaluaci´on preliminar Para la evaluaci´on, se han seleccionado un total de 8 operaciones de 6 APIs industriales. Para cada una de estas operaciones, se han generado autom´aticamente 50 llamadas v´alidas (C´odigos 2XX) utilizando para ello el framework de generaci´on autom´atica de pruebas de caja negra RESTest [3]. Estas llamadas as´ı como las respuestas correspondientes han sido utilizadas como entradas para nuestro instrumenter de Daikon, resultando en un conjunto de invariantes potenciales (or´aculos) para cada operaci´on. Los invariantes generados son clasificados manualmente como verdaderos positivos, falsos positivos o como invariantes que revelan la existencia de una inconsistencia o un bug. Los resultados de esta evaluaci´on (Tabla 1) muestran la capacidad de la propuesta para la generaci´on autom´atica de or´aculos en sistemas
4 Alonso et al. reales de gran complejidad, obteniendo una precisi´on total del 65.1 % y detectando errores e inconsistencias en la documentaci´on e implementaci´on de sistemas reales con millones de usuarios como GitHub y OMDb. API Operaci´on # Or´aculos Precisi´on ( %) TP FP Inconsistencia/Bug Amadeus Hotel Find hotel offers 93 60.2 56 37 0 GitHub List organization repositories 106 70.1 68 29 9 OMDb By ID or Title 20 70 14 6 0 OMDb By Search 7 100 5 0 2 Spotify Create Playlist 28 100 28 0 0 Spotify Get Album tracks 51 76.5 39 12 0 Yelp Search businesses 25 32 8 17 0 YouTube List videos 171 59.1 101 70 0 Total 501 65.1 319 171 11 Tabla 1. Or´aculos generados. TP=Verdaderos Positivos, FP=Falsos Positivos En la API de GitHub, nuestra propuesta detect´o autom´aticamente que uno de los campos de la respuesta, template repository, no estaba presente en ninguno de los repositorios devueltos, aunque estos tuviesen un template repository. Este error ha sido confirmado por los desarrolladores de la API, que han creado una issue interna para actualizar la documentaci´on. Seg´un su documentaci´on oficial, la operaci´on ”By Search”de la API de OMDb permite buscar t´ıtulos filtrando por tipo (“movie”, “series” o “episode”). No obstante, nuestra propuesta detect´o no solo que la API nunca devuelve resultados de tipo “episode”, sino que devuelve resultados de un cuarto tipo no contemplado en la documentaci´on (“game”), que adem´as puede usarse como valor del par´ametro usado para filtrar la b´usqueda. 4. Trabajo futuro Nuestro trabajo futuro incluye utilizar los or´aculos generados para la creaci´on autom´atica de assertions que permitan evaluar la validez de las respuestas de una API, adem´as de desarrollar un m´etodo que nos permita priorizar los or´aculos generados y detectar falsos positivos. Referencias 1. Barr, E.T., Harman, M., McMinn, P., Shahbaz, M., Yoo, S.: The oracle problem in software testing: A survey. IEEE transactions on software engineering 41(5), 507–525 (2014) 2. Ernst, M.D., Perkins, J.H., Guo, P.J., McCamant, S., Pacheco, C., Tschantz, M.S., Xiao, C.: The daikon system for dynamic detection of likely invariants. Science of Computer Programming 69(1), 35– 45 (2007). https://doi.org/https://doi.org/10.1016/j.scico.2007.01.015, https://www.sciencedirect.com/science/article/pii/S016764230700161X, special issue on Experimental Software and Toolkits 3. Martin-Lopez, A., Segura, S., Ruiz-Cort´es, A.: RESTest: Black-Box Constraint- Based Testing of RESTful Web APIs. In: International Conference on Service- Oriented Computing. pp. 459–475 (2020) 4. Myeongsoo Kim, Qi Xin, S.S., Orso, A.: Automated Test Generation for REST APIs: No Time to Rest Yet. In: Proceedings of the 31st ACM SIGSOFT International Symposium on Software Testing and Analysis (2022)