如何测试使用Sys.time()的R函数?

时间:2018-03-13 16:46:01

标签: r unit-testing testing testthat

我在软件包中有以下R函数,它将Sys.time()输出到输出,以便用户知道算法的进展情况:

func = function(num1, num2){
    result = num1 + num2
    return(paste0(' ', as.character(Sys.time()), ':  with result: ', result))
}

使用此功能的示例如下:

> func(2, 2)
[1] " 2018-03-11 07:24:05:  with result: 4"
> 

我需要测试这个功能。通常,我会使用testthat包:

https://cran.r-project.org/web/packages/testthat/index.html

问题:为了测试这个功能,如何set Sys.time()?还有其他方法可以测试吗?

如果没有Sys.time(),这个过程很简单:

library(testthat)
expect_equal(func(2, 2), 4)
expect_equal(func(2, -2), 0)
expect_error(func('a', 'b'))

2 个答案:

答案 0 :(得分:3)

我认为你应该重写你的函数,以便在列表中返回结果和时间。然后创建一个执行格式化的自定义打印功能。这样,您仍然可以以编程方式直接使用结果,而无需使用正则表达式来提取结果。这是一个例子。

func <- function(num1, num2){
  result <- num1 + num2
  time <- Sys.time()
  output <- list(result = result, time = time)
  class(output) <- "MyClass"
  return(output)
}

print.MyClass <- function(obj, ...){
  text <- paste0(' ', as.character(obj$time), ': with result: ', obj$result)
  print.default(text)
}

并使用此...

> func(2, 2)
[1] " 2018-03-13 13:26:22: with result: 4"
> o <- func(2,2)
> o$result
[1] 4
> o$time
[1] "2018-03-13 13:26:27 CDT"
> 
> expect_equal(func(2, 2)$result, 4)
> expect_equal(func(2, 2)$result, 5) # should give the required error...
Error: func(2, 2)$result not equal to 5.
1/1 mismatches
[1] 4 - 5 == -1

请注意这里更容易测试的优点。如果/当您决定更改打印功能内的格式时,您也不必更改正确计算结果的测试。

答案 1 :(得分:1)

你可以使用这样的东西。

func <- function(num1, num2){
    result = num1 + num2
    return(paste0(' ', as.character(Sys.time()), ':  with result: ', result))
}

library(testthat)

使用stringr

expect_equal(as.numeric(stringr::str_extract(func(2, 2), "[0-9]*\\.*[0-9]*$")), 4)
expect_equal(as.numeric(stringr::str_extract(func(2, -2), "[0-9]*\\.*[0-9]+$")), 0)
expect_equal(as.numeric(stringr::str_extract(func(15, 21.3), "[0-9]*\\.*[0-9]+$")), 36.3)

使用base r

expect_equal(as.numeric(regmatches(func(2, 2), regexpr("[0-9]*\\.*[0-9]*$", func(2, 2)))), 4)
expect_equal(as.numeric(regmatches(func(2, -2), regexpr("[0-9]*\\.*[0-9]*$", func(2, -2)))), 0)
expect_equal(as.numeric(regmatches(func(15, 21.3), regexpr("[0-9]*\\.*[0-9]*$",func(15, 21.3)))), 36.3)

或准确测试函数的内部,但这取决于函数内部的确切内容。

expect_equal(func(2, 2), paste0(' ', as.character(Sys.time()), ': with result: ', 4))
expect_equal(func(2, -2), paste0(' ', as.character(Sys.time()), ': with result: ', 0))
expect_equal(func(15, 21.3), paste0(' ', as.character(Sys.time()), ': with result: ', 36.3))