¡Es una trampa (de pruebas iniciales)! Seis errores comunes en las pruebas y cómo resolverlos

 

 

 

  • SmashingConf Friburgo 2024
  • Clase magistral de CSS moderno avanzado, con Manuel Matuzović

  • Índice
    1. Trampas de prueba de front-end
    2. ¿Por qué deberíamos molestarnos en probar trampas?
    3. La regla de oro
    4. Trampas en el diseño de pruebas
      1. La regla de tres
      2. “Organizar, actuar, afirmar” frente a “dado, cuándo y entonces”
      3. Datos que solíamos compartir
    5. Trampas de implementación
      1. Foo Bar ¿Qué?
      2. Mire los selectores, debe
      3. ¡Espéralo!

    Al escribir pruebas de front-end, encontrará muchos obstáculos en el camino. En resumen, pueden provocar una pésima capacidad de mantenimiento, un tiempo de ejecución lento y, en el peor de los casos, pruebas en las que no se puede confiar. Pero no tiene por qué ser así. En este artículo, hablaré sobre los errores comunes que cometen los desarrolladores, al menos según mi experiencia, y, por supuesto, cómo evitarlos. Después de todo, las pruebas no tienen por qué ser dolorosas.

     

    Mientras volvía a ver una película que me encantaba cuando era niño, se destacó una cita en particular. Es de la película de Star Wars de 1983 “ El retorno del Jedi ”. La frase se dice durante la Batalla de Endor, donde la Alianza moviliza sus fuerzas en un esfuerzo concentrado para destruir la Estrella de la Muerte. Allí, el almirante Ackbar, líder de los rebeldes mon calamari, dice su memorable frase:

    "¡Es una trampa!" — Almirante Akbar (Crédito de la imagen: Ramona Schwering)

    "¡Es una trampa!" Esta línea nos alerta de una emboscada inesperada, de un peligro inminente. Muy bien, pero ¿qué tiene esto que ver con las pruebas? Bueno, es simplemente una alegoría adecuada cuando se trata de pruebas en un código base. Estas trampas pueden parecer una emboscada inesperada cuando trabajas en una base de código, especialmente cuando lo haces durante mucho tiempo.

    En este artículo, te contaré los obstáculos con los que me he topado en mi carrera, algunos de los cuales fueron culpa mía. En este contexto, debo hacer un pequeño descargo de responsabilidad: mi negocio diario está fuertemente influenciado por mi uso del marco Jest para pruebas unitarias y por el marco Cypress para pruebas de un extremo a otro. Haré todo lo posible para mantener mi análisis abstracto, para que puedas utilizar los consejos también con otros marcos. Si encuentra que eso no es posible, comente a continuación para que podamos hablar de ello. Algunos ejemplos podrían incluso ser aplicables a todos los tipos de pruebas, ya sean pruebas unitarias, de integración o de un extremo a otro.

     

    Trampas de prueba de front-end

    Las pruebas, sean del tipo que sean, tienen muchos beneficios. Las pruebas de front-end son un conjunto de prácticas para probar la interfaz de usuario de una aplicación web. Probamos su funcionalidad poniendo su interfaz de usuario bajo estrés permanente. Dependiendo del tipo de prueba, podemos lograrlo de varias maneras y en varios niveles:

    • Las pruebas unitarias analizan las unidades menores en sus aplicaciones. Estas unidades pueden ser clases, interfaces o métodos. Las pruebas verifican si dan el resultado esperado, utilizando entradas predefinidas; por lo tanto, prueban unidades por separado y de forma aislada.
    • Las pruebas de integración tienen un alcance más amplio. Prueban unidades de código juntas, observando su interacción.
    • Las pruebas de un extremo a otro prueban la aplicación, como lo haría un usuario real. Por lo tanto, se parece a las pruebas de sistemas si analizamos el aseguramiento de la calidad en teoría.

    En conjunto, hacer todo esto puede darnos mucha confianza a la hora de enviar nuestra aplicación: las pruebas de front-end garantizan que las personas interactuarán con la interfaz de usuario como deseamos. Desde otra perspectiva, al utilizar estas prácticas, podemos garantizar lanzamientos sin errores de una aplicación sin muchas pruebas manuales, que consumen recursos y energía.

    Sin embargo, este valor puede verse eclipsado porque muchos puntos débiles tienen varias causas. Muchas de ellas podrían considerarse “trampas”. Imagínese hacer algo con la mejor de las intenciones, pero que termine siendo doloroso y agotador: este es el peor tipo de deuda técnica.

    ¿Por qué deberíamos molestarnos en probar trampas?

    Cuando pienso en las causas y efectos de las trampas de las pruebas de front-end en las que he caído, me vienen a la mente ciertos problemas. Tres causas en particular vuelven a mí una y otra vez, derivadas del código heredado que escribí hace años.

    1. Pruebas lentas, o al menos ejecución lenta de pruebas.
      Cuando se desarrolla localmente, los desarrolladores tienden a impacientarse con las pruebas, especialmente si alguien de su equipo necesita fusionar las solicitudes de extracción correspondientes. En cualquier caso, los largos tiempos de espera resultan abrumadoramente molestos. Esta trampa puede surgir por muchas causas menores, por ejemplo, no prestar mucha atención a los tiempos de espera adecuados o al alcance de una prueba.
    2. Pruebas difíciles de mantener.
      Este segundo punto débil es aún más crítico y una causa más importante de pruebas abandonadas. Por ejemplo, es posible que regreses a una prueba meses después y no comprendas en absoluto su contenido o su intención. O los miembros del equipo podrían preguntarle qué quería lograr con una prueba anterior que usted escribió. En general, demasiadas clases o abstracciones esparcidas por las paredes de texto o código pueden acabar rápidamente con la motivación de un desarrollador y conducir a un caos total. Las trampas en esta área pueden deberse a seguir mejores prácticas que no son adecuadas para las pruebas.
    3. Pruebas que no le dan ningún valor consistente.
      A estos se les puede llamar Heisenfails o Heisentests, como el famoso Heisenbug, que sólo ocurre si miras hacia otro lado, no lo mides o, en nuestro caso, no lo depuras. El peor de los casos es una prueba inestable , una prueba no determinante que no logra ofrecer el mismo resultado entre compilaciones sin ningún cambio. Esto puede ocurrir por varias razones, pero generalmente sucede cuando se intenta tomar un atajo fácil y aparentemente conveniente, sin tener en cuenta las mejores prácticas de prueba.

    Pero no te preocupes demasiado por mis propias experiencias. ¡Probar y manejar pruebas puede ser divertido! Sólo necesitamos estar atentos a algunas cosas para evitar un resultado doloroso. Por supuesto, lo mejor es, en primer lugar, evitar trampas en nuestros diseños de prueba. Pero si el daño ya está hecho, la mejor opción es refactorizar una base de prueba.

     

    La regla de oro

    Supongamos que está trabajando en un trabajo apasionante pero exigente. Estás concentrado en ello por completo. Su cerebro está lleno de código de producción, sin espacio para ninguna complejidad adicional, especialmente para las pruebas. Ocupar mucho espacio de cabeza va totalmente en contra del propósito de las pruebas. En el peor de los casos, las pruebas que parecen una carga son una razón por la que muchos equipos las abandonan.

    En su guía " Mejores prácticas de pruebas de JavaScript ", Yoni Goldberg articula la regla de oro para evitar que las pruebas se sientan como una carga: una prueba debe sentirse como un asistente amigable, ahí para ayudarlo, y nunca debe sentirse como un obstáculo.

    Estoy de acuerdo. Esto es lo más crucial en las pruebas. Pero, ¿cómo logramos esto exactamente? Ligera alerta de spoiler: la mayoría de mis ejemplos ilustrarán esto. El principio KISS (mantenlo simple, estúpido) es clave. Cualquier prueba, sin importar el tipo, debe diseñarse simple y llanamente.

    Entonces, ¿qué es una prueba simple y llanamente? ¿Cómo sabrá si su prueba es lo suficientemente simple? No complicar tus pruebas es de suma importancia. El objetivo principal lo resume perfectamente Yoni Goldberg:

    "Uno debería mirar una prueba y captar la intención al instante".

    Por tanto, el diseño de una prueba debe ser plano. Minimalista lo describe mejor. Una prueba no debe tener mucha lógica y pocas o ninguna abstracción. Esto también significa que debe tener cuidado con los objetos y comandos de la página, y debe nombrar y documentar los comandos de manera significativa. Si tiene intención de utilizarlos, preste atención a los comandos, funciones y nombres de clases indicativos. De esta manera, una prueba seguirá siendo una delicia tanto para los desarrolladores como para los evaluadores.

     

    Mi principio de prueba favorito se relaciona con la duplicación, el principio SECO: no te repitas. Si la abstracción obstaculiza la comprensibilidad de su prueba, evite por completo el código duplicado.

    Este fragmento de código es un ejemplo:

    // CypressbeforeEach(() = { // It’s difficult to see at first glance what those // command really do cy.setInitialState() .then(() = { return cy.login(); })}):

    Para que la prueba sea más comprensible, se podría pensar que nombrar los comandos de manera significativa no es suficiente. Más bien, también podrías considerar documentar los comandos en comentarios, así:

    // Cypress/*** Logs in silently using API* @memberOf Cypress.Chainable#* @name loginViaApi* @function*/Cypress.Commands.add('loginViaApi', () = { return cy.authenticate().then((result) = { return cy.window().then(() = { cy.setCookie('bearerAuth', result); }).then(() = { cy.log('Fixtures are created.'); }); });});

    Dicha documentación podría ser esencial en este caso porque ayudará a su yo futuro y a su equipo a comprender mejor la prueba . Verá, algunas de las mejores prácticas para el código de producción no son adecuadas para el código de prueba. Las pruebas simplemente no son código de producción y nunca debemos tratarlas como tal. Por supuesto, debemos tratar el código de prueba con el mismo cuidado que el código de producción. Sin embargo, algunas convenciones y mejores prácticas pueden entrar en conflicto con la comprensibilidad. En tales casos, recuerde la regla de oro y anteponga la experiencia del desarrollador.

    Trampas en el diseño de pruebas

    En los primeros ejemplos de esta sección, hablaré sobre cómo evitar caer en trampas de prueba en primer lugar. Después de eso, hablaré sobre el diseño de pruebas. Si ya estás trabajando en un proyecto de larga data, esto debería seguir siendo útil.

    La regla de tres

    Comencemos con el siguiente ejemplo. Presta atención a su título. El contenido de la prueba en sí es secundario.

    // Jestdescribe('deprecated.plugin', () = { it('should throw error',() = { // Actual test, shortened for component throwing // an error const component = createComponent(); expect(global.console.error).toBeCalled(); });});

    Al observar esta prueba, ¿puede decir a primera vista qué se pretende lograr? En particular, imagine mirar este título en los resultados de sus pruebas (por ejemplo, podría estar mirando las entradas de registro en sus canalizaciones en integración continua). Bueno, obviamente debería arrojar un error. ¿Pero qué error es ese? ¿En qué circunstancias se debe tirar? Verá, comprender a primera vista lo que se pretende lograr con esta prueba no es fácil porque el título no es muy significativo.

     

    Recuerde nuestra regla de oro: debemos saber instantáneamente qué debe hacer la prueba. Entonces, necesitamos cambiar esta parte. Afortunadamente, existe una solución que es fácil de comprender. Titularemos esta prueba con la regla de tres.

    Esta regla, introducida por Roy Osherove , le ayudará a aclarar lo que se supone que debe lograr una prueba. Es una práctica bien conocida en las pruebas unitarias, pero también sería útil en las pruebas de un extremo a otro. Según la norma, el título de una prueba debe constar de tres partes:

    1. ¿Qué se está probando?
    2. ¿En qué circunstancias se probaría?
    3. ¿Cuál es el resultado esperado?

    Bien, ¿cómo sería nuestra prueba si siguiéramos esta regla? Vamos a ver:

    // Jestdescribe('deprecated.plugin', () = {it('Property: Should throw an error if the deprecated prop is used', () = { // Actual test, shortened for component throwing // an error const component = createComponent(); expect(global.console.error).toBeCalled(); });});

    Sí, el título es largo, pero encontrarás las tres partes en él:

    1. ¿Qué se está probando? En este caso, es la propiedad.
    2. ¿Bajo que circunstancias? Queremos probar una propiedad obsoleta.
    3. ¿Qué esperamos? La aplicación debería arrojar un error.

    Siguiendo esta regla, podremos ver el resultado de la prueba a primera vista, sin necesidad de leer los registros. Entonces, en este caso podemos seguir nuestra regla de oro.

    “Organizar, actuar, afirmar” frente a “dado, cuándo y entonces”

    Otra trampa, otro ejemplo de código. ¿Entiendes la siguiente prueba en la primera lectura?

    // Jestdescribe('Context menu', () = { it('should open the context menu on click', async () = { const contextButtonSelector = 'sw-context-button'; const contextButton = wrapper.find(contextButtonSelector); await contextButton.trigger('click'); const contextMenuSelector = '.sw-context-menu'; let contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(false); contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(true); });});

    Si es así, ¡enhorabuena! Eres notablemente rápido procesando información. Si no es así, no se preocupe; Esto es bastante normal, porque la estructura de la prueba podría mejorarse mucho. Por ejemplo, las declaraciones y afirmaciones se escriben y confunden sin prestar atención a la estructura. ¿Cómo podemos mejorar esta prueba?

    Hay un patrón que puede resultar útil: el patrón AAA . AAA es la abreviatura de "organizar, actuar, afirmar", que le indica qué hacer para estructurar una prueba con claridad. Divida la prueba en tres partes importantes. Al ser adecuado para pruebas relativamente cortas, este patrón se encuentra principalmente en pruebas unitarias. En resumen, estas son las tres partes: Relatos Cortos

    • Organizar
      Aquí, configuraría el sistema que se está probando para alcanzar el escenario que la prueba pretende simular. Esto podría implicar cualquier cosa, desde configurar variables hasta trabajar con simulacros y apéndices.
    • Actuar
      En esta parte, ejecutará la unidad bajo prueba. Por lo tanto, deberá seguir todos los pasos y todo lo que sea necesario para llegar al estado de resultado de la prueba.
    • Afirmar
      Esta parte se explica por sí misma. Simplemente haría sus afirmaciones y comprobaciones en esta última parte.

    Esta es otra forma de diseñar una prueba de forma sencilla y comprensible. Con esta regla en mente, podríamos cambiar nuestra prueba mal escrita por la siguiente:

     

    // Jestdescribe('Context menu', () = { it('should open the context menu on click', () = { // Arrange const contextButtonSelector = 'sw-context-button'; const contextMenuSelector = '.sw-context-menu'; // Assert state before test let contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(false); // Act const contextButton = wrapper.find(contextButtonSelector); await contextButton.trigger('click'); // Assert contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(true); });});

    ¡Pero espera! ¿Qué es esa parte de actuar antes de afirmar? Y ya que estamos en eso, ¿no crees que esta prueba tiene demasiado contexto, al ser una prueba unitaria? Correcto. Estamos lidiando con pruebas de integración aquí. Si estamos probando el DOM, como lo estamos haciendo aquí, necesitaremos verificar los estados antes y después. Por lo tanto, si bien el patrón AAA se adapta bien a las pruebas unitarias y API, no lo es para este caso.

    Miremos el patrón AAA desde la siguiente perspectiva. Como afirma Claudio Lassala en una de las entradas de su blog , en lugar de pensar en cómo voy a…

    • "... organizar mi prueba, creo que lo que me dan ".
      Este es el escenario con todas las condiciones previas de la prueba.
    • “… actúo en mi prueba, creo que cuando pasa algo”.
      Aquí vemos las acciones de la prueba.
    • "... afirmar los resultados, creo que si algo sucede entonces esto es lo que espero como resultado".
      Aquí encontramos las cosas que queremos afirmar, siendo la intención de la prueba.

    Las palabras clave en negrita en el último punto insinúan otro patrón del desarrollo impulsado por el comportamiento (BDD). Es el patrón dado-cuándo-entonces , desarrollado por Daniel Terhorst-North y Chris Matts. Es posible que esté familiarizado con este si ha escrito pruebas en el idioma Gherkin:

    Feature: Context menu Scenario: Given I have a selector for the context menu And I have a selector for the context button When the context menu can be found And this menu is visible And this context button can be found And is clicked Then I should be able to find the contextMenu in the DOM And this context menu is visible

    Sin embargo, puede utilizarlo en todo tipo de pruebas, por ejemplo, estructurando bloques. Usando la idea de los puntos anteriores, reescribir nuestra prueba de ejemplo es bastante fácil:

    // Jestdescribe('Context menu', () = { it('should open the context menu on click', () = { // Given const contextButtonSelector = 'sw-context-button'; const contextMenuSelector = '.sw-context-menu'; // When let contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(false); const contextButton = wrapper.find(contextButtonSelector); await contextButton.trigger('click'); // Then contextMenu = wrapper.find(contextMenuSelector); expect(contextMenu.isVisible()).toBe(true); });});

    Datos que solíamos compartir

    Hemos llegado a la siguiente trampa. La siguiente imagen parece pacífica y feliz, dos personas compartiendo un papel:

     

    Datos de prueba que solíamos compartir. (Crédito de la imagen: Ramona Schwering)

    Sin embargo, es posible que les espera un duro despertar. Aplique esta imagen a una prueba, con las dos personas representando las pruebas y el papel representando los datos de la prueba. Llamemos a estas dos pruebas, prueba A y prueba B. Muy creativo, ¿verdad? La cuestión es que la prueba A y la prueba B comparten los mismos datos de prueba o, peor aún, se basan en una prueba anterior.

    Esto es problemático porque conduce a pruebas inestables . Por ejemplo, si la prueba anterior falla o si los datos de prueba compartidos se dañan, las pruebas en sí no pueden ejecutarse correctamente. Otro escenario sería que sus pruebas se ejecutaran en orden aleatorio. Cuando esto sucede, no se puede predecir si la prueba anterior permanecerá en ese orden o se completará después de las demás, en cuyo caso las pruebas A y B perderían su base. Esto tampoco se limita a pruebas de un extremo a otro; Un caso típico en las pruebas unitarias son dos pruebas que mutan los mismos datos de semillas.

    Muy bien, veamos un ejemplo de código de una prueba de un extremo a otro de mi negocio diario. La siguiente prueba cubre la funcionalidad de inicio de sesión de una tienda en línea.

    // Cypressdescribe('Customer login', () = { // Executed before every test beforeEach(() = { // Step 1: Set application to clean state cy.setInitialState() .then(() = { // Step 2: Create test data return cy.setFixture('customer'); }) // … use cy.request to create the customer }): // … tests will start below})

    Para evitar los problemas mencionados anteriormente, ejecutaremos el beforeEachenlace de esta prueba antes de cada prueba en su archivo. Allí, el primer y más importante paso que daremos es restablecer nuestra aplicación a su configuración de fábrica, sin ningún dato personalizado ni nada. Nuestro objetivo aquí es garantizar que todas nuestras pruebas tengan la misma base . Además, protege esta prueba de cualquier efecto secundario fuera de la prueba. Básicamente, lo estamos aislando, manteniendo alejada cualquier influencia del exterior.

    El segundo paso es crear todos los datos necesarios para ejecutar la prueba. En nuestro ejemplo, necesitamos crear un cliente que pueda iniciar sesión en nuestra tienda. Quiero crear todos los datos que necesita la prueba, adaptados específicamente a la prueba en sí. De esta forma, la prueba será independiente y el orden de ejecución podrá ser aleatorio. En resumen, ambos pasos son esenciales para garantizar que las pruebas estén aisladas de cualquier otra prueba o efecto secundario, manteniendo como resultado la estabilidad.

     

    Trampas de implementación

    Muy bien, hemos hablado sobre el diseño de pruebas. Sin embargo, hablar de un buen diseño de pruebas no es suficiente, porque el diablo está en los detalles. Así que inspeccionemos nuestras pruebas y cuestionemos su implementación real.

    Foo Bar ¿Qué?

    Para esta primera trampa en la implementación de pruebas, ¡tenemos un invitado! Es BB-8, y encontró algo en una de nuestras pruebas:

    ¿Qué significa “Foo Bar”? (Crédito de la imagen: Ramona Schwering)

    Ha encontrado un nombre que quizá nos resulte familiar pero no a ella: Foo Bar. Por supuesto, los desarrolladores sabemos que Foo Bar se utiliza a menudo como nombre de marcador de posición. Pero si lo ves en una prueba, ¿sabrás inmediatamente lo que representa? Una vez más, la prueba puede resultar más difícil de entender a primera vista.

    Afortunadamente, esta trampa es fácil de solucionar. Veamos la prueba de Cypress a continuación. Es una prueba de un extremo a otro, pero los consejos no se limitan a este tipo.

    // Cypressit('should create and read product', () = { // Open module to add product cy.get('a[href="#/sw/product/create"]').click(); // Add basic data to product cy.get('.sw-field—product-name').type('T-Shirt Ackbar'); cy.get('.sw-select-product__select_manufacturer') .type('Space Company'); // … test continues …});

    Esta prueba debe comprobar si un producto se puede crear y leer. En esta prueba, simplemente quiero usar nombres y marcadores de posición conectados a un producto real:

    • Para el nombre de un producto de camiseta, quiero usar "Camiseta Akbar".
    • Para el nombre del fabricante, “Space Company” es una idea.

    Sin embargo, no es necesario que inventes todos los nombres de los productos. Puede generar datos automáticamente o, lo que es más bonito, importarlos desde su estado de producción. De todos modos, quiero ceñirme a la regla de oro, incluso cuando se trata de nombrar.

    Mire los selectores, debe

    Nueva trampa, misma prueba. Míralo de nuevo, ¿notas algo?

    // Cypressit('should create and read product', () = { // Open module to add product cy.get('a[href="#/sw/product/create"]').click(); // Add basic data to product cy.get('.sw-field—product-name').type('T-Shirt Ackbar'); cy.get('.sw-select-product__select_manufacturer') .type('Space Company'); // … Test continues …});

    ¿Te diste cuenta de esos selectores? Son selectores de CSS. Bueno, quizás te preguntes: “¿Por qué son problemáticos? ¡Son únicos, fáciles de manejar y mantener y puedo usarlos sin problemas!” Sin embargo, ¿estás seguro de que ese es siempre el caso?

    La verdad es que los selectores de CSS son propensos a cambiar. Si refactorizas y, por ejemplo, cambias de clase, la prueba podría fallar, incluso si no has introducido un error. Este tipo de refactorización es común, por lo que esos fallos pueden resultar molestos y agotadores para los desarrolladores corregirlos. Por lo tanto, tenga en cuenta que una prueba que falla sin un error es un falso positivo y no proporciona un informe confiable para su aplicación.

     

    "¡Mira los selectores que debes!" (Crédito de la imagen: Ramona Schwering)

    En este caso, esta trampa se refiere principalmente a las pruebas de un extremo a otro. En otras circunstancias, también podría aplicarse a las pruebas unitarias, por ejemplo, si utiliza selectores en las pruebas de componentes. Como afirma Kent C. Dodds en su artículo sobre el tema:

    "No deberías probar los detalles de implementación".

    En mi opinión, existen mejores alternativas al uso de detalles de implementación para las pruebas. En su lugar, pruebe cosas que un usuario notaría . Mejor aún, elija selectores menos propensos a cambiar. Mi tipo de selector favorito es el atributo de datos. Es menos probable que un desarrollador cambie los atributos de los datos mientras los refactoriza, lo que los hace perfectos para ubicar elementos en las pruebas. Recomiendo nombrarlos de manera significativa para transmitir claramente su propósito a cualquier desarrollador que trabaje en el código fuente. Podría verse así:

    // Cypresscy.get('[data-test=sw-field—product-name]') .type('T-Shirt Ackbar');cy.get('[data-test=sw-select-product__select_manufacturer]') .type('Space Company');

    Los falsos positivos son sólo uno de los problemas en los que nos encontramos cuando probamos los detalles de implementación. Lo contrario, los falsos negativos, también pueden ocurrir al probar los detalles de implementación. Un falso positivo ocurre cuando una prueba pasa incluso cuando la aplicación tiene un error. El resultado es que las pruebas vuelven a consumir espacio de cabeza, lo que contradice nuestra regla de oro. Por tanto, debemos evitar esto en la medida de lo posible.

    Nota : Este tema es enorme, por lo que sería mejor tratarlo en otro artículo. Hasta entonces, sugeriría consultar el artículo de Dodds sobre " Detalles de implementación de pruebas " para obtener más información sobre el tema.

    ¡Espéralo!

    Por último, pero no menos importante, este es un tema que no puedo enfatizar lo suficiente. Sé que esto será molesto, pero todavía veo que mucha gente lo hace, así que necesito mencionarlo aquí como una trampa.

    Es el problema del tiempo de espera fijo del que hablé en mi artículo sobre pruebas inestables . Echa un vistazo a esta prueba:

    // CypressCypress.Commands.add('typeSingleSelect', { prevSubject: 'element', }, (subject, value, selector) = { cy.wrap(subject).should('be.visible'); cy.wrap(subject).click(); cy.wait(500); cy.get(`${selector} input`) .type(value);});

    La pequeña línea cy.wait(500)es un tiempo de espera fijo que detiene la ejecución de la prueba durante medio segundo. Para hacer este error más grave, lo encontrará en un comando personalizado, de modo que la prueba utilizará esta espera varias veces. La cantidad de segundos se sumará con cada uso de este comando. Eso ralentizará demasiado la prueba y no es necesario en absoluto. Y esa ni siquiera es la peor parte. La peor parte es que estaremos esperando muy poco tiempo, por lo que nuestra prueba se ejecutará más rápido de lo que nuestro sitio web puede reaccionar. Esto provocará descamación, porque a veces la prueba fallará. Afortunadamente, podemos hacer muchas cosas para evitar tiempos de espera fijos.

    Todos los caminos conducen a la espera dinámica. Sugeriría favorecer los métodos más deterministas que ofrecen la mayoría de las plataformas de prueba. Echemos un vistazo más de cerca a mis dos métodos favoritos.

    • Espere los cambios en la interfaz de usuario.
      Mi primer método de elección es esperar cambios en la interfaz de usuario de la aplicación que un usuario humano pueda notar o incluso reaccionar. Los ejemplos pueden incluir un cambio en la interfaz de usuario (como una rueda de carga que desaparece), esperar a que se detenga una animación y cosas similares. Si usa Cypress, esto podría verse de la siguiente manera:
      // Cypresscy.get('data-cy="submit"').should('be.visible');

      Casi todos los marcos de prueba ofrecen tales posibilidades de espera.

    • Esperando solicitudes de API.
      Otra posibilidad que me encanta es esperar las solicitudes de API y sus respuestas, respectivamente. Por nombrar un ejemplo, Cypress ofrece funciones interesantes para ello. Al principio, definiría una ruta por la que Cypress debería esperar:
      // Cypresscy.intercept({ url: '/widgets/checkout/info', method: 'GET'}).as('checkoutAvailable');

      Luego, puedes afirmarlo en tu prueba, así:

      // Cypresscy.wait('@request').its('response.statusCode') .should('equal', 200);

      De esta manera, su prueba permanecerá estable y confiable, mientras administr






      Tal vez te puede interesar:

      1. ¿Deberían abrirse los enlaces en ventanas nuevas?
      2. 24 excelentes tutoriales de AJAX
      3. 70 técnicas nuevas y útiles de AJAX y JavaScript
      4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    ¡Es una trampa (de pruebas iniciales)! Seis errores comunes en las pruebas y cómo resolverlos

    ¡Es una trampa (de pruebas iniciales)! Seis errores comunes en las pruebas y cómo resolverlos

    SmashingConf Friburgo 2024 Clase magistral de CSS moderno avanzado, con Manuel Matuzović Índice Trampas

    programar

    es

    https://aprendeprogramando.es/static/images/programar-es-una-trampa-de-pruebas-iniciales-seis-errores-comunes-en-las-pruebas-y-como-resolverlos-1108-0.jpg

    2024-04-04

     

    ¡Es una trampa (de pruebas iniciales)! Seis errores comunes en las pruebas y cómo resolverlos
    ¡Es una trampa (de pruebas iniciales)! Seis errores comunes en las pruebas y cómo resolverlos

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20