scriptests (version 1.0-16)

scriptests-package: Support for running transcript-style tests

Description

Support for running transcript-style tests

Arguments

Details

Transcript-style tests are text files containing R commands and output, as though copied verbatim from an interactive R session. The output in the transcript file must match the actual output from running the command for the test to pass (with some exceptions - see "Control over matching" below). This testing framework is identical in concept to the standard .R/.Rout.save tests that are run by the R CMD check, but with some enhancements that are intended to make test development and maintanance faster, more convenient, and easier to automate:

  • Only the output file is needed - the inputs are parsed from the output file (i.e., .Rt file, which is analogous to an .Rout.save file)
  • Test output matching is more lenient on white space differences, and more flexible in that some test output can be transformed by regular expressions prior to matching, or ignored entirely
  • directives can specify whether a test-case output mismatch should be noted as an informational message, a warning, or an error (one or more errors results in R CMD check stopping with an indication of error after running all tests). Unlike the standard tests in R CMD check, output mismatch detected by scriptests results in R CMD check stopping with an error.
  • A concise summary of warnings and errors is given at the end
  • Testing can continue after errors and can report multiple errors at the end, rather than stopping at the first error.

To make it so that "R CMD check" will run transcript-style tests, do the following:

  1. Make sure the scriptests package is installed on your system
  2. Put a file named "runtests.R" in the "tests" directory in your own package with the following contents:
    library(scriptests)
    runScripTests() 
  3. add transcript files ending in .Rt in the "tests" directory in your own package, e.g.:
    > 1 + 2
    [1] 3
    >   
  4. add the line Suggests: scriptests to DESCRIPTION file. If there is an existing "Suggests:" line, just add scriptests to it. (It's better to use the Suggests: than the Depends: fields, because packages listed in the depends field are loaded when the package is loaded for normal use, and the scriptests package is usually not needed for normal use of a package -- the scriptests package will only be needed for testing.

At the end of testing, the file test-summary.txt will be left in the tests directory. To be entirely sure that the tests were run, also check for the existence of test-summary.txt.

If any tests fail, the file test-summary.fail (a copy of test-summary.txt) will also be left in the tests directory -- the existence of this file can be used in a programmatic check for whether all tests passed.

Tests can be run interactively using the function runtests(). The function source.pkg() can be useful to quickly re-read the function definitions in a package during code development. See the section "Running tests" in the documentation for runtests() for further details.

Notes:

  • All commands in the transcript file must be prefixed with command or continuation prompts, exactly as they appear in a transcript.
  • scriptests uses simple heuristics to identify commands, comments and output. If the transcript cannot be separated into comments, commands and output by these heuristics (e.g., if a command prints out a line starting with the command prompt "> "), things will not work properly.
  • When running tests in a package, scriptests uses a heuristic to guess the package name and automatically include an appropriate library(package-being-tested) command before the tests. If this heuristic fails, the functions from the package being tested may not be accessible. If this problem occurs, it can be worked around by explicitly including a library(package-being-tested) command at the beginning of each .Rt file.
  • To have tests continue to run after encountering an error, put the command options(error=function() NULL) at the beginning of the transcript file. This will cause the non-interactive R session that runs the commands in the scripts to continue after an error, instead of stopping, which is the default behavior for non-interactive R.

Control over matching

Actual output is matched to desired output extracted from the transcript file in a line-by-line fashion. If text is wrapped differently over multiple lines, the tests will fail (unless ignore-linebreaks is used). Different output width can easily happen if options("width") was different in the session that generated the desired output. Before trying to match, scriptests converts all white-space to single white-space, unless a control line specifies otherwise.

The following control lines can be present in the transcript after a command and before its output:

E.g.,
> cat("The date is <", date(),="" "="">\n", sep="")
#@gsub("<[^>]*>", "", both)
The date is 
> 

The tests directory can also contain a CONFIG file, which can specify the functions to call for testing. The defaults are equivalent to the following lines in the CONFIG file:

Depends: scriptests
Debug: FALSE
Rsuffix: R
StopOnError: FALSE
Initialize: scriptests:::initializeTests()
Diff: scriptests:::ScripDiff()
Finalize: scriptests:::summarizeTests() 
The CONFIG file is optional and is not needed in ordinary usage.