-1

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?

2 Answers2

4

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

Miff
  • 7,486
  • 20
  • 20
  • Thank you for pointing that out! I'm actually quite confused about how to actually use the test because this is new to me. I'm assuming we provide the test some examples? Or is there any way to make the test become more general? – Thuy Nguyen Sep 23 '21 at 12:00
  • @ThuyNguyen I'd suggest that [this link](https://r-pkgs.org/tests.html) 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. – Miff Sep 23 '21 at 12:20
  • Thank you so much! I've just had a look, very useful material. – Thuy Nguyen Sep 24 '21 at 05:24
0

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.

sashahafner
  • 435
  • 1
  • 7