TestMain-没有要运行的测试

时间:2019-02-10 11:24:28

标签: go testing

我正在编写一个可编译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)
}

go test输出:

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.

2 个答案:

答案 0 :(得分:2)

奇怪的是,您的问题出在传递给os.Mkdir(...) mode 值附近。您提供的666十进制数是八进制的01232(或者,如果愿意,您可以提供d-w--wx-wT permissions 字符串),我认为这并不是您真正想要的正在寻找。

您应该指定666而不是0666-前导0表示您的值采用八进制表示法。


此外,您的两个测试实际上是相同的。建议不要使用TestMain(...)来执行设置,而建议您使用*T.Run(...)从单个顶级Test*函数来执行测试。像这样:

gcc_test.go:

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 :(得分:2)

#1

尝试运行TestMain()就像尝试运行main()。您无需执行此操作,操作系统会为您执行此操作。

在Go 1.4中引入了

TestMain来帮助设置/删除测试环境,并且调用它而不是运行测试。引用发行说明:

  

如果测试代码包含一个函数

func TestMain(m *testing.M) 
     

将调用该函数,而不是直接运行测试。 M结构包含访问和运行测试的方法。


#2

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

tmpDir, err := ioutil.TempDir("", "test_output")
if err != nil {
    // handle err
}

它将负责创建目录。您稍后应使用os.Remove(tmpDir)删除临时目录。

您可以将其与来自Tim Peoples的建议的稍作修改版本一起使用,例如:

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)
            }
        })
    }
}