Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to maintain good Go package test coverage when dealing with obscure errors?

Tags:

testing

go

I'm trying to maintain 100% code coverage on some of my Go packages. This isn't viable everywhere, even with some tests that I select with a -integration build tag on a build system, but it should be possible for my relatively isolated library packages.

I'm having trouble dealing coverage for obscure error paths, though.

Here is an example of one of my methodss that's part of an integration test where there's a real filesystem:

func (idx Index) LoadPost(title string) (*PostSpec, string, error) {
    postFolder := strings.Replace(strings.ToLower(title), " ", "_", -1)
    spec, err := idx.getSpec(postFolder)
    if err != nil {
            return nil, "", err
    }
    f, err := os.Open(path.Join(idx.blogdir, postFolder, "content.html"))
    if err != nil {
            return nil, "", err
    }
    defer f.Close()

    b, err := ioutil.ReadAll(f)
    if err != nil {
            return nil, "", err
    }
    return spec, string(b), nil
}

Here's what it looks like in go tool -cover:

go tool cover html output

Hitting that block is not easy. I can't think of any way to do it other than creating a special test directory where the file it's trying to open is something other than a regular file. That seems like a lot of complexity.

This isn't too much of a deal on its own, but it means that I have to remember that 97.3% coverage is the right figure. If I see that number go down, does it mean I've broken my tests and there's now more uncovered code? Or just that I've managed to improve my package through simplification and removal or dead code? It leads to second guessing.

More importantly to some, in a business context it's an obstacle to a nice build dashboard.

like image 775
Cera Avatar asked Jul 08 '14 09:07

Cera


1 Answers

io/ioutil/ioutil_test.go does test that error simply by calling ioutil.ReadFile() function with a non-existing file.

That shouldn't require any setup.

filename := "rumpelstilzchen"

contents, err := ReadFile(filename)
if err == nil {
    t.Fatalf("ReadFile %s: error expected, none found", filename)
}
like image 101
VonC Avatar answered Sep 28 '22 02:09

VonC