La única lógica real está en la sintaxis de consulta para la API externa. No quiero probar si consulta la API, quiero comprobar que la consulta de tal manera que se devuelvan los datos correctos. Por ejemplo, algunos pseudocódigo:
function retrieve_related_data(id)
{
query = "[potentially long, syntactically complex query that
uses param id to get some data]";
results = api_wrapper.query(query);
return results;
}
Un ejemplo más concreto con una API inventada:
function retrieveLifeSupportingObjectsWithinRegion(id)
{
query = "
within region(" + id + ") as r
find objects matching hydration>0 and temp_range has 75
send name, id, relative(position, r)
";
results = astronomicalObjectApiWrapper.query(query);
return results;
}
La consulta está en una sintaxis personalizada para la API y es compleja y hay varias formas de lograr los mismos resultados o resultados similares. El propósito de la función no es obtener datos identificados por, id
sino encontrar un subconjunto de otros datos basados en una relación difusa con los datos identificados por id
eso que también cumple con algunos otros requisitos. Los otros requisitos son siempre los mismos independientemente de, id
pero pueden cambiar con el tiempo a medida que se modifica el sistema. Por ejemplo, si la API de ejemplo agrega soporte para información de gravedad, es posible que queramos cambiar la consulta para usar también la gravedad para refinar los resultados. O tal vez se nos ocurra una forma más eficiente de verificar el rango de temperatura, pero no cambia los resultados.
Lo que quiero probar es que para una entrada dada id
se devuelve el conjunto correcto de datos. Quiero probar esto para que si alguien desordena la consulta de modo que ya no devuelva los datos correctos en función de id
que fallará, pero también quiero que las personas puedan modificar la consulta para refinarla sin necesidad de modificar también la prueba.
Opciones que he considerado:
Podría tropezar la API, pero eso sería demasiado simple (verifique que
id
esté presente en la consulta y luego devuelva un conjunto de datos esperado si es así o un conjunto inesperado si no), demasiado frágil (verifique que la cadena de consulta sea exactamente lo que está en la función), o demasiado complejo (verifique que la consulta utilizada sea sintácticamente correcta y dará como resultado la devolución de los datos correctos).Podría enviar la consulta a la API real, pero los resultados esperados podrían cambiar con el tiempo a medida que cambien los datos en el sistema externo, fuera del control del sistema de prueba.
Podría considerar configurar una instalación de prueba de la API real para controlar los datos que tiene, pero eso es un gran esfuerzo.
Me estoy inclinando hacia el n. ° 2 y estoy haciendo esto más como una prueba de integración que no se ejecuta con frecuencia y viendo con qué frecuencia los cambios en los datos del sistema externo hacen que la prueba se rompa. Creo que eso sería más simple por ahora, pero me pregunto si hay alternativas en las que no estoy pensando o mejores formas de abordar este problema. Cualquier consejo sería apreciado.
fuente
Respuestas:
Puede parecer que validar la respuesta API externa estaríamos probando nuestra función, pero no sería totalmente cierto. De alguna manera, estaríamos probando la API externa y el entorno en el que se ejecuta la API.
Nuestras pruebas deben abordarse para garantizar el comportamiento esperado del código que hemos escrito, no el escrito por terceros.
Hasta cierto punto, tenemos que confiar en la función adecuada de las API y las bibliotecas en las que confiamos. Por ejemplo, generalmente no probamos los componentes del marco que implementamos.
¿Por qué lo digo yo?
¿Qué se probaría aquí? Como dijiste, los datos y su corrección no están bajo nuestro control, por lo que estaríamos restringiendo el éxito de la fase de prueba a un agente externo que no tenemos ningún control. Estas pruebas son candidatas para volverse no deterministas y definitivamente, no queremos este tipo de pruebas en nuestra cartera de proyectos .
Una preocupación diferente es validar el contrato. Me resultaría bastante útil probar un contrato 1 para garantizar que la integración siga funcionando como se esperaba, antes de cualquier lanzamiento o implementación.
¿Qué sucede si la consulta está bien, pero los datos son incorrectos debido a errores en la API? No solo los datos están fuera de nuestro control. La lógica también lo es.
La implementación de pruebas funcionales o pruebas de extremo a extremo puede ayudar aquí. Puede abordar estas pruebas para validar ciertas rutas de ejecución de modo que si las API devuelven datos incorrectos, esto probablemente causará comportamientos y resultados inesperados. Por otro lado, esperaría que la API arroje errores si mis consultas tienen un formato incorrecto.
Sugiero implementar una herramienta para tal propósito. Podría ser tan simple como:
O algo más sofisticado. Por ejemplo, un cliente independiente.
En cualquier caso, la función bajo la pregunta, bien vale dos tipos de pruebas:
Prueba de unidad. Como dijiste, tienes que bloquear la API externa, pero ese es el propósito de las pruebas unitarias. Probar nuestro código aislando las dependencias.
Examen de integración. Verifique que el código no solo envíe la solicitud correcta, sino que maneje adecuadamente el contenido de respuesta, errores, redireccionamientos, etc. Realice pruebas para todos estos casos, pero no pruebe datos .
Nota al margen: su pregunta es similar a -como prueba las declaraciones SQL de la aplicación-?
Preguntas relacionadas :
1: Quizás te interese la respuesta de @ DocBrown sobre este tema
fuente
He visto comprobaciones de unidades que comprueban que la cadena de consulta generada coincide con un valor esperado.
Sin embargo. Esto fue en mi opinión si uso limitado. La sintaxis de la consulta era complicada, posiblemente con errores, por lo que A tenía infinitas posibilidades de verificar y B, incluso si la cadena se generaba "correctamente", se podían devolver resultados inesperados en el entorno en vivo.
Creo que tiene razón al elegir su opción 2. ejecutar pruebas de integración contra la instancia en vivo.
Siempre y cuando no sean destructivos, estas son las primeras pruebas que debe escribir, ya que detectarán, aunque no identificarán la causa de ningún error.
La opción 3 'desplegar una instancia de prueba con datos ficticios' es superior. Pero no afecta su escritura de prueba, ya que puede apuntar las mismas pruebas al servidor de prueba si se convierte en un buen uso del tiempo para implementar una.
fuente
Depende de la API, pero si es posible, vaya a la opción # 3 (instancia de prueba privada).
Rebajar la API (opción n. ° 1) es la peor opción, debido a las razones que mencionó, y seguir esta ruta probablemente hará más daño que bien (mucho tiempo perdido).
Correr contra la API real (opción # 2) hace que las pruebas sean escamosas y poco confiables, y después de algunos falsos positivos, la gente simplemente dejará de usarlas. No solo pueden cambiar los datos, sino que el servicio también puede estar inactivo. En mi opinión, esto es similar a no tener pruebas para las consultas y confiar en las pruebas de integración / sistema para encontrar los problemas. Dicho esto, si los datos de la API rara vez cambian y la API en sí está casi siempre activa, entonces esta podría ser una opción viable. La mayoría de las API no se ajustan a esta descripción.
Eventualmente, todo se reduce a cuán importantes y complejas son estas consultas: si hay más de un puñado y algunas de ellas son lo suficientemente complejas como para que sienta la necesidad de probarlas, invertiría el esfuerzo de configurar una instancia privada para la prueba . Se pagará solo como otras pruebas unitarias.
fuente