Testthis contains tools to make unit testing in R more comfortable. It is designed to complement the packages testthat, devtools and usethis.
Testthis provides RStudio addins for common tasks. These can be called like normal R function, but it is also possible to assigned to hotkeys to them in RStudio (Tools/Modify Keyboard Shortcuts). I recommend assigning ctrl+alt+Insert
, ctrl+alt+Pos1
and ctrl+alt+PageUp
to the following functions:
test_this()
: Run tests associated with the currently open R script file.lest_this()
: “Load and test”; As above, but call devtools::load_all()
firstopen_testfile()
: Opens the associated testfile in an editor window. If the currently open file already is a testfile, it opens the associated file in the /R
directory. Can be used to jump back and forth between both.test_with_skip()
: Like devtools::test()
, but does not run test files that contain the line #' @skip.
The functions above assume that if the current filename is currentfile.R
, the associated test file is /tests/testthat/test_currentfile.R
. If you want to modify this behaviour you can put the tag #* @testfile anotherfile
anywhere in your code, usually the top or bottom of your .R
file. Each R script can only have a single associated testfile.
The following example will associate the file /tests/testthat/other_test_file.R
instead of /tests/testthat/test_open_testfile.R
with R/open_testfile
:
# file R/open_testfile.R
#* @testfile other_testfile
open_testfile <- function(){
fname <- get_testfile_name()
if(file.exists(fname)){
rstudioapi::navigateToFile(fname)
} else {
test_skeleton(fname, open = TRUE)
}
}
Sometimes, it might become necessary to have access to complex data sets for tests. The recommended way for dealing with this is to provide an example dataset in your packages data/
directory; however, there are also usecases where you want seperate data files for your tests.
Testthis provides three functions to to make dealing with separate test data files a bit easier:
use_testdata()
places a single R object in the tests/testhat/testdata
directory. It is analoguous to usethis::use_data()
, except that it saves the Object in the .rds
format, which is more convenient for single R Objects than .rda
or .Rdata
(see ?readRDS
).use_testdata_raw()
creates the directory tests/testhat/testdata-raw
. Use this directory to put scripts that generate the data in tests/testhat/testdata
.read_testdata()
is a simple wrapper for readRDS()
to read files in tests/testhat/testdata
.use_testdata(iris)
## Saving to
## * r/testthis/tests/testthat/testdata/iris.rds
tdat <- read_testdata("iris.rds")
use_testdata_raw()
## ✔ Creating 'tests/testthat/testdata-raw/'
Sometimes it is useful to create tests for a package that go beyond simple best-practice unit tests. For example you might have some tests that require external ressources (web, databases) or take long to execute. If you put such tests in subdirectories of test/testthat
they will neither be automaticaly executed by devtools::test()
nor run on CRAN.
testthis provides helpers do deal with files in subdirectories of tests/testthat
.
use_test_subdir()
create a subdir in tests/testthat/
and (optionally) an R script in /R
that contains a helper function to run all tests in that subdir. By default, said .R script will be added to your packages .Rbuildignore
as it is only useful during package development. Tests in subdirectories of a packages test dir will not be run on CRAN on CRAN or by devtools::test()
.test_subdir("mysubdir")
to run tests in a subdir of tests/testthat
.test_acceptance()
, test_manual()
and test_integration()
are presets to run tests in the integration_tests
, acceptance_tests
and manual_tests
subdirectories of test/testthat
.use_test_subdir("foobar_tests")
## ✔ Creating 'tests/testthat/foobar_tests/'
## creating tester function test_foobar_tests() in r/testthis/R/testthis-testers.R
test_subdir("foobar_tests")
## No tests: no files in r/testthis/tests/testthat/foobar_tests match '^test.*\.[rR]$'
This is an experimental feature, comments and feature request are welcome. Testthis provides a checklist like test coverage analyser. This is non-automatic and requires you to manually mark functions as tested in your code via special comments. If you look for automatic test coverage analysis, you might want to check out the covr
package instead.
For testthis to recognize wheter a unit test exists for a function, the function name must either be mention in a testthat()
desc
argument, or marked via special comment tag: #* @testing functionname
. If you want to mark a function as not requiring testing, you can add the function name to the file /tests/testthat/_testignore
manually, or with use_testignore()
.
The following example will mark the functions parse_testthis_comments
and detect_testthis_comments
as tested:
# file /tests/testhis/parse_testthis_comments.R
test_that("parse_testthis_comments works as expected", {
#* @testing detect_testthis_comments
...
}
To display the test coverage use:
get_test_coverage()