For R packages that have Shiny
applications, there are generally two ways that the applications will be
present in the package. The first is to have an app.R
in a
subdirectory of inst/
. The second way is to have a function
which returns a Shiny app object.
π§ Using
{chromote}
in CRAN tests
{chromote}
utilizes the Google Chrome application installed on testing machines, which can change over time. CRAN has requested that no package utilize{chromote}
βs functionality when testing on CRAN. This is because the package may not work as expected if the version of Google Chrome changes.To address this,
{shinytest2}
will calltestthat::skip_on_cran()
when creating anAppDriver
during CRAN testing.To learn more about CRANβs reasoning and how to test your package using CI, please visit
{chromote}
βs Using{chromote}
in CRAN tests.
inst/
An application could live in a subdirectory of inst/
, as
shown below:
/
βββ DESCRIPTION
βββ NAMESPACE
βββ R
βββ inst
β βββ sample_app
β βββ app.R
β βββ tests
β βββ testthat
β β βββ _snaps
β β β βββ shinytest2
β β β βββ 001.json
β β βββ test-shinytest2.R
β βββ testthat.R
βββ tests
βββ testthat
β βββ test-inst-apps.R
βββ testthat.R
In this case, you can run record_test()
and
test_app()
as normal. After you create and run the tests,
there will be a tests/
subdirectory in the application
directory that stores the test scripts and results.
Since we are using {testthat}
for automated tests, you
would create a test driver script in tests/testthat/
. In
this example, itβs named test-inst-apps.R
and contains the
following:
# File: tests/testthat/test-inst-apps.R
library(shinytest2)
test_that("sample_app works", {
# Don't run these tests on the CRAN build servers
skip_on_cran()
appdir <- system.file(package = "exPackage", "sample_app")
test_app(appdir)
})
If the application directory is not meant to be public, it can also
be located in ./tests/testthat/apps
.
{shinytest2}
does this with many application and has
appdir
above point to the relative path to the
application.
The second way have an application in an R package is by having a
function that returns a Shiny application object. In this example,
thereβs a function hello_world_app()
, which lives in
R/hello-world.R
:
/
βββ .Rbuildignore
βββ DESCRIPTION
βββ NAMESPACE
βββ R
β βββ hello-world.R
βββ tests
βββ testthat
β βββ _snaps
β β βββ app-function
β β βββ 001.json
β βββ test-app-function.R
βββ testthat.R
The function simply returns an object from
shinyApp()
:
# File: R/hello-world.R
hello_world_app <- function() {
utils::data(cars)
shinyApp(
ui = fluidPage(
sliderInput("n", "n", 1, nrow(cars), 10),
plotOutput("plot")
),
server = function(input, output) {
output$plot <- renderPlot({
plot(
head(cars, input$n),
xlim = range(cars[[1]]),
ylim = range(cars[[2]])
)
})
}
)
}
Once we have the object, it can be supplied directly to
AppDriver$new()
.
# File: tests/testthat/test-app-function.R
test_that("hello-world app initial values are consistent", {
# Don't run these tests on the CRAN build servers
skip_on_cran()
shiny_app <- hello_world_app()
app <- AppDriver$new(shiny_app, name = "hello")
app$expect_values()
})
To help create tests, you can call record_test()
on your
shiny application object directly. Unfortunately, the test file will not
be able to be saved. Instead, the test commands can be copied into a
test script manually.
There are a few steps that are needed for both types of tests.
It is recommended to call shinytest2::use_shinytest2()
to enable different test config set-ups.
You will need to add {shinytest2}
to the
Suggests
section in your DESCRIPTION
file.
Suggests:
shinytest2
When all of these items are in place, you can test your package using
devtools::install(); testthat::test_local()
or by running
R CMD check
on your package. If you are using the RStudio
IDE, you can also run Build -> Test Package or Build -> Check
Package.
{shinytest2}
requires that your package to be
installed when testing. testthat::test_local()
(and related wrappers) eventually call pkgload::load_all()
to temporarily source the local R package. You can use
test_local()
to test non-{shinytest2}
tests,
but you will need to install your R package to safely execute your
{shinytest2}
tests. If not installed, it will create a
confusing situation where your {shinytest2}
tests are
running on a different version of your R package (whichever was
last installed), than the rest of your tests (the current source).
You can call shinytest2::test_app()
multiple times
within a test script. It does not need to be wrapped within a
testthat::test_that()
call.
{shinytest2}
tests many internal apps using the code
similar to the code below:
If you would like your package to be tested with every commit, you can set it up with GitHub Actions. Please see Using shinytest2 with continuous integration for inspiration.