Go TestMain-没有要运行的测试

Go TestMain-没有要运行的测试,go,testing,Go,Testing,我正在编写一个包,它编译一个C源文件并将输出写入另一个文件。我正在为此包编写测试,需要创建一个临时目录来编写输出文件。我正在使用TestMain函数来执行此操作。出于某种原因,当我只运行TestMain测试时,总是会收到警告“没有要运行的测试”。我试着调试TestMain函数,我可以看到临时目录确实被创建了。当我手动创建testoutput目录时,所有测试都通过了 我正在从testdata目录加载两个C源文件,其中一个是故意错误的 gcc.go: package gcc import (

我正在编写一个包,它编译一个C源文件并将输出写入另一个文件。我正在为此包编写测试,需要创建一个临时目录来编写输出文件。我正在使用
TestMain
函数来执行此操作。出于某种原因,当我只运行
TestMain
测试时,总是会收到警告“没有要运行的测试”。我试着调试
TestMain
函数,我可以看到临时目录确实被创建了。当我手动创建
testoutput
目录时,所有测试都通过了

我正在从
testdata
目录加载两个C源文件,其中一个是故意错误的

gcc.go:

package gcc

import (
    "os/exec"
)

func Compile(inPath, outPath string) error {
    cmd := exec.Command("gcc", inPath, "-o", outPath)
    return cmd.Run()
}
gcc_test.go:

package gcc

import (
    "os"
    "path/filepath"
    "testing"
)

func TestOuputFileCreated(t *testing.T) {
    var inFile = filepath.Join("testdata", "correct.c")
    var outFile = filepath.Join("testoutput", "correct_out")

    if err := Compile(inFile, outFile); err != nil {
        t.Errorf("Expected err to be nil, got %s", err.Error())
    }

    if _, err := os.Stat(outFile); os.IsNotExist(err) {
        t.Error("Expected output file to be created")
    }
}

func TestOuputFileNotCreatedForIncorrectSource(t *testing.T) {
    var inFile = filepath.Join("testdata", "wrong.c")
    var outFile = filepath.Join("testoutput", "wrong_out")

    if err := Compile(inFile, outFile); err == nil {
        t.Errorf("Expected err to be nil, got %v", err)
    }

    if _, err := os.Stat(outFile); os.IsExist(err) {
        t.Error("Expected output file to not be created")
    }
}

func TestMain(m *testing.M) {
    os.Mkdir("testoutput", 666)
    code := m.Run()
    os.RemoveAll("testoutput")
    os.Exit(code)
}
package gcc

import (
  "testing"
  "path/filepath"
  "os"
)

const testoutput = "testoutput"

type testcase struct {
  inFile  string
  outFile string
  err     error
}

func (tc *testcase) test(t *testing.T) {
  var (
    in  = filepath.Join("testdata", tc.inFile)
    out = filepath.Join(testoutput, tc.outFile)
  )

  if err := Compile(in, out); err != tc.err {
    t.Errorf("Compile(%q, %q) == %v; Wanted %v", in, out, err, tc.err)
  }
}

func TestCompile(t *testing.T) {
  os.Mkdir(testoutput, 0666)

  tests := map[string]*testcase{
    "correct": &testcase{"correct.c", "correct_out", nil},
    "wrong":   &testcase{"wrong.c", "wrong_out", expectedError},
  }

  for name, tc := range tests {
    t.Run(name, tc.test)
  }
}
go测试
输出:

sriram@sriram-Vostro-15:~/go/src/github.com/sriram-kailasam/relab/pkg/gcc$ go test
--- FAIL: TestOuputFileCreated (0.22s)
        gcc_test.go:14: Expected err to be nil, got exit status 1
FAIL
FAIL    github.com/sriram-kailasam/relab/pkg/gcc        0.257s
正在运行TestMain:

Running tool: /usr/bin/go test -timeout 30s github.com/sriram-kailasam/relab/pkg/gcc -run ^(TestMain)$

ok      github.com/sriram-kailasam/relab/pkg/gcc    0.001s [no tests to run]
Success: Tests passed.

很有可能,您的问题与传递给
os.Mkdir(…)
的模式值有关。您提供的是
666
decimal,它是
01232
octall(或者如果您愿意,是一个
d-w--wx wT
)权限字符串,我认为这不是您真正想要的

您应该指定
0666
,而不是
666
——前导的0表示您的值是八进制的


而且,您的两个测试实际上是相同的;与其使用
TestMain(…)
执行设置,我建议使用
*T.Run(…)
从单个顶级
Test*
函数执行测试。大概是这样的:

gcc_test.go:

package gcc

import (
    "os"
    "path/filepath"
    "testing"
)

func TestOuputFileCreated(t *testing.T) {
    var inFile = filepath.Join("testdata", "correct.c")
    var outFile = filepath.Join("testoutput", "correct_out")

    if err := Compile(inFile, outFile); err != nil {
        t.Errorf("Expected err to be nil, got %s", err.Error())
    }

    if _, err := os.Stat(outFile); os.IsNotExist(err) {
        t.Error("Expected output file to be created")
    }
}

func TestOuputFileNotCreatedForIncorrectSource(t *testing.T) {
    var inFile = filepath.Join("testdata", "wrong.c")
    var outFile = filepath.Join("testoutput", "wrong_out")

    if err := Compile(inFile, outFile); err == nil {
        t.Errorf("Expected err to be nil, got %v", err)
    }

    if _, err := os.Stat(outFile); os.IsExist(err) {
        t.Error("Expected output file to not be created")
    }
}

func TestMain(m *testing.M) {
    os.Mkdir("testoutput", 666)
    code := m.Run()
    os.RemoveAll("testoutput")
    os.Exit(code)
}
package gcc

import (
  "testing"
  "path/filepath"
  "os"
)

const testoutput = "testoutput"

type testcase struct {
  inFile  string
  outFile string
  err     error
}

func (tc *testcase) test(t *testing.T) {
  var (
    in  = filepath.Join("testdata", tc.inFile)
    out = filepath.Join(testoutput, tc.outFile)
  )

  if err := Compile(in, out); err != tc.err {
    t.Errorf("Compile(%q, %q) == %v; Wanted %v", in, out, err, tc.err)
  }
}

func TestCompile(t *testing.T) {
  os.Mkdir(testoutput, 0666)

  tests := map[string]*testcase{
    "correct": &testcase{"correct.c", "correct_out", nil},
    "wrong":   &testcase{"wrong.c", "wrong_out", expectedError},
  }

  for name, tc := range tests {
    t.Run(name, tc.test)
  }
}
#1

尝试运行
TestMain()
就像尝试运行
main()
。如果你不这样做,操作系统会为你这样做

在Go 1.4中引入,以帮助设置/拆除测试环境,并被调用,而不是运行测试;引用发行说明:

如果测试代码包含函数

func TestMain(m *testing.M) 
将调用该函数,而不是直接运行测试。M结构包含访问和运行测试的方法


#2

使用
ioutil.TempDir()
创建临时目录

tmpDir, err := ioutil.TempDir("", "test_output")
if err != nil {
    // handle err
}
它将负责创建目录。您应该稍后使用
os.Remove(tmpDir)
删除临时目录

您可以将其与建议的稍加修改的版本一起使用,例如:

func TestCompile(t *testing.T) {
    tmpDir, err := ioutil.TempDir("", "testdata")
    if err != nil {
        t.Error(err)
    }
    defer os.Remove(tmpDir)

    tests := []struct {
        name, inFile, outFile string
        err                   error
    }{
        {"OutputFileCreated", "correct.c", "correct_out", nil},
        {"OutputFileNotCreatedForIncorrectSource", "wrong.c", "wrong_out", someErr},
    }

    for _, test := range tests {
        var (
            in  = filepath.Join("testdata", test.inFile)
            out = filepath.Join(tmpDir, test.outFile)
        )

        t.Run(test.name, func(t *testing.T) {
            err = Compile(in, out)
            if err != test.err {
                t.Errorf("Compile(%q, %q) == %v; Wanted %v", in, out, err, test.err)
            }
        })
    }
}

您不能只运行TestMain,它不是一个测试
TestMain
运行所有其他测试。我明白了。但我仍然不知道为什么我会在创建临时目录时出错,但是当我手动创建它时它会工作。谢谢。问题是我没有权限使用
0666
模式写入
testoutput
。我把它改成了
0777
,所有的测试都通过了。