2016-03-31 10 views
12

Così ho scritto un'app lucida abbastanza dettagliata, e in futuro avrò bisogno di un aggiornamento in quanto la funzionalità dietro ciò che viene eseguito è in continua evoluzione.Unit Testing Shiny Apps

Quello che devo essere in grado di fare è avere dei test unitari (usando testthat o un'altra libreria più utile per le app lucide) che mi consente di eseguire questi test in modo più automatizzato.

Ho scritto una semplice app lucida. Per motivi di testing in questo vorrei un modo per sapere che se scelgo il numero 20 nell'input numerico allora ottengo 400 come output $ out text. Ma voglio essere in grado di farlo senza effettivamente eseguire l'app da solo.

library(shiny) 

ui <- fluidPage(title = 'Test App', 
    numericInput('num', 'Number', 50, 1, 100, 0.5), 
    'Numeric output', 
    textOutput('out') 
) 

server <- function(input, output, session) { 
    aux <- reactive(input$num^2) 

    output$out <- renderText(aux()) 
} 

shinyApp(ui = ui, server = server) 
+3

credo siete alla ricerca di [RSelenium] (https://cran.r-project.org/web/packages/RSelenium/). Vedere la vignetta 'vignetta (" shinytesting "," RSelenium ")'. Tuttavia sembra avere un po 'di curva di apprendimento. – cdeterman

+0

Grazie, sembra esattamente quello di cui ho bisogno. Basti pensare a come salire sui server Selenium mentre sei al lavoro! –

+3

Il selenio non è tecnicamente un test unitario. Penso che se volessi testare l'unità dovresti scomporre la funzionalità dell'app RShiny finché non puoi semplicemente usare testthat –

risposta

0

vedo due possibili approcci qui - testare la funzionalità sottostante e l'esecuzione di test dell'applicazione web stesso. Nota che in questo caso in realtà richiederebbe l'esecuzione del server, ma è una rappresentazione più accurata di se la tua app web funziona o meno.

Testando la funzionalità sottostante, ciò che intendo è il refactoring dei calcoli attualmente eseguiti nel server per le proprie funzioni indipendenti. Invece di quadrare il numero direttamente nel server, è necessario separare la funzionalità dal server in modo che possa essere testata. Ad esempio, in questo modo:

square_of_number <- function(n) return(n^2) 

Ora, è possibile verificare separatamente la funzione square_of_number per la sua uscita prevista.

library('testthat') 

square_of_number <- function(n) return(n^2) 

expect_equal(square_of_number(4), 16) 

Inoltre, se si vuole testare l'applicazione stessa, si potrebbe anche creare test usando un browser senza testa sul reale interfaccia utente si genera con lucido. Un metodo come suggerito nei commenti utilizza Shinytest, ma un approccio che io suggerirei di provare è:

  • Esecuzione del server con una porta specifica,
  • interfacciamento questo server con uno strumento come rvest o RSelenium a manipolare la pagina e quindi raschiare l'output,
  • quindi verificare la suddetta uscita con testthat.
1

Come già detto, è possibile utilizzare il pacchetto shinytest combinato con testthat.

Ecco un semplice esempio:

library(shinytest) 
library(testthat) 

context("Test shiny app") 

#open shiny app 
app <- ShinyDriver$new('path_to_shiny_app') 

test_that("app gets expected output", { 
    #set numeric input 
    app$setInputs(num = 20) 
    #get output 
    output <- app$getValue(name = "out") 
    #test 
    expect_equal(output, "400") 
}) 

#stop shiny app 
app$stop()