--- /dev/null
+pkg testing, func Testing() bool #52600
pxtest.collectDeps()
}
+ // Arrange for testing.Testing to report true.
+ ldflags := append(p.Internal.Ldflags, "-X", "testing.testBinary=1")
+ gccgoflags := append(p.Internal.Gccgoflags, "-Wl,--defsym,testing.gccgoTestBinary=1")
+
// Build main package.
pmain = &Package{
PackagePublic: PackagePublic{
BuildInfo: p.Internal.BuildInfo,
Asmflags: p.Internal.Asmflags,
Gcflags: p.Internal.Gcflags,
- Ldflags: p.Internal.Ldflags,
- Gccgoflags: p.Internal.Gccgoflags,
+ Ldflags: ldflags,
+ Gccgoflags: gccgoflags,
OrigImportPath: p.Internal.OrigImportPath,
PGOProfile: p.Internal.PGOProfile,
},
return *short
}
+// testBinary is set by cmd/go to "1" if this is a binary built by "go test".
+// The value is set to "1" by a -X option to cmd/link. We assume that
+// because this is possible, the compiler will not optimize testBinary
+// into a constant on the basis that it is an unexported package-scope
+// variable that is never changed. If the compiler ever starts implementing
+// such an optimization, we will need some technique to mark this variable
+// as "changed by a cmd/link -X option".
+var testBinary = "0"
+
+// Testing reports whether the current code is being run in a test.
+// This will report true in programs created by "go test",
+// false in programs created by "go build".
+func Testing() bool {
+ return testBinary == "1"
+}
+
// CoverMode reports what the test coverage mode is set to. The
// values are "set", "count", or "atomic". The return value will be
// empty if test coverage is not enabled.
package testing_test
import (
+ "bytes"
+ "internal/testenv"
"os"
"path/filepath"
"testing"
})
})
}
+
+// testingTrueInInit is part of TestTesting.
+var testingTrueInInit = false
+
+// testingTrueInPackageVarInit is part of TestTesting.
+var testingTrueInPackageVarInit = testing.Testing()
+
+// init is part of TestTesting.
+func init() {
+ if testing.Testing() {
+ testingTrueInInit = true
+ }
+}
+
+var testingProg = `
+package main
+
+import (
+ "fmt"
+ "testing"
+)
+
+func main() {
+ fmt.Println(testing.Testing())
+}
+`
+
+func TestTesting(t *testing.T) {
+ if !testing.Testing() {
+ t.Errorf("testing.Testing() == %t, want %t", testing.Testing(), true)
+ }
+ if !testingTrueInInit {
+ t.Errorf("testing.Testing() called by init function == %t, want %t", testingTrueInInit, true)
+ }
+ if !testingTrueInPackageVarInit {
+ t.Errorf("testing.Testing() variable initialized as %t, want %t", testingTrueInPackageVarInit, true)
+ }
+
+ if testing.Short() {
+ t.Skip("skipping building a binary in short mode")
+ }
+ testenv.MustHaveGoRun(t)
+
+ fn := filepath.Join(t.TempDir(), "x.go")
+ if err := os.WriteFile(fn, []byte(testingProg), 0644); err != nil {
+ t.Fatal(err)
+ }
+
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "run", fn)
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("%v failed: %v\n%s", cmd, err, out)
+ }
+
+ s := string(bytes.TrimSpace(out))
+ if s != "false" {
+ t.Errorf("in non-test testing.Test() returned %q, want %q", s, "false")
+ }
+}