Pruebas de software: pruebas simuladas

La prueba simulada es el procedimiento de probar el código sin interferencia de las dependencias y diferentes variables, como problemas de red y fluctuaciones de tráfico, aislándolo de los demás. Los objetos dependientes se reemplazan por objetos simulados que simulan el comportamiento de objetos reales y exhiben características auténticas. El lema de las pruebas simuladas es centrarse en las pruebas sin priorizar las dependencias. Aquí, hablaremos de los siguientes temas:

  1. ¿Dónde son útiles las pruebas simuladas?
  2. Ejemplos de pruebas simuladas
  3. ¿Cómo funciona la prueba simulada?
  4. ¿La simulación requiere que los desarrolladores modifiquen su base de código?
  5. Pruebas simuladas frente a pruebas unitarias tradicionales
  6. Tipos de pruebas simuladas
  7. Mejores prácticas para pruebas simuladas
  8. Marcos burlones
  9. Precauciones durante las pruebas simuladas
  10. Ventajas de las pruebas simuladas
  11. Limitaciones de las pruebas simuladas

Comencemos discutiendo cada uno de estos temas en detalle.

¿Dónde son útiles las pruebas simuladas?

Estos son algunos de los escenarios en los que las pruebas simuladas son útiles.

  • Es más útil al realizar pruebas unitarias.
  • Cuando se quiere evitar dependencias externas.
  • Si bien desea acelerar el proceso de prueba con objetos simulados.
  • Si bien es necesario conocer el aspecto anterior de la prueba real. 

Ejemplos de pruebas simuladas

Tomemos un ejemplo de falsificación de llamadas a la API.

  • Supongamos que hay un servicio web y cada vez que se envía un formulario, realiza una solicitud POST para actualizar o almacenar nuevas entradas en el servidor API.
  • Pero no es necesario almacenar datos innecesarios en la base de datos mientras se prueba cada vez. 
  • Con la ayuda de las pruebas simuladas, se puede reemplazar el servicio con un objeto simulado para validar la funcionalidad, de modo que se pueda evitar el almacenamiento de información redundante innecesaria. 

¿Cómo funciona la prueba simulada?

Es un enfoque para las pruebas unitarias que permite la creación de afirmaciones sobre cómo el código detrás de la prueba interactúa con módulos alternativos del sistema. 

  • En las pruebas simuladas, la unidad del área de dependencias se reemplaza con objetos que simulan el comportamiento de los importantes. Se basa en la verificación basada en el comportamiento.
  • El objeto simulado implementa la interfaz del objeto real creando una pseudo. Por lo tanto, se llama simulacro.
  • No se enfoca en todo el código, sino que enfatiza la parte particular del código que se va a probar.
  • El objeto simulado simplemente lee y responde con datos de prueba de un sistema de archivos local.
  • La simulación no requiere ninguna modificación del código base.
  • La clase heredada mientras que la herencia o las dependencias en el caso de los constructores y otros métodos se reemplazan con objetos simulados durante la prueba.
  • A diferencia de las pruebas unitarias tradicionales, la aserción se realiza mediante objetos simulados que se inicializan de antemano con respecto a qué llamadas de método se esperan y cómo deben responder.
  • La simulación se utiliza para las pruebas de protocolo en las que prueba cómo usar la API y cómo reaccionará a la API implementada en consecuencia.

¿La simulación requiere que los desarrolladores modifiquen su base de código?

La simulación no requiere modificar el código base. El objeto simulado simplemente lee y responde con datos de prueba de un sistema de archivos local. 

  • La clase heredada, mientras que la herencia o las dependencias en el caso de los constructores y otros métodos, se reemplazan con objetos simulados durante la prueba.
  • Hay un punto considerable, que si el código usa objetos estáticos o singletons, entonces será difícil realizar pruebas simuladas burlándose de los objetos. En este escenario, es necesario refactorizar el código en consecuencia para que se pueda simular cómodamente.

A diferencia de las pruebas unitarias tradicionales, la afirmación se realiza mediante objetos simulados que se inicializan de antemano con respecto a qué llamadas de método se esperan y cómo deben responder. La simulación se utiliza para las pruebas de protocolo en las que prueba cómo usar la API y cómo reaccionará a la API implementada en consecuencia.

Pruebas simuladas frente a pruebas unitarias tradicionales

A continuación se presentan algunas de las diferencias entre las pruebas simuladas y las pruebas unitarias tradicionales:

prueba simulada

Pruebas unitarias tradicionales

En las pruebas simuladas, las afirmaciones se realizan mediante objetos simulados y no se requieren afirmaciones de las pruebas unitarias. Mientras que en las pruebas unitarias tradicionales, las afirmaciones se realizan para las dependencias.
En las pruebas simuladas, se centra en cómo se puede incorporar y probar el objeto falso/simulado. En las pruebas unitarias tradicionales, se centró en cómo se puede incorporar y probar el objeto real.
Las pruebas simuladas tienen más que ver con la verificación basada en el comportamiento. Las pruebas unitarias tradicionales tienen más que ver con la verificación basada en el estado.

Tipos de pruebas simuladas

  1. Simulacro basado en la reasignación del cargador de clases: en este caso, el cargador de clases reasigna la referencia para que el objeto simulado se cargue en lugar del objeto original.
  2. Simulación basada en proxy: en este caso, se utiliza un objeto proxy en lugar de un objeto proxy original que maneja todas las llamadas a los objetos originales.
  3. Simulación basada en base de datos : en una simulación basada en base de datos, el usuario no realiza la operación real de la base de datos, sino que reemplaza la operación con un objeto simulado para validar la funcionalidad.
  4. Simulación basada en API: en la simulación basada en API, las simulaciones de API se utilizan para simular dependencias externas y comportamientos inesperados. 

Mejores prácticas para pruebas simuladas

  • Evite el uso de dependencias en la infraestructura mientras escribe pruebas unitarias para que pueda reservarse para pruebas de integración.
  • Mantenga las pruebas unitarias en un proyecto separado de las pruebas de integración, lo que garantiza que el proyecto de prueba esté alejado de las referencias en los paquetes de infraestructura.
  • La entrada que se utilizará debe ser la mejor posible para verificar el comportamiento que simplemente mide el comportamiento de las pruebas actuales. Mediante esta prueba, se vuelve más resistente a los cambios que se produzcan en el futuro en el código base.
  • Evite las condiciones lógicas y la concatenación manual de strings al escribir pruebas unitarias para centrarse en los resultados finales y hacerlo menos propenso a errores.
  • Al agrupar objetos o estados similares, se prefiere el método auxiliar para aprovechar los atributos de configuración y desmontaje para evitar confusiones al leer las pruebas. 
  • Los estándares de nomenclatura expresan explícitamente el contenido de la prueba, por lo que el nombre de la prueba debe incorporar 3 partes:
    • Nombre del método que se está probando.
    • El escenario de prueba.
    • El comportamiento esperado una vez invocado.
  • AAA es el mito principal de las pruebas unitarias, es decir, Organizar, Actuar, Afirmar el patrón utilizado en las pruebas unitarias.
    • Organice los objetos, creándolos y configurándolos según sea necesario.
    • Acto sobre asociado en el objeto.
    • Afirmar que según la expectativa.
  • Intente incluir un acto por prueba en lugar de utilizar varios actos al escribir el código de prueba. La creación de una prueba separada para cada acto garantiza que la prueba se centre solo en un solo caso y se pueda saber qué acto ocurre si alguna prueba falla. 

Marcos burlones

Los frameworks de simulación están acostumbrados a generar objetos de reemplazo como Stubs y Mocks. Los marcos simulados complementan los marcos de pruebas unitarias al erradicar las dependencias; sin embargo, no parecen sustituir a los marcos de pruebas unitarias. Al borrar las dependencias, ayudan al método de prueba unitaria y ayudan a los desarrolladores a escribir muchas pruebas unitarias específicas y concisas. Las pruebas simuladas también funcionan más rápido al aislar realmente el sistema debajo de la prueba.
Algunos marcos burlones son:

  1. Uso de EasyMock: es un marco de código abierto que proporciona clases útiles para simular objetos. Crea objetos simulados de clases e interfaces utilizando los métodos importados estáticamente de las extensiones de clase.
  2. Uso de JMock: no se basa en ninguna función de importación estática. Se burla de las interfaces solamente. La biblioteca JMock es fácil de usar y proporciona una mejor integración con Junit5. 
  3. Uso de Mockito: tampoco se basa en funciones de importación estática. Crea objetos simulados a través de anotaciones. Por lo tanto, se utiliza para registrar extensiones para la clase de prueba anotada o el método de prueba.

Precauciones durante las pruebas simuladas

  1. Simular solo el tipo que se acaba de poseer: los tipos externos tienen dependencias por sí mismos, incluso podrían modificar su comportamiento en una etapa posterior. Un mejor enfoque es producir un adaptador asociado y simular ese adaptador.
  2. No se burle de los valores: no se debe burlar de los valores. La burla tiene como objetivo crear las relaciones e interacciones entre los objetos visibles. La obtención de un valor no está asociada a la interacción.
  3. Evite burlarse de categorías concretas: las relaciones se hacen para ver más fácilmente a través de interfaces en lugar de clases concretas. Nos encontraríamos burlándonos de algunos métodos pero olvidando otros. Simulacros de roles, no de objetos.
  4. No te burles de todo: esto a menudo se asocia con antipatrones. Si se burla de todo, es probable que nos encontremos probando algo completamente diferente del sistema de producción.
  5. Use pruebas de integración: una vez que pruebe varios módulos o si tiene curiosidad acerca de la información que proviene de la información externa asociada, se deben realizar pruebas de integración en lugar de simulacros.
  6. Pruebas negativas: los simulacros deben usarse para simular errores y probar el manejo de errores, así como para verificar algunos otros métodos.

Ventajas de las pruebas simuladas

  • Crea una versión falsa de un servicio externo o interno que puede sustituir al real, lo que ayuda a ejecutar las pruebas de manera más rápida y confiable. 
  • Cuando el modelo de implementación interactúa con las propiedades de un objeto, se puede usar un simulacro en lugar de su función o comportamiento.
  • El objeto simulado aísla las dependencias que permiten administrar la prueba en un lapso límite. A partir de esto, se puede identificar si una prueba falla, se debe al código de la unidad y no a las dependencias.
  • La simulación proporciona un alcance limitado en pruebas más cortas y más enfocadas para facilitar la comprensión de las pruebas administradas en un alcance pequeño mediante la simulación de objetos.
  • La prueba simulada es más rápida ya que utiliza bases de datos simuladas, operaciones del sistema de archivos y servicios externos. Además, la prueba se puede comenzar en cualquier momento, ya que no es necesario esperar a que haya otras dependencias, y el aislamiento de fallas acelera el desarrollo.
  • Mientras ejecuta varios usuarios simultáneamente, es aconsejable simular las dependencias para que la prueba sea más eficiente. Las pruebas simuladas no crearán ningún efecto negativo en los servicios de terceros.

Limitaciones de las pruebas simuladas

  • Los simulacros deben comprender correctamente todas las dependencias; de lo contrario, es posible que no representen con precisión el comportamiento del mundo real.
  • El simulacro puede conducir a un acoplamiento estrecho entre los simulacros y el código durante las pruebas. 
  • El uso excesivo de pruebas simuladas puede aumentar los gastos de mantenimiento necesarios para realizar las pruebas.
  • Burlarse de la clase puede obligar a hacer que todo sea virtual, lo que es demasiado instructivo, en última instancia, conduce a un mal diseño de la clase.
  • Si se simulan las clases en lugar de la interfaz, empeora ya que el simulacro tiene una clase real en forma heredada en segundo plano. Por lo tanto, existe la posibilidad de que se ejecute una implementación real mientras se realiza la prueba.
     

Publicación traducida automáticamente

Artículo escrito por Satyabrata_Jena y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *