测试与R包中的用户的交互

时间:2016-12-29 01:52:34

标签: r readline r-package testthat

我正在开发一个R包,其中一个函数通过readline标准输入实现与用户的交互。我现在想知道如何测试这个函数的行为,最好用testthat库。

似乎test_that函数假定用户输入的答案为""。我希望我可以测试用户可能输入的各种答案条件下的行为。

下面是一个小示例代码。在实际开发中,marryme函数在单独的文件中定义并导出到命名空间。 devtools::test()在最后一行收到错误,因为答案永远不会变为是。我想在用户输入"y"时测试函数是否正确返回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
})

1 个答案:

答案 0 :(得分:4)

将readLines()与自定义连接

一起使用

使用readLines()代替readline(),您可以定义连接,允许您使用全局选项对其进行自定义。

您需要执行两个步骤:

  1. zzz.R中的包中设置一个默认选项,指向stdin:

    .onAttach <- function(){
      options(mypkg.connection = stdin())
    }
    
  2. 在您的函数中,将readline更改为readLines(n = 1)并将readLines()中的连接设置为getOption("mypkg.connection")

  3. 实施例

    根据您的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) >