简体   繁体   中英

Testing conditions on a function's parameter using testthat

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?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM