From ca0543ede5e5ffe335fcf232e2a06ba748068e8e Mon Sep 17 00:00:00 2001 From: Ricardo Rodrigo Basa Date: Tue, 29 Aug 2023 12:33:17 +0200 Subject: [PATCH 1/3] Updated source code from rlib/testthat/main (#5) Give test_dir() a recursive option (#1605) The recursive argument allows test files in nested directories. --- DESCRIPTION | 2 +- NEWS.md | 2 ++ R/test-files.R | 9 +++++--- man/find_test_scripts.Rd | 5 ++++- man/test_dir.Rd | 3 +++ tests/testthat/_snaps/test-files.md | 21 ++++++++++++++++++ tests/testthat/test-test-files.R | 11 ++++++++++ .../test_dir_recursive/helper_hello.R | 1 + .../nested_folder/test-errors.R | 22 +++++++++++++++++++ .../nested_folder/test-failures.R | 13 +++++++++++ .../nested_folder/test-skip.R | 4 ++++ .../test-bare-expectations.R | 1 + .../testthat/test_dir_recursive/test-basic.R | 22 +++++++++++++++++++ .../testthat/test_dir_recursive/test-empty.R | 3 +++ .../testthat/test_dir_recursive/test-helper.R | 4 ++++ 15 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 tests/testthat/test_dir_recursive/helper_hello.R create mode 100644 tests/testthat/test_dir_recursive/nested_folder/test-errors.R create mode 100644 tests/testthat/test_dir_recursive/nested_folder/test-failures.R create mode 100644 tests/testthat/test_dir_recursive/nested_folder/test-skip.R create mode 100644 tests/testthat/test_dir_recursive/test-bare-expectations.R create mode 100644 tests/testthat/test_dir_recursive/test-basic.R create mode 100644 tests/testthat/test_dir_recursive/test-empty.R create mode 100644 tests/testthat/test_dir_recursive/test-helper.R diff --git a/DESCRIPTION b/DESCRIPTION index 9460b2231..094132ba7 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: testthat Title: Unit Testing for R -Version: 3.1.10.9000 +Version: 3.1.10.9001 Authors@R: c( person("Hadley", "Wickham", , "hadley@posit.co", role = c("aut", "cre")), person("Posit Software, PBC", role = c("cph", "fnd")), diff --git a/NEWS.md b/NEWS.md index 2acf97eca..014533892 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,8 @@ * `expect_setequal()` correctly displays results when only one of actual and expected is missing values (#1835). + +* `test_dir()` gains a `recursive` argument which allows test files in nested directories (#1605). # testthat 3.1.10 diff --git a/R/test-files.R b/R/test-files.R index b45640c78..5ddd401fb 100644 --- a/R/test-files.R +++ b/R/test-files.R @@ -26,6 +26,7 @@ #' @param stop_on_failure If `TRUE`, throw an error if any tests fail. #' @param stop_on_warning If `TRUE`, throw an error if any tests generate #' warnings. +#' @param recursive If `TRUE` Test that will search for test files in the nested directories. #' @param load_package Strategy to use for load package code: #' * "none", the default, doesn't load the package. #' * "installed", uses [library()] to load an installed package. @@ -52,6 +53,7 @@ test_dir <- function(path, stop_on_warning = FALSE, wrap = lifecycle::deprecated(), package = NULL, + recursive = FALSE, load_package = c("none", "installed", "source") ) { @@ -63,7 +65,8 @@ test_dir <- function(path, filter = filter, ..., full.names = FALSE, - start_first = start_first + start_first = start_first, + recursive = recursive ) if (length(test_paths) == 0) { abort("No test files found") @@ -380,8 +383,8 @@ local_teardown_env <- function(frame = parent.frame()) { #' @return A character vector of paths #' @keywords internal #' @export -find_test_scripts <- function(path, filter = NULL, invert = FALSE, ..., full.names = TRUE, start_first = NULL) { - files <- dir(path, "^test.*\\.[rR]$", full.names = full.names) +find_test_scripts <- function(path, filter = NULL, invert = FALSE, ..., full.names = TRUE, start_first = NULL, recursive = FALSE) { + files <- dir(path, "^test.*\\.[rR]$", full.names = full.names, recursive = recursive) files <- filter_test_scripts(files, filter, invert, ...) order_test_scripts(files, start_first) } diff --git a/man/find_test_scripts.Rd b/man/find_test_scripts.Rd index 0e5dfc618..007999518 100644 --- a/man/find_test_scripts.Rd +++ b/man/find_test_scripts.Rd @@ -10,7 +10,8 @@ find_test_scripts( invert = FALSE, ..., full.names = TRUE, - start_first = NULL + start_first = NULL, + recursive = FALSE ) } \arguments{ @@ -31,6 +32,8 @@ first pattern first, then the ones matching the second, etc. and then the rest of the files, alphabetically. Parallel tests tend to finish quicker if you start the slowest files first. \code{NULL} means alphabetical order.} + +\item{recursive}{If \code{TRUE} Test that will search for test files in the nested directories.} } \value{ A character vector of paths diff --git a/man/test_dir.Rd b/man/test_dir.Rd index 937895f21..edc770420 100644 --- a/man/test_dir.Rd +++ b/man/test_dir.Rd @@ -15,6 +15,7 @@ test_dir( stop_on_warning = FALSE, wrap = lifecycle::deprecated(), package = NULL, + recursive = FALSE, load_package = c("none", "installed", "source") ) } @@ -46,6 +47,8 @@ warnings.} \item{package}{If these tests belong to a package, the name of the package.} +\item{recursive}{If \code{TRUE} Test that will search for test files in the nested directories.} + \item{load_package}{Strategy to use for load package code: \itemize{ \item "none", the default, doesn't load the package. diff --git a/tests/testthat/_snaps/test-files.md b/tests/testthat/_snaps/test-files.md index 13e011d73..9958864d6 100644 --- a/tests/testthat/_snaps/test-files.md +++ b/tests/testthat/_snaps/test-files.md @@ -19,3 +19,24 @@ 16 test-helper.R helper test 1 0 FALSE FALSE 0 1 17 test-skip.R Skips skip 1 0 TRUE FALSE 0 0 +# runs all tests in nested directories and records output + + file context test nb failed skipped error warning passed + 1 nested_folder/test-errors.R simple 0 0 FALSE TRUE 0 0 + 2 nested_folder/test-errors.R after one success 1 0 FALSE TRUE 0 1 + 3 nested_folder/test-errors.R after one failure 1 1 FALSE TRUE 0 0 + 4 nested_folder/test-errors.R in the test 0 0 FALSE TRUE 0 0 + 5 nested_folder/test-errors.R in expect_error 1 0 FALSE FALSE 0 1 + 6 nested_folder/test-failures.R just one failure 1 1 FALSE FALSE 0 0 + 7 nested_folder/test-failures.R one failure on two 2 1 FALSE FALSE 0 1 + 8 nested_folder/test-failures.R no failure 2 0 FALSE FALSE 0 2 + 9 nested_folder/test-skip.R Skips skip 1 0 TRUE FALSE 0 0 + 10 test-basic.R logical tests act as expected 2 0 FALSE FALSE 0 2 + 11 test-basic.R logical tests ignore attributes 2 0 FALSE FALSE 0 2 + 12 test-basic.R equality holds 2 0 FALSE FALSE 0 2 + 13 test-basic.R can't access variables from other tests 2 1 0 TRUE FALSE 0 0 + 14 test-basic.R can't access variables from other tests 1 1 0 FALSE FALSE 0 1 + 15 test-empty.R empty test 1 0 TRUE FALSE 0 0 + 16 test-empty.R empty test with error 0 0 FALSE TRUE 0 0 + 17 test-helper.R helper test 1 0 FALSE FALSE 0 1 + diff --git a/tests/testthat/test-test-files.R b/tests/testthat/test-test-files.R index 2c0666acc..6bba84ec2 100644 --- a/tests/testthat/test-test-files.R +++ b/tests/testthat/test-test-files.R @@ -46,6 +46,17 @@ test_that("can control if warnings errors", { expect_error(test_warning(stop_on_warning = FALSE), NA) }) +test_that("runs all tests in nested directories and records output", { + withr::local_envvar(TESTTHAT_PARALLEL = "FALSE") + res <- test_dir(test_path("test_dir_recursive"), reporter = "silent", stop_on_failure = FALSE, recursive = TRUE) + df <- as.data.frame(res) + df$user <- df$system <- df$real <- df$result <- NULL + + local_reproducible_output(width = 200) + local_edition(3) + expect_snapshot_output(print(df)) +}) + # test_file --------------------------------------------------------------- test_that("can test single file", { diff --git a/tests/testthat/test_dir_recursive/helper_hello.R b/tests/testthat/test_dir_recursive/helper_hello.R new file mode 100644 index 000000000..dd96afc4c --- /dev/null +++ b/tests/testthat/test_dir_recursive/helper_hello.R @@ -0,0 +1 @@ +hello <- function() "Hello World" diff --git a/tests/testthat/test_dir_recursive/nested_folder/test-errors.R b/tests/testthat/test_dir_recursive/nested_folder/test-errors.R new file mode 100644 index 000000000..fdeb9d564 --- /dev/null +++ b/tests/testthat/test_dir_recursive/nested_folder/test-errors.R @@ -0,0 +1,22 @@ +test_that("simple", { + stop("argh") +}) + +test_that("after one success", { + expect_true(TRUE) + stop("argh") + expect_true(TRUE) +}) + +test_that("after one failure", { + expect_true(FALSE) + stop("argh") +}) + +test_that("in the test", { + expect_true(stop("Argh")) +}) + +test_that("in expect_error", { + expect_error(stop("Argh")) +}) diff --git a/tests/testthat/test_dir_recursive/nested_folder/test-failures.R b/tests/testthat/test_dir_recursive/nested_folder/test-failures.R new file mode 100644 index 000000000..21204f22f --- /dev/null +++ b/tests/testthat/test_dir_recursive/nested_folder/test-failures.R @@ -0,0 +1,13 @@ +test_that("just one failure", { + expect_true(FALSE) +}) + +test_that("one failure on two", { + expect_false(FALSE) + expect_true(FALSE) +}) + +test_that("no failure", { + expect_false(FALSE) + expect_true(TRUE) +}) diff --git a/tests/testthat/test_dir_recursive/nested_folder/test-skip.R b/tests/testthat/test_dir_recursive/nested_folder/test-skip.R new file mode 100644 index 000000000..5796fa6f1 --- /dev/null +++ b/tests/testthat/test_dir_recursive/nested_folder/test-skip.R @@ -0,0 +1,4 @@ +test_that("Skips skip", { + skip("Skipping to avoid certain failure") + expect_true(FALSE) +}) diff --git a/tests/testthat/test_dir_recursive/test-bare-expectations.R b/tests/testthat/test_dir_recursive/test-bare-expectations.R new file mode 100644 index 000000000..cd99df26e --- /dev/null +++ b/tests/testthat/test_dir_recursive/test-bare-expectations.R @@ -0,0 +1 @@ +expect_equal(2, 2) diff --git a/tests/testthat/test_dir_recursive/test-basic.R b/tests/testthat/test_dir_recursive/test-basic.R new file mode 100644 index 000000000..9baa743e6 --- /dev/null +++ b/tests/testthat/test_dir_recursive/test-basic.R @@ -0,0 +1,22 @@ +test_that("logical tests act as expected", { + expect_true(TRUE) + expect_false(FALSE) +}) + +test_that("logical tests ignore attributes", { + expect_true(c(a = TRUE)) + expect_false(c(a = FALSE)) +}) + +test_that("equality holds", { + expect_equal(5, 5) + expect_identical(10, 10) +}) + +test_that("can't access variables from other tests 2", { + a <- 10 +}) + +test_that("can't access variables from other tests 1", { + expect_false(exists("a")) +}) diff --git a/tests/testthat/test_dir_recursive/test-empty.R b/tests/testthat/test_dir_recursive/test-empty.R new file mode 100644 index 000000000..f31a703e4 --- /dev/null +++ b/tests/testthat/test_dir_recursive/test-empty.R @@ -0,0 +1,3 @@ +test_that("empty test", NULL) + +test_that("empty test with error", stop("Argh")) diff --git a/tests/testthat/test_dir_recursive/test-helper.R b/tests/testthat/test_dir_recursive/test-helper.R new file mode 100644 index 000000000..26da9303f --- /dev/null +++ b/tests/testthat/test_dir_recursive/test-helper.R @@ -0,0 +1,4 @@ +# test that the companion helper script is sourced by test_dir +test_that("helper test", { + expect_equal(hello(), "Hello World") +}) From 79d77b1aed00c6b6162cd8bfc4251d7ee43deabc Mon Sep 17 00:00:00 2001 From: Rodrigo Basa Date: Mon, 9 Oct 2023 19:42:44 +0800 Subject: [PATCH 2/3] fix news.md --- NEWS.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0850bde2c..e739bd084 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,6 @@ # testthat (development version) -* Adds `recursive` parameter to `test_dir()` to allow the use of directories to - organize test files (@radbasa, #1605). +* `test_dir()` gains a `recursive` argument which allows test files in nested directories (#1605). # testthat 3.2.0 @@ -60,8 +59,6 @@ * `expect_setequal()` correctly displays results when only one of actual and expected is missing values (#1835). - -* `test_dir()` gains a `recursive` argument which allows test files in nested directories (#1605). # testthat 3.1.10 From dde1741143fb727251589414a018236de2b2e658 Mon Sep 17 00:00:00 2001 From: Rodrigo Basa Date: Mon, 9 Oct 2023 19:50:46 +0800 Subject: [PATCH 3/3] cleaning up some post-merge duplication --- NEWS.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index e739bd084..756d3e7ed 100644 --- a/NEWS.md +++ b/NEWS.md @@ -57,9 +57,6 @@ * `test_file()` gains a `desc` argument which allows you to run a single test from a file (#1776). -* `expect_setequal()` correctly displays results when only one of actual and - expected is missing values (#1835). - # testthat 3.1.10 * Fix for upcoming R-devel release.