cmdtest

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2019 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

The cmdtest package simplifies testing of command-line interfaces. It provides a simple, cross-platform, shell-like language to express command execution. It can compare actual output with the expected output, and can also update a file with new "golden" output that is deemed correct.

Start using cmdtest by writing a test file with commands and expected output, giving it the extension ".ct". All test files in the same directory make up a test suite. See the TestSuite documentation for the syntax of test files.

To test, first read the suite:

ts, err := cmdtest.Read("testdata")

Then configure the resulting TestSuite by adding commands or enabling debugging features. Lastly, call TestSuite.Run with false to compare or true to update. Typically, this boolean will be the value of a flag:

var update = flag.Bool("update", false, "update test files with results")
...
err := ts.Run(*update)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CommandFunc

type CommandFunc func(args []string, inputFile string) ([]byte, error)

CommandFunc is the signature of a command function. The function takes the subsequent words on the command line (so that arg[0] is the first argument), as well as the name of a file to use for input redirection. It returns the command's output.

func InProcessProgram

func InProcessProgram(name string, f func() int) CommandFunc

InProcessProgram defines a command function that will invoke f, which must behave like an actual main function except that it returns an error code instead of calling os.Exit. Before calling f: - os.Args is set to the concatenation of name and args. - If inputFile is non-empty, it is redirected to standard input. - Standard output and standard error are redirected to a buffer, which is returned.

func Program

func Program(path string) CommandFunc

Program defines a command function that will run the executable at path using the exec.Command package and return its combined output. If path is relative, it is converted to an absolute path using the current directory at the time Program is called.

In the unlikely event that Program cannot obtain the current directory, it panics.

type TestSuite

type TestSuite struct {
	// If non-nil, this function is called for each test. It is passed the root
	// directory after it has been made the current directory.
	Setup func(string) error

	// The commands that can be executed (that is, whose names can occur as the
	// first word of a command line).
	Commands map[string]CommandFunc

	// If true, don't delete the temporary root directories for each test file,
	// and print out their names for debugging.
	KeepRootDirs bool
	// contains filtered or unexported fields
}

A TestSuite contains a set of test files, each of which may contain multiple test cases. Use Read to build a TestSuite from all the test files in a directory. Then configure it and call Run.

Format of a test file:

Before the first line starting with a '$', empty lines and lines beginning with "#" are ignored.

A sequence of consecutive lines starting with '$' begin a test case. These lines are commands to execute. See below for the valid commands.

Lines following the '$' lines are command output (merged stdout and stderr). Output is always treated literally. After the command output there should be a blank line. Between that blank line and the next '$' line, empty lines and lines beginning with '#' are ignored. (Because of these rules, cmdtest cannot distinguish trailing blank lines in the output.)

Syntax of a line beginning with '$': A sequence of space-separated words (no quoting is supported). The first word is the command, the rest are its args. If the next-to-last word is '<', the last word is interpreted as a file and becomes the standard input to the command. None of the built-in commands (see below) support input redirection, but commands defined with Program do.

By default, commands are expected to succeed, and the test will fail otherwise. However, commands that are expected to fail can be marked with a " --> FAIL" suffix.

The cases of a test file are executed in order, starting in a freshly created temporary directory.

The built-in commands (initial contents of the Commands map) are:

cd DIR
cat FILE
mkdir DIR
setenv VAR VALUE
echo ARG1 ARG2 ...
echof FILE ARG1 ARG2 ...

These all have their usual Unix shell meaning, except for echof, which writes its arguments to a file (output redirection is not supported). All file and directory arguments must refer to the current directory; that is, they cannot contain slashes.

cmdtest does its own environment variable substitution, using the syntax "${VAR}". Test execution inherits the full environment of the test binary caller (typically, your shell). The environment variable ROOTDIR is set to the temporary directory created to run the test file.

func Read

func Read(dir string) (*TestSuite, error)

Read reads all the files in dir with extension ".ct" and returns a TestSuite containing them. See the TestSuite documentation for syntax.

func (*TestSuite) Run

func (ts *TestSuite) Run(t *testing.T, update bool)

Run runs the commands in each file in the test suite. Each file runs in a separate subtest.

If update is false, it compares their output with the output in the file, line by line.

If update is true, it writes the output back to the file, overwriting the previous output.

Before comparing/updating, occurrences of the root directory in the output are replaced by ${ROOTDIR}.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL