https://d226lax1qjow5r.cloudfront.net/blog/blogposts/use-mutation-testing-to-improve-your-software-engineering-skills/mutation-testing.png

Utilice las pruebas de mutación para mejorar sus habilidades en ingeniería de software.

Publicado el October 19, 2023

Tiempo de lectura: 23 minutos

La cobertura del código (el porcentaje de código ejecutado al ejecutar las pruebas) es una gran métrica. Sin embargo, la cobertura no te dice lo buenas que son tus pruebas a la hora de detectar cambios en tu código base, simplemente porque es una métrica cuantitativa. Si tus pruebas no están bien diseñadas, los cambios pueden pasar tus pruebas unitarias pero romper la producción.

Las pruebas de mutación son una forma excelente (y muy infravalorada) de cuantificar hasta qué punto puedes confiar en tus pruebas. Las pruebas de mutación funcionan cambiando el código de forma sutil y aplicando las pruebas unitarias a estas versiones "mutadas" del código. Si las pruebas fallan, ¡genial! Si pasan... significa que tu prueba no era lo suficientemente buena como para detectar este cambio.

En este Video, Max del equipo de Vonage Developer Experience te mostrará cómo comenzar con las pruebas de mutación en cualquier lenguaje y cómo integrarlas en tu canal de CI/CD. Pronto, la captura de código mutante será una parte rutinaria de su proceso de ingeniería de lanzamiento, ¡y nunca volverá a ver a los pingüinos de la misma manera!

A continuación encontrará la transcripción del Video, así como algunos enlaces útiles.

Puedes registrarte para obtener una cuenta de desarrollador gratuita con Vonage aquí.

Si tiene alguna pregunta, por favor, póngase en contacto con nosotros en nuestra Comunidad Slack.


Hola. Mi nombre es Max, y soy defensor de los desarrolladores en Vonage. Y hoy quiero hablarles sobre las pruebas de mutación. Quiero contarte cómo lo uso yo y cómo puedes usarlo tú también. Antes de empezar, quiero mencionar brevemente la empresa para la que trabajo.

Somos una empresa llamada Vonage y nos dedicamos, entre otras cosas, a las API de comunicaciones. Así que gran parte del código con el que trabajo es cosas como enviar SMS o hacer llamadas de voz, crear video chatsy cosas por el estilo. Muchas cosas relacionadas con la comunicación. Y la razón por la que estoy mencionando esto es porque en realidad he aplicado pruebas de mutación a nuestro código. Quiero mostrarte cómo lo hice, por qué fue una buena opción para nosotros, y quiero mostrarte cómo puedes hacerlo. Pero antes de empezar, quiero presentar al verdadero protagonista de esta charla.

Yo soy el orador, pero el verdadero protagonista es en realidad Henry. Este es Henry. Usted puede ver, con suerte, que es un pequeño pingüino adorable. Y la razón por la que él es el personaje realmente importante aquí es porque como yo estaba aprendiendo pruebas de mutación para usarlo yo mismo, yo estaba usando Henry como una analogía para un montón de cosas. Verás por qué, porque voy a usarlo hoy también para mostrarte cómo funciona realmente la prueba de mutación. Antes de empezar, vamos a establecer algunas líneas de base.

En primer lugar, quiero que pienses en esto: ¿has oído hablar de las pruebas? Supongo que si has hecho clic en este Video, si estás viendo esto, probablemente sepas lo que es el testing para el software.

También me gustaría que pensaras en la cobertura de código. Puede que conozcas o no la cobertura de código. No te preocupes si no, porque es algo que definitivamente vamos a mencionar. También hay pruebas de mutación. Usted ha oído hablar de esto, supongo, si usted ha visto el título de este video, pero es una cosa muy útil en su propio derecho. Espero que al final del vídeo sepas mucho más sobre las pruebas de mutaciones y te sientas cómodo utilizándolas. Así que si te parece bien, ¡continuemos!

Lo que me gustaría hacer es establecer una línea de base. Así que sólo quiero mencionar las pruebas, en primer lugar. Así que realmente, sólo esta gran pregunta: ¿por qué escribimos pruebas unitarias? ¿Qué razones tenemos para escribir pruebas para nuestro código? Y es posible que desee hacer una pausa y pensar en esto por sí mismo. Puede que no. Tampoco pasa nada.

En cuyo caso, te mostraré lo que creo que podría implicar. Y esto es lo que tengo. Puedes escribirlos para probar que tu código funciona. Puedes escribirlos por razones de documentación para inspirar confianza en tu código, para pruebas de regresión, para refactorización, y también por razones de cumplimiento.

Así que básicamente, aquí están todas las cosas que podrían animarte a escribir una prueba unitaria. Y es genial que tengamos esto, es genial que tengamos una forma de verificar que nuestro código funciona. Es genial que tengamos una forma de documentar y todas estas grandes cosas. Pero hay un pequeño problema aquí también. El problema es que usted puede comenzar con un pequeño proyecto, pero ese proyecto puede crecer rápidamente, y lo que hace puede evolucionar con el tiempo. Y luego, como usted hace refactorizaciones y cosas por el estilo, es posible que se pierda el código, puede omitir secciones. Es posible que se pierda cosas. Puede que ya no estés probando todo tu código. Y el problema aquí es que a menudo no controlamos nuestras pruebas.

Si no controlamos nuestras pruebas, no sabemos qué falla en el código que tenemos, porque no tenemos forma de probarlo, y no sabemos si las pruebas nos van a ayudar. Así que espero que podamos ver cuál es el reto aquí. Me gustaría decir que se pone mejor porque tenemos cobertura de código, ¿verdad? Y si usted no está seguro de lo que es, voy a explicar rápidamente. Esto es en mis palabras: "cuánto del código fuente de un programa se ejecuta cuando se ejecuta el conjunto de pruebas". Así es como yo lo explicaría.

Pero dejemos de hablar de ello y mostremos un ejemplo real de esto en la práctica. Este es uno de los SDK de código abierto que mantengo. Y, básicamente, es un SDK de Python para hacer llamadas a la API para diferentes cosas. Tenemos una API que estoy apoyando en este SDK llamado nuestro Messages API. Y dentro de eso, usted puede enviar mensajes con SMS, MMS, WhatsApp, Facebook, cosas por el estilo - un montón de diferentes canales. Tengo el código y corrí algunas métricas de cobertura de código en él, así que pude ver qué declaraciones en el código que estaba probando, y qué declaraciones me faltaba. Puedes ver aquí que he cubierto la mayor parte, pero hay una declaración que falta en la línea 23 y esa línea es una que me dice, oh, en realidad no escribí una prueba para eso.

En este caso, no he probado ese tipo de autenticación. Y lo que eso significa es que puedo ir y escribir una prueba para eso. Y así la cobertura de código ya ha mejorado mi código, ¡y eso es impresionante! ¿Qué más puede hacer?

En realidad, puede darte una visión general de todo tu proyecto y todas las diferentes declaraciones en él - básicamente, cuánta cobertura tienes. Así que esto es lo que parece para mí. Y esto parece genial. Hay realmente un gran potencial aquí, porque en primer lugar, le permite escribir más pruebas y mejores pruebas.

También es muy fácil y barato medir estas cosas. No es muy intenso computacionalmente sólo para ejecutar la cobertura de código y decir, "¿qué he cubierto"? La otra cosa buena, realmente lo mejor aquí es que muestra lo que no has probado y así sabes, hey, tengo que prestar atención a esto. Si no confío en este código, que realmente a menudo no debería. Eso es realmente útil. Y así la cobertura de código realmente cubre mucho.

Así que en realidad, creo que hemos terminado aquí, muchas gracias. Ha sido genial hablar contigo hoy. Te veré de nuevo... excepto que en realidad, hay algunas cosas que no son tan buenas sobre esto.

Bueno, en primer lugar, la cobertura del código puede ser un poco engañosa. Tampoco garantiza la calidad de tus pruebas. Así que lo que voy a hacer es mostrarte un ejemplo de una pieza muy simple de código Python, aquí está. Y todo lo que estoy haciendo aquí es importar el módulo requests módulo, que es la biblioteca que estoy usando.

Entonces estoy haciendo una llamada a la API con esa biblioteca. Así que todo lo que estoy haciendo es hacer una solicitud GET a una URL específica, y luego estoy recibiendo la respuesta y devolver el JSON de la respuesta de nuevo al usuario. Y eso está bien. Eso es todo bien. Podemos ver sin embargo en la siguiente diapositiva, la siguiente página, lo que tengo aquí, es una prueba para esto.

En realidad tiene una cobertura del 100%, pero no es muy útil. Podemos ver aquí, tenemos algo que llama a la API. Pero lo que realmente está haciendo es llamar a la API y luego sólo decir si yo lo llamé, eso es bueno. Así que si ese código se ejecuta, estamos bien. Pero lo que no hace es validar cualquiera de las cosas que podrían volver.

Podríamos recibir una respuesta de 200. Podríamos obtener un 400. Podríamos recibir algo más. Podríamos obtener algo que no esperamos, y no manejamos ninguno de esos casos. Y tampoco probamos ninguno de esos casos. Así que en realidad, esta prueba no es muy útil para ayudarle con eso.

Así que lo que me gustaría hacer es una pregunta muy rápida: ¿alguna vez has escrito un fragmento de código y luego has escrito una prueba para él, no porque esa prueba fuera a ser útil, sino porque necesitabas aumentar un poco la cobertura de tu código? Yo lo he hecho y mucha gente también. Si no lo has hecho, genial, estoy orgulloso de ti, pero en realidad, la mayoría de nosotros hemos hecho este tipo de cosas.

Lo que ocurre a menudo con la cobertura de código es que acabamos convirtiéndola en un objetivo en lugar de en algo que se supone que nos proporciona información. Y esto es en realidad un principio que tiene un nombre. Es una cosa real, y se llama la Ley de Goodhart. No es sólo para la cobertura de pruebas, pero la afirmación es esencialmente la siguiente: "Cuando una métrica se convierte en un objetivo, deja de ser una buena métrica".

Esto es muy importante, así que lo repetiré: "Cuando una métrica se convierte en un objetivo, deja de ser una buena métrica". ¿Qué quiero decir con esto? Bueno, lo que quiero decir es que hemos tomado la cobertura de código, que se supone que nos dice acerca de nuestro código y nuestras pruebas y cómo funcionan, pero en realidad lo hemos convertido en un número que nos importa optimizar.

Así que en lugar de pensar en hacer mejores pruebas, estamos pensando en optimizar un número, que no es tan bueno. Eso lleva a algunas preguntas. Como, ¿cómo podemos entender lo que nuestras pruebas están haciendo realmente? ¿Cómo sabemos si nuestras pruebas son fiables? Y en realidad la mejor afirmación de esto se le ocurrió alrededor del año 100 d.C. al pensador romano Juvenal (después de una cuarta copa de vino), y la afirmación que se le ocurrió fue "¿Quién vigila a los vigilantes?". Quién vigila a los que deberían vigilarnos a nosotros. Y del mismo modo, ¿quién pone a prueba nuestras pruebas?

Hoy les ofrezco una respuesta: las pruebas de mutación. Habrán notado que Henry ha reaparecido un poco.

Y eso es genial porque, en primer lugar, es adorable, pero lo más importante es que ahora nos va a ayudar. Así que el año pasado, cuando empecé a aprender acerca de las pruebas de mutación, yo estaba pensando mucho acerca de cómo podría aplicarlo a mi código, y yo estaba pensando en maneras de conceptualizar y entender que por mí mismo. Y la forma en que lo hice es que me imaginé que mi código, que básicamente envía un montón de llamadas a la API y se ocupa de las llamadas a la API y los mensajes, a ser como una paloma o una paloma, como un pájaro que puede volar. Y así lo que puedo hacer en esta analogía es atar un mensaje a la pata del pájaro y dejar que el pájaro vaya, y volará y entregará mi mensaje.

Así que volará y hará lo que necesito que haga. Ahora bien, lo que pasa con los pingüinos es que son pájaros, así que cumplen ese criterio, pero no pueden volar, como bien sabrás, no pueden volar, y eso les enfada un poco. Pero lo más importante es que un mutante de esta manera es como un pájaro normal cambiado en un pingüino que ahora no puede hacer esa cosa central que necesito, que es que ese pájaro vuele. Veamos un ejemplo real usando fotos de pájaros porque eso es lo que estamos haciendo hoy.

En primer lugar, partimos de un código de producción, que funciona como se espera. Luego hacemos algún tipo de operación de mutación y creamos una versión mutante de este código. Así que tenemos, por ejemplo, esta función, esto es Python. Simplemente suma 2 números y devuelve la suma de esos 2 números. Ahora, una versión mutante de esto podría, por ejemplo, restar números o podría añadir una constante, o podría devolver la suma de las dos cadenas, cosas por el estilo.

Puede que no devuelva nada en absoluto, o cualquiera de los tipos de operación lógica que pueden cambiar lo que devuelve esa línea de código. Entonces, ¿qué hacemos con las pruebas de mutación? Hemos creado algunos mutantes, ¿qué hacemos ahora?

Bueno, tomo los mutantes que tenemos. Los llamo los Fab 4 por razones que deberían ser obvias, y esencialmente lo que tenemos que hacer es ejecutarlos contra nuestro conjunto de pruebas. Así que tomamos cada mutante. Y lo que estamos haciendo esencialmente en esta analogía es ver si ese mutante puede volar, si puede pasar la prueba que necesita para ser capaz de volar y llevar ese mensaje. Por lo tanto, Henry, nuestro hermoso pingüino mutante aquí, tiene que tratar de volar.

Así que cuando tomamos este mutante, vamos a ejecutar nuestras suites de prueba. Y en el mejor de los casos, nuestras pruebas van a fallar. Eso es bueno porque significa que hemos expuesto Henry por lo que es, que es un pingüino adorable, que es impresionante, porque significa que en realidad no vamos a dejar que vaya a la producción. Lo hemos atrapado en nuestras pruebas. Ahora bien, si las pruebas pasan, mal vamos, porque lo que ha pasado es que en realidad no nos hemos dado cuenta de que Henry es un pingüino y no una paloma.

Y es capaz de volar. Quiero decir, mira estas alas, este pingüino puede levantar un autobús, ¿verdad? Muy impresionante. Pero significa que este mutante podría entrar en producción, y eso es lo que no queremos. Entonces, ¿qué nos da esto?

Y afirmo que esto nos da una forma de evaluar la calidad de nuestras pruebas. Eso es lo que son las pruebas de mutación.

Hablemos de un par de frameworks en los que podrías querer pensar. Así que con los frameworks, hay varias opciones para varios lenguajes, ya sabes, cada lenguaje tiene alguna versión de esto. En mi caso, uso mutmut, que es un framework de pruebas de mutación basado en Python.

Pero si te interesan otros lenguajes, hay cosas como Pitest para Java o Stryker para JavaScript, C#, cosas así. Así que hay opciones para varios idiomas. Y si el lenguaje no se ha mencionado, probablemente todavía hay algo para él. Ahora bien, no soy médico profesional, asesor financiero, profesor ni nada por el estilo: el valor de tu inversión puede bajar tanto como subir. Pero lo más importante para mí es lo que he utilizado.

Así que voy a hablar de mutmut hoy porque eso es lo que usé yo mismo. Y lo que hice fue aplicar esta prueba de mutación a mi propio SDK, y te voy a mostrar cómo lo hice en este momento. Así que en primer lugar, yo pip install mutmutque es sólo una forma pitónica de instalar cosas, y luego ejecuto eso. Eso fue todo.

Por suerte, tiene algunos valores por defecto sensatos, que no necesité cambiar. Puede que necesites cambiar lo que hay ahí dependiendo de lo que estés haciendo. Hay diferentes opciones de configuración que puede elegir, pero para mí, esto estaba bien. Y cuando corrí esto, lo que sucedió fue que básicamente me dijo lo que iba a suceder. Así que imprimió esto.

Imprimió el hecho de que iba a ejecutar todo el conjunto de pruebas en primer lugar para entender la sincronización y cosas por el estilo. Y luego generaría los mutantes y los comprobaría. Así que hay algunos resultados diferentes que pueden surgir aquí. Así, por ejemplo, podemos coger un mutante, podemos tener un tiempo de espera mutante, que no es bueno, podemos tener unos que parece sospechoso. y tal vez no confiar, y también podemos tener unos que sobrevivieron. Y en este caso, esa es una situación realmente mala donde sabemos que no atrapamos a ese mutante. Así que cuando corrí esto, lo que vimos en primer lugar fue que corrió mi conjunto de pruebas y luego comprobó esos mutantes y pudo ver que atrapé 512 de ellos, pero no atrapó 170 de ellos. Ahora, piensa en esto.

¿Es un buen número o un mal número? Hablaremos de eso más tarde, pero por ahora, echemos un vistazo a algunos mutantes. Así que aquí está uno simple que somos capaces de atrapar. Empezamos con aquí. Esta es nuestra clase Messages API.

Tenemos algunos canales de mensajes válidos por los que podemos enviar mensajes. Y el mutante acaba de cambiar uno de ellos. Acaba de cambiar una de las cadenas. Así que, en realidad, ya no podíamos enviar mensajes con SMS. Y así, cuando tuvimos una prueba para hacer eso, falló, y eso es genial.

Eso significa que llamamos a eso. Aquí hay otro. No sé si la gente ha utilizado Pydantic que están viendo esto, pero Pydantic es una gran biblioteca de validación, y lo usamos en el SDK. Aquí hay un ejemplo donde tenemos un validador, este es Pydantic V1, esto es algo que redondea un número. Pero la versión mutada eliminó esa anotación, ese decorador (dependiendo de tu lenguaje, lo llamarás de otra manera, nosotros los llamamos decoradores en Python).

Así que eliminamos eso. Y, que significaba en realidad este código nunca sería llamado así que cuando tuve una prueba para redondear un número, que nunca sería llamado. Y así que falló también. Esto es bueno porque significa que estas son 2 versiones de la base de código, dos Henries poco que hemos sido capaces de atrapar y decir, hey, eres un pingüino, que es lo que necesitamos.

Entonces, ¿cómo vemos a los mutantes? Bueno, si lo haces mutmut showpuede darle una lista de ellos. Y usted puede, por ejemplo, el nombre 1, como mostrar el número 1, mostrar el primer mutante y que son capaces de ver eso. Así que en nuestro caso, el número uno aquí, por ejemplo, cambia el tipo de autenticación y, por supuesto, que uno era fácil de atrapar. Pero lo realmente interesante que podemos hacer es que podemos ver los resultados de todas estas pruebas.

Así que tenemos un informe en formato HTML. Dependiendo de su idioma y lo que la mutación de software de prueba que está utilizando, será más fácil o más difícil de hacer esto. Para nosotros, es una interfaz bastante simple, pero esencialmente lo que hará es que le mostrará todos los mutantes que no se captura dentro de cada archivo. Así que echemos un vistazo a algunos.

Aquí está el mutante 58, que no atrapamos, y verás que no todos estos son creados iguales. Así que este mutante, se puede ver todo lo que hicimos aquí es que hemos cambiado el nombre del registrador. Y creo que el registro está fuera del alcance de mis pruebas. Y así para mi dinero, no me importa que este mutante se metió, esto estaba bien porque no creo que esto es lo que debería estar probando.

Así que está bien. Aquí hay otro ejemplo. Este es Mutant 62. Y dentro de aquí, todo lo que hacemos es cambiar el valor de una constante. Y, de nuevo, no creo que esto esté en el ámbito de lo que quiero probar.

No creo que sea importante para mí probar si un valor por defecto se establece o no. Eso no es importante para mí en este contexto. Pero veamos uno que es más importante, que sí me importa. Aquí hay uno. Este es el Mutante 112.

Y lo que estoy haciendo aquí es que estoy creando instancias de todas las clases para todas las APIs que utilizamos. Usted puede ver aquí que tenemos una clase de voz. En la versión mutante, no creamos una clase de voz, pero nuestras pruebas siguen pasando. a pesar de que no estamos creando una clase para todos nuestros métodos de voz. Entonces, ¿por qué sucede esto?

¿Por qué no fallan mis pruebas? ¿Cuál es el problema? Bueno, resulta que la forma en que usamos esto y la forma en que probamos en el SDK es que en realidad no sólo llamamos a través de los objetos del cliente. En realidad llamamos a la clase Voice API directamente, pero nuestros usuarios la llamarán así. Y así, en realidad, probablemente debería tener una prueba para esto.

Así que éste me dice algo muy importante sobre mi código que mejorará la calidad de la prueba porque puedo escribir una prueba para este caso exacto, que es representativo de lo que nuestros usuarios harán. Así que volvamos a este número. Entonces atrapamos un montón de mutantes. Tampoco capturamos bastantes mutantes. De hecho, en realidad sólo capturamos alrededor del 75% de estos mutantes.

En realidad, nos faltó un 25%. Y la pregunta que tengo para ti es, ¿es un buen número? 75%. ¿Es buena? Y si estás viendo esto y encogiéndote de hombros, esa es la respuesta correcta.

Lo interesante aquí es que ¡el 100% no tiene sentido! Porque hay casos que no me importan, ¿verdad? Como el registrador o como la constante que cambia. No me importa eso. Lo que estoy usando esto no es para obtener el 100% de cobertura de mutación, porque entonces todo lo que he hecho es tomar la cuestión con la puntuación de cobertura de código y abstraído de nuevo. Lo que realmente me importa es obtener una buena visión de mi código, eso es lo que realmente me importa.

Con suerte, te he convencido de que tal vez quieras explorar las pruebas de mutaciones un poco por ti mismo. Espero haberlo hecho, pero si no es así, no te preocupes porque lo que voy a hacer ahora es mostrarte cómo puedes empezar con las pruebas de mutación, y es tan sencillo que en realidad creo que cualquiera podría hacerlo si ya estás escribiendo pruebas. En primer lugar, algunos consejos a grandes rasgos: empezar a nivel local, ejecutarlo en su máquina en primer lugar. Eso es lo que yo hice. Acabo de ejecutar localmente en mi máquina. empezar poco a poco. Si tienes una base de pruebas mayor que la mía, si tienes un conjunto de pruebas mayor, puede que quieras empezar con un subconjunto de ellas. También es posible que desee ajustar el rendimiento. Así que es posible que desee excluir las pruebas específicas que no son relevantes para usted. Por ejemplo, cosas como las pruebas de integración, puede que no te importen tanto.

Alternativamente, puede que desee excluir partes del código, por ejemplo, si ha autogenerado algún código, probablemente no le importe.

Vale. Así que cuando quieras salir corriendo de tu máquina, que es muy posible que lo hagas, entonces esta parte te va a ayudar de verdad. En primer lugar, estoy muy contento con esta foto del pingüino. No sé por qué existe de esta manera, pero estoy muy feliz de que lo haga.

Pero, ¿por qué querrías salir corriendo de tu máquina? Se lo diré. Las pruebas llevan su tiempo. Es posible que desee utilizar los recursos en la nube en lugar de utilizar su propia máquina cada vez que desee ejecutar un conjunto de pruebas. esto también significa que usted puede agregar a su sistema de CI, que es muy útil.

Significa que puedes especificar diferentes plataformas en las que quieres correr, diferentes sistemas operativos, diferentes versiones de tu lenguaje, diferentes versiones de tu código. Así que déjame mostrarte esto. Te he dicho por qué podría ser una ventaja. Permítanme mostrarles lo que hice y cómo lo hice.

Apliqué esto a mi SDK de Python. Y lo que hice aquí fue crear una acción de GitHub. Usted puede hacer esto en cualquier sistema de CI que te gusta. Yo uso GitHub Acciones. He creado algo para las pruebas de mutación - una pieza muy, muy simple de YAML. Esencialmente, lo que va a hacer es dejarme elegir manualmente para ejecutar la prueba de mutación para mi conjunto de pruebas. Y en realidad, fue una elección que tengo que ejecutar manualmente.

No quiero que se ejecute automáticamente. Usted podría hacer que se ejecute en el empuje, pero yo elegí no hacerlo. Así que cuando se ejecuta esto, se puede ver lo que va a hacer es en realidad sólo completar ese trabajo. Y lo que también hará es darme ese informe HTML. Me dará que como un artefacto de ejecución que puedo descargar, y de esa manera puedo ver exactamente cómo mis pruebas se están realizando y que los mutantes no están siendo capturados.

¿Cómo lo hago? Bueno, esta es realmente la pregunta interesante aquí. Te voy a mostrar el YAML que he utilizado. Así que de nuevo, yo uso GitHub Acciones. Eso es lo que yo uso, pero usted puede hacer esto en cualquier sistema de CI que te gusta - es sólo un poco de secuencias de comandos simples. Y honestamente, lo que yo diría también es no dude en ir a la SDK que estoy manteniendo. El código está ahí. Usted puede tomar el archivo YAML. Y por favor, úsalo tú mismo, eres muy bienvenido. Si te pone en marcha con las pruebas de mutación, todo el mundo gana. Pero de cualquier manera, te mostraré el YAML ahora mismo. Voy a explicar lo que cada parte está haciendo y cómo funciona.

En primer lugar, se puede ver aquí que tenemos una prueba de mutación YAML. Usted puede ver que estamos corriendo en Ubuntu. Sólo estamos corriendo con una versión de Python. Eso está bien. podemos ver aquí los diferentes pasos. Por lo tanto, comprobamos el código y luego configuramos Python.

Una vez hecho esto, instalamos nuestras dependencias, pero ahora incluimos la dependencia mutmut. Una vez hecho esto, ejecutamos nuestra prueba de mutación, que hacemos con mutmut runy usamos dos banderas. Usamos --no-progressque básicamente significa que nuestros resultados se ven mejor cuando lo leemos de nuevo en nuestro sistema CI. Y también usamos el modo --CI que nos devuelve un código de error sensible. Voy a destacar que porque era mi única contribución a mutmutpero todavía estoy orgulloso de ello, así que voy a mencionarlo. En realidad es muy útil aquí porque de lo contrario no obtenemos un código de error sensible y eso hace que las Acciones de GitHub fallen. Una vez que hemos hecho eso, realmente obtenemos esa salida HTML y subimos eso para que podamos descargar eso de GitHub más tarde. Y eso es todo. Es de 35 líneas, eso es todo lo que hacemos, y eso es todo bien.

¿Qué otras preocupaciones tenemos sobre CI? ¿En qué otras cosas quieres pensar? En primer lugar, hay que pensar en la activación manual frente a la automática. Personalmente, me gusta ejecutar estas cosas manualmente porque no quiero que esto sea parte de un proceso de relaciones públicas donde tiene que obtener cierta puntuación para ser aprobado.

Quiero ejecutar esto cuando he añadido algo nuevo que podría cambiar las cosas o si necesita una visión de mi código. Puedes ejecutarlo automáticamente si quieres, pero ten en cuenta que no tienes que hacerlo. No queremos simplemente abstraer la Ley de Goodhart de nuevo y tratar de convertir la puntuación de mutación en una nueva métrica para abstraer. También queremos pensar en correr en múltiples sistemas operativos. Para mi código, realmente no necesitaba porque no espero que cambie lo suficiente - no jugamos con el sistema operativo. Estamos más haciendo llamadas a la API, por lo que no es un gran problema para nosotros. También es posible que desee ejecutar con varias versiones de sus dependencias y cosas por el estilo, para ver si algunas cosas cambian allí para usted también.

En resumen, las pruebas de mutación prueban sus pruebas. Te ayuda a superar la Ley de Goodhart en cuanto a cobertura de código. Si desea utilizarlo, yo diría que empezar poco a poco y local, pero luego, una vez que esté listo, ejecutar en un sistema de CI para que pueda obtener esas cosas hecho de forma asíncrona y no estás perdiendo el tiempo y los recursos de su máquina. Por último, sólo quiero decir que los mutantes son valiosos, y son maravillosos también. Si pensamos en Henry y todo lo que nos ha dado, como, de acuerdo, no puede volar, no puede hacer el trabajo del código que necesitamos, pero lo que ha hecho nos ha dado tanto de una visión de nuestra base de código que es super maravilloso. Y así, como dije al principio de esta presentación, no hay que temer a los mutantes, porque hay que amarlos.

Muchísimas gracias. Ha sido muy, muy agradable hablar contigo hoy. Si quieres contactarme con alguna pregunta, por favor únete al Slack de la Comunidad de Vonage. Si quieres ver el SDK de Pythonno dudes en echarle un vistazo. Y si quieres crear una Account con Vonage y probar nuestras cosas, de nuevo, hay un enlace aquí también.

Así que espero que estas cosas te sean útiles. Muchas gracias y nos vemos en otra ocasión. Saludos.

Compartir:

https://a.storyblok.com/f/270183/400x400/92109caf6a/max-kahan.png
Max KahanVonage Antiguo miembro del equipo

Max es un defensor de los desarrolladores de Python e ingeniero de software interesado en las API de comunicaciones, el aprendizaje automático, la experiencia de los desarrolladores y el baile. Su formación es en Física, pero ahora trabaja en proyectos de código abierto y hace cosas para mejorar la vida de los desarrolladores.