gogo-testinggo-build

Achieving partial build for broken Go codebase


I have a generator which generates me code in Go, for example:

After generation, I need to test if my generator is doing good job. For every generated file, I have a test counterpart:

Now, the problem is that there are hundreds of these tests, and given nature of the project, some of them will be sometimes broken — i.e. potentially "foo.go" might even fail to compile due to syntax error or something like that.

What I want to do is:

  1. Attempt to compile everything
  2. For files which fail to compile, capture compiler problems in a separate file and ignore them onwards for test purposes
  3. For the rest of files (which are syntactically correct and compile successfully), along with their tests, I want to run the tests and capture test output

To make things more complicated, ideally I'd love to keep generates files (foo.go) separate from test files (foo_test.go) — both in separate directories and separate Go packages, something like that:

Keeping them in separate dir allows easy cleanups and separation of version control concerns. Keeping them in separate Go package allows testing that all interfaces I need to be generated are indeed public and would guarantee that tests would never touch private fields.

What I've tried so far

Single dir, single package

Algorithm:

It kind of works, but the downsides are massive: I have to put everything in one directory (so git management becomes very messy) and I have to put everything in one Go package (which means that errors of test using private field occasionally might slip in).

Two modules

Algorithm:

Disable compilation offending files by deleting/renaming them

Same as previous, but instead of removing files from go build / go test invocation, hard disable go compiler from finding them to deleting or renaming them.

Works, but it's really ugly as it modifies test directory, so I either need to do full copy of it and run it in separate place, or rename .go -> .disabled and then rename it back after test run.

So, the question is: is there any better method/algorithm I can employ here? Maybe some non-obvious switch in go build system?


Solution

  • Maybe some non-obvious switch in go build system?

    As mentioned in the comments, build constraints may provide an alternative to deleting files.

    For example if foo.go and foo_test.go have the constraint //go:build !foo then using go test -tags foo would exclude those files (and you can specify multiple tags go test -tags foo,bar).

    Note: This really just answers your specific question seeking another option. I cannot comment on whether this is really a good option (you question focuses on the what, and does not really mention the why).