8

Take a look at this directory structure:

/root
    /one
        go.mod
        go.sum
        main.go
        main_test.go
    /two
        go.mod
        go.sum
        main.go
        main_test.go

Let's say I'm in the parent directory root/ and I want to run all the tests in all subdirectories. What do I do? I've tried go test./... and got the following error:

go: warning: "./..." matched no packages
no packages to test
Jay K.
  • 546
  • 2
  • 10
  • 17

3 Answers3

7

Yes, this will not work with go test, which expects to work on a single module rooted in the current directory or its parent. It won't work with nested modules either.

You'll need a shell trick like using find or something equivalent to execute in each module (see Cerise Limón's comment for example). Projects will typically use a Makefile or a test.sh script to run that.


One larger project I was working on has a list of all its modules (https://github.com/google/go-cloud/blob/master/allmodules) and then several scripts that operate on this list. For example the test script just loops through this file and runs go test for each directory, along other things.

You don't necessarily need a separate file listing the modules (the go-cloud project uses that for other management tasks) but it just demonstrates one way large projects with multiple modules handle things.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
  • So then what is the point of "./..." if it won't work with sub-packages? – Jeff Learman Jan 04 '22 at 15:12
  • Also, `go test root/one` produces `main module (root) does not contain package root/one` (even if `one/go.mod` specifies that package name.) – Jeff Learman Jan 04 '22 at 15:15
  • 2
    @JeffLearman the point of `go test ./...` is to run all tests on sub packages, not on submodules. In 99.9% of the cases what you want are actually sub packages, not submodules so `go test` actually covers the most common use-case very well. – VinGarcia Mar 15 '22 at 21:53
1

Promoting @Cerise Limón's comment to answer:

find . -name go.mod -execdir go test ./... \;
blackgreen
  • 34,072
  • 23
  • 111
  • 129
  • 2
    This is awesome, but it always returns a 0 exit code, which is not desirable in CI. I'm trying to figure out a way to make it exit with nonzero if one of the tests fails. I will report back if I figure it out – yalestar Nov 17 '22 at 05:31
  • https://apple.stackexchange.com/a/337961/62907 – quanta Dec 29 '22 at 06:45
0

Building on other answers here:

find . -name go.mod -execdir go test ./... \;

works but always returns a 0 exit code. I need this to fail my CI if any test fails.

find . -name go.mod -execdir go test ./... \; | grep -zqv FAIL

works for me (note by default grep returns status code 0 if there is a match)

Kurtis Streutker
  • 1,157
  • 10
  • 13