I'm trying to generate the code coverage for my golang project.
My setup is as follows:
- my_project
| - my_package
| | - my_dev_file.go
| | - test
| | | - my_dev_file_test.go
This setup allows to test the code from the point of view of a client that would call the package, without knowing anything about its internal implementation. At the sale time, dev dirs and test dirs are clearly separated which enforces global readability of the project.
The test code looks like this:
import (
"..."
"testing"
"path-to/my_package"
"..."
)
func TestSomething(t *testing.T) {
t.Run("should do something", func(t *testing.T) {
my_package.MyStruct.DoSomething()
// test something...
})
}
This setup works fine as far as testing is concerned.
However, i can't seem to be able to generate a coverage report. Coverage is 0% whatever command i launch, starting with:
go test -coverprofile=coverage.out ./.../test
OK path-to/test 0.005s coverage: 0.0% of statements
OK other-path-to/test 0.007s coverage: 0.0% of statements
I'm looking for a way to generate proper code coverage without compromising the way the project is organized.
Is it possible to do so?
You should run
go test -coverprofile=coverage.out ./...
Related
Hi I am using Go version 1.16:
$ go version
go version go1.16.2 darwin/amd64
# .zshrc
#
# Go Setup
export GOPATH="$HOME/go"
export PATH=$PATH:$GOPATH/bin
and have this setup:
tree ./
./
├── go.mod
├── sum.go
└── sum_test.go
// go.mod
module mysum
go 1.16
// sum.go
package mysum
func Sum(numbers [5]int) int {
sum := 0
for _, number := range numbers {
sum += number
}
return sum
}
// sum_test.go
package mysum
import "testing"
func TestSum(t *testing.T) {
numbers := [5]int{1, 2, 3, 4, 5}
got := Sum(numbers)
want := 15
if got != want {
t.Errorf("got %d want %d given, %v", got, want, numbers)
}
}
And when I click run test (above function TestSum) in below screenshot, I got an error says:
Running tool: /usr/local/go/bin/go test -timeout 30s -run ^TestSum$ main
package main is not in GOROOT (/usr/local/go/src/main)
If I manually run go test -run ^TestSum$ in the folder it works fine:
$ go test -run ^TestSum$ mysum
PASS
ok mysum 0.005s
Does anyone know if I miss any configuration for Go with VS Code?
How do I tell the extension to run tests in mysum package instead of main package?
$ /usr/local/go/bin/go test -timeout 30s -run ^TestSum$ mysum
Go extension v0.23.2, VS Code Version: 1.54.2
Have you changed the module name in go.mod from main to mysum before running 'run test'? Are you still seeing an issue if you reload the window? (Cmd+Shift+P -> "Developer: Reload Window")
I found an issue in the current go extension https://github.com/golang/vscode-go/issues/1373 but I am not yet sure if this is the same issue you are seeing.
(sorry - I meant to add as a comment, but I don't have enough credit to add my reply as a comment :-))
When I am running a benchmark on this repository (just a placeholder for any go project) using:
go test -run="^$" -bench="^BenchmarkLessorRevoke1000$" ./...
The output I am getting is this, the benchmark results are shown:
BenchmarkLessorRevoke1000-8 1033351 1141 ns/op
but also with a whole bunch of other test output. how do I make it only show the benchmarks and not the test outputs?
You can supply a dummy name to the -run parameter of the go test tool and providing you don't have any tests matching that name, then only the benchmarks should get ran.
You covered this with "^$" so all good, you are also have a pattern to match a benchmarks with "^BenchmarkLessorRevoke1000$".
The issue is that you are running go test throughout the entire package and/or subdirectories with the ./....
You should specify the benchmarks that you want to run on a per package basis.
go test -run="$^" -bench="^BenchmarkLessorRevoke1000$" .
go test -run="$^" -bench="^BenchmarkLessorRevoke1000$" ./pkg1/
go test -run="$^" -bench="^BenchmarkLessorRevoke1000$" ./pkg2/
Also be mindful, if you do want to run benchmarks in mass you should do so on a per-package basis.
Running benchmarks for multiple packages will execute them concurrently, skewing your results.
I've come across an odd error. I have this larger project that compiles fine with the typical go build. However when I switch to TinyGo (v0.8.0). I get the above error from this code:
func main() {
_ = lib.NewObject{
Version: lib.Const,
}
}
I changed the names to be less confusing but the symbols are completely identical. lib.Const is a constant of a lib.Version. And neither are pointers.
I understand this is a very specific question in the sense that it's in the realm TinyGo. This is more "for the record"... plus I even had to create the "tinygo" tag because this question is so specific. But to add further detail:
It has been compiling before the above code was added.
The build command in exact is tinygo build -target=wasm -o build/out.wasm src/main-wasm.go
This is a bug with the compiler: https://github.com/tinygo-org/tinygo/issues/726
It stems from importing the same package twice under different names. In this case, it was:
// file1:
import "./lib"
// file2:
import "../lib"
The above made 2 instances of the package "lib". This is normally okay to do when working with the normal Go compiler. But TinyGo does not have mechanisms in place to deal with this properly.
It is recommended to append to the $GOPATH to prevent the use of relative paths:
// file1:
import "lib"
// file2:
import "lib"
I have to take over a go project from a colleague and I've never touched Go before and it doesn't have tests so I've started to add them but I cannot run them.
The go command for running tests is go test but it doesn't seem to run at the root level.
My project structure is:
/project/main.go
/project/engine/*.go
/project/api/*.go
If I cd into either engine or api, and run go test it works but not in the root folder.
cd /project
go test
? /project [no test files]
Is there anyway to run all tests from the root?
You can use the ... (ellipsis) operator to test all subpackages of the current package. Like that: go test ./....
There are other solutions that you might want to try later if you do something more sophisticated, like using the list tool. Like that (for example): go test $(go list ./... | grep [regex]). That's useful to exclude the vendor directory from your tests.
Another thing you may want to know about is the gt command that can be found here https://godoc.org/rsc.io/gt and add caching to the go test command.
Finally, don't hesitate to read https://blog.golang.org/cover to get informations about code-coverage analysis in golang.
I find this irritating that go test ./... when run from project root will actually run from pkg/pkg_name/ folder. There is a way you can set the tests to project root by setting cwd in the init() helper function.
I found the solution here You could try the following snippet in your _file:
func init() {
_, filename, _, _ := runtime.Caller(0)
dir := path.Join(path.Dir(filename), "../..") // change to suit test file location
err := os.Chdir(dir)
if err != nil {
panic(err)
}
}
This snippet above works for my tests in pkg/$name/$name_test.go.
just running sudo go test -v ./... will probably fail because you probably do not have your root environment setup for GO just like you set the non-root env.
You can go and reset everything in the root, or do this easy step:
sudo -E go test -v ./...
This will run as root but keep your env settings.
I'm setting up go and trying to get a simple project working with http://goconvey.co/
I have my $GOPATH set to /Users/joe/Desktop/playground/go
and when I run
$ go get github.com/smartystreets/goconvey
it downloads all good to my GOPATH
so when I create a project here
/Users/joe/Desktop/playground/go/some-project
and run goconvey I get
2015/02/04 14:41:05 shell.go:93: Please run goconvey from within your $GOPATH
My testing code is
package main
import (
. "github.com/smartystreets/goconvey/convey"
"testing"
)
func TestStuff(t *testing.T) {
Convey("Truth", t, func() {
Convey("is falsey", func() {
So(false, ShouldBeFalse)
})
})
}
I don't know why it connot find the files.
When I run go test it works perfectly.
Help?
All go code needs to be within $GOPATH/src/ for the GoConvey UI to work.
So, if your $GOPATH is set to
/Users/joe/Desktop/playground/go
then you will need to put your project at
/Users/joe/Desktop/playground/go/src/some-project
Your code is currently at
/Users/joe/Desktop/playground/go/some-project
Having said all that, the error message should probably be modified to read something like this:
Please run goconvey from within $GOPATH/src (also, symlinks might be problematic).
The name of the variable referenced by #VonC is probably a slight misnomer in this case.