Testing conditions on a function's parameter using testthat

孤街浪徒 提交于 2020-07-22 06:07:08

问题


I have a function of the form func(expr, data.sizes), where the parameter expr is an expression and the one named data.sizes is ordinarily as the name suggests, a vector or sequence of data sizes. (eg: c(10, 100, 1000) or 10^seq(1, 3))

I would like to write some test-cases for my function's parameters using testthat, but am new to unit-testing in R so I would like to know how does one test conditions for a function's parameter(s) using testthat?

For instance, I want to check for a possible NA value for the parameter data.size in my function and I wrote this snippet to test in my console: (function is available in Global Env.)

test_that("NA test for data.sizes", {
  expect_false(is.na(data.sizes %in% func(expression, data.sizes = c(10, 100))))
})

which throws the error:

* object 'data.sizes' not found
1: expect_false(is.na(data.sizes %in% func(expression, data.sizes = c(10, 
       10)))) at :2
2: quasi_label(enquo(object), label, arg = "object")
3: eval_bare(get_expr(quo), get_env(quo))
4: data.sizes %in% func(expression, data.sizes = c(10, 10))

What might I be possibly doing wrong? Also what would be the syntax in general to apply test conditions on a function's parameters using testthat?


回答1:


testthat checks if the result of the function is what you expect.

If you want to test the result of the function to NAs, you can make a specific test for this :

library(testthat)
library(assertthat)

func <- function(expr,data.sizes) {
  assert_that(noNA(data.sizes))
  eval(expr)
}

test_that("data.sizes test for func", {
  # Success
  expect_error(func(expression(data.sizes[1]+data.sizes[2]), data.sizes = c(1,NA)))
  expect_equal(func(expression(data.sizes[1]+data.sizes[2]), data.sizes = c(1,2)),3)
  # Failure
  expect_equal(func(expression(data.sizes[1]+data.sizes[2]), data.sizes = c(1,2)),4)
})

To test validity of parameters inside the function, you can use assertive programming packages like assertthat.




回答2:


Your unit test can test the output of your function with a given input. It is not a way of allowing your function to screen the given variables for inappropriate inputs. This has to be done inside your function.

The unit test must simply call your function with some parameters and ensure the output is what is expected.

Suppose for example that you want func to return a list containing repetitions of the evaluated expression according to data.sizes, like this:

func <- function(expression, data.sizes)
{
  expression <- as.expression(as.list(match.call())$expression)
  if(!all(!is.na(data.sizes))) stop("data.sizes may not contain NAs")
  lapply(data.sizes, function(x) rep(eval(expression), x))
}

So that it does something like this:

y <- 5
func(y^2 + 3, 1:3)
#> [[1]]
#> [1] 28
#> 
#> [[2]]
#> [1] 28 28
#> 
#> [[3]]
#> [1] 28 28 28

But you want an exception to be thrown if there are NA values in data.sizes:

func(y^2 + 3, c(1, NA))
#> Error in func(y^2 + 3, c(1, NA)) : data.sizes may not contain NAs

Then your unit test would look like this:

test_that("NA test for data.sizes", {
  expect_list(func(y^2 + 3, 1:3))
  expect_error(func(y^2 + 3, c(1, NA)))
})

So you know if this test passes, your error is being picked up appropriately



来源:https://stackoverflow.com/questions/62244007/testing-conditions-on-a-functions-parameter-using-testthat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!