3. Error Message APIs¶
There are four APIs for inserting sef-defined messages in this packages:
registerPreMsgregisterPostMsgaddPreMsgaddPostMsg
There are three APIs for controlling the automatic tracing feature:
- The
traceargument and thesuppressErrargument inexpect_XXXfunctions turnOnTracebackandturnOffTraceback
3.1. Pre Message¶
Pre message means insert before the default error.
There is a vector storing the pre messages, let us call this vector pre_vector.
The registerPreMsg function always overwrite pre_vector, while the
addPreMsg function append messages in pre_vector.
library(autotest)
f <- function(x) ifelse(x < 5, x + 1, x)
test_that('testing f', {
for (i in 1:10){
registerPreMsg('In testing f(%d):', i)
expect_equal(f(i), i + 1, trace=FALSE)
}
})
Error
As we know error occurs when i = 5, which means the code have called the
registerPreMsg function 5 times. According to the error message, you can
see that only the last registered one is returned.
library(autotest)
f <- function(x) ifelse(x < 5, x + 1, x)
test_that('testing f', {
for (i in 1:10){
addPreMsg('In testing f(%d):', i)
expect_equal(f(i), i + 1, trace=FALSE)
}
})
Here is the error message if you replace registerPreMsg with addPreMsg.
Error
It will keep appending messages in the pre_vector.
You should not use addPreMsg in this case.
3.2. Post Message¶
Post message means insert after the default error.
There is a vector storing the post messages, let us call this vector post_vector.
The registerPostMsg function always overwrite post_vector, while the
addPostMsg function append messages in post_vector.
Suppose we want to records the log of testing in the for loop. Let us add post message after one test is passed.
library(autotest)
f <- function(x) ifelse(x < 5, x + 1, x)
test_that('testing f', {
for (i in 1:10){
registerPreMsg('In testing f(%d): ', i)
expect_equal(f(i), i + 1, trace=FALSE)
registerPostMsg('Testing f(%d): pass', i)
}
})
By using registerPostMsg, only Testing f(4): pass is shown. Because in the 4th loop
this post message overwrite the previous messages, and in the 5th loop error occurs the
register line does not run any more.
Error
library(autotest)
f <- function(x) ifelse(x < 5, x + 1, x)
test_that('testing f', {
for (i in 1:10){
registerPreMsg('In testing f(%d): ', i)
expect_equal(f(i), i + 1, trace=FALSE)
addPostMsg('Testing f(%d): pass', i)
}
})
This time we switch to addPostMsg, the error message below shows it was appending messages
after the default error.
Error
3.3. More about Messages Hooks¶
Previously, we said that the pre message and post message are stored in pre_vector and
post_vector. The vectors are really exist in the autotest package, however,
you can not access to them directly.
Here is an example shows you how to access to them:
library(autotest)
autotest:::ErrorHandler$pre
## NULL
autotest:::ErrorHandler$post
## NULL
registerPreMsg('Register pre message')
addPreMsg('--------------')
autotest:::ErrorHandler$pre
## [1] "Register pre message" "--------------"
registerPostMsg('Register pre message')
addPostMsg('**************')
autotest:::ErrorHandler$post
## [1] "Register pre message" "**************"
Note
One more thing, the customized messages does not work outside the test_that function.
A test_that call is a testing block that tests a specific variable(or function).
Consider the following example that testing x and y. We know that the first test block
will pass and the second test block will have a trouble.
The registered message in the first test should not work in the second test block.
library(autotest)
x = 1; y = 2
test_that('', {
registerPreMsg('testing x')
expect_equal(x, 1, trace=FALSE) # this test will pass
})
test_that('', {
expect_equal(y, 1) # error, the registered message 'testing x' should not show here
})
Error
3.4. Turn On/Off Automatic Tracing¶
- Turn on/off locally:
expect_equal(x, y, trace=FALSE) # only close tracing in this
- Turn on/off globally:
turnOnTraceback() # turn on globally
turnOffTraceback() # turn off globally
Warning
You should be careful do not use it unless you readlly know what you are doing.
Local VS Global
- If you turn off globally, then set
trace=TRUEdoes not work. - If you turn on globally, set
trace=FALSEworks.
- If you turn off globally, then set
3.5. Turn On/Off Default Error¶
In the expect_XXX functions, the error message usually means something.
x = 1
expect_equal(x, 2)
## AutoTestCaseError:
## Testing variable/expression: x
## Your answer is 1, which is not equal to the correct answer 2
## The maximum tolerance is 0.00001
The second line of the error is automatic tracing, and the last two lines are defined
in the expect_equal function, you can not change it.
However, you can set suppressErr=TRUE to remove it.
In some cases, if you really want to change the error message,
register a post message and disable the default error.
Here is an example:
test_that('', {
registerPostMsg('You answer is wrong')
expect_equal(x, 2, suppressErr=TRUE)
})
## AutoTestCaseError:
## Testing variable/expression: x
## You answer is wrong
3.6. Conclusion¶
Usually, the default error will be understandable without doing any extra argument settings in the expect_XXX function.
However, by using the APIs, you can fully control the error messages. Enjoy!