在 R 包中测试与用户的交互
Test interaction with users in R package
我正在开发一个 R 包,其中一个函数通过 readline
通过标准输入实现与用户的交互。我现在想知道如何测试此函数的行为,最好使用 testthat
库。
似乎 test_that
函数假设用户输入的答案是 ""
。我希望我可以测试用户可能输入的各种答案的行为条件。
下面是一个小示例代码。在实际开发中,marryme
函数是在单独的文件中定义的,并导出到命名空间中。
devtools::test()
在最后一行给我一个错误,因为答案永远不会变成是。当用户输入 "y"
.
时,我想测试功能是否正确 returns true
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
})
通过自定义连接使用 readLines()
通过使用 readLines()
而不是 readline()
,您可以定义连接,这允许您使用全局选项对其进行自定义。
您需要执行两个步骤:
在 zzz.R
中的包中设置一个指向标准输入的默认选项:
.onAttach <- function(libname, pkgname){
options(mypkg.connection = stdin())
}
在您的函数中,将 readline
更改为 readLines(n = 1)
并将 readLines()
中的连接设置为 getOption("mypkg.connection")
例子
根据您的 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) >
我正在开发一个 R 包,其中一个函数通过 readline
通过标准输入实现与用户的交互。我现在想知道如何测试此函数的行为,最好使用 testthat
库。
似乎 test_that
函数假设用户输入的答案是 ""
。我希望我可以测试用户可能输入的各种答案的行为条件。
下面是一个小示例代码。在实际开发中,marryme
函数是在单独的文件中定义的,并导出到命名空间中。
devtools::test()
在最后一行给我一个错误,因为答案永远不会变成是。当用户输入 "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
})
通过自定义连接使用 readLines()
通过使用 readLines()
而不是 readline()
,您可以定义连接,这允许您使用全局选项对其进行自定义。
您需要执行两个步骤:
在
zzz.R
中的包中设置一个指向标准输入的默认选项:.onAttach <- function(libname, pkgname){ options(mypkg.connection = stdin()) }
在您的函数中,将
readline
更改为readLines(n = 1)
并将readLines()
中的连接设置为getOption("mypkg.connection")
例子
根据您的 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) >