使用testthat测试输出或观察Shiny中的元素

huangapple go评论62阅读模式
英文:

test output or observe elements in shiny using testthat

问题

我有一个Shiny应用程序,我在其中使用testthattestServer来测试服务器组件。应用程序的服务器部分具有一些响应式值,但还在observe()元素中渲染一些元素(出于性能原因,我将多个渲染组合在一起)。

一个简单的服务器+testServer示例函数如下:

library(shiny)
library(dplyr)
library(testthat)

server <- function(input, output, session) {
  data <- reactive(mtcars)
  
  observe({
    print("Observe is active")
    
    # 在这里对数据进行进一步的分析
    data2 <- data() %>%
      filter(mpg > 20)
    
    output$nrows <- renderUI(nrow(data2)) # 14
    output$unique_mpgs <- renderUI(length(unique(data2$mpg))) # 10
  })
}

testServer(server, {
  expect_equal(data(), mtcars) # 可以工作,因为data()是reactive()而不是observe()...
  
  # 在这里如何测试nrows == 14和unique_mpgs == 10?
})

如前所述,如果可能的话,我不想有多个响应式值(例如一个用于nrows,然后另一个用于unique_mpgs)。

是否有一种方法可以在testServer中检查observe元素的值?

英文:

I have a shiny app, where I test the server component using testthat and testServer. The server part of the app has a couple of reactive values but also renders some elements in an observe() element (I group multiple renders together for performance reasons).

A simple server + testServer example function looks like this

library(shiny)
library(dplyr)
library(testthat)

server &lt;- function(input, output, session) {
  data &lt;- reactive(mtcars)
  
  observe({
    print(&quot;Observe is active&quot;)
    
    # do some further analysis on the data here
    data2 &lt;- data() |&gt; filter(mpg &gt; 20)
    
    
    output$nrows &lt;- renderUI(nrow(data2)) # 14
    output$unique_mpgs &lt;- renderUI(length(unique(data2$mpg))) # 10
  })
}

testServer(server, {
  expect_equal(data(), mtcars) # works because data() is a reactive() not observe()...
  
  # how can I test here that nrows == 14 and unique_mpgs == 10
})

As mentioned earlier, I don't want to have multiple reactive values (eg one for nrows, then another for unique_mpgs) if possible.

Is there a way to check the value of an observe element in testServer?

答案1

得分: 1

session$flushReact() 运行后似乎触发了 observe 部分(print 部分对于识别这一点非常有帮助)。这强制手动刷新所有的响应式组件。之后 output$nrowsoutput$unique_mpgs 变得可用。

testServer(server, {
    expect_equal(data(), mtcars) # works because data() is a reactive() not observe()...
    
    # manually force a flush of reactives
    session$flushReact()
    
    # check output is available
    expect_error(output$nrows, NA)
    expect_error(output$unique_mpgs, NA)
    # or just
    output$nrows
    output$unique_mpgs
    # since these are rendered as UI, so the output is HTML
    expect_equal(
        as.character(output$nrows$html), 
        '14'
    )
    expect_equal(
        as.character(output$unique_mpgs$html), 
        '10'
    )
})
英文:

Running session$flushReact() seems to trigger the observe part (the print part was helpful in identifying this). This forces manual refresh of all reactives. After that output$nrows and output$unique_mpgs become available.

testServer(server, {
expect_equal(data(), mtcars) # works because data() is a reactive() not observe()...

# manually force a flush of reactives
session$flushReact()

# check output is available
expect_error(output$nrows, NA)
expect_error(output$unique_mpgs, NA)
# or just
output$nrows
output$unique_mpgs
# since these are rendered as UI, so the output is HTML
expect_equal(
    as.character(output$nrows$html), 
    &#39;14&#39;
)
expect_equal(
    as.character(output$unique_mpgs$html), 
    &#39;10&#39;
)
})

huangapple
  • 本文由 发表于 2023年2月9日 01:17:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75389431.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定