如何测试单个Shiny模块的独立应用运行状态以提升代码覆盖率?
问题描述
我构建了一个包含多个模块的Shiny应用,为每个模块都开发了独立应用,用于在浏览器中测试其功能。目前我已单独测试了模块的Server和UI部分,但希望找到简便方法测试该独立应用是否正常运行,以此提升代码覆盖率。考虑使用shinytest R包进行测试,但该独立应用无输入参数,不知以什么为测试基准。
模块构建的Shiny应用代码
library("shiny") featureOutput <- function(id) { plotOutput(NS(id, "plot")) } featureServer <- function(id, value) { moduleServer(id, function(input, output, session) { output$plot <- renderPlot({ graphics::hist(value()) }, res = 96) }) } featureApp <- function() { ui <- fluidPage( featureOutput("test") ) server <- function(input, output, session) { dat <- reactive({datasets::mtcars$disp}) featureServer("test", dat) } shinyApp(ui, server) }
现有testthat测试代码
library("testthat") test_that("Test module", { testServer(featureServer, args = list(value = reactive(cars$speed)), { testthat::expect_output(str(output$plot), NULL) }) expect_snapshot(featureOutput("x")) })
解决方案
1. 用shinytest做快照验证
即使没有输入参数,也可以通过快照对比验证应用的渲染结果:
- 初始化并运行独立应用,捕获界面的完整状态(包括生成的直方图)
- 将首次捕获的状态作为基准快照,后续测试时对比当前渲染结果与快照是否一致
示例测试代码:
library(shinytest) library(testthat) test_that("独立应用正常运行并渲染正确", { # 初始化应用 app <- ShinyDriver$new(featureApp(), load_timeout = 5000) on.exit(app$stop()) # 捕获应用界面快照(首次运行生成基准,后续对比) app$expect_snapshot() # 额外验证:确认plot元素存在且已渲染 plot_element <- app$findElement("#test-plot") expect_true(plot_element$isVisible()) })
2. 补充应用启动与无报错测试
可以直接验证应用能否正常启动且运行过程中无报错:
test_that("独立应用可正常启动无报错", { # 启动应用并检查状态 app <- featureApp() process <- shiny::runApp(app, port = shiny::randomPort(), launch.browser = FALSE) on.exit(process$stop()) # 验证应用服务正常响应 resp <- httr::GET(paste0("http://localhost:", process$getPort())) expect_equal(resp$status_code, 200) })
3. 结合现有模块测试提升覆盖率
- 现有
testServer测试可以补充验证输出的直方图数据逻辑,比如检查直方图的区间、频数是否符合预期 - 对
featureApp的server部分,可通过testServer模拟调用,验证datreactive传递是否正确
内容的提问来源于stack exchange,提问作者moremo
相关产品推荐
相关产品推荐

