Function Testing
nf-test allows testing of functions that are defined in a Nextflow file or defined in lib
. Please checkout the CLI to generate a function test.
Syntax
nextflow_function {
name "<NAME>"
script "<PATH/TO/NEXTFLOW_SCRIPT.nf>"
function "<FUNCTION_NAME>"
test("<TEST_NAME>") {
}
}
Script paths that start with
./
or../
are considered relative paths. These paths are resolved based on the location of the test script. Relative paths are beneficial when you want to reference files or directories located within the same directory as your test script or in a parent directory. These paths provide a convenient way to access files without specifying the entire path.
Multiple Functions
If a Nextflow script contains multiple functions and you want to test them all in the same testsuite, you can override the function
property in each test. For example:
functions.nf
def function1() {
...
}
def function2() {
...
}
functions.nf.test
nextflow_function {
name "Test functions"
script "functions.nf"
test("Test function1") {
function "function1"
...
}
test("Test function2") {
function "function2"
...
}
}
Functions in lib
folder
If you want to test a function that is inside a groovy file in your lib
folder, you can ignore the script
property, because Nextflow adds them automatically to the classpath. For example:
lib\Utils.groovy
class Utils {
public static void sayHello(name) {
if (name == null) {
error('Cannot greet a null person')
}
def greeting = "Hello ${name}"
println(greeting)
}
}
tests\lib\Utils.groovy.test
nextflow_function {
name "Test Utils.groovy"
test("Test function1") {
function "Utils.sayHello"
...
}
}
Note: the generate function
command works only with Nextflow functions.
Assertions
The function
object can be used in asserts to check its status, result value or error messages.
// function status
assert function.success
assert function.failed
// return value
assert function.result == 27
//returns a list containing all lines from stdout
assert function.stdout.contains("Hello World") == 3
Example
Nextflow script
Create a new file and name it functions.nf
.
def say_hello(name) {
if (name == null) {
error('Cannot greet a null person')
}
def greeting = "Hello ${name}"
println(greeting)
return greeting
}
nf-test script
Create a new file and name it functions.nf.test
.
nextflow_function {
name "Test Function Say Hello"
script "functions.nf"
function "say_hello"
test("Passing case") {
when {
function {
"""
input[0] = "aaron"
"""
}
}
then {
assert function.success
assert function.result == "Hello aaron"
assert function.stdout.contains("Hello aaron")
assert function.stderr.isEmpty()
}
}
test("Failure Case") {
when {
function {
"""
input[0] = null
"""
}
}
then {
assert function.failed
//It seems to me that error(..) writes message to stdout
assert function.stdout.contains("Cannot greet a null person")
}
}
}
Execute test
nf-test test functions.nf.test