# install.packages('pak')
::pak('mjfrigaard/shinypak') pak
10 Test suite
Testing shiny applications poses some unique challenges. Shiny functions are written in the context of its reactive model,1 so some standard testing techniques and methods for regular R packages don’t directly apply. This chapter covers setting up the testthat
’s infrastructure for unit tests. I’ll also introduce some keyboard shortcuts for commonly used functions while developing tests.
10.1 testthat
framework
testthat
is the standard package for testing in R packages and one of the most widely used and supported packages on CRAN. Its widespread adoption is likely due to its ability to simplify the setup, creation, and execution of unit tests.
In our app-packages, we’ll use testthat
unit tests to ensure the underlying logic (i.e., non-reactive utility functions) behaves correctly. Combining Shiny’s testServer()
function and the shinytest2
package with testthat
provides a comprehensive testing suite for our app-package.
10.2 Setting up testthat
tests
The testthat
package has been around for over a decade and thus has undergone various changes that require us to specify the edition we intend to use (currently, it’s the third):2
::use_testthat(3) usethis
Setting up your testing infrastructure with use_testthat()
does the following (3
is the edition):
In the
DESCRIPTION
file,testthat (>= 3.0.0)
is listed underSuggests
Config/testthat/edition: 3
is also listed in theDESCRIPTION
to specify thetestthat
editionA new
tests/
folder is created, with atestthat/
subfolderThe
tests/testthat/testthat.R
file is created
We now have a tests/
folder to store our testthat
tests.
tests/
├── testthat/
└── testthat.R
2 directories, 1 file
- 1
- Referred to as the ‘test runner,’ because it runs all our tests (do not edit this file).
10.3 Creating unit tests
The standard workflow for writing testthat
unit tests consists of the following:
New tests are created with usethis::use_test()
:
::use_test("scatter_plot") usethis
testthat
recommends having a corresponding test file intests/testthat/
(with thetest-
prefix) for the files inR/
.
10.3.1 test-
files
Test files: the IDE will automatically create and open the new test file:
✔ Writing 'tests/testthat/test-scatter_plot.R' • Modify 'tests/testthat/test-scatter_plot.R'
10.3.2 test_that()
tests
Each new test file contains a boilerplate test_that()
test:
test_that(desc = "multiplication works", code = {
})
- 1
-
desc
is the test context (supplied in"quotes"
), andcode
is the test code (supplied in{curly brackets}
).
10.3.3 expect_
ations
Expectation typically have two parts: an observed
object, and an expected
object:
expect_equal(
object = 2 * 2,
expected = 4
)
- 1
-
A
testthat
expectation function
- 2
-
The output or behavior being tested
- 3
- A predefined output or behavior
The observed
object is an artifact of some code we’ve written, and it’s being compared against an expected
result.
10.3.4 BDD test functions
testthat
also has two behavior-driven development (BDD) functions for performing tests: describe()
and it()
.
“Use
describe()
to verify that you implement the right things and use [it()
] to ensure you do the things right.” -testthat
documentation
describe("Description of feature or specification",
code = {
it("Functionality under test",
code = {
expect_equal(
object = 2 * 2,
expected = 4
)
}) })
- 1
-
describe()
the feature or specification
- 2
-
Capture
it()
in a test
- 3
- Write expectations
We’ll cover BDD more in the next chapter, but for now just know that each call to it()
behaves like test_that()
.
10.3.5 Running tests
Another devtools
habit to adopt is regularly writing and running tests. If you’re using Posit Workbench and have devtools
installed, you can test your app-package using the Build pane or the keyboard shortcut: Ctrl/Cmd + Shift + T
10.3.6 Keyboard shortcuts
R Packages, 2ed also suggests binding test_active_file()
and test_coverage_active_file()
to keyboard shortcuts. I highly recommend using a shortcut while developing tests because it will improve your ability to iterate quickly.
devtools
function
test()
Keyboard shortcut
Ctrl/Cmd + Shift + T
test_active_file()
Ctrl/Cmd + T
test_coverage_active_file()
Ctrl/Cmd + Shift + R
When the test is run, we’ll see feedback on whether it passes or fails (and occasionally some encouragement):
test_that("multiplication works", {
expect_equal(
object = 2 * 2,
expected = 4
)
})## Test passed 🥇
Recap
The ‘Reactivity - An overview’ article gives an excellent description (and mental module) of reactive programming.↩︎
Read more about changes to the third edition to
testthat
in R Packages, 2ed↩︎