Commit 8350e065 authored by Russ Cox's avatar Russ Cox

cmd/go: add -args to 'go test' to resolve -v ambiguity

The new flag -args stops flag processing, leaving the rest of the command line
to be passed to the underlying test binary verbatim. Thus, both of these pass
a literal -v -n on the test binary command line, without putting the go command
into verbose mode or disabling execution of commands:

	go test . -args -v -n
	go test -args -v -n

Also try to make the documentation a bit clearer.

Fixes #7221.
Fixes #12177.

Change-Id: Ief9e830a6fbb9475d96011716a86e2524a35eceb
Reviewed-on: https://go-review.googlesource.com/17775Reviewed-by: 's avatarRob Pike <r@golang.org>
parent 5c596b51
......@@ -660,7 +660,7 @@ Test packages
Usage:
go test [-c] [-i] [build and test flags] [packages] [flags for test binary]
go test [build/test flags] [packages] [build/test flags & test binary flags]
'Go test' automates testing the packages named by the import paths.
It prints a summary of the test results in the format:
......@@ -690,10 +690,16 @@ non-test installation.
In addition to the build flags, the flags handled by 'go test' itself are:
-args
Pass the remainder of the command line (everything after -args)
to the test binary, uninterpreted and unchanged.
Because this flag consumes the remainder of the command line,
the package list (if present) must appear before this flag.
-c
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.
-exec xprog
Run the test binary using xprog. The behavior is the same as
......@@ -704,17 +710,12 @@ In addition to the build flags, the flags handled by 'go test' itself are:
Do not run the test.
-o file
Compile the test binary to the named file.
The test still runs (unless -c or -i is specified).
Compile the test binary to the named file.
The test still runs (unless -c or -i is specified).
The test binary also accepts flags that control execution of the test; these
flags are also accessible by 'go test'. See 'go help testflag' for details.
If the test binary needs any other flags, they should be presented after the
package names. The go tool treats as a flag the first argument that begins with
a minus sign that it does not recognize itself; that argument and all subsequent
arguments are passed as arguments to the test binary.
For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
......@@ -1442,25 +1443,58 @@ control the execution of any test:
Verbose output: log all tests as they are run. Also print all
text from Log and Logf calls even if the test succeeds.
The test binary, called pkg.test where pkg is the name of the
directory containing the package sources, can be invoked directly
after building it with 'go test -c'. When invoking the test binary
directly, each of the standard flag names must be prefixed with 'test.',
as in -test.run=TestMyFunc or -test.v.
Each of these flags is also recognized with an optional 'test.' prefix,
as in -test.v. When invoking the generated test binary (the result of
'go test -c') directly, however, the prefix is mandatory.
When running 'go test', flags not listed above are passed through
unaltered. For instance, the command
The 'go test' command rewrites or removes recognized flags,
as appropriate, both before and after the optional package list,
before invoking the test binary.
go test -x -v -cpuprofile=prof.out -dir=testdata -update
For instance, the command
go test -v -myflag testdata -cpuprofile=prof.out -x
will compile the test binary and then run it as
pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
(The -x flag is removed because it applies only to the go command's
execution, not to the test itself.)
The test flags that generate profiles (other than for coverage) also
leave the test binary in pkg.test for use when analyzing the profiles.
Flags not recognized by 'go test' must be placed after any specified packages.
The command-line package list, if present, must appear before any
flag not known to the go test command. Continuing the example above,
the package list would have to appear before -myflag, but could appear
on either side of -v.
To keep an argument for a test binary from being interpreted as a
known flag or a package name, use -args (see 'go help test') which
passes the remainder of the command line through to the test binary
uninterpreted and unaltered.
For instance, the command
go test -v -args -x -v
will compile the test binary and then run it as
pkg.test -test.v -x -v
Similarly,
go test -args math
will compile the test binary and then run it as
pkg.test math
In the first example, the -x and the second -v are passed through to the
test binary unchanged and with no effect on the go command itself.
In the second example, the argument math is passed through to the test
binary, instead of being interpreted as the package list.
Description of testing functions
......
......@@ -1983,6 +1983,13 @@ func TestGoTestFooTestWorks(t *testing.T) {
tg.run("test", "testdata/standalone_test.go")
}
func TestGoTestFlagsAfterPackage(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
tg.run("test", "testdata/flag_test.go", "-v", "-args", "-v=7") // Two distinct -v flags.
tg.run("test", "-v", "testdata/flag_test.go", "-args", "-v=7") // Two distinct -v flags.
}
func TestGoTestXtestonlyWorks(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
......
......@@ -32,7 +32,7 @@ func init() {
cmdTest.Run = runTest
}
const testUsage = "test [-c] [-i] [build and test flags] [packages] [flags for test binary]"
const testUsage = "test [build/test flags] [packages] [build/test flags & test binary flags]"
var cmdTest = &Command{
CustomFlags: true,
......@@ -67,11 +67,6 @@ non-test installation.
` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
If the test binary needs any other flags, they should be presented after the
package names. The go tool treats as a flag the first argument that begins with
a minus sign that it does not recognize itself; that argument and all subsequent
arguments are passed as arguments to the test binary.
For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
......@@ -82,10 +77,16 @@ See also: go build, go vet.
const testFlag1 = `
In addition to the build flags, the flags handled by 'go test' itself are:
-args
Pass the remainder of the command line (everything after -args)
to the test binary, uninterpreted and unchanged.
Because this flag consumes the remainder of the command line,
the package list (if present) must appear before this flag.
-c
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.
-exec xprog
Run the test binary using xprog. The behavior is the same as
......@@ -96,8 +97,8 @@ In addition to the build flags, the flags handled by 'go test' itself are:
Do not run the test.
-o file
Compile the test binary to the named file.
The test still runs (unless -c or -i is specified).
Compile the test binary to the named file.
The test still runs (unless -c or -i is specified).
The test binary also accepts flags that control execution of the test; these
flags are also accessible by 'go test'.
......@@ -229,25 +230,58 @@ const testFlag2 = `
Verbose output: log all tests as they are run. Also print all
text from Log and Logf calls even if the test succeeds.
The test binary, called pkg.test where pkg is the name of the
directory containing the package sources, can be invoked directly
after building it with 'go test -c'. When invoking the test binary
directly, each of the standard flag names must be prefixed with 'test.',
as in -test.run=TestMyFunc or -test.v.
Each of these flags is also recognized with an optional 'test.' prefix,
as in -test.v. When invoking the generated test binary (the result of
'go test -c') directly, however, the prefix is mandatory.
When running 'go test', flags not listed above are passed through
unaltered. For instance, the command
The 'go test' command rewrites or removes recognized flags,
as appropriate, both before and after the optional package list,
before invoking the test binary.
go test -x -v -cpuprofile=prof.out -dir=testdata -update
For instance, the command
go test -v -myflag testdata -cpuprofile=prof.out -x
will compile the test binary and then run it as
pkg.test -test.v -test.cpuprofile=prof.out -dir=testdata -update
pkg.test -test.v -myflag testdata -test.cpuprofile=prof.out
(The -x flag is removed because it applies only to the go command's
execution, not to the test itself.)
The test flags that generate profiles (other than for coverage) also
leave the test binary in pkg.test for use when analyzing the profiles.
Flags not recognized by 'go test' must be placed after any specified packages.
The command-line package list, if present, must appear before any
flag not known to the go test command. Continuing the example above,
the package list would have to appear before -myflag, but could appear
on either side of -v.
To keep an argument for a test binary from being interpreted as a
known flag or a package name, use -args (see 'go help test') which
passes the remainder of the command line through to the test binary
uninterpreted and unaltered.
For instance, the command
go test -v -args -x -v
will compile the test binary and then run it as
pkg.test -test.v -x -v
Similarly,
go test -args math
will compile the test binary and then run it as
pkg.test math
In the first example, the -x and the second -v are passed through to the
test binary unchanged and with no effect on the go command itself.
In the second example, the argument math is passed through to the test
binary, instead of being interpreted as the package list.
`
var helpTestfunc = &Command{
......
......@@ -87,6 +87,7 @@ func init() {
func testFlags(args []string) (packageNames, passToTest []string) {
inPkg := false
outputDir := ""
var explicitArgs []string
for i := 0; i < len(args); i++ {
if !strings.HasPrefix(args[i], "-") {
if !inPkg && packageNames == nil {
......@@ -114,6 +115,12 @@ func testFlags(args []string) (packageNames, passToTest []string) {
// make non-nil: we have seen the empty package list
packageNames = []string{}
}
if args[i] == "-args" || args[i] == "--args" {
// -args or --args signals that everything that follows
// should be passed to the test.
explicitArgs = args[i+1:]
break
}
passToTest = append(passToTest, args[i])
continue
}
......@@ -191,6 +198,8 @@ func testFlags(args []string) (packageNames, passToTest []string) {
}
passToTest = append(passToTest, "-test.outputdir", dir)
}
passToTest = append(passToTest, explicitArgs...)
return
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment