Home > OS >  Can we use funtions from testthat package to test elements of a vector?
Can we use funtions from testthat package to test elements of a vector?

Time:09-23

I've created a package that has a function, in this case is myfunction(argument1, argument2), that requires only positive inputs that have the same length as arguments. And I want to test whether the input is in a correct format using functions from testthat package. The point here is that I want to test whether the inputs are qualified to be the arguments of the function or not?

I have something like:

test_that("myfunction works", {
 input1 <- c(200, -220, 250)
 input2 <- c(30, 40, 50)
 myfunction(input1, input2)
 
 expect_equal(length(input1), length(input2))
})

Now I want to test that all my arguments (input1, input2) contain only positive numbers. How could I do that? I actually tried this:

expect_true(input1[] > 0)
expect_true(input2[] >0)

and

expect_gt(input1[], 0)
expect_gt(input2[], 0)

but then receive an error message:

Error: Result of comparison must be a single logical value

It seems like the expect_...() family functions are only applied for single values rather than a vector or a data frame? Any suggestions on what I should try?

CodePudding user response:

Your example is slightly unusual, in that normally you'd use the test to check that the return values from the function meet some assumptions, rather than the input values that you've just specified. As it's written you're not checking anything about whether the function actually works.

Having said that, you can use:

myfunction <- sum

test_that("myfunction works", {
   input1 <- c(200, -220, 250)
   input2 <- c(30, 40, 50)
   myfunction(input1, input2)
   
   expect_true(all(input1>0))
 })
#-- Failure (Line 6): myfunction works ------------------------------------------
#all(input1 > 0) is not TRUE
#
#`actual`:   FALSE
#`expected`: TRUE 

Which correctly fails because not all of input1 is greater than zero.

As a more concrete example of how you might normally use expectations, if you expect that for these inputs your function should return a single number, and that value should be 350, you might write a test as:

myfunction <- sum #The function you're writing

test_that("myfunction works", {
  input1 <- c(200, -220, 250)
  input2 <- c(30, 40, 50)
  
  expect_true(length(myfunction(input1, input2)) == 1) 
  expect_equal(myfunction(input1, input2), 350)
})

This link on testing might be useful background (although it's written from the point of view of package development, much of it is useful for anyone writing code). In particular 12.2 gives some examples

CodePudding user response:

The checkArgClassValue() function (non-exported) in the biogas package on CRAN is meant for this type of check. You can copy it from here: https://github.com/sashahafner/biogas/blob/master/R/checkArgClassValue.R. To make your function return an error when the actual arguments are not positive, you could add this:

checkArgClassValue(input1, expected.class = c('integer', 'numeric'), expected.range = c(0, Inf))

If you want a warning only add warn.only = TRUE.

See the functions defined in the R directory of that same repo for some other examples of how it can be used.

  • Related