Skip to content

Commit 9366d4f

Browse files
committed
A bit more
1 parent 8258144 commit 9366d4f

File tree

1 file changed

+5
-39
lines changed

1 file changed

+5
-39
lines changed

vignettes/challenging-tests.Rmd

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ knitr::opts_chunk$set(
1616

1717
Testing is easy when your functions are pure: they take some inputs and return predictable outputs. But real-world code often involves randomness, external state, graphics, user interaction, and other challenging elements. This vignette provides practical solutions these tricky scenarios.
1818

19-
In principle, it's often possible to test these things by explicitly parameterising them as arguments to your functions so you can more easily override the default values. And where possible you should do so, especially when testing internal functions. But it's often impractical to provide arguments to explicitly control every last feature without exploding user-facing interfaces. So the techniques in this vignette will help you test all your code, regardless of where it lives and what it does.
19+
In principle, it's often possible to test these things by explicitly parameterising them as arguments to your functions so you can more easily override the default values. And where possible you should do so, especially when testing internal functions. But it's often impractical to provide arguments to explicitly control every last feature without exploding user-facing interfaces. So the techniques in this vignette will help you test all your code, regardless of where it lives and what it does. In other situations, it might not be your function that is the problem, but some other function that you can't edit directly.
2020

2121
This vignette is divided into sections based on the underlying tool you'll use:
2222

@@ -39,7 +39,7 @@ library(testthat)
3939

4040
### Options, env vars, and working directory
4141

42-
If your code depends on global options, environment variables, or the working directory. In most cases, it's good practice to make these dependencies explicit by making them the default value of an argument so you can control directly in your tests. However, sometimes you are testing deeply embedded code and it would be painful to thread the values all the way through to the right place. In this case can temporarily override with withr functions:
42+
In this case can temporarily override with withr functions:
4343

4444
* Temporarily change options with `withr::local_options()`.
4545
* Temporarily change env vars with `withr::local_envvar()`.
@@ -60,6 +60,8 @@ test_that("format_number respects digits option", {
6060
})
6161
```
6262

63+
{withr} provides a number of other `local_` helpers; see the package docs for me.
64+
6365
### Random numbers
6466

6567
Random number generation also falls into the same bucket because it depends on the value of the special `.Random.seed` variable which is updated whenever you generate a random number. You can temporarily change this seed and reproducibly generate "random" numbers with `withr::local_seed()`.
@@ -103,7 +105,6 @@ local({
103105
local_my_helper()
104106
getOption("x")
105107
})
106-
107108
```
108109

109110
We strongly recommend giving such functions a `local_` prefix to clearly communicate that they have "local" effects.
@@ -132,42 +133,7 @@ test_that("divide_positive gives helpful error", {
132133

133134
When generating sophisticated error messages that use cli's interpolation and formatting features, snapshot tests are essential for ensuring the messages render correctly with proper styling and content.
134135

135-
```{r}
136-
process_order <- function(item_count, price, discount_code, shipping_country) {
137-
if (item_count <= 0 || price <= 0 || nchar(shipping_country) != 2) {
138-
cli::cli_abort(c(
139-
"Invalid order parameters:",
140-
"x" = "Item count: {.val {item_count}} (must be > 0)",
141-
"x" = "Price: {.val {price}} (must be > 0)",
142-
"x" = "Shipping country: {.val {shipping_country}} (must be 2-letter code)",
143-
"x" = "Discount code: {.val {discount_code}} ({length(discount_code)} character{?s})",
144-
"i" = "Order processing failed for {.pkg {Sys.info()[['user']]}} at {.timestamp {Sys.time()}}"
145-
))
146-
}
147-
148-
list(items = item_count, total = price, country = shipping_country)
149-
}
150-
151-
test_that("process_order shows complex cli interpolated errors", {
152-
expect_snapshot_error(process_order(0, -10, "INVALID", "USA"))
153-
expect_snapshot_error(process_order(-5, 25.99, "", "X"))
154-
})
155-
```
156-
157-
### Testing complex output
158-
159-
```{r}
160-
summarize_data <- function(x) {
161-
cat("Summary of data:\n")
162-
cat("Length:", length(x), "\n")
163-
cat("Mean:", mean(x), "\n")
164-
cat("Range:", range(x), "\n")
165-
}
166-
167-
test_that("summarize_data output is correct", {
168-
expect_snapshot(summarize_data(1:10))
169-
})
170-
```
136+
TODO: insert complex `cli::cli_abort()` example.
171137

172138
The same idea applies to messages and warnings.
173139

0 commit comments

Comments
 (0)