Entrega Estable de Productos con Cypress
Fei Han
February 7, 2021
El panel de control de Apache APISIX está diseñado para que los usuarios puedan operar Apache APISIX de la manera más sencilla posible a través de una interfaz frontal. Desde el inicio del proyecto, se han realizado 552 commits y 10 lanzamientos. Con una iteración de producto tan rápida, es importante garantizar la calidad del producto de código abierto. Por esta razón, hemos introducido un módulo de pruebas E2E para asegurar una entrega estable del producto.
¿Qué es E2E Front-End?
E2E, que significa "End to End", puede traducirse como pruebas "de extremo a extremo". Simula el comportamiento del usuario, comenzando con un punto de entrada y ejecutando acciones paso a paso hasta que se completa una tarea. Las pruebas sólidas evitan que los cambios en el código rompan la lógica original.
Por qué Cypress
Utilizamos Taiko, Puppeteer, TestCafe y Cypress para escribir casos de prueba durante el período de investigación de selección, y usamos cada marco de pruebas para escribir casos y experimentar sus características respectivas.
Taiko se caracteriza por su selector inteligente, que puede localizar de manera inteligente los elementos que deseas operar basándose en el contenido del texto y las relaciones de ubicación, y tiene un bajo costo de inicio, por lo que puedes terminar los casos de prueba rápidamente. Sin embargo, no es muy amigable al escribir casos de prueba. Cuando el usuario sale del terminal por error, todos los casos de prueba escritos se pierden, y si deseas ejecutar un caso de prueba completo, necesitas usarlo junto con otros ejecutores de pruebas, lo que sin duda aumenta el costo de aprendizaje para el usuario.
Puppeteer tiene el mejor rendimiento. Sin embargo, las pruebas no son el enfoque principal de Puppeteer. Se utiliza ampliamente para rastreadores web. Nuestro proyecto comenzó con Puppeteer, el marco de pruebas E2E oficial recomendado por ANTD, y después de usarlo por un tiempo, descubrimos que Puppeteer no parecía tan amigable para los desarrolladores que no son del front-end y era difícil involucrar a otros usuarios. Cuando los usuarios escriben casos de prueba, la falta de posicionamiento inteligente de elementos hace que la curva de aprendizaje sea muy alta.
TestCafe es sorprendentemente fácil de instalar, tiene un mecanismo de espera incorporado para que los usuarios no tengan que esperar activamente las interacciones de la página, y admite pruebas concurrentes en múltiples navegadores, lo que es útil para pruebas de compatibilidad en múltiples navegadores. La desventaja es que su proceso de depuración no es tan amigable, y tienes que ejecutar un nuevo caso de uso después de cada cambio en el caso de prueba. Para los desarrolladores, necesitan tener algo de conocimiento básico de sintaxis de Javascript. En segundo lugar, su velocidad de ejecución es relativamente lenta en comparación con otros marcos, especialmente cuando se ejecuta withText() para encontrar elementos.
Después de una comparación exhaustiva, finalmente elegimos Cypress como nuestro marco E2E front-end, enumerando cuatro razones principales:
- Sintaxis simple
La sintaxis utilizada en las pruebas de Cypress es muy simple y fácil de leer y escribir. Con un poco de práctica, puedes dominar la creación de casos de prueba, lo cual es importante para proyectos de código abierto porque permite que la comunidad interesada en casos de prueba E2E participe en la escritura de casos de prueba con un costo de aprendizaje mínimo.
- Depuración fácil
Al depurar casos de prueba, podemos usar el Test Runner de Cypress, que presenta datos multidimensionales que nos permiten identificar rápidamente el problema.
- Muestra el estado de la ejecución del caso de prueba, incluyendo el número de éxitos, fallos y ejecuciones en curso.
- Muestra el tiempo total invertido en la ejecución de todo el conjunto de pruebas.
- Un Selector Playground incorporado para ayudar a localizar elementos.
- Muestra cada paso de ejecución para cada caso de uso y forma una instantánea que puede mostrar información sobre cada paso de ejecución después de que se complete.
- Comunidad activa
Cypress tiene una gran comunidad de usuarios, y siempre hay muchas personas dentro de la comunidad compartiendo sus experiencias e ideas.
Esto es útil cuando se encuentran problemas, y es probable que encuentres problemas que otros han encontrado antes. Además, cuando se solicitan nuevas características, podemos participar en la comunidad discutiendo y agregando características a Cypress que queremos agregar, tal como lo hacemos en la comunidad de APISIX: escuchando a la comunidad y retroalimentándola.
- Documentación clara
La estructura de la documentación de Cypress es más clara y completa. En las primeras etapas de uso, pudimos introducir rápidamente Cypress en nuestro proyecto y escribir nuestro primer caso basado en las pautas de la documentación oficial. Además, hay una gran cantidad de documentación disponible en el sitio de documentación que brinda a los usuarios una buena guía sobre las mejores prácticas.
Cypress y el Panel de Control de APISIX
Actualmente, se han escrito 49 casos de prueba para el Panel de Control de APISIX. Configuramos el CI correspondiente en GitHub Action para asegurar que el código pase antes de cada fusión para garantizar la calidad del código. Compartimos el uso de Cypress en el Panel de Control de APISIX con ustedes refiriéndonos a las mejores prácticas de Cypress y combinándolas con nuestro proyecto.
- Funciones comunes encapsuladas en comandos.
Tomemos el inicio de sesión como ejemplo, el inicio de sesión es una parte esencial para ingresar al sistema, por lo que lo encapsulamos como un comando, de modo que el comando de inicio de sesión pueda ser llamado antes de cada ejecución de caso.
Cypress.Commands.add("login", () => {
cy.request(
"POST",
'http://127.0.0.1/apisix/admin/user/login',
{
username: "user",
password: "user",
}
).then((res) => {
expect(res.body.code).to.equal(0);
localStorage.setItem("token", res.body.data.token);
});
});
beforeEach(() => {
// init login
cy.login();
})
- Extraer el selector y los datos como variables públicas.
Para que sea más intuitivo para el usuario entender el significado del código de prueba, extraemos el selector y los datos como variables públicas.
const data = {
name: 'hmac-auth',
deleteSuccess: 'Delete Plugin Successfully',
};
const domSelector = {
tableCell: '.ant-table-cell',
empty: '.ant-empty-normal',
refresh: '.anticon-reload',
codemirror: '.CodeMirror',
switch: '#disable',
deleteBtn: '.ant-btn-dangerous',
};
- Eliminar cy.wait(someTime)
Usamos cy.wait(someTime) en los primeros días de Cypress, pero descubrimos que cy.wait(someTime) depende demasiado del entorno de red y del rendimiento de la máquina de prueba, lo que puede hacer que los casos de prueba informen errores cuando el entorno de red o el rendimiento de la máquina es deficiente. La práctica recomendada es usarlo en conjunto con cy.intercept() para especificar explícitamente los recursos de red que se deben esperar.
cy.intercept("https://apisix.apache.org/").as("fetchURL");
cy.wait("@fetchURL");
Resumen
Actualmente, el Panel de Control de APISIX ha escrito 49 casos de prueba. En el futuro, continuaremos mejorando la cobertura de E2E front-end, y requeriremos que la comunidad esté de acuerdo en escribir casos de prueba para cada nueva característica o corrección de errores para garantizar la estabilidad del producto.
Bienvenidos a unirse a nosotros para pulir el producto de puerta de enlace de clase mundial.
Dirección del proyecto: https://github.com/apache/apisix-dashboard