Teil 4: Tests hinzufügen¶
KI-gestützte Übersetzung - mehr erfahren & Verbesserungen vorschlagen
Im ersten Teil dieses Kurses hast du eine Varianten-Calling-Pipeline erstellt, die vollständig linear war und die Daten jeder Probe unabhängig von den anderen verarbeitet hat.
Im zweiten Teil haben wir dir gezeigt, wie du Channels und Channel-Operatoren verwendest, um gemeinsames Varianten-Calling mit GATK zu implementieren.
Im dritten Teil haben wir die Pipeline modularisiert.
In diesem Teil des Trainings zeigen wir dir, wie du nf-test verwendest, ein Test-Framework, das sich gut in Nextflow integriert und es einfach macht, sowohl Tests auf Modul-Ebene als auch auf Workflow-Ebene zu deiner Pipeline hinzuzufügen. Um diesem Teil des Trainings zu folgen, solltest du Teil 1, Teil 2 und Teil 3 abgeschlossen haben, sowie die nf-test Side Quest, die die Grundlagen von nf-test behandelt und erklärt, warum Testen wichtig ist.
0. Aufwärmen¶
Hinweis
Stelle sicher, dass du im richtigen Arbeitsverzeichnis bist:
cd /workspaces/training/nf4-science/genomics
Wenn du die vorherigen Teile dieses Trainingskurses durchgearbeitet hast, solltest du eine funktionierende Version der Genomik-Pipeline mit der entsprechenden Modulverzeichnisstruktur haben.
Verzeichnisinhalte
Dieses Modulverzeichnis findest du im solutions-Verzeichnis, falls du es benötigst.
Wir beginnen mit demselben Workflow wie in Teil 3, den wir dir in der Datei genomics-4.nf bereitgestellt haben. Genau wie bei der nf-test Side Quest werden wir den drei Prozessen in dieser Pipeline verschiedene Arten von Tests hinzufügen sowie einen Test auf Workflow-Ebene.
0.1. Prüfen, ob der Workflow läuft¶
Bevor wir mit dem Hinzufügen von Tests beginnen, stelle sicher, dass der Workflow wie erwartet läuft.
Das sollte inzwischen sehr vertraut aussehen, wenn du diesen Trainingskurs von Anfang an durchgearbeitet hast.
Befehlsausgabe
Wie zuvor wird es jetzt ein work-Verzeichnis und ein results_genomics-Verzeichnis in deinem Projektverzeichnis geben. Diese Ergebnisse werden wir später beim Testen tatsächlich verwenden. Aber ab jetzt werden wir das nf-test-Paket verwenden, um die Pipeline zu testen.
0.2. nf-test initialisieren¶
Wie bei der nf-test Side Quest müssen wir das nf-test-Paket initialisieren.
Befehlsausgabe
nf-test.config-Inhalte
Es erstellt auch ein tests-Verzeichnis mit einer Konfigurationsdatei-Vorlage.
Zusammenfassung¶
Jetzt sind wir bereit, Tests für unsere Genomik-Pipeline zu schreiben.
Wie geht es weiter?¶
Schreibe grundlegende Tests, die prüfen, ob die Prozessaufrufe erfolgreich waren und die richtigen Ausgaben produziert haben.
1. Einen Prozess auf Erfolg und übereinstimmende Ausgaben testen¶
Wir beginnen mit dem Testen des SAMTOOLS_INDEX-Prozesses, der Indexdateien für BAM-Dateien erstellt, um effizienten Direktzugriff zu ermöglichen. Dies ist ein guter erster Testfall, weil:
- Er eine einzelne, klar definierte Eingabe hat (eine BAM-Datei)
- Er eine vorhersagbare Ausgabe produziert (eine BAI-Indexdatei)
- Die Ausgabe bei identischen Eingaben identisch sein sollte
1.1. Eine Test-Datei-Vorlage generieren¶
Generiere zunächst eine Test-Datei-Vorlage:
Befehlsausgabe
Dies erstellt eine Datei im selben Verzeichnis wie main.nf.
Du kannst im Datei-Explorer zu dem Verzeichnis navigieren und die Datei öffnen, die folgenden Code enthalten sollte:
Die anfänglichen Assertions sollten aus der nf-test Side Quest bekannt sein:
assert process.successbesagt, dass wir erwarten, dass der Prozess erfolgreich läuft und ohne Fehler abgeschlossen wird.snapshot(process.out).match()besagt, dass wir erwarten, dass das Ergebnis des Laufs mit dem Ergebnis eines vorherigen Laufs identisch ist (falls zutreffend). Wir besprechen dies später ausführlicher.
Mit diesem Ausgangspunkt müssen wir die richtigen Test-Eingaben für den samtools index-Prozess hinzufügen und gegebenenfalls Parameter.
1.2. Die Test-Datei verschieben und den Script-Pfad aktualisieren¶
Bevor wir mit dem Ausfüllen des Tests beginnen, müssen wir die Datei an ihren endgültigen Speicherort verschieben. Ein Teil des Grundes, warum wir ein Verzeichnis für jedes Modul hinzugefügt haben, ist, dass wir jetzt Tests in einem tests-Verzeichnis zusammen mit der main.nf-Datei jedes Moduls ablegen können. Erstelle dieses Verzeichnis und verschiebe die Test-Datei dorthin.
mkdir -p modules/samtools/index/tests
mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/
Jetzt können wir den script-Abschnitt der Test-Datei zu einem relativen Pfad vereinfachen:
Dies teilt dem Test mit, wo die main.nf-Datei des Moduls zu finden ist, ohne den vollständigen Pfad angeben zu müssen.
1.3. Test-Eingaben für SAMTOOLS_INDEX bereitstellen¶
Die Vorlagendatei enthält einen Platzhalter, den wir durch eine tatsächliche Test-Eingabe ersetzen müssen, die für die Eingabe von samtools index geeignet ist. Die passende Eingabe ist eine BAM-Datei, die wir im Verzeichnis data/bam verfügbar haben.
1.4. Den Test basierend auf der Funktionalität benennen¶
Wie wir zuvor gelernt haben, ist es eine gute Praxis, den Test so umzubenennen, dass er im Kontext des Tests sinnvoll ist.
| modules/samtools/index/tests/main.nf.test | |
|---|---|
Dies nimmt eine beliebige Zeichenkette, wir könnten also alles eingeben, was wir wollen. Hier wählen wir, uns auf den Dateinamen und sein Format zu beziehen.
| modules/samtools/index/tests/main.nf.test | |
|---|---|
1.5. Den Test ausführen und die Ausgabe untersuchen¶
Führe den Test aus:
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process SAMTOOLS_INDEX
Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s)
Snapshots:
1 created [Should index reads_son.bam correctly]
Snapshot Summary:
1 created
SUCCESS: Executed 1 tests in 7.727s
Wie wir zuvor gelernt haben, hat dies die grundlegende Assertion über den Erfolg des Prozesses verifiziert und eine Snapshot-Datei basierend auf der Ausgabe des Prozesses erstellt. Wir können den Inhalt der Snapshot-Datei in der Datei tests/modules/samtools/index/tests/main.nf.test.snap sehen:
| modules/samtools/index/tests/main.nf.test.snap | |
|---|---|
Wir können den Test auch erneut ausführen und sehen, dass er besteht, weil die Ausgabe mit dem Snapshot identisch ist:
Befehlsausgabe
1.6. Weitere Tests zu SAMTOOLS_INDEX hinzufügen¶
Manchmal ist es nützlich, eine Reihe verschiedener Eingabedateien zu testen, um sicherzustellen, dass wir auf verschiedene potenzielle Probleme testen. Füge Tests für die BAM-Dateien von Mutter und Vater im Trio aus unseren Testdaten hinzu.
test("Should index reads_mother.bam correctly") {
when {
params {
// Parameter hier definieren
}
process {
"""
input[0] = file("${projectDir}/data/bam/reads_mother.bam")
"""
}
}
then {
assert process.success
assert snapshot(process.out).match()
}
}
test("Should index reads_father.bam correctly") {
when {
params {
// Parameter hier definieren
}
process {
"""
input[0] = file("${projectDir}/data/bam/reads_father.bam")
"""
}
}
then {
assert process.success
assert snapshot(process.out).match()
}
}
Dann kannst du den Test erneut ausführen:
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process SAMTOOLS_INDEX
Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s)
Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s)
Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s)
Snapshots:
2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly]
Snapshot Summary:
2 created
SUCCESS: Executed 3 tests in 20.117s
Beachte die Warnung, die sich auf die Wirkung des Parameters --update-snapshot bezieht.
Hinweis
Hier verwenden wir Testdaten, die wir zuvor verwendet haben, um die wissenschaftlichen Ausgaben der Pipeline zu demonstrieren. Wenn wir geplant hätten, diese Tests in einer Produktionsumgebung zu betreiben, hätten wir kleinere Eingaben zu Testzwecken generiert.
Im Allgemeinen ist es wichtig, Unit-Tests so leicht wie möglich zu halten, indem man die kleinsten notwendigen und ausreichenden Datenmengen zur Bewertung der Prozessfunktionalität verwendet, da sich sonst die Gesamtlaufzeit erheblich summieren kann. Eine Test-Suite, die zu lange dauert, um regelmäßig ausgeführt zu werden, ist eine Test-Suite, die wahrscheinlich im Interesse der Schnelligkeit übersprungen wird.
Zusammenfassung¶
Du hast deinen ersten Modultest für einen Genomik-Prozess geschrieben und verifiziert, dass SAMTOOLS_INDEX korrekt Indexdateien für verschiedene BAM-Dateien erstellt. Die Test-Suite stellt sicher, dass:
- Der Prozess erfolgreich läuft
- Indexdateien erstellt werden
- Die Ausgaben über Läufe hinweg konsistent sind
- Der Prozess für alle Proben-BAM-Dateien funktioniert
Wie geht es weiter?¶
Lerne, wie du Tests für andere Prozesse in unserem Genomik-Workflow schreibst, indem du die setup-Methode verwendest, um verkettete Prozesse zu handhaben. Wir werden auch prüfen, ob Ausgaben, insbesondere unsere VCF-Dateien, erwartete Variantenaufrufe enthalten.
2. Tests zu einem verketteten Prozess hinzufügen und auf Inhalte testen¶
Um GATK_HAPLOTYPECALLER zu testen, müssen wir dem Prozess die Ausgabe von SAMTOOLS_INDEX als Eingabe bereitstellen. Wir könnten das tun, indem wir SAMTOOLS_INDEX ausführen, seine Ausgaben abrufen und sie mit den Testdaten für den Workflow speichern. Das ist tatsächlich der empfohlene Ansatz für eine ausgereifte Pipeline, aber nf-test bietet einen alternativen Ansatz mit der setup-Methode.
Mit der setup-Methode können wir den SAMTOOLS_INDEX-Prozess als Teil des Test-Setups auslösen und dann seine Ausgabe als Eingabe für GATK_HAPLOTYPECALLER verwenden. Das hat einen Preis: Wir müssen den SAMTOOLS_INDEX-Prozess jedes Mal ausführen, wenn wir den Test für GATK_HAPLOTYPECALLER durchführen. Vielleicht entwickeln wir jedoch noch den Workflow und wollen keine Testdaten vorab generieren, die wir später möglicherweise ändern müssen. Der SAMTOOLS_INDEX-Prozess ist auch sehr schnell, sodass die Vorteile des Vorab-Generierens und Speicherns seiner Ausgaben vielleicht vernachlässigbar sind. So funktioniert die setup-Methode.
2.1. Die Test-Datei generieren und platzieren¶
Wie zuvor generieren wir zunächst die Datei-Vorlage:
Befehlsausgabe
Dies erzeugt die folgende Test-Vorlage:
2.2. Die Test-Datei verschieben und den Script-Pfad aktualisieren¶
Wir erstellen ein Verzeichnis für die Test-Datei zusammen mit der main.nf-Datei des Moduls:
Und verschieben die Test-Vorlagendatei dorthin:
Vergiss nicht, den Script-Pfad zu aktualisieren:
2.3. Eingaben mit der setup-Methode bereitstellen¶
Wir fügen vor dem when-Block einen setup-Block ein, in dem wir einen Lauf des SAMTOOLS_INDEX-Prozesses auf einer unserer ursprünglichen Eingabedateien auslösen können. Denke auch daran, wie zuvor den Testnamen in etwas Aussagekräftiges zu ändern.
Dann können wir auf die Ausgabe dieses Prozesses im when-Block verweisen, wo wir die Test-Eingaben spezifizieren:
Führe diese Änderung durch und führe den Test erneut aus:
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process GATK_HAPLOTYPECALLER
Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s)
Snapshots:
1 created [Should call son's haplotype correctly]
Snapshot Summary:
1 created
SUCCESS: Executed 1 tests in 40.555s
Es erzeugt auch wie zuvor eine Snapshot-Datei.
2.4. Erneut ausführen und Fehler beobachten¶
Interessanterweise wird der Test fehlschlagen, wenn du genau denselben Befehl noch einmal ausführst.
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process GATK_HAPLOTYPECALLER
Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s)
java.lang.RuntimeException: Different Snapshot:
[ [
{ {
"0": [ "0": [
"reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac"
], ],
"1": [ "1": [
"reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242"
], ],
"idx": [ "idx": [
"reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242"
], ],
"vcf": [ "vcf": [
"reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac"
] ]
} }
] ]
Nextflow stdout:
Nextflow stderr:
Obsolete snapshots can only be checked if all tests of a file are executed successful.
FAILURE: Executed 1 tests in 40.156s (1 failed)
Die Fehlermeldung sagt dir, dass es Unterschiede zwischen den Snapshots für die beiden Läufe gab; insbesondere sind die md5sum-Werte für die VCF-Dateien unterschiedlich.
Warum? Um es kurz zu machen: Das HaplotypeCaller-Tool fügt einen Zeitstempel in den VCF-Header ein, der jedes Mal anders ist (per Definition). Folglich können wir nicht einfach erwarten, dass die Dateien identische md5sums haben, selbst wenn sie in Bezug auf die Variantenaufrufe selbst identischen Inhalt haben.
Wie gehen wir damit um?
2.5. Eine Inhaltsassertion-Methode verwenden, um eine bestimmte Variante zu prüfen¶
Eine Möglichkeit, das Problem zu lösen, besteht darin, eine andere Art von Assertion zu verwenden. In diesem Fall werden wir auf spezifischen Inhalt prüfen, anstatt Identität zu behaupten. Genauer gesagt lassen wir das Tool die Zeilen der VCF-Datei lesen und prüfen auf das Vorhandensein bestimmter Zeilen.
In der Praxis ersetzen wir die zweite Assertion im then-Block wie folgt:
| modules/gatk/haplotypecaller/tests/main.nf.test | |
|---|---|
Hier lesen wir den vollständigen Inhalt der VCF-Ausgabedatei ein und suchen nach einer Inhaltsübereinstimmung, was bei einer kleinen Testdatei in Ordnung ist, aber du würdest das nicht bei einer größeren Datei tun wollen. Stattdessen könntest du dich entscheiden, bestimmte Zeilen einzulesen.
Dieser Ansatz erfordert eine sorgfältigere Auswahl dessen, was wir als "Signal" zum Testen verwenden möchten. Auf der positiven Seite kann es verwendet werden, um mit großer Präzision zu testen, ob ein Analyse-Tool konsistent "schwierige" Merkmale (wie seltene Varianten) identifizieren kann, während es sich weiterentwickelt.
2.6. Erneut ausführen und Erfolg beobachten¶
Sobald wir den Test auf diese Weise geändert haben, können wir den Test mehrmals ausführen, und er wird konsistent bestehen.
Befehlsausgabe
2.7. Weitere Tests hinzufügen¶
Füge ähnliche Tests für die Mutter- und Vaterproben hinzu:
2.8. Den Testbefehl ausführen¶
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process GATK_HAPLOTYPECALLER
Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s)
Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s)
Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s)
SUCCESS: Executed 3 tests in 127.586s
Das vervollständigt den grundlegenden Testplan für diesen zweiten Schritt in der Pipeline. Weiter zum dritten und letzten Test auf Modulebene!
Zusammenfassung¶
Du hast gelernt, wie man:
- Prozesse testet, die von Ausgaben anderer Prozesse abhängen
- Spezifische genomische Varianten in VCF-Ausgabedateien verifiziert
- Nicht-deterministische Ausgaben handhabt, indem man spezifischen Inhalt prüft
- Variantenaufruf über mehrere Proben hinweg testet
Wie geht es weiter?¶
Lerne, wie man Tests schreibt, die vorab generierte Testdaten für den Joint-Genotyping-Schritt verwenden.
3. Vorab generierte Testdaten verwenden¶
Für den Joint-Genotyping-Schritt verwenden wir einen anderen Ansatz - die Verwendung vorab generierter Testdaten. Dies ist oft vorzuziehen für:
- Komplexe Prozesse mit mehreren Abhängigkeiten
- Prozesse, die lange laufen
- Prozesse, die Teil einer stabilen Produktions-Pipeline sind
3.1. Testdaten generieren¶
Untersuche die Ergebnisse, die wir zu Beginn dieses Abschnitts generiert haben:
results_genomics/
├── family_trio.joint.vcf
├── family_trio.joint.vcf.idx
├── gvcf
│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf
│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx
│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf
│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx
│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf
│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx
└── indexed_bam
├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam
├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai
├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam
├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai
├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam
└── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai
2 directories, 14 files
Der Joint-Genotyping-Schritt benötigt die von den Haplotype-Caller-Schritten erzeugten VCF-Dateien als Eingaben, zusammen mit den Indizes. Also lass uns die Ergebnisse, die wir haben, in das Test-Verzeichnis des jointgenotyping-Moduls kopieren.
mkdir -p modules/gatk/jointgenotyping/tests/inputs/
cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/
Jetzt können wir diese Dateien als Eingaben für den Test verwenden, den wir für den Joint-Genotyping-Schritt schreiben werden.
3.2. Die Test-Datei-Vorlage generieren¶
Wie zuvor generieren wir zunächst die Datei-Vorlage:
Befehlsausgabe
Dies erzeugt die folgende Test-Vorlage:
3.3. Die Test-Datei verschieben und den Script-Pfad aktualisieren¶
Diesmal haben wir bereits ein Verzeichnis für Tests zusammen mit der main.nf-Datei des Moduls, sodass wir die Test-Vorlagendatei dorthin verschieben können:
Und vergiss nicht, den Script-Pfad zu aktualisieren:
3.4. Eingaben bereitstellen¶
Fülle die Eingaben basierend auf den Prozess-Eingabedefinitionen aus und benenne den Test entsprechend um:
3.5. Inhaltsassertions verwenden¶
Die Ausgabe des Joint-Genotyping-Schritts ist wieder eine VCF-Datei, also werden wir wieder eine Inhaltsassertion verwenden.
Durch die Überprüfung des Inhalts einer bestimmten Variante in der Ausgabedatei verifiziert dieser Test, dass:
- Der Joint-Genotyping-Prozess erfolgreich läuft
- Die Ausgabe-VCF alle drei Proben in der richtigen Reihenfolge enthält
- Eine spezifische Variante korrekt aufgerufen wird mit:
- Genauen Genotypen für jede Probe (0/1 für Vater, 1/1 für Mutter und Sohn)
- Korrekten Read-Tiefen und Genotyp-Qualitäten
- Populationsweiten Statistiken wie Allelfrequenz (AF=0.833)
Wir haben nicht die gesamte Datei als Snapshot gespeichert, aber indem wir eine spezifische Variante überprüfen, können wir sicher sein, dass der Joint-Genotyping-Prozess wie erwartet funktioniert.
3.6. Den Test ausführen¶
Befehlsausgabe
Der Test besteht und verifiziert, dass unser Joint-Genotyping-Prozess korrekt:
- Individuelle Proben-VCFs kombiniert
- Gemeinsames Varianten-Calling durchführt
- Eine Multi-Proben-VCF mit konsistenten Genotyp-Aufrufen über Läufe hinweg produziert
Zusammenfassung¶
Du weißt, wie man:
- Zuvor generierte Ergebnisse als Eingaben für Tests verwendet
- Tests mit vorab generierten Testdaten schreibt
Wie geht es weiter?¶
Füge einen Test auf Workflow-Ebene hinzu, um zu verifizieren, dass die gesamte Varianten-Calling-Pipeline end-to-end funktioniert.
4. Einen Test auf Workflow-Ebene hinzufügen¶
Jetzt testen wir die vollständige Varianten-Calling-Pipeline, von BAM-Dateien bis zu Joint-Genotypen. Dies verifiziert, dass:
- Alle Prozesse korrekt zusammenarbeiten
- Daten ordnungsgemäß zwischen den Schritten fließen
- Abschließende Variantenaufrufe konsistent sind
4.1. Den Workflow-Test generieren¶
Generiere eine Test-Datei für die vollständige Pipeline:
Befehlsausgabe
Dies erstellt eine grundlegende Test-Vorlage:
| tests/genomics-4.nf.test | |
|---|---|
Korrigiere einfach den Namen zu etwas Aussagekräftigem (du wirst bald sehen, warum das nützlich ist).
Hinweis
In diesem Fall kann die Test-Datei dort bleiben, wo nf-test sie erstellt hat.
4.2. Eingabeparameter spezifizieren¶
Wir müssen noch Eingaben spezifizieren, was auf Workflow-Ebene etwas anders gemacht wird als bei Tests auf Modulebene.
Es gibt mehrere Möglichkeiten, dies zu tun, einschließlich durch Angabe eines Profils.
Ein einfacherer Weg ist jedoch, einen params {}-Block in der nextflow.config-Datei einzurichten, die nf-test init ursprünglich im tests-Verzeichnis erstellt hat.
Wenn wir den Test ausführen, übernimmt nf-test diese Konfigurationsdatei und zieht die Eingaben entsprechend heran.
4.3. Den Workflow-Test ausführen¶
Befehlsausgabe
Der Test besteht und bestätigt, dass unsere vollständige Varianten-Calling-Pipeline:
- Alle Proben erfolgreich verarbeitet
- Alle Schritte korrekt verkettet
4.4. ALLE Tests ausführen¶
nf-test hat noch einen weiteren Trick auf Lager. Wir können alle Tests auf einmal ausführen! Ändere die nf-test.config-Datei so, dass nf-test in jedem Verzeichnis nach nf-test-Dateien sucht. Du kannst dies tun, indem du den testsDir-Parameter änderst:
Jetzt können wir einfach nf-test ausführen und es wird jeden einzelnen Test in unserem Repository ausführen:
Befehlsausgabe
🚀 nf-test 0.9.3
https://www.nf-test.com
(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr
Test Process GATK_HAPLOTYPECALLER
Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s)
Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s)
Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s)
Test Process GATK_JOINTGENOTYPING
Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s)
Test Process SAMTOOLS_INDEX
Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s)
Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s)
Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s)
Test Workflow genomics-4.nf
Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s)
SUCCESS: Executed 8 tests in 380.801s
8 Tests mit 1 Befehl! Wir haben lange damit verbracht, viele Tests zu konfigurieren, aber als es darum ging, sie auszuführen, war es sehr schnell und einfach. Du kannst sehen, wie nützlich das bei der Wartung einer großen Pipeline ist, die Hunderte verschiedener Elemente enthalten könnte. Wir investieren Zeit in das Schreiben von Tests einmal, damit wir Zeit sparen können, wenn wir sie viele Male ausführen.
Außerdem können wir das automatisieren! Stell dir vor, Tests laufen jedes Mal, wenn du oder ein Kollege versucht, neuen Code hinzuzufügen. So stellen wir sicher, dass unsere Pipelines einen hohen Standard aufrechterhalten.
Zusammenfassung¶
Du weißt jetzt, wie man mehrere Arten von Tests für deine Genomik-Pipeline mit nf-test schreibt und ausführt. Dieses Test-Framework hilft sicherzustellen, dass dein Varianten-Calling-Workflow konsistente, zuverlässige Ergebnisse über verschiedene Umgebungen hinweg produziert und wenn du Code-Änderungen vornimmst.
Du hast gelernt, kritische Komponenten zu testen wie:
- Den
SAMTOOLS_INDEX-Prozess, der BAM-Dateien für Varianten-Calling vorbereitet - Den
GATK_HAPLOTYPECALLER-Prozess, der Varianten in einzelnen Proben identifiziert - Den
GATK_JOINTGENOTYPING-Prozess, der Variantenaufrufe über eine Kohorte hinweg kombiniert
Du hast auch verschiedene Teststrategien implementiert, die spezifisch für Genomik-Daten sind:
- Verifizieren, dass VCF-Dateien erwartete Variantenaufrufe enthalten, trotz nicht-deterministischer Elemente wie Zeitstempel
- Testen mit einem Familien-Trio-Datensatz, um die ordnungsgemäße Variantenidentifikation über verwandte Proben hinweg sicherzustellen
- Überprüfen auf spezifische genomische Koordinaten und Varianteninformationen in deinen Ausgabedateien
Diese Testfähigkeiten sind wesentlich für die Entwicklung robuster Bioinformatik-Pipelines, die zuverlässig Genomdaten verarbeiten und genaue Variantenaufrufe produzieren können. Während du weiterhin mit Nextflow für Genomik-Analysen arbeitest, wird dir diese Test-Grundlage helfen, qualitativ hochwertigen Code aufrechtzuerhalten, der vertrauenswürdige wissenschaftliche Ergebnisse produziert.