Smoke Testing Shiny Apps
ThinkR has some nice posts about Shiny.
Here I am using tips from https://rtask.thinkr.fr/building-a-shiny-app-as-a-package.
My focus here is on their neat idea about a simple way to test Shiny apps.
The Simplest Shiny Test
The idea of the test is simple:
If we start a Shiny app it should still be running N
seconds later for an appropriate choice of N
.
We run the app in a separate process using the processx package.
p <- processx::process$new(
file.path(Sys.getenv("R_HOME"), "bin", "R.exe"),
c("-e", "shiny::runApp()"),
cleanup_tree = TRUE
)
print(p)
Sys.sleep(5)
if (isFALSE(p$is_alive())) {
stop("App not running")
}
p$kill()
print(p)
I am a little more verbose than in the ThinkR post, printing more information about the process p
and explicitly writing out the path to the R executable.
All of this could be wrapped in testthat
statement, but here I am keeping it simple.
Windows
At first, I did not include the cleanup_tree
argument when creating the process p
.
But leaving it out caused some annoyances on Windows.
It also turned out to be necessary when running tests on Windows through GitLab.
When R is started on Linux we have a single R process running, which can be found with this shell command:
$ ps aux | grep "R"
robert 99 4.0 0.2 426776 41944 pts/0 Sl 11:16 0:01 R
When R is started on Windows we get two R processes and one Rterm process, which can be found with this PowerShell command:
> Get-Process -Name R,Rterm
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
52 6 1532 4012 0,00 2416 1 R
113 7 1924 5688 0,02 5216 1 R
164 68 68088 47020 0,16 15484 1 Rterm
There are apparently some legacy reasons for this and usually it is not a problem – when the “main” R process (one of the two R
s above) is closed, Rterm
and the other R
is also closed.
However, when R is started with the processx
package without cleanup_tree
and later killed (with p$kill()
in the R code above), only the “main” R process is closed, leaving Rterm and the other R hanging.
This can cause frustration on Windows, e.g. where the files being used by the hanging processes are not allowed to be edited because they are “in use by another program”.
On GitLab, the test runner that handles communication between GitLab and the computer running the test does not register the test as completed when there are two hanging processes.