Running benchmarks of subfolders from the project root - go

I have a project with a binary which entrypoint is located in ./cmd/<my-project>/main.go.
I've added a benchmark in ./cmd/<my-project>/main_test.go.
Now I want to execute this benchmark from the repository root.
I've tried to execute something like go test -bench=./cmd/<my-project>/main in various alternations (like for example go test -bench=./cmd/<my-project>/main_test.go or go test -bench=./cmd/<my-project>) but I couldn't get it to work.
The error I always get is:
can't load package: package github.com/<username>/<my-project>: no Go files in /home/<user>/go/src/github.com/<username>/<my-project>
and it's true, I have no *.go files in my project root.
All I came up with is changing into the directory first and run the benchmark with `go test -bench=.
However, as my program depends on the current working directory and the result is heavily depending on that it would be great to be able to execute it in another directory than the cmd/<my-project> one. (If this is good or not isn't part of the question :))
Update after the first comment:
I get it to run with go test -bench=. /cmd/<my-project> but the benchmark get's executed as if it would be run in the ./cmd/<my-project> directory.
I've noticed similiar behaviour in 'normal tests' - but that wasn't a problem for me at any time.
So, my program does scan the current directory for files directories depending on the current working directory, this results in only two files found (main.go and main_test.go) where the benchmark isn't really helpful.

So to run the benchmarks:
go test -bench=. ./cmd/<my-project>
However, you are wanting to control the working directory, so really you want to run it from somewhere else. What you are looking for is the -c flag. It will create a binary instead of running the tests. You can then run the binary (and therefore your tests and benchmarks) where you want.
go test -c ./cmd/my_proj
my_proj.test -test.bench=.
NOTE: Flags are prefixed with test. when you compile the tests.

Related

Can't run test function in GoLand: cannot find package "."

I have used VS Code as my code editor for building service using Go for almost one year. Then, I tried to switch to GoLand. But, when I tried run a test function there is an error: cannot find package "." What is the problem?
Note: I use go module as go dependency management tool. When I use dep (in another project), there is no error when running a test function. My project is in GOPATH.
Please make sure there's a valid go.mod file defined at the ROOT of your project i.e. in $GOPATH/src/<Project-name>.
If you don't have, you can create one using go mod init command using the shell. More information on the same - https://github.com/golang/go/wiki/Modules
After that please try running the test from the shell. First cd into the directory where the test file is present. Then, use go test . -test "<TestName>" -v to run your test. If the issue goes away, you can run the test from IDE and it should work fine.

Go build error: no non-test Go files in <dir>

Getting an error when trying to run go build ./... from my $GOPATH/src .
no non-test Go files in <dir>
The error is correct there are no test files in <dir> but why is that causing a compile error? Is it a bug?
I don't think this is a bug, unless you see somewhere in the docs that contradicts this behaviour you should probably close the issue you've created.
Tests in go normally live in the package they are testing. You have made a new package with package main at the top (invalid if you also have main elsewhere), and then have included no go source files in that tests/main package (invalid as package has no go source files apart from tests, which the compiler complains about explicitly).
Possible solutions for you (assuming this isn't just a hypothetical question):
Move tests for main to test_main.go (this is what readers will
expect)
Add doc.go file to your tests pkg and call it package tests in
both files
The reason for putting tests in the same package is to ensure they have access to the entire package, if you want to split them to another package you'll find you have to test as an external user of the pkg - this may be painful. Main is also a special case as well as you don't normally import it.
Calling it a bug… the build shouldn't fail if the tests compile. Filed here: https://github.com/golang/go/issues/22409
The bug I filed was a duplicate of https://github.com/golang/go/issues/8279 looks like it was broken in 1.3.
First, check your $GOPATH has been set correctly. Learn more at here.
Then, check if any '_' in your file name. Remove these '_'s and try again.
;-)

Move main out of the repository root in go

I am creating a project in go. Since there is already a lot of things at the root of the repository of the project (doc, README.md...), I want all the source code to go in a folder src, and all the test code in a folder named test :
\go
\src
\github.com
\user
\my_project
\src
main.go
some_func.go
\test
test_main.go
test_some_func.go
\doc
README.md
But I have two issues :
The build command is not working while I am in the my_project folder. I have to go in the my_project/src to successfully run build. I want to do it from the my_project folder. How to inforce go to understand that the source for my_project is in the src code ?
Then the executable produced by the go install command is named src. How to change the name of that executable ?
I want all the source code to go in a folder src, and all the test code in a folder named test :
Go has a way that it organizes source code. Do not fight this. It is how the system works. Organize your code the way Go wants you to. Do not try to force Go to work the way you have learned working in some other language. Every language has its own ways of doing things. None of them are "correct." Like Java, Go has very specific ideas of what you're supposed to do. Do it that way. (This isn't an argument about whether Go is "right" or Go is "wrong." Go is Go, and it does things in the Go way.)
In particular, you should not create another "src" directory. There is already a "src" directory at the top of the "go" tree. If you create another, redundant, "src" directory, then the package name for your project is "github.com/user/my_project/src" which is likely not what you want.
To make the executable be named what you want, put it in a directory named what you want (probably "my_project"). Put test files with the files they test. This is how go works.
So your tree should look like:
\go
\src
\github.com
\user
\my_project
main.go
some_func.go
main_test.go
some_func_test.go
\doc
README.md
Attempts to do something other than this is going to blow up over and over again, and questions of "how do I make the build system do this other thing" will continually return "put your code in the way the build system expects."
For details on what Go expects, and how you should organize your code, see GOPATH environment variable in the Command Go documentation. Once you've built your system this way for a while, you will start to see where you can deviate from it (like creating other directories for test utilities, but not test cases). Don't start deviating until you've tried it the standard Go way.

Check if all tests are successful in `after(:all)`

In before(:all) I set up a temporary directory (#work_dir) where the tests can place their files. I would like to remove this directory inside after(:all), but only if all the tests have been successful. If one of the tests failed I would like the directory to be left intact so I can look at the generated files.
What code can I use inside after(:all) to check whether all the tests have been successful run?
You can write custom bash script, that starts running you test suite.
After that it checks return code, if it is non-zero, it keeps files. In other case it removes.
As a second solution, you can clean your directory before running tests.
In such case, when your test suite is failed, you can go and check files.

How do I set up a Ginkgo test suite?

I have inherited a Go project that consists of a lot of common files, a library of sorts, two executables, and theoretically a test suite. The test suite is being written after the fact. But I dislike the only way I've found of setting up is rather unpalatable
I'm using Ginkgo, and this is my starting directory structure
component1/component1.go
component2/component2.go
cmd1/cmd1.go
cmd2/cmd2.go
project_suite_test.go
component1_test.go
Each cmd?.go file will be compiled into a separate executable.
What I would like is a multi-file test suite, usually one file per component. Where do I put the files so that go test will find and run all of them, without leaving them here in the root of the project?
ginkgo init and ginkgo bootstrap will set up your tests. ginkgo -r will run all your tests recursively.
Reason:
Ginkgo command will only work if you have actually bootstrap your project via ginkgo.
Options:
To use that you have to go to your test dir in terminal and run
ginkgo init : To Initialise project:
ginkgo bootstrap : This will generate new file with test suite config
ginkgo or ginkgo test : this will now be able to run tests based on your new generated file because that's what it is trying to search.
Alternatively:
If you like to keep your tests in a sub-folder, say test, then running
go test ./...
will attempt to run tests in every folder, even those that do not contain any test, thus having a ? in the subsequent report for non-test folders.
Running
go test ./.../test
instead will target only your test folders, thus having a clean report focused on your tests folders only.
you can alternatively use 'go run $(ls *.go)' to run all the files in a given folder.
Notice you have regular expression within () braces.
In-case you want to run test in different path update path as per your desired dir in the regular expression
You can use go test ./... in the root and it will go into child folders and execute the tests:
component1/component1.go
component1/component1_test.go
component2/component2.go
component2/component2_test.go
cmd1/cmd1.go
cmd1/cmd1_test.go
cmd2/cmd2.go
cmd2/cmd2_test.go

Resources