How to run tests in a multimodule Go project

Issue

I’m learning Go with the specialization Programming with Google Go. It has several courses, each of which has several modules.

My project looks like the following (made with https://ascii-tree-generator.com/):

google-golang/
├─ .github/
│  ├─ workflows/
│  │  ├─ ci.yml
├─ golang-getting-started/
│  ├─ module1/
│  │  ├─ main.go
│  │  ├─ main_test.go
│  ├─ module2/
│  │  ├─ trunc/
│  │  │  ├─ main.go
│  │  │  ├─ main_test.go
├─ .gitignore
├─ README.md

I’d like to run all the tests in the *_test.go files for every commit, and it’s not clear to me how to do that from the root directory (google-golang). I don’t see a need for one module to import another as the exercises can be done independently. This question has two answers, one suggests using submodules, another recommends using Go workspace, but neither provide specific instructions that someone new like me can learn from.

I’m not asking for help on GitHub Actions, I know how to write those. I’m looking for one or more commands that’ll find and run the tests.

Solution

You seem confused about what a module is. The rule of thumb is, one go.mod file equals one module. Go Wiki, gomod:

A module is defined by a tree of Go source files with a go.mod file in the tree’s root directory.

Based on your directory tree shown in your question, there is no go.mod file in sight, hence nothing there is a Go module. As a matter of fact, if you attempt running a module-aware command from google-golang or golang-getting-started you’ll have:

go: go.mod file not found in current directory or any parent directory; see ‘go help modules’

If you want to run all tests from the root of a multi-module repo, as the title of your question says, with Go 1.17 you can:

  1. init the sub-modules:
$ cd google-golang/golang-getting-started/module1
$ go mod init example.com/module1
$ cd ../module2
$ go mod init example.com/module2
  1. use the trick suggested by Cerise Limón from the root dir of the multi-module project
$ cd google-golang
$ find . -name go.mod -execdir go test ./... \;

If you don’t actually care about keeping the sub-repos as separate modules, you can init a module in the root repo and run all tests from there:

$ cd google-golang # or google-golang/golang-getting-started/
$ go mod init example.com/mainmod
$ go test ./...

…however, even this hack works right now, it doesn’t make a lot of sense, because your repos named moduleN have main.go files, whose packages are supposedly named main, in each of them. So they are indeed organized as separate sub-modules.

Answered By – blackgreen

Answer Checked By – Gilberto Lyons (GoLangFix Admin)

Leave a Reply

Your email address will not be published.