Fixing 'no Restart' Error In Shinytest2 With Testthat
Experiencing the frustrating “no ‘restart’ ‘continue_test’ found” error when using shinytest2::AppDriver$expect_values() within test_that()? You're not alone! This issue has surfaced with the newest release of testthat (3.3.0) while testing Shiny applications using shinytest2. Let's dive into what causes this error and how to resolve it.
Understanding the Problem
This error typically arises when trying to record tests for a Shiny app, particularly within an R package development context. The core issue seems to stem from an incompatibility introduced in testthat version 3.3.0, as downgrading to version 3.2.3 often resolves the problem. The error manifests during the snapshot testing process, specifically when shinytest2 attempts to capture and compare application states. The error message, “Error in invokeRestart("continue_test"): no 'restart' 'continue_test' found”, indicates that a necessary restart point within the testing framework is not being properly recognized or invoked.
To put it simply, testthat uses restarts as a mechanism to handle errors and continue testing, especially in interactive environments. shinytest2, which builds on top of testthat, leverages this mechanism for its snapshot testing capabilities. When testthat 3.3.0 fails to find the continue_test restart, it disrupts the testing flow, leading to the error. This often happens during the expect_values() call, where shinytest2 tries to capture the application’s state and compare it against a stored snapshot.
Minimal Working Example
To illustrate the issue, consider the following minimal Shiny application and test case:
library(testthat)
library(shiny)
library(shinytest2)
minimal_app <- function() {
shinyApp(
ui = fluidPage(
actionButton("next_btn", "Next"),
textOutput("txt")
),
server = function(input, output, session) {
counter <- reactiveVal(1)
observeEvent(input$next_btn, {
counter(counter() + 1)
})
output$txt <- renderText(counter())
}
)}
test_that("shinytest2 snapshot triggers invokeRestart error", {
app <- AppDriver$new(
app = minimal_app(),
name = "minimal_snapshot",
variant = platform_variant()
)
app$click("next_btn")
app$wait_for_idle()
app$expect_values()
})
This example sets up a simple Shiny app with a button and a text output. The test case uses shinytest2 to interact with the app, clicking the button and then attempting to capture the app’s state using expect_values(). When running this test with testthat 3.3.0, the “no ‘restart’ ‘continue_test’ found” error will likely occur. This is a clear demonstration of the incompatibility issue between the latest testthat and shinytest2.
Decoding the Error Message
The full error message and backtrace provide valuable clues for diagnosing the problem. Let's break down the key parts:
Error in `invokeRestart("continue_test")`: no 'restart' 'continue_test' found
Backtrace:
▆
1. ├─app$expect_values() at test_shiny_minimal.R:33:3
2. │ └─shinytest2:::app_expect_values(...)
3. │ ├─base::withCallingHandlers(...)
4. │ └─shinytest2:::app_expect_screenshot(...)
5. │ └─shinytest2:::app__expect_snapshot_file(...)
6. │ ├─base::withCallingHandlers(...)
7. │ └─testthat::expect_snapshot_file(...)
8. │ └─testthat::pass()
9. │ └─testthat::expectation("success", "success")
10. │ └─testthat::exp_signal(exp)
11. │ ├─base::withRestarts(...)
12. │ │ └─base (local) withOneRestart(expr, restarts[[1L]])
13. │ │ └─base (local) doWithOneRestart(return(expr), restart)
14. │ └─base::signalCondition(exp)
15. └─shinytest2 (local) <fn>(<expcttn_>)
16. └─base::invokeRestart("continue_test")
- Error in
invokeRestart("continue_test"): This is the primary error, indicating the missing restart point. - Backtrace: The backtrace shows the sequence of function calls that led to the error. It starts with
app$expect_values()in your test file and traces down throughshinytest2internals, eventually reachingtestthatfunctions related to snapshot testing and error handling. - testthat::expect_snapshot_file(...) This part of the trace suggests the issue arises during snapshot file comparison, a key part of
shinytest2'sexpect_values()functionality. - base::withRestarts(...) and base::invokeRestart("continue_test"): These lines highlight the failure to find and invoke the
continue_testrestart point.
This detailed backtrace helps pinpoint the problem within the interaction between shinytest2 and testthat's error handling mechanisms.
Solutions and Workarounds
Fortunately, there are a couple of straightforward ways to address this issue:
1. Downgrade testthat
The simplest and most reliable solution is to downgrade testthat to version 3.2.3. This version is known to be compatible with shinytest2 and does not exhibit the “no ‘restart’ ‘continue_test’ found” error. You can downgrade using the following command:
remotes::install_version("testthat", "3.2.3")
After downgrading, restart your R session and rerun your tests. The error should be resolved.
2. Consider Alternatives for Snapshot Testing
If downgrading isn't an option for your project, you might explore alternative approaches for snapshot testing your Shiny applications. While shinytest2 is a powerful tool, other packages and techniques can help you achieve similar results. For example, you could consider using image comparison techniques or focus on testing specific UI elements and reactive behaviors directly.
Why Does This Happen?
The exact cause of this incompatibility is still under investigation within the testthat and shinytest2 communities. It's likely related to changes in how testthat 3.3.0 handles restarts or error conditions, which inadvertently affects shinytest2's snapshot testing process. As both packages are actively maintained, a future update might address this issue directly. Keep an eye on the respective package repositories and issue trackers for updates and discussions.
Broader Context and Potential Impact
This issue highlights the importance of carefully managing package dependencies and testing your code against different versions of libraries. In the R ecosystem, where package updates are frequent, compatibility issues can arise. It's always a good practice to:
- Specify package versions in your project: Use tools like
renvorpackratto manage your project's dependencies and ensure consistent behavior across different environments. - Run tests regularly: Integrate testing into your development workflow to catch issues early.
- Stay informed about package updates: Follow package release announcements and discussions to be aware of potential compatibility concerns.
By being proactive about dependency management and testing, you can minimize disruptions caused by package updates and ensure the stability of your R applications.
Conclusion
The “no ‘restart’ ‘continue_test’ found” error in shinytest2 with testthat 3.3.0 can be a frustrating roadblock when testing Shiny applications. However, by understanding the root cause and applying the solutions discussed—primarily downgrading testthat—you can overcome this hurdle and continue developing robust and reliable Shiny apps. Remember to stay informed about package updates and manage your dependencies effectively to prevent similar issues in the future. For further information on testthat and its functionalities, you can visit the official testthat website.