Search code examples
rr-packagetestthat

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


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?


Solution

  • 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