% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/svSuite.R
\name{svSuite}
\alias{svSuite}
\alias{as.svSuite}
\alias{is.svSuite}
\alias{print.svSuite}
\alias{svSuiteList}
\alias{makeUnit.svSuite}
\alias{runTest.svSuite}
\title{Create and run test suites by collecting together unit tests and function
tests defined in objects}
\usage{
svSuite(tests)

as.svSuite(x)

is.svSuite(x)

\method{print}{svSuite}(x, ...)

svSuiteList(
  packages = TRUE,
  objects = TRUE,
  dirs = getOption("svUnit.dirs"),
  excludeList = getOption("svUnit.excludeList"),
  pos = .GlobalEnv,
  loadPackages = FALSE
)

\method{makeUnit}{svSuite}(
  x,
  name = make.names(deparse(substitute(x))),
  dir = tempdir(),
  objfile = "",
  codeSetUp = NULL,
  codeTearDown = NULL,
  pos = .GlobalEnv,
  ...
)

\method{runTest}{svSuite}(x, name = make.names(deparse(substitute(x))), unitname = NULL, ...)
}
\arguments{
\item{tests}{A character string with items to include in the test suite. It
could be 'package:PKG' for including test units located in the /unitTests
subdirectory of the package PGK, or 'package:PKG (SUITE)' for test units
located in the subdirectory /unitTests/SUITE of package PKG, or 'dir:MYDIR'
for including test units in MYDIR, or 'test(OBJ)' for tests embedded in an
object, or 'OBJ' for 'svTest' object directly.}

\item{x}{Any kind of object.}

\item{...}{Further arguments to pass to \code{\link[=makeUnit]{makeUnit()}} or \code{\link[=runTest]{runTest()}} (not used
yet).}

\item{packages}{Do we list test units available in loaded packages?
Alternatively one can provide a character vector of package names, and it
will be used to filter packages (take care: in this case it will look at
installed packages, not only loaded packages)!}

\item{objects}{Do we list test available in objects? Alternatively, one can
provide a character vector of object names, and it will filter objects in
'pos' according to this vector.}

\item{dirs}{An additional list of directories where to look for more test
units. For convenience, this list can simply be saved as an 'svUnit.dirs'
options.}

\item{excludeList}{A list of items to exclude from the listing. The function
uses regular expression to match the exclusions. So, for instance, specifying
\code{"package:MYPKG"} will exclude all items from package 'MYPKG', while using
\code{"package:MYPKG$"} will exclude only tests suites defined in the
.../MYPKG/unitTests directory, bur not in its subdirectories. For
convenience, it can be saved in a 'svUnit.excludeList' option. By default,
all tests for packages whose name start with 'sv' or 'RUnit' are excluded,
that is, \code{c("package:sv", "package:RUnit")}.}

\item{pos}{The environment to look for 'objects' (environment, character
string with name of an environment, or integer with position of the
environment in the search path.}

\item{loadPackages}{In the case a list of packages is provided in
\verb{packages =}, do we make sure that these packages are loaded? If yes, the
function will try to load all packages in that list that are not loaded yet
and will issue a warning for the packages not found. Default, \code{FALSE}.}

\item{name}{The name of the test suite to build.}

\item{dir}{The directory where to create the test unit file.}

\item{objfile}{The path to the file containing the original source code of
the object being tested. This argument is used to bring a context for a
test and allow a GUI to automatically open the source file for edition when
the user clicks on a test that failed or raised an error.}

\item{codeSetUp}{An expression with some code you want to add to the
\code{.setUp()} function in your unit file (this function is executed before each
test.}

\item{codeTearDown}{An expression with some code you want to add to the
\code{.tearDown()} function in your unit file (this function is executed after
each test.}

\item{unitname}{The name of a unit to run inside the suite. If \code{NULL} (by
default), all units are run.}
}
\value{
\code{\link[=svSuite]{svSuite()}}, \code{\link[=as.svSuite]{as.svSuite()}} and \code{\link[=svSuiteList]{svSuiteList()}} return a 'svSuite' object.
\code{\link[=is.svSuite]{is.svSuite()}} returns \code{TRUE} if the object is an 'svSuite'.

\code{\link[=makeUnit]{makeUnit()}} creates a test unit file on disk, and \code{\link[=runTest]{runTest()}} runs the tests
in such a file. They are used for their side-effect, but the first one also
returns the file created, and the second one returns invisibly the list of
all test unit files that where sourced ans run.
}
\description{
A 'svSuite' object is essentially a list of test units directories (or
packages, in this case, corresponding directories are PKG/unitTests and its
subdirectories), and of object names containing tests to add temporarily to
the test suite. These must be formatted in a concise way as described for the
'tests' argument.
}
\details{
\code{\link[=svSuiteList]{svSuiteList()}} lists all loaded packages having /unitTests/runit*.R files
(or similar files in subdirectories), and all objects in the user workspace
that have a 'test' attribute, or are 'svTest' objects (by default). It is a
rather exhaustive list of all test items currently available in the current R
session, but restricted by \code{getOption("svUnit.excludeList")}.

\code{\link[=makeUnit]{makeUnit()}} writes a test unit on disk with the tests from the objects
listed in the 'svSuite' object that do not belong yet to a test unit.
\code{\link[=runTest]{runTest()}} runs all the test in packages, directories and objects listed in
the 'svSuite' object.

Thanks to the variety of sources allowed for tests, it is possible to define
these tests in a structured way, inside packages, like for the 'RUnit'
package (but with automatic recognition of test units associated to packages,
in the present case). It is also easy to define tests more loosely by just
attaching those tests to the objects you want to check. Whenever there objects
are loaded in the user's workspace, their tests are available. In both cases,
a test unit file on disk is sourced in a local environment and test functions
are run (same approach as in the 'RUnit' package, and the same test unit files
should be compatibles with both 'RUnit' and 'svUnit' packages), but in the
case of a loosely definition of the tests by attachment to objects, the test
unit file is created on the fly in the temporary directory (by default).

At any time, you can transform a series of tests loosely attached to objects
into a test unit file by applying \code{\link[=makeUnit]{makeUnit()}} to a 'svSuite' object,
probably specifying another directory than the (default) temporary dir for
more permanent storage of your test unit file. The best choice is the
'/inst/unitTests' directory of a package source, or one of its
subdirectories. That way, your test unit file(s) will be automatically listed
and available each time you load the compiled package in R (if you list them
using \code{\link[=svSuiteList]{svSuiteList()}}). Of course, you still can exclude tests from given
packages by adding 'package:PKG' in the exclusion list with something
like: \code{options(svUnit.excludeList = c(getOption("svUnit.excludeList"), "package:PKG"))}.
}
\examples{
svSuiteList() # List all currently available test units and test cases
# Exclusion list is used (regular expression filtering!). It contains:
(oex <- getOption("svUnit.excludeList"))
# Clear it, and relist available test units
options(svUnit.excludeList = NULL)
svSuiteList()

# Two functions that include their test cases
Square <- function(x)
  return(x^2)
test(Square) <- function() {
  checkEquals(9, Square(3))
  checkEquals(c(1, 4, 9), Square(1:3))
  checkException(Square("xx"))
}

Cube <- function(x)
  return(x^3)
test(Cube) <- function() {
  checkEquals(27, Cube(3))
  checkEquals(c(1, 8, 28), Cube(1:3))
  checkException(Cube("xx"))
}

# A separate test case object (not attached to a particular object)
# This is the simplest way to define quick and durty integration tests
test_Integrate <- svTest(function() {
  checkTrue(1 < 2, "check1")
  v <- 1:3 	# The reference
  w <- 1:3 	# The value to compare to the reference
  checkEquals(v, w)
})

# A function without test cases (will be filtered out of the suite list)
foo <- function(x)
  return(x)

# Look now which tests are available
svSuiteList()

# Only objects, no package units
svSuiteList(packages = FALSE)

\dontrun{
# Create the test unit file for all objects with tests in .GlobalEnv
myunit <- makeUnit(svSuiteList(), name = "AllTests")
file.show(myunit, delete.file = TRUE)
}

# Filter objects using a list (object with/without tests and a nonexisting obj)
svSuiteList(packages = FALSE, objects = c("Cube", "foo", "bar"))

# Create another svSuite object with selected test items
(mysuite <- svSuite(c("package:svUnit (VirtualClass)", "test(Cube)")))
is.svSuite(mysuite)	# Should be!

\dontrun{
# Run all the tests currently available
(runTest(svSuiteList(), name = "AllTests"))
summary(Log())
}

# Restore previous exclusion list, and clean up the environment
options(svUnit.excludeList = oex)
rm(Square, Cube, foo, test_Integrate, mysuite, myunit, oex)
}
\seealso{
\code{\link[=svSuiteData]{svSuiteData()}}, \code{\link[=svTest]{svTest()}}, \code{\link[=Log]{Log()}}, \code{\link[=checkEquals]{checkEquals()}}, \code{\link[RUnit:checkEquals]{RUnit::checkEquals()}}
}
\author{
Philippe Grosjean
}
\concept{unit testing}
\keyword{utilities}
