问题
I am developing an R package and one of the function implements interaction with users through standard input via readline. I now wonder how to test the behavior of this function, preferably with testthat library.
It seems test_that function assumes the answer is "" for user-input. I wish I could test the behavior conditional of various answers users may type in.
Below is a small example code. In the actual development, the marryme function is defined in a separate file and exported to the namespace.
devtools::test() gets me an error on the last line because the answer never becomes yes. I would like to test if the function correctly returns true when user types "y".
library(testthat)
test_that("input", {
marryme <- function() {
ans <- readline("will you marry me? (y/n) > ")
return(ans == "y")
}
expect_false(marryme()) # this is good
expect_true(marryme()) # this is no good
})
回答1:
Use readLines() with a custom connection
By using readLines() instead of readline(), you can define the connection, which allows you to customize it using global options.
There are two steps that you need to do:
set a default option in your package in
zzz.Rthat points to stdin:.onAttach <- function(libname, pkgname){ options(mypkg.connection = stdin()) }In your function, change
readlinetoreadLines(n = 1)and set the connection inreadLines()togetOption("mypkg.connection")
Example
Based on your MWE:
library(testthat)
options(mypkg.connection = stdin())
marryme <- function() {
cat("will you marry me? (y/n) > ")
ans <- readLines(con = getOption("mypkg.connection"), n = 1)
cat("\n")
return(ans == "y")
}
test_that("input", {
f <- file()
options(mypkg.connection = f)
ans <- paste(c("n", "y"), collapse = "\n") # set this to the number of tests you want to run
write(ans, f)
expect_false(marryme()) # this is good
expect_true(marryme()) # this is no good
# reset connection
options(mypkg.connection = stdin())
# close the file
close(f)
})
#> will you marry me? (y/n) >
#> will you marry me? (y/n) >
来源:https://stackoverflow.com/questions/41372146/test-interaction-with-users-in-r-package