@mjfrigaard
  • About
  • All Posts
  • Books
  • Talks
  • Publications
  • Series
  • Code

Series

Testing shiny apps

These posts focus on testing Shiny applications with testthat, shiny’s testServer() function, and shinytest2.

Title Subtitle
Behavior Driven Unit Tests Part 1 (series): testthat’s BDD testing functions
Testing Non-Package Shiny Apps Part 2 (series): Using testthat with Shiny outside of a package
Testing Shiny modules Part 3 (series): module server functions and testServer()
Shiny System Tests With shinytest2 Part 4 (series): writing efficient system tests
Testing rhino apps Part 5 (series): Testing with box modules
No matching items
Testing details

testthat

testthat is a popular unit testing framework that allows R package developers to create tests scripts for functions and logic systematically. In a shiny app-package, it’s used for testing the non-reactive components (i.e., utility functions). This includes functions for data processing, plots, modeling, and other code that’s part of the package. However, it is not designed to work with shiny’s reactive model.

  • Post: Behavior Driven Unit Tests: This post covers unit testing a set of utility functions with testthat. You can also read the documentation from the package website, in R packages, and in Mastering Shiny. The app-package for this post is stored in this Github Repo.

  • Post: Testing Non-Package Shiny Apps: Your shiny app should be developed as a package, but this isn’t always the case. If you’d like to test your application’s code without converting it to a package, check out the second post (and the GitHub repo).

testServer()

testServer() comes from the shiny package and is designed to test the server-side logic of your app. These tests can be used to simulate user inputs and verify the corresponding outputs. testServer() can also test the functionality of module server functions (reactivity, outputs, and any returned values) in isolation from their UI function counterparts. However, testServer() doesn’t capture how UI elements are rendered or simulate key user interactions (i.e., execution paths) through the application.

  • Post: Testing Shiny Modules: If you’ve built your shiny application as a package and it contains modules, this post covers testing module server functions using the examples from the ‘Modules’ chapter of Mastering Shiny. The code and examples are in this GitHub repo

shinytest2

shinytest2 is designed to perform end-to-end testing of shiny apps. These tests can capture a shiny app’s current state (i.e., a snapshot) and compare it with a previously saved (or expected) states. Snapshots are useful for end-to-end testing because they can simulate key user interaction in a way that unit tests and testServer() can’t (i.e., the delay between input changes and rendering updated outputs, specific sequences of selections on action buttons, radio buttons, etc.). shinytest2 tests are resource-intensive, so it’s recommended to write these tests after writing testthat unit tests and testServer() tests.

  • Post: Shiny system tests with shinytest2: This post picks up where the previous post left off with the shinytest2 package. The app-package used in the examples is stored in this GitHub repo.

In summary, use testthat for unit testing utility/helper functions, then testServer() for the server-side logic, and finish off with shinytest2 tests for end-to-end functionality of your shiny app. These tools complement each other to provide a comprehensive testing framework.