测试模块化 R Shiny (golem) 仪表板

如何解决测试模块化 R Shiny (golem) 仪表板

我一直在探索(**并且喜欢)使用 R Shiny 开发模块化仪表板的 golem 包。但我正在努力思考如何测试模块化仪表板。

例如在下面的 repex 中,如果导入模块中的 input$n_rows 设置为 15,我将如何测试显示模块中的输出包含 15 行?

如果您对此提供任何支持,我将不胜感激!


library(shiny)
library(reactable)
library(dplyr)

# Import module UI
mod_import_ui <- function(id){
  
  ns <- NS(id)
  
  fluidRow(
    # Allow the user to select the number of rows to view
    numericInput(ns("n_rows"),"Select number of observations",value = 10)
    
  )
}

# Import module Server
mod_import_server <- function(id){
  
  moduleServer(
    id,function(input,output,session){
      
      data <- reactive({
        
        # Sample the requested number of rows from mtcars and return this to the application server
        mtcars %>%
          slice_sample(n = input$n_rows)
        # [....] # Some complex formatting and transformations
        
      })
      
      return(data)
      
      
      
    }
  )}

# display module UI
mod_display_ui <- function(id){
  
  ns <- NS(id)
  
  fluidRow(
    
    reactableOutput(ns("table"))
    
  )
}

# display module Server
mod_display_server <- function(id,data_in){
  
  moduleServer(
    id,session){
      
      # [....] # Some more transformations and merging with data from other modules
      
      output$table <- renderReactable(reactable(data_in()))
      
    }
  )}


app_ui <- function(request) { 
  
  tagList(
  
    mod_import_ui("import_1"),mod_display_ui("display_1")

  )
  
  }


app_server <- function(input,session) { 
  
  data_in <- mod_import_server("import_1")
  mod_display_server("display_1",data_in)
  
}

shinyApp(ui = app_ui,server = app_server)


解决方法

我建议将应用的核心与用户界面分开。

{golem} 框架允许在 R 包中构建您的应用程序,这意味着您可以使用从包构建到文档和测试代码的所有工具。
如果您遵循我们在 engineering-shiny.org/ 中的指南,您将看到我们建议从您的“服务器”部分提取所有 R 代码以在小插图中对其进行测试,将其转换为常规函数,以便您可以照常进行测试带有 R 包。
因此,您 ShinyApp 只调用内部函数,已经记录和测试。使用这种方法,您可以测试应用程序中可能发生的不同场景的输出。在静态脚本中尝试不同的输入参数并验证输出,无论您在接下来的开发步骤中在应用中发生什么变化。

这本书给出了很多建议。如果我必须将它们总结为一个工作流程,这将是:

  1. 直接在 Rmd 中构建必要的代码。这使您无需进行所有必要的单击即可测试操作。我们称之为“Rmd 优先”方法:https://rtask.thinkr.fr/when-development-starts-with-documentation/
  2. 将此代码分解为 R 函数,以尽可能少地放入 Shiny 应用本身。
  3. 在没有服务器的情况下(或不要太多)创建您的 UI 部分,只是为了看看总体外观
  4. 在应用的适当位置包含您的函数。
  5. 加强代码。可重现的示例、单元测试、文档、代码版本控制等(与代码并行执行时,此步骤更好)
,

作为对 Sebastien 回答的补充,我想指出从 {shiny} v 1.5.0 开始,您可以直接使用 testServer 函数测试服务器功能,这可能就是您正在寻找的

以下是您如何实现这一目标的代表:

library(shiny)
library(magrittr)
library(dplyr)

mod_import_server <- function(id){
  moduleServer( id,function(input,output,session){
    data <- reactive({
      mtcars %>%
        slice(n = 1:input$n_rows)
    })
    return(data)
  })
}

shiny::testServer(mod_import_server,{
  
  for (i in 1:10){
    
    session$setInputs(n_rows = i)
    testthat::expect_equal(
      data(),slice(mtcars,n = 1:i)
    )
    
  }
})

在这里,您可以测试 reactive() 的行为是否符合您的预期。 这并不完美,但这是一个好的开始:) 但是,很难找到一种方法来测试第二个模块的行为,因为它取决于作为值传递的 react()。

科林

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?