I have been introduced to a project at work that uses R along with some other languages in a simple reporting tool. I'd like to add some tests to the R code for all the good stuff that tests give you.
I've found using testthat to be a great experience when developing R packages. I think the natural answer to this problem is to package the R code, and use the package in the reporting tool. The package can then be tested, documented, etc separately and easily.
Although I think this is the best long term solution, separating out the R code and packaging it would take time from other, more pressing projects. So I'm wondering if there's a quick win to be had in the short term by introducing tests to the project as it is. I'm also interested in hearing more about people's approaches to testing generally.
Has anyone found a successful way to test R scripts/code outside of package development?
2 Likes
You can run testthat tests without package structure, but it is less clean/convenient.
-
I would put your test files in the same location as if you had already done the package conversion stuff. That means put test files into folder "tests/testthat".
-
When you run tests on a package in Rstudio, you can just Ctrl-Shift-T, which automatically loads the package and then runs the tests in the appropriate place. If not a package you can do these steps manually:
- Prior to testing, load the functions you want to test and their dependencies. Source the function files and load packages, either manually or at the top of the test file.
- Then you can run
testthat::test_dir("tests/testthat")
which should run all the tests in your testthat directory.
All that said, I have found that it is possible to quickly convert projects into package format with the following:
-
usethis::create_package
to give a basic description file, etc
- Separate out your functions from your scripts. Script files go in a new /scripts directory (or whatever), and functions go in /R.
- Add all the libraries in your setup.R script as Depends of the package (this is the quick-and-dirty approach -- eventually want to just import the necessary functions from other packages)
9 Likes
This seems like the sensible solution I was looking for. Thank you very much. As you've pointed out it also allows for a relatively clean transition to using a package.