Test Functions and Expressions - for automated testing

Share:

Description

Expressions are parsed and evaluated from file. Each expression should evaluate to a logical TRUE. Otherwise, do.test() prints the expression and its value.

Usage

1
do.test(file, verbose=FALSE, strict=FALSE, local=FALSE, check)

Arguments

file

a file or connection containing code to test.

verbose

logical flag. If TRUE, all expressions are printed, not just those that fail. Regardless of this flag, the value is also printed for failures.

strict

logical flag. If TRUE, any validity failures cause an error; that is, you get to debug after the first failed assertion.

local

logical flag controlling where the evaluation takes place: by default (local=FALSE), in the environment that called do.test, typically the global environment, (objects created remain there after do.test is finished). local=TRUE, causes do.test to create and work in a new environment.

check

an unevaluated expression. If checkis supplied, do.testevaluates this expression (it should be given via Quote()) between each parse and evaluation. (This is for when you need to check some global information.)

Details

A test file typically contains a sequence of expressions to test different aspects of a function or set of functions, including testing that each input argument is handled appropriately, error handling, the output has the expected structure, correct output under a number of combinations of inputs, and error handling (warning and stop invoked when appropriate and with appropriate messages). Each expression may contain multiple lines grouped using {}, where early lines may do computations and the last line checks for expected results, usually using all.equal.

Some expressions may be included that aren't intended to test anything by finishing them with TRUE, e.g. to read data: {read.table("data.txt"); TRUE} or to remove objects at the end of a test file: {rm(a, b, x, y); TRUE}.

We recommend including comments inside expressions to indicate the purpose of each test; then if errors occur the comments are printed too.

To compare just numbers, not names or matrix dimensions, functions unname and drop are useful.

To exclude certain components or attributes from the comparison the function all.equal.excluding is useful. This is defined in the examples below.

Each test should run silently if everything is working correctly; there should be nothing printed. expectWarnings can be used to intercept warning statements.

Value

NULL

See Also

all.equal, allTrue, drop, expectStop, expectWarnings, identical, Quote, unname

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
## Not run: 
# Create a toy test file, and run it
cat('{all.equal(24/8, 3)}',
    '{all.equal(5, 6)}',      # this one will fail
    'expectWarnings( { # Test subscript replacement ',
    '  x <- data.frame(a=1:3,b=2:4)',
    '  x[,3] <- x',
    '  all.equal(ncol(x), 3)',
    '}, expected = "provided 2 variables to replace 1 var")',
    'expectStop(lm(5), expected = "invalid formula")',
    '{ rm(x) ; TRUE }',       # cleanup at end of test
    sep="\n", file = "testfile.t")
do.test("testfile.t")
## ------- Test file: testfile.t ---------
## {all.equal(5, 6)}
## [1] "Mean relative difference: 0.2"
#
# The test that fails is printed, with the results of the test.
# In R 2.6.1 the subscript replacement test above also fails
# (bug reported 14 Jan 2008), resulting in the additional printout:
## expectWarnings( {
##   x <- data.frame(a=1:3,b=2:4)
##   x[,3] <- x
##   all.equal(ncol(x), 3)
## }, expected = "provided 2 variables to replace 1 var")
## $`Test result`
## [1] "Mean relative  difference: 0.25"

## End(Not run)

# This function is useful in some tests:
all.equal.excluding <- function(x, y, ..., excluding=NULL, attrs=NULL){
  # Like all.equal, but exclude components in `excluding',
  #   and excluding attributes named in `attrs'.
  #
  # `excluding' and `attrs' should be character, names of components 
  #   and attributes.
  # 
  # For example:
  #   all.equal.excluding(obj1, obj2, excluding = c("call", "x"))
  for(i in intersect(names(x), excluding)) x[[i]] <- NULL
  for(i in intersect(names(y), excluding)) y[[i]] <- NULL
  for(i in intersect(names(attributes(x)), attrs)) attr(x,i) <- NULL
  for(i in intersect(names(attributes(y)), attrs)) attr(y,i) <- NULL
  all.equal(x,y, ...)
}
# Test if two objects are the same except for "call" and "x":
data <- data.frame(x = 1:20, y = exp(1:20/20))
fit1 <- lm(y ~ x, data = data, x=TRUE)
fit2 <- update(fit1, x=)
all.equal.excluding(fit1, fit2, excluding = c("call", "x"))

Want to suggest features or report bugs for rdrr.io? Use the GitHub issue tracker.