Pruebas con nf-test¶
Traducción asistida por IA - más información y sugerencias
Poder verificar sistemáticamente que cada parte de su workflow hace lo que se supone que debe hacer es fundamental para la reproducibilidad y el mantenimiento a largo plazo, y puede ser de gran ayuda durante el proceso de desarrollo.
Tomemos un momento para hablar sobre por qué las pruebas son tan importantes. Si está desarrollando un workflow, una de las primeras cosas que hará es obtener algunos datos de prueba que sabe que son válidos y deberían producir un resultado. Agrega el primer proceso al pipeline y lo conecta a sus entradas para que funcione. Luego, para verificar que todo funciona, lo ejecuta con los datos de prueba. Suponiendo que funciona, pasa al siguiente proceso y ejecuta los datos de prueba nuevamente. Repite este proceso hasta tener un pipeline con el que esté satisfecho.
Luego, quizás agrega un parámetro simple de verdadero o falso como --skip_process. Ahora debe ejecutar el pipeline dos veces, una con cada parámetro para asegurarse de que funciona como se espera. Pero espere, ¿cómo verificamos si --skip_process realmente omite el proceso? ¡Tenemos que revisar las salidas o verificar los archivos de registro! Esto es tedioso y propenso a errores.
A medida que desarrolla su pipeline, rápidamente se volverá tan complejo que probar manualmente cada iteración es lento y propenso a errores. Además, si encuentra un error, será muy difícil determinar exactamente de dónde proviene en su pipeline. Aquí es donde entran las pruebas.
Las pruebas le permiten verificar sistemáticamente que cada parte de su pipeline funciona como se espera. Los beneficios para un desarrollador de pruebas bien escritas son enormes:
- Confianza: Debido a que las pruebas cubren todo el pipeline, puede estar seguro de que cambiar algo no afecta nada más
- Confiabilidad: Cuando múltiples desarrolladores trabajan en el pipeline, saben que los otros desarrolladores no han roto el pipeline ni ninguno de sus componentes.
- Transparencia: Las pruebas muestran dónde falla un pipeline y facilitan la identificación del problema. También funcionan como una forma de documentación, mostrando cómo ejecutar un proceso o workflow.
- Velocidad: Debido a que las pruebas son automatizadas, pueden ejecutarse muy rápidamente y de forma repetida. Puede iterar rápidamente con menos temor de introducir nuevos errores.
Hay muchos tipos diferentes de pruebas que podemos escribir:
- Pruebas a nivel de módulo: Para procesos individuales
- Pruebas a nivel de workflow: Para un único workflow
- Pruebas a nivel de pipeline: Para el pipeline en su conjunto
- Pruebas de rendimiento: Para la velocidad y eficiencia del pipeline
- Pruebas de estrés: Para evaluar el rendimiento del pipeline bajo condiciones extremas y determinar sus límites
Probar procesos individuales es análogo a las pruebas unitarias en otros lenguajes. Probar el workflow o el pipeline completo es análogo a lo que se llama pruebas de integración en otros lenguajes, donde probamos las interacciones de los componentes.
nf-test es una herramienta que le permite escribir pruebas a nivel de módulo, workflow y pipeline. En resumen, le permite verificar sistemáticamente que cada parte individual del pipeline funciona como se espera, de forma aislada.
Objetivos de aprendizaje¶
En esta misión secundaria, aprenderá a usar nf-test para escribir una prueba a nivel de workflow para el pipeline, así como pruebas a nivel de módulo para los tres procesos que invoca.
Al finalizar esta misión secundaria, podrá usar las siguientes técnicas de manera efectiva:
- Inicializar nf-test en su proyecto
- Generar pruebas a nivel de módulo y a nivel de workflow
- Agregar tipos comunes de aserciones
- Entender cuándo usar snapshots vs. aserciones de contenido
- Ejecutar pruebas para un proyecto completo
Estas habilidades le ayudarán a implementar una estrategia de pruebas integral en sus proyectos de pipeline, asegurando que sean más robustos y mantenibles.
Requisitos previos¶
Antes de abordar esta misión secundaria, debe:
- Haber completado el tutorial Hello Nextflow o un curso equivalente para principiantes.
- Estar familiarizado con los conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores, trabajo con archivos, metadatos)
0. Primeros pasos¶
Abra el codespace de capacitación¶
Si aún no lo ha hecho, asegúrese de abrir el entorno de capacitación como se describe en la Configuración del entorno.
Muévase al directorio del proyecto¶
Vamos a movernos al directorio donde se encuentran los archivos de este tutorial.
Puede configurar VSCode para que se enfoque en este directorio:
Revise los materiales¶
Encontrará un archivo de workflow principal y un archivo CSV llamado greetings.csv que contiene la entrada al pipeline.
Para una descripción detallada de los archivos, consulte el calentamiento de Hello Nextflow.
El workflow que probaremos es un subconjunto del workflow Hello construido en Hello Workflow.
¿Qué hace el workflow Hello Nextflow?
Si no ha realizado la capacitación de Hello Nextflow, aquí tiene una descripción general de lo que hace este sencillo workflow.
El workflow toma un archivo CSV que contiene saludos, ejecuta cuatro pasos de transformación consecutivos sobre ellos y genera un único archivo de texto que contiene una imagen ASCII de un personaje divertido diciendo los saludos.
Los cuatro pasos están implementados como procesos de Nextflow (sayHello, convertToUpper, collectGreetings y cowpy) almacenados en archivos de módulo separados.
sayHello: Escribe cada saludo en su propio archivo de salida (por ejemplo, "Hello-output.txt")convertToUpper: Convierte cada saludo a mayúsculas (por ejemplo, "HELLO")collectGreetings: Recopila todos los saludos en mayúsculas en un único archivo por lotescowpy: Genera arte ASCII usando la herramientacowpy
Los resultados se publican en un directorio llamado results/, y la salida final del pipeline (cuando se ejecuta con los parámetros predeterminados) es un archivo de texto plano que contiene arte ASCII de un personaje diciendo los saludos en mayúsculas.
En esta misión secundaria, usamos una forma intermedia del workflow Hello que solo contiene los primeros dos procesos.
El subconjunto con el que trabajaremos está compuesto por dos procesos: sayHello y convertToUpper.
Puede ver el código completo del workflow a continuación.
Código del flujo de trabajo
/*
* Parámetros del pipeline
*/
params.input_file = "greetings.csv"
/*
* Usa echo para imprimir 'Hello World!' en la salida estándar
*/
process sayHello {
publishDir 'results', mode: 'copy'
input:
val greeting
output:
path "${greeting}-output.txt"
script:
"""
echo '$greeting' > '$greeting-output.txt'
"""
}
/*
* Usa una utilidad de reemplazo de texto para convertir el saludo a mayúsculas
*/
process convertToUpper {
publishDir 'results', mode: 'copy'
input:
path input_file
output:
path "UPPER-${input_file}"
script:
"""
cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file}
"""
}
workflow {
// crea un canal para las entradas desde un archivo CSV
greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten()
// emite un saludo
sayHello(greeting_ch)
// convierte el saludo a mayúsculas
convertToUpper(sayHello.out)
}
Ejecute el workflow¶
Vamos a ejecutar el workflow para asegurarnos de que funciona como se espera.
N E X T F L O W ~ version 24.10.2
Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31
executor > local (6)
[f7/c3be66] sayHello (3) | 3 of 3 ✔
[cd/e15303] convertToUpper (3) | 3 of 3 ✔
¡FELICIDADES! ¡Acaba de ejecutar una prueba!
"¿Espere, qué? ¡Acabo de ejecutar el workflow y funcionó! ¿Cómo es eso una prueba?"
¡Buena pregunta!
Analicemos lo que acaba de ocurrir.
Ejecutó el workflow con los parámetros predeterminados, confirmó que funcionó y está satisfecho con los resultados. Esta es la esencia de las pruebas. Si trabajó en el curso de capacitación Hello Nextflow, habrá notado que siempre comenzamos cada sección ejecutando el workflow que usábamos como punto de partida, para confirmar que todo está configurado correctamente.
Las pruebas de software esencialmente realizan este proceso por nosotros.
Revise la tarea¶
Su desafío es agregar pruebas estandarizadas a este workflow usando nf-test, con el fin de facilitar la verificación de que cada parte continúa funcionando como se espera en caso de que se realicen más cambios.
Lista de verificación de preparación¶
¿Cree que está listo para comenzar?
- Entiendo el objetivo de este curso y sus requisitos previos
- Mi codespace está en funcionamiento
- He configurado mi directorio de trabajo correctamente
- He ejecutado el workflow exitosamente
- Entiendo la tarea
Si puede marcar todas las casillas, está listo para continuar.
1. Inicializar nf-test¶
El paquete nf-test proporciona un comando de inicialización que configura algunas cosas para que podamos comenzar a desarrollar pruebas para nuestro proyecto.
Esto debería producir la siguiente salida:
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Project configured. Configuration is stored in nf-test.config
También crea un directorio tests que contiene un archivo de configuración base.
1.1. Generar un nf-test¶
nf-test viene con un conjunto de herramientas para construir archivos nf-test, lo que nos ahorra la mayor parte del trabajo. Estas se encuentran bajo el subcomando generate. Vamos a generar una prueba para el pipeline:
> nf-test generate pipeline main.nf
Load source file '/workspaces/training/side-quests/nf-test/main.nf'
Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test
SUCCESS: Generated 1 test files.
Esto creará un archivo main.nf.test dentro del directorio tests. Este es nuestro archivo de prueba a nivel de pipeline. Si ejecuta tree tests/ debería ver algo como esto:
El archivo main.nf.test es nuestro archivo de prueba a nivel de pipeline. Vamos a abrirlo y examinar su contenido.
nextflow_pipeline {
name "Test Workflow main.nf"
script "main.nf"
test("Should run without failures") {
when {
params {
// define parameters here. Example:
// outdir = "tests/results"
}
}
then {
assert workflow.success
}
}
}
Tomemos un momento para entender la estructura del archivo de prueba.
El bloque nextflow_pipeline es el punto de entrada para todas las pruebas a nivel de pipeline. Contiene lo siguiente:
name: El nombre de la prueba.script: La ruta al script del pipeline.
El bloque test es la prueba en sí. Contiene lo siguiente:
when: Las condiciones bajo las cuales se debe ejecutar la prueba. Esto incluye los parámetros que se usarán para ejecutar el pipeline.then: Las aserciones que se deben realizar. Esto incluye los resultados esperados del pipeline.
En términos simples, la lógica de la prueba se lee de la siguiente manera: "Cuando se proporcionan estos parámetros a este pipeline, entonces esperamos ver estos resultados."
Esta no es una prueba funcional; demostraremos cómo convertirla en una en la siguiente sección.
Una nota sobre los nombres de las pruebas¶
En el ejemplo anterior, usamos el nombre predeterminado "Should run without failures" que es apropiado para una prueba básica que solo verifica si el pipeline se ejecuta exitosamente. Sin embargo, a medida que agregamos casos de prueba más específicos, debemos usar nombres más descriptivos que indiquen qué estamos probando realmente. Por ejemplo:
- "Should convert input to uppercase" - al probar funcionalidad específica
- "Should handle empty input gracefully" - al probar casos límite
- "Should respect max memory parameter" - al probar restricciones de recursos
- "Should create expected output files" - al probar la generación de archivos
Los buenos nombres de prueba deben:
- Comenzar con "Should" para dejar claro cuál es el comportamiento esperado
- Describir la funcionalidad o el escenario específico que se está probando
- Ser lo suficientemente claros para que, si la prueba falla, sepa qué funcionalidad está rota
A medida que agreguemos más aserciones y casos de prueba específicos más adelante, usaremos estos nombres más descriptivos para dejar claro qué está verificando cada prueba.
1.2. Ejecutar la prueba¶
Vamos a ejecutar la prueba para ver qué sucede.
> nf-test test tests/main.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Workflow main.nf
Test [693ba951] 'Should run without failures' FAILED (4.652s)
Assertion failed:
assert workflow.success
| |
workflow false
Nextflow stdout:
ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv
-- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details
Nextflow stderr:
FAILURE: Executed 1 tests in 4.679s (1 failed)
¡La prueba falla! ¿Qué ocurrió?
- nf-test intentó ejecutar el pipeline tal como está, usando la configuración del bloque
when:
when {
params {
// define parameters here. Example:
// outdir = "tests/results"
}
}
- nf-test verificó el estado del pipeline y lo comparó con el bloque
when:
Observe cómo nf-test ha reportado que el pipeline falló y proporcionó el mensaje de error de Nextflow:
ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv
¿Cuál fue el problema? Recuerde que el pipeline tiene un archivo greetings.csv en el directorio del proyecto. Cuando nf-test ejecuta el pipeline, buscará este archivo, pero no puede encontrarlo. El archivo está ahí, ¿qué está pasando? Bueno, si miramos la ruta podemos ver que la prueba ocurre en la ruta ./nf-test/tests/longHashString/. Al igual que Nextflow, nf-test crea un nuevo directorio para cada prueba para mantener todo aislado. El archivo de datos no está ubicado allí, por lo que debemos corregir la ruta al archivo en la prueba original.
Volvamos al archivo de prueba y cambiemos la ruta al archivo en el bloque when.
Quizás se pregunte cómo vamos a apuntar a la raíz del pipeline en la prueba. Dado que esta es una situación común, nf-test tiene un conjunto de variables globales que podemos usar para facilitarnos la vida. Puede encontrar la lista completa aquí pero por ahora usaremos la variable projectDir, que representa la raíz del proyecto del pipeline.
Vamos a ejecutar la prueba nuevamente para ver si funciona.
> nf-test test tests/main.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Workflow main.nf
Test [1d4aaf12] 'Should run without failures' PASSED (1.619s)
SUCCESS: Executed 1 tests in 1.626s
¡Éxito! El pipeline se ejecuta exitosamente y la prueba pasa. ¡Ejecútelo tantas veces como quiera y siempre obtendrá el mismo resultado!
Por defecto, la salida de Nextflow está oculta, pero para convencerse de que nf-test definitivamente está ejecutando el workflow, puede usar el indicador --verbose:
> nf-test test tests/main.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Workflow main.nf
Test [693ba951] 'Should run without failures'
> Nextflow 24.10.4 is available - Please consider updating your version to it
> N E X T F L O W ~ version 24.10.0
> Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31
> [2b/61e453] Submitted process > sayHello (2)
> [31/4e1606] Submitted process > sayHello (1)
> [bb/5209ee] Submitted process > sayHello (3)
> [83/83db6f] Submitted process > convertToUpper (2)
> [9b/3428b1] Submitted process > convertToUpper (1)
> [ca/0ba51b] Submitted process > convertToUpper (3)
PASSED (5.206s)
SUCCESS: Executed 1 tests in 5.239s
1.3. Agregar aserciones¶
Una verificación simple es asegurarse de que nuestro pipeline esté ejecutando todos los procesos que esperamos y que no omita ninguno silenciosamente. Recuerde que nuestro pipeline ejecuta 6 procesos, uno llamado sayHello y uno llamado convertToUpper para cada uno de los 3 saludos.
Vamos a agregar una aserción a nuestra prueba para verificar que el pipeline ejecuta el número esperado de procesos. También actualizaremos el nombre de nuestra prueba para reflejar mejor lo que estamos probando.
El nombre de la prueba ahora refleja mejor lo que realmente estamos verificando: no solo que el pipeline se ejecuta sin fallar, sino que ejecuta el número esperado de procesos.
Vamos a ejecutar la prueba nuevamente para ver si funciona.
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Workflow main.nf
Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s)
SUCCESS: Executed 1 tests in 1.588s
¡Éxito! El pipeline se ejecuta exitosamente y la prueba pasa. Ahora hemos comenzado a probar los detalles del pipeline, además del estado general.
1.4. Probar la salida¶
Vamos a agregar una aserción a nuestra prueba para verificar que el archivo de salida fue creado. Lo agregaremos como una prueba separada, con un nombre informativo, para que los resultados sean más fáciles de interpretar.
Ejecute la prueba nuevamente para ver si funciona.
> nf-test test tests/main.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Workflow main.nf
Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s)
Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s)
SUCCESS: Executed 2 tests in 15.165s
¡Éxito! Las pruebas pasan porque el pipeline se completó exitosamente, el número correcto de procesos se ejecutó y los archivos de salida fueron creados. Esto también debería mostrarle cuán útil es proporcionar esos nombres informativos para sus pruebas.
Esto es solo la superficie; podemos seguir escribiendo aserciones para verificar los detalles del pipeline, pero por ahora avancemos a probar los componentes internos del pipeline.
Conclusión¶
Sabe cómo escribir un nf-test para un pipeline.
¿Qué sigue?¶
Aprenda cómo probar un proceso de Nextflow.
2. Probar un proceso de Nextflow¶
No tenemos que escribir pruebas para cada parte del pipeline, pero cuantas más pruebas tengamos, más exhaustivos podemos ser sobre el pipeline y más seguros podemos estar de que funciona como se espera. En esta sección vamos a probar ambos procesos del pipeline como unidades individuales.
2.1. Probar el proceso sayHello¶
Comencemos con el proceso sayHello.
Usemos el comando nf-test generate nuevamente para generar pruebas para el proceso.
> nf-test generate process main.nf
Load source file '/workspaces/training/side-quests/nf-test/main.nf'
Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test
Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test
SUCCESS: Generated 2 test files.
Por ahora centrémonos en el proceso sayhello en el archivo main.sayhello.nf.test.
Vamos a abrir el archivo y examinar su contenido.
nextflow_process {
name "Test Process sayHello"
script "main.nf"
process "sayHello"
test("Should run without failures") {
when {
params {
// define parameters here. Example:
// outdir = "tests/results"
}
process {
"""
// define inputs of the process here. Example:
// input[0] = file("test-file.txt")
"""
}
}
then {
assert process.success
assert snapshot(process.out).match()
}
}
}
Como antes, comenzamos con los detalles de la prueba, seguidos de los bloques when y then. Sin embargo, también tenemos un bloque process adicional que nos permite definir las entradas al proceso.
Vamos a ejecutar la prueba para ver si funciona.
> nf-test test tests/main.sayhello.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process sayHello
Test [1eaad118] 'Should run without failures' FAILED (4.876s)
Assertion failed:
assert process.success
| |
| false
sayHello
Nextflow stdout:
Process `sayHello` declares 1 input but was called with 0 arguments
Nextflow stderr:
FAILURE: Executed 1 tests in 4.884s (1 failed)
La prueba falla porque el proceso sayHello declara 1 entrada pero fue llamado con 0 argumentos. Vamos a corregir eso agregando una entrada al proceso. Recuerde de Hello Workflow (y la sección de calentamiento anterior) que nuestro proceso sayHello toma una única entrada de valor, que necesitaremos proporcionar. También debemos corregir el nombre de la prueba para reflejar mejor lo que estamos probando.
| tests/main.sayhello.nf.test | |
|---|---|
| tests/main.sayhello.nf.test | |
|---|---|
Vamos a ejecutar la prueba nuevamente para ver si funciona.
> nf-test test tests/main.sayhello.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process sayHello
Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s)
Snapshots:
1 created [Should run without failures and produce correct output]
Snapshot Summary:
1 created
SUCCESS: Executed 1 tests in 1.611s
¡Éxito! La prueba pasa porque el proceso sayHello se ejecutó exitosamente y la salida fue creada.
2.2. Examine el snapshot creado por la prueba¶
Si miramos el archivo tests/main.sayhello.nf.test, podemos ver que usa un método snapshot() en el bloque de aserciones:
Esto le indica a nf-test que cree un snapshot de la salida del proceso sayHello. Vamos a examinar el contenido del archivo de snapshot.
No lo imprimiremos aquí, pero debería ver un archivo JSON que contiene detalles del proceso y sus salidas. En particular, podemos ver una línea que se ve así:
Esto representa las salidas creadas por el proceso sayHello, que estamos probando explícitamente. Si volvemos a ejecutar la prueba, el programa verificará que la nueva salida coincida con la salida que se registró originalmente. Esta es una forma rápida y sencilla de probar que las salidas del proceso no cambian, razón por la cual nf-test la proporciona como opción predeterminada.
Advertencia
¡Eso significa que debemos asegurarnos de que la salida que registramos en la ejecución original sea correcta!
Si, en el transcurso del desarrollo futuro, algo en el código cambia y hace que la salida sea diferente, la prueba fallará y tendremos que determinar si el cambio es esperado o no.
- Si resulta que algo en el código se rompió, tendremos que corregirlo, con la expectativa de que el código corregido pase la prueba.
- Si es un cambio esperado (por ejemplo, la herramienta ha sido mejorada y los resultados son mejores), entonces necesitaremos actualizar el snapshot para aceptar la nueva salida como referencia. nf-test tiene un parámetro
--update-snapshotpara este propósito.
Podemos ejecutar la prueba nuevamente y ver que debería pasar:
> nf-test test tests/main.sayhello.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process sayHello
Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s)
SUCCESS: Executed 1 tests in 1.685s
¡Éxito! La prueba pasa porque el proceso sayHello se ejecutó exitosamente y la salida coincidió con el snapshot.
2.3. Alternativa a los snapshots: aserciones de contenido directo¶
Si bien los snapshots son excelentes para detectar cualquier cambio en la salida, a veces se desea verificar contenido específico sin ser tan estricto sobre que todo el archivo coincida. Por ejemplo:
- Cuando partes de la salida pueden cambiar (marcas de tiempo, IDs aleatorios, etc.) pero cierto contenido clave debe estar presente
- Cuando se desea verificar patrones o valores específicos en la salida
- Cuando se desea hacer la prueba más explícita sobre qué constituye el éxito
Así es como podríamos modificar nuestra prueba para verificar contenido específico:
| tests/main.sayhello.nf.test | |
|---|---|
Tenga en cuenta que nf-test ve las salidas del proceso como una lista de listas, por lo que process.out[0][0] está obteniendo la primera parte del primer elemento del canal (o 'emisión') de este proceso.
Este enfoque:
- Deja claro exactamente qué esperamos en la salida
- Es más resistente a cambios irrelevantes en la salida
- Proporciona mejores mensajes de error cuando las pruebas fallan
- Permite validaciones más complejas (patrones regex, comparaciones numéricas, etc.)
Vamos a ejecutar la prueba para ver si funciona.
> nf-test test tests/main.sayhello.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process sayHello
Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s)
SUCCESS: Executed 1 tests in 7.208s
2.4. Probar el proceso convertToUpper¶
Vamos a abrir el archivo tests/main.converttoupper.nf.test y examinar su contenido:
nextflow_process {
name "Test Process convertToUpper"
script "main.nf"
process "convertToUpper"
test("Should run without failures") {
when {
params {
// define parameters here. Example:
// outdir = "tests/results"
}
process {
"""
// define inputs of the process here. Example:
// input[0] = file("test-file.txt")
"""
}
}
then {
assert process.success
assert snapshot(process.out).match()
}
}
}
Esta es una prueba similar a la del proceso sayHello, pero está probando el proceso convertToUpper. Sabemos que esta fallará porque, al igual que con sayHello, el proceso convertToUpper toma una única entrada de ruta, pero no hemos especificado ninguna.
Ahora necesitamos proporcionar un único archivo de entrada al proceso convertToUpper, que incluya algún texto que queramos convertir a mayúsculas. Hay muchas formas de hacer esto:
- Podríamos crear un archivo dedicado para la prueba
- Podríamos reutilizar el archivo data/greetings.csv existente
- Podríamos crearlo sobre la marcha dentro de la prueba
Por ahora, reutilicemos el archivo data/greetings.csv existente usando el ejemplo que usamos con la prueba a nivel de pipeline. Como antes, podemos nombrar la prueba para reflejar mejor lo que estamos probando, pero esta vez dejemos que 'capture' el contenido en lugar de verificar cadenas específicas (como hicimos en el otro proceso).
| tests/main.converttoupper.nf.test | |
|---|---|
| tests/main.converttoupper.nf.test | |
|---|---|
¡Y ejecute la prueba!
> nf-test test tests/main.converttoupper.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process convertToUpper
Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s)
Snapshots:
1 created [Should run without failures and produce correct output]
Snapshot Summary:
1 created
SUCCESS: Executed 1 tests in 1.764s
Tenga en cuenta que hemos creado un archivo de snapshot para el proceso convertToUpper en tests/main.converttoupper.nf.test.snap. Si ejecutamos la prueba nuevamente, deberíamos ver que nf-test pasa de nuevo.
> nf-test test tests/main.converttoupper.nf.test
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process convertToUpper
Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s)
SUCCESS: Executed 1 tests in 1.811s
Conclusión¶
Sabe cómo escribir pruebas para un proceso de Nextflow y ejecutarlas.
¿Qué sigue?¶
¡Aprenda cómo ejecutar todas las pruebas a la vez!
3. Ejecutar pruebas para todo el repositorio¶
Ejecutar nf-test en cada componente está bien, pero es laborioso y propenso a errores. ¿No podemos simplemente probar todo a la vez?
¡Sí podemos!
Vamos a ejecutar nf-test en todo el repositorio.
3.1. Ejecutar nf-test en todo el repositorio¶
Podemos ejecutar nf-test en todo el repositorio ejecutando el comando nf-test test.
Tenga en cuenta que simplemente usamos . para ejecutar todo desde nuestro directorio actual. ¡Esto incluirá cada prueba!
> nf-test test .
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process convertToUpper
Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s)
Test Workflow main.nf
Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s)
Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s)
Test Process sayHello
Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s)
SUCCESS: Executed 4 tests in 13.481s
¡Mire eso! Ejecutamos 4 pruebas, 1 para cada proceso y 2 para todo el pipeline con un solo comando. ¡Imagine lo poderoso que es esto en una base de código grande!
Resumen¶
En esta misión secundaria, ha aprendido a aprovechar las funcionalidades de nf-test para crear y ejecutar pruebas para procesos individuales, así como pruebas de extremo a extremo para todo el pipeline. Ahora conoce los dos enfoques principales para la validación de salidas, los snapshots y las aserciones de contenido directo, y cuándo usar cada uno. También sabe cómo ejecutar pruebas una por una o para un proyecto completo.
Aplicar estas técnicas en su propio trabajo le permitirá asegurarse de que:
- Su código funciona como se espera
- Los cambios no rompen la funcionalidad existente
- Otros desarrolladores pueden contribuir con confianza
- Los problemas pueden identificarse y corregirse rápidamente
- El contenido de la salida cumple con las expectativas
Patrones clave¶
- Pruebas a nivel de pipeline:
- Prueba básica de éxito
- Verificación del número de procesos
- Verificación de la existencia de archivos de salida
- Pruebas a nivel de proceso
- Dos enfoques para la validación de salidas:
- Uso de snapshots para la verificación completa de la salida
- Uso de aserciones de contenido directo para verificaciones de contenido específico
- Ejecución de todas las pruebas en un repositorio con un solo comando
Recursos adicionales¶
Consulte la documentación de nf-test para conocer funcionalidades de prueba más avanzadas y mejores prácticas. Es posible que desee:
- Agregar aserciones más completas a sus pruebas
- Escribir pruebas para casos límite y condiciones de error
- Configurar integración continua para ejecutar pruebas automáticamente
- Aprender sobre otros tipos de pruebas como pruebas de workflow y de módulo
- Explorar técnicas de validación de contenido más avanzadas
Recuerde: Las pruebas son documentación viva de cómo debe comportarse su código. Cuantas más pruebas escriba, y cuanto más específicas sean sus aserciones, más seguro podrá estar de la confiabilidad de su pipeline.
¿Qué sigue?¶
Regrese al menú de misiones secundarias o haga clic en el botón en la parte inferior derecha de la página para continuar con el siguiente tema de la lista.