You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: vignettes/skipping.Rmd
+43-34
Original file line number
Diff line number
Diff line change
@@ -51,57 +51,66 @@ All reporters show which tests as skipped.
51
51
As of testthat 3.0.0, ProgressReporter (used interactively) and CheckReporter (used inside of `R CMD check`) also display a summary of skips across all tests.
You should keep an on eye this when developing interactively to make sure that you're not accidentally skipping the wrong things.
59
61
60
62
## Helpers
61
63
62
64
If you find yourself using the same `skip_if()`/`skip_if_not()` expression across multiple tests, it's a good idea to create a helper function.
63
-
This function should start with `skip_` and live somewhere in your `R/` directory.
65
+
This function should start with `skip_` and live in a `test/helper-{something}.R` file:
64
66
65
67
```{r}
66
-
skip_if_Tuesday <- function() {
67
-
if (as.POSIXlt(Sys.Date())$wday != 2) {
68
-
return(invisible(TRUE))
68
+
skip_if_dangerous <- function() {
69
+
if (!identical(Sys.getenv("DANGER"), "")) {
70
+
skip("Not run in dangerous environments.")
71
+
} else {
72
+
invisible()
69
73
}
70
-
71
-
skip("Not run on Tuesday")
72
74
}
73
75
```
74
76
75
-
It's important to test your skip helpers because it's easy to miss if you're skipping more often than desired, and the test code is never run.
76
-
This is unlikely to happen locally (since you'll see the skipped tests in the summary), but is quite possible in continuous integration.
77
-
78
-
For that reason, it's a good idea to add a test that you skip is activated when you expect.
79
-
skips are a special type of condition, so you can test for their presence/absence with `expect_condition()`.
80
-
For example, imagine that you've defined a custom skipper that skips tests whenever an environment variable `DANGER` is set:
81
-
82
-
```{r}
83
-
skip_if_dangerous <- function() {
84
-
if (identical(Sys.getenv("DANGER"), "")) {
85
-
return(invisible(TRUE))
77
+
## Embedding `skip()` in package functions
78
+
79
+
Another useful technique that can sometimes be useful is to build a `skip()` directly into a package function.
80
+
For example take a look at [`pkgdown:::convert_markdown_to_html()`](https://github.com/r-lib/pkgdown/blob/v2.0.7/R/markdown.R#L95-L106), which absolutely, positively cannot work if the Pandoc tool is unavailable:
from <- "markdown+gfm_auto_identifiers-citations+emoji+autolink_bare_uris"
86
+
} else if (rmarkdown::pandoc_available("1.12.3")) {
87
+
from <- "markdown_github-hard_line_breaks+tex_math_dollars+tex_math_single_backslash+header_attributes"
88
+
} else {
89
+
if (is_testing()) {
90
+
testthat::skip("Pandoc not available")
91
+
} else {
92
+
abort("Pandoc not available")
93
+
}
86
94
}
87
95
88
-
skip("Not run in dangerous enviromnents")
96
+
...
89
97
}
90
98
```
91
99
92
-
Then you can use `expect_condition()` to test that it skips tests when it should, and doesn't skip when it shouldn't:
100
+
If Pandoc is not available when `convert_markdown_to_html()` executes, it throws an error *unless* it appears to be part of a test run, in which case the test is skipped.
101
+
This is an alternative to implementing a custom skipper, e.g. `skip_if_no_pandoc()`, and inserting it into many of pkgdown's tests.
93
102
94
-
```{r}
95
-
test_that("skip_if_dangerous work", {
96
-
# Test that a skip happens
97
-
withr::local_envvar(DANGER = "yes")
98
-
expect_condition(skip_if_dangerous(), class = "skip")
99
-
100
-
# Test that a skip doesn't happen
101
-
withr::local_envvar(DANGER = "")
102
-
expect_condition(skip_if_dangerous(), NA, class = "skip")
103
-
})
103
+
We don't want pkgdown to have a runtime dependency on testthat, so pkgdown includes a copy of `testthat::is_testing()`:
104
+
105
+
```{r eval = FALSE}
106
+
is_testing <- function() {
107
+
identical(Sys.getenv("TESTTHAT"), "true")
108
+
}
104
109
```
105
110
106
-
Testing `skip_if_Tuesday()` is harder because there's no way to control the skipping from the outside.
107
-
That means you'd need to "mock" its behaviour in a test, using the [mockery](https://github.com/r-lib/mockery) or [mockr](https://krlmlr.github.io/mockr/) packages.
111
+
It might look like the code appears to still have a runtime dependency on testthat, because of the call to `testthat::skip()`.
112
+
But `testthat::skip()` is only executed during a test run, which implies that testthat is installed.
113
+
114
+
We have mixed feelings about this approach.
115
+
On the one hand, it feels elegant and concise, and it absolutely guarantees that you'll never miss a needed skip in one of your tests.
116
+
On the other hand, it mixes code and tests in an unusual way, and when you're focused on the tests, it's easy to miss the fact that a package function contains a `skip()`.
0 commit comments