David LeBauer
David LeBauer

Reputation: 31741

How to test that an error does not occur?

I am starting to implement testing for an R package, and have been using the testthat package. Note that I am new to testing, so perhaps my approach is off.

I have a function that currently fails the 16th time it is executed, and before fixing this, I want to write a regression test that will catch it if it re-appears.

e.g., the following always throws the same error message:

 for i in (1:17) myfun()

myfun does not return anything, it only has a side-effect of opening a database connection. It is clear to me that I can write a test that expects an error and passes if it is returned:

 expect_error(for (i in 1:17) myfun()) 

But I don't quite get how to write a test to ensure that the error does not occur. As it is not obvious, perhaps my approach is wrong. I can figure out how to write more specific tests, but I would like to start with this one.

What type of test would I write to make sure that such an error does not appear?

Upvotes: 46

Views: 7078

Answers (4)

Marek
Marek

Reputation: 50704

edit due to changes in testthat

Since version 3.2.0 (2023-10) there are functions to test lack of conditions (https://testthat.r-lib.org/reference/expect_no_error.html):

expect_no_error(my_fun())
expect_no_warning(my_fun())
expect_no_message(my_fun())
expect_no_condition(my_fun())

Minus: it does not support info argument.

Since version 0.11 (via RStudio blog) there is direct support to testing lack of errors:

expect_error(myfun(), NA)

Same for catching warning and message:

expect_warning(myfun(), NA)
expect_message(myfun(), NA)

Side note: There is an info parameter in expect_xxx functions to pass additional info. So you can do:

for (i in 1:17) expect_error(myfun(), NA, info = paste("i =", i))

Upvotes: 50

zhangns07
zhangns07

Reputation: 109

Maybe wrap it with another expect_error.

Example:

expect_error(1)
expect_error(expect_error(1))

Upvotes: 10

David LeBauer
David LeBauer

Reputation: 31741

Here is one solution using the expectation that tryCatch returns 0 when the error does not occur:

expect_equal(tryCatch(for(i in 1:17) myfun()), 0)

Upvotes: 4

kohske
kohske

Reputation: 66842

For example:

context("test error")
test_that("test error 1", {
  expect_true({log(10); TRUE})
})

test_that("test error 2", {
  expect_true({log("a"); TRUE})
})

will test if there is an error.

> test_file("x.r")
test error : .1


    1. Error: test error 2 -------------------------
    Non-numeric argument to mathematical function
    1: expect_true({
           log("a")
        TRUE
    })
    2: expect_that(object, is_true(), info, label)
    3: condition(object)
    4: expectation(identical(x, TRUE), "isn't true")
    5: identical(x, TRUE)

this means the first part passed the test while the second part failed.

Upvotes: 8

Related Questions