Welcome!

This site contains the materials for the R/Pharma workshop titled, Developing & Testing Your Shiny Application.

Workshop Description

This talk takes a deep dive into the world of testing shiny applications, covering strategies for determining what needs to be tested to ensure your app’s functional accuracy and reliability. Shiny’s reactive programming model requires specialized approaches to testing, distinct from traditional R package testing.

I’ll begin by describing the application of unit, integration, and end-to-end testing in Shiny apps. Then we’ll move into the role of testing in development and highlight the need for code organization when designing your testing suite.

The focus then shifts to practical aspects of testing by illustrating tools like test data and fixtures. Attendees will see example tests for utility functions, modules, and tests to capture specific user interactions (and confirm the application behaves as expected).

Finally, I will demonstrate advanced topics like test coverage, what it measures, and why 100% coverage isn’t necessarily a metric worth chasing.

This presentation will give R developers a toolkit of testing techniques (building a test suite, writing effective tests, and automated testing) regardless of their familiarity with Shiny.

Workshop Topic Index

Below is an index for each topic, slide, and chapter in Shiny App-Packages. The quickest way to access each branch/app is with the shinypak package.

# install.packages("pak")
pak::pak("mjfrigaard/shinypak")
library(shinypak)

List all the apps with list_apps()

head(list_apps())
#>                  branch        last_updated
#> 2     01_whole-app-game 2024-01-01 14:11:32
#> 1        02.1_shiny-app 2024-01-04 13:05:58
#> 4       02.2_movies-app 2024-01-04 13:07:59
#> 5         02.3_proj-app 2024-01-04 13:08:58
#> 6      03.1_description 2024-01-04 13:10:00
#> 7            03.2_rproj 2024-01-04 13:25:06

Launch an app with launch()

launch(app = "02.3_proj-app")

Shiny Apps and R packages

Topic

Video/Slide/Branch

Book section

Basic Shiny Apps 6:15 / 5 /02.1_shiny-app Shiny Apps covers creating a new Shiny app in Posit Workbench and the boilerplate code.
Advanced Shiny Apps 8:37 / 7 / 02.2_movies-app, 02.3_proj-app The code for our application is introduced in Movie review data app, and the utility function, modules, and data are covered in Project folders
Rproj fields 13:38 / 14 / 03.2_rproj R Projects discusses what’s in the .Rproj file (and project vs. package fields).
Transitioning to a Package 20:18 / 15 / 03.1_description, 03.3_create-package Creating app-packages covers converting and creating app-packages with usethis::create_package()
DESCRIPTION fields 25:51 / 16 / 03.3_create-package Storing/supplying your personal information in new packages is discussed in DESCRIPTION arguments
Load, document, and install 28:01 / 18 / 04_devtools Building R packages means adopting new package development habits
The benefits of document() 31:26 / 20 / 04_devtools Documentation covers the multiple outputs created with devtools::document()
Running check() 35:14 / 23 / 04_devtools How often/should you run Check?

R Package Contents

Topic

Video/Slide/Branch

Book section

Documentation 41:39 / 26 / 05_roxygen2 Learn the basics of function documentation with roxygen2 basics
Help files 45:03 / 27 / 05_roxygen2 Preview help files while documenting app functions
Dependencies 47:21 / 28 / 06.1_pkg-exports Introduction to managing dependencies
Exports 49:44 / 29 / 06.1_pkg-exports Exports from your app-package
Imports 53:01 / 30 / 06.2_pkg-imports Imports into your app-package
Data 1:03:15 / 33 / 07_data Storing, loading, and documenting data
Accessing files with system.file() 1:08:51 / 37 / 07_data How to use the inst/extdata folder

App-Package Contents

Topic

Video/Slide/Branch

Book section

Launching apps 1:21:17 / 40 / 08_launch-app Launch covers Shiny’s three functions for running apps (shinyApp(), runApp(), and shinyAppDir())
Standalone app functions 1:22:07 / 41 / 08_launch-app Standalone options provides some methods/approaches to writing the primary function to run your application.
app.R files 1:27:07 / 44 / 08_launch-app app.R options includes packages and functions to consider including in the root app.R file (and how to use it non-interactively).
External resources 1:30:32 / 45 / 09.1_inst-www Most Shiny apps require some external files–this chapter covers how to include them.
addResourcePath() and system.file() 1:31:12 / 46 / 09.1_inst-www, 09.2_inst-bslib The differences between the ‘source’ and ‘installed’ package is covered in package files, and including alternative image files/UI arguments is discussed in bslib layout
‘development’ vs ‘production’ directories 1:43:41 / 48 / 09.3_inst-dev, 09.4_inst-prod This chapter also covers how to use inst/ to store dev data and production (prod) versions of your app

Questions from chat

  1. Am I planning on contrasting this package development approach with a [Shiny] framework?

    1. Discussion of the rhino framework: 1:48:29

    2. Shiny framework comparisons website: 1:50:35

    1. Brief discussion of the golem framework: 1:51:09
  2. Choosing one framework over another in terms of design and how to best prepare your app as it becomes more complicated or how you choose the best way to ‘future proof’ your app?

    1. My rather lengthy non-answer starts at 1:54:14
  3. The order of learning when it comes to our Shiny versus R packages (like learning before the other)

    1. Shameless plug for my Shiny App-Packages book starting at: 1:56:15

Tests

Topic

Video/Slide/Branch

Book section

Tests 2:00:45 / 51 / 11_tests-specs Tests gives an overview of the testing section (and links to additional resources)
Test suite 2:02:15/ 52 / 11_tests-specs Test suite covers how to setup your testthat tests, creating new tests, running tests interactively, etc.
App specifications 2:09:46/ 56 / 11_tests-specs Specifications compares user specifications, features, and functional requirements (or how to figure out what to test)
Connecting user specifications and tests 2:11:40 / 57 / 11_tests-specs The traceability matrix section gives an example of a user specification mapped to a feature linked to a functional requirement connected to a test.
testthat BDD functions 2:18:25 / 59 / 11_tests-specs BDD and testthat covers using describe() and it() with the Gherkin syntax
Test fixtures 2:22:07 / 61 / 12.1_tests-fixtures The fixtures section uses the same (data) example fixture, but gives more information on using them in tests.
Test helpers 2:32:09 / 66 / 12.2_tests-helpers Test helpers covers some dos and don’ts of writing test helpers (it’s OK if test code doesn’t 100% adhere to the DRY principle)
Testing modules 2:37:59 / 72 / 13_tests-modules Integration tests discusses testing module server functions with testServer()
System tests 2:48:54 / 82 / 14_tests-system System tests covers setting up shinytest2, recording and writing tests.

About Me

Martin Frigaard is a Shiny Developer and tidyverse instructor. Find him on LinkedIn.