runit-testingtestthatrunit

Source an R file without running it (unit-testing)


We're building an R codebase and are hoping to unittest any functions that we write. So far, we have found two testing libraries for R: RUnit and testthat.

After doing a bit of sandboxing, we have developed a solid method for testing code every time it runs. E.g.:

# sample.R

library(methods) #required for testthat
library(testthat)

print("Running fun()...")
fun <- function(num1, num2){
    num3 = num1 + num2
    return(num3)
}

expect_that(fun(1,2), equals(3))

Simple enough. However, we would also like the ability to test the function (with a unittest flag in a makefile for example) without running the script it is defined in. To do this we would write unittests in test.R

# test.R

source("sample.R")

expect_that(fun(2,3), equals(5))

and run it without running the rest of sample.R. But, when the code above is run, not only the functions but the rest of the code from sample.R will be run, in this example outputting "Running fun()...". Is there any way to source() only the user-defined functions from a file?

If not, would you recommend putting functions in a separate file (say, functions.R) which can be unittested by being sourced into test.R and run when sourced in sample.R? The drawback there, it would seem, is the boilerplate needed: a file for the process, a file for the functions, and a file to run the tests.


Solution

    1. In each script, set a name variable that is defined only if it is not already defined. See exists(). I'm fond of __name__.

    2. Create a main function in each script that only runs if the name is correct. This function contains everything you only want to run if this is the top level script.

    This is similar to the python structure of

    if __name__ == "__main__": main()