Skip to content

Commit 4588502

Browse files
authored
Allow test_path() to work in helper files (#1760)
And generally improve code, tests, and docs. Closes #1756. Fixes #1562.
1 parent f6a0bc0 commit 4588502

File tree

7 files changed

+85
-35
lines changed

7 files changed

+85
-35
lines changed

NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# testthat (development version)
22

3+
* `test_path()` now works when called within helper files (#1562).
4+
35
* `it()` now calls `local_test_context()` so that it behaves more
46
similarly to `test_that()` (#1731), and is now exported so that you
57
can more easily run BDD tests interactively (#1587)

R/test-path.R

+31-12
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
1-
#' Locate file in testing directory.
1+
#' Locate a file in the testing directory
22
#'
3-
#' This function is designed to work both interactively and during tests,
4-
#' locating files in the `tests/testthat` directory
3+
#' Many tests require some external file (e.g. a `.csv` if you're testing a
4+
#' data import function) but the working directory varies depending on the way
5+
#' that you're running the test (e.g. interactively, with `devtools::test()`,
6+
#' or with `R CMD check`). `test_path()` understands these variations and
7+
#' automatically generates a path relative to `tests/testthat`, regardless of
8+
#' where that directory might reside relative to the current working directory.
59
#'
6-
#' @param ... Character vectors giving path component.
10+
#' @param ... Character vectors giving path components.
711
#' @return A character vector giving the path.
812
#' @export
13+
#' @examples
14+
#' \dontrun{
15+
#' test_path("foo.csv")
16+
#' test_path("data", "foo.csv")
17+
#' }
918
test_path <- function(...) {
1019
if (is_testing() && !isTRUE(getOption("testthat_interactive"))) {
11-
if (missing(...)) {
12-
"."
13-
} else {
14-
file.path(...)
15-
}
20+
base <- NULL
21+
} else if (pkgload::is_loading()) {
22+
# Probably called from a helper file
23+
base <- NULL
1624
} else {
17-
base <- file.path("tests", "testthat")
25+
base <- "tests/testthat"
26+
1827
if (!dir.exists(base)) {
19-
abort("Can't find `tests/testthat/` in current directory.")
28+
cli::cli_abort("Can't find {.path {base}}.")
2029
}
21-
file.path(base, ...)
30+
}
31+
32+
file_path(base, ...)
33+
}
34+
35+
file_path <- function(...) {
36+
paths <- compact(list2(...))
37+
if (length(paths) == 0) {
38+
"."
39+
} else {
40+
do.call(file.path, paths)
2241
}
2342
}

man/test_path.Rd

+14-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/_snaps/test-path.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# throws error if can't find tests/testthat
2+
3+
Code
4+
test_path("empty")
5+
Condition
6+
Error in `test_path()`:
7+
! Can't find 'tests/testthat'.
8+

tests/testthat/test-path-installed/testthat-tests/testthat/empty

Whitespace-only changes.

tests/testthat/test-path-missing/empty

Whitespace-only changes.

tests/testthat/test-test-path.R

+30-19
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
1-
test_that("returns local path when called in tests", {
2-
expect_equal(test_path("test-test-path.R"), "test-test-path.R")
1+
test_that("always returns a path",{
2+
withr::local_envvar(TESTTHAT = "true")
3+
withr::local_options(testthat_interactive = FALSE)
34

4-
# even if path doesn't (yet) exists
5-
expect_equal(test_path("xxxx"), "xxxx")
5+
expect_equal(test_path(), ".")
66
})
77

8-
test_that("returns local path when called from tools::testInstalledPackages", {
9-
old <- setwd("test-path-installed/testthat-tests/testthat")
10-
on.exit(setwd(old))
8+
test_that("is vectorised", {
9+
withr::local_envvar(TESTTHAT = "true")
10+
withr::local_options(testthat_interactive = FALSE)
1111

12-
expect_equal(test_path("test-test-path.R"), "test-test-path.R")
13-
expect_equal(test_path("xxxx"), "xxxx")
12+
expect_equal(test_path("x", c("a", "b")), c("x/a", "x/b"))
1413
})
1514

16-
test_that("returns full path when called outside tests", {
17-
withr::local_dir(test_path("test-path-present"))
15+
test_that("uses local path when called from test_file()/tools::testInstalledPackages()", {
16+
withr::local_envvar(TESTTHAT = "true")
17+
withr::local_options(testthat_interactive = FALSE)
18+
19+
expect_equal(test_path("path"), "path")
20+
})
21+
22+
test_that("returns local path during package loading", {
23+
withr::local_envvar(TESTTHAT = "false", DEVTOOLS_LOAD = "testthat")
24+
25+
expect_equal(test_path("path"), "path")
26+
})
27+
28+
test_that("returns full path when called interactively", {
1829
withr::local_envvar("TESTTHAT" = "false")
30+
pkg <- withr::local_tempdir()
31+
dir.create(file.path(pkg, "tests", "testthat"), recursive = TRUE)
32+
withr::local_dir(pkg)
1933

20-
expect_equal(test_path("empty"), "tests/testthat/empty")
21-
# even when file doesn't exist
22-
expect_equal(test_path("xxx"), "tests/testthat/xxx")
34+
expect_equal(test_path("path"), "tests/testthat/path")
2335
})
2436

2537
test_that("throws error if can't find tests/testthat", {
26-
withr::local_dir(test_path("test-path-missing"))
2738
withr::local_envvar("TESTTHAT" = "false")
39+
withr::local_dir(withr::local_tempdir())
2840

29-
expect_error(test_path("empty"), "Can't find `tests/testthat/`")
30-
})
41+
local_edition(3)
42+
local_reproducible_output()
3143

32-
test_that("test_path() always returns a path",{
33-
expect_equal(test_path(), ".")
44+
expect_snapshot(test_path("empty"), error = TRUE)
3445
})

0 commit comments

Comments
 (0)