Skip to content

Commit 1154cbf

Browse files
authored
Handle interrupts in tests (#2148)
I don't see any way to test this programmatically, so I've just been adding `Sys.sleep(10)` to a random test. Fixes #1464
1 parent 6099802 commit 1154cbf

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# testthat (development version)
22

3+
* Interrupting a test now prints the test name. This makes it easier to tell where a very slow test might be hanging (#1464)
34
* Parallel testthat now does not ignore test files with syntax errors (#1360).
45
* `expect_lt()`, `expect_gt()`, and friends have a refined display that is more likely to display the correct number of digits and shows you the actual values compared.
56
* `describe()`, `it()`, and `test_that()` now have a shared stack of descriptions so that if you nest any inside of each other, any resulting failures will show you the full path.

R/reporter-stop.R

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,48 +14,53 @@ StopReporter <- R6::R6Class(
1414
"StopReporter",
1515
inherit = Reporter,
1616
public = list(
17-
failures = NULL,
17+
# All expectations that need to be reported (error, failure, warning, skip)
18+
issues = NULL,
19+
# Expectations that should cause the test to fail (error, failure)
1820
n_fail = 0L,
21+
# Successful expectations
22+
n_success = 0L,
1923
stop_reporter = TRUE,
2024
praise = TRUE,
2125

2226
initialize = function(stop_reporter = TRUE, praise = TRUE) {
2327
super$initialize()
24-
self$failures <- Stack$new()
28+
self$issues <- Stack$new()
2529
self$praise <- praise
2630
self$stop_reporter <- stop_reporter
2731
},
2832

2933
start_test = function(context, test) {
30-
self$failures <- Stack$new()
34+
self$issues <- Stack$new()
3135
},
3236

3337
add_result = function(context, test, result) {
3438
if (expectation_success(result)) {
39+
self$n_success <- self$n_success + 1
3540
return()
3641
}
3742

3843
if (expectation_broken(result)) {
3944
self$n_fail <- self$n_fail + 1
4045
}
41-
42-
self$failures$push(result)
46+
self$issues$push(result)
4347
},
4448

4549
end_test = function(context, test) {
4650
self$local_user_output()
4751

48-
failures <- self$failures$as_list()
49-
if (length(failures) == 0 && self$praise) {
50-
self$cat_line(colourise("Test passed", "success"), " ", praise_emoji())
51-
return()
52-
}
53-
54-
messages <- map_chr(failures, issue_summary, rule = TRUE)
55-
if (length(messages) > 0) {
52+
if (self$issues$size() == 0) {
53+
if (self$praise && self$n_success > 0) {
54+
emoji <- praise_emoji()
55+
self$cat_line(colourise("Test passed", "success"), " ", emoji)
56+
}
57+
} else {
58+
issues <- self$issues$as_list()
59+
messages <- map_chr(issues, issue_summary, rule = TRUE)
5660
self$cat_line(messages, "\n")
5761
}
5862
},
63+
5964
stop_if_needed = function() {
6065
if (self$stop_reporter && self$n_fail > 0) {
6166
abort("Test failed", call = NULL)

R/test-that.R

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ test_code <- function(code, env, reporter = NULL, skip_on_empty = TRUE) {
149149
register_expectation(e, debug_end)
150150
invokeRestart("end_test")
151151
}
152+
handle_interrupt <- function(e) {
153+
if (!is.null(test)) {
154+
cat("\n")
155+
cli::cli_inform(c("!" = "Interrupting test: {test}"))
156+
}
157+
}
152158

153159
test_env <- new.env(parent = env)
154160
old <- options(rlang_trace_top_env = test_env)[[1]]
@@ -170,7 +176,8 @@ test_code <- function(code, env, reporter = NULL, skip_on_empty = TRUE) {
170176
skip = handle_skip,
171177
warning = handle_warning,
172178
message = handle_message,
173-
error = handle_error
179+
error = handle_error,
180+
interrupt = handle_interrupt
174181
),
175182
# some errors may need handling here, e.g., stack overflow
176183
error = handle_fatal

0 commit comments

Comments
 (0)