Go Test - empty coverage file - go

I have a go project, test directory contains a single sample test file.
Few Functions of the test file are
func TestMain(m *testing.M) {
setup()
code := m.Run()
shutdown()
os.Exit(code)
}
func TestUserLogin(t *testing.T) {
//sample code to make api call and validate response
}
func setup() {
//start service
}
func shutdown() {
//stop service
}
I want to see/generate a coverage report. The following command is being used to run tests:
go test -coverprofile=coverage.out
Output on terminal is
PASS
coverage: 100.0% of statements
coverage.out is getting generated but it consists of only single line
mode: set
coverage.out should have information about the files, lines, etc.
Anything that I am doing wrong here?

test directory contains a single sample test file
Here it is, Go coverage does not work if your *_test.go files are not in the same directory a.k.a they have been put in another folder.

Related

Go - Cucumber - Error on godog run - failed to compile testmain package: exit status 2

I'm trying to include godog in a go project in order to test some APIs.
This is the structure
Project Folder
...
...
src
cmd
features
ready.feature
main.go
main_test.go
The webserver starts in the main() function contained in a file named main.go under the cmd folder. So I have added under the cmd folder a new features folder with a ready.feature file:
Feature: get ready
In order to know if microservice is ready
As an API user
I need to be able to check the ready
Scenario: should get ready
When I send "GET" request to "/ready"
Then the response code should be 200
And the response should match json:
"""
{
service is ready
}
"""
Now, after the execution of this command:
godog run ready.feature
I get :
func iSendRequestTo(arg1, arg2 string) error {
return godog.ErrPending
}
func theResponseCodeShouldBe(arg1 int) error {
return godog.ErrPending
}
func theResponseShouldMatchJson(arg1 *godog.DocString) error {
return godog.ErrPending
}
func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Step(`^I send "([^"]*)" request to "([^"]*)"$`, iSendRequestTo)
ctx.Step(`^the response code should be (\d+)$`, theResponseCodeShouldBe)
ctx.Step(`^the response should match json:$`, theResponseShouldMatchJson)
}
So I've created the main_test.go file under the cmd folder with the content suggested by godog and tried to run godog (in order to run the test) with the command "godog run" but I get every time (and yes, I've reworked the main_test.go file) this error:
failed to compile testmain package: exit status 2 - output: /tmp/go-build2631598204/b001/_testmain.go:5:8: could not import project/src/cmd (open : no such file or directory)
Could you help me, please ?

How to use go test flag to execute test and bench function correctly?

I learn from the go flags from Testing flags
And I write some test files in my project.
This is my service folder:
service
family_limit_settings.go
family_limit_settings_test.go
xxxxxx.go (others go source files)
xxxxxx_test.go (others go test source files)
and my family_limit_settings_test.go content is as follows:
func TestSaveSettings(t *testing.T) {
// todo
}
func TestListByFamilyId(t *testing.T) {
// todo
}
func TestFamilyLimitVerify(t *testing.T) {
// todo
}
func BenchmarkFamilyListByFamilyId(b *testing.B) {
// todo
}
func BenchmarkFamilySaveSettings(b *testing.B) {
// todo
}
func BenchmarkFamilyLimitVerify(b *testing.B) {
// todo
}
my first question
I cd this service file and run command follow:
go test -v -bench=.
But I find it run other test function those are not benchmark function.(I know it because something wrong occurs in other common test function)
my second question
go test -v -bench=. -run=BenchmarkFamilyListByFamilyId
I want to execute the benchmark function with the name BenchmarkFamilyListByFamilyId but I found it execute all the benchmark functions.
The -run argument matches tests and examples only, -bench matches benchmarks. And . is a regular expression that matches every name, so -bench=. executes all benchmarks.
To execute only the BenchmarkFamilyListByFamilyId benchmark and none of the tests, run something like
go test -v -bench=ByFamilyId -run=XXX

Unit test mode identification in golang

I am building unit testing of the application that uses os.Exit(1), once os.Exit(1) executes remaining test file are skipped with go test,
I am thinking about suppressing os.Exit during the unit test execution only. I wonder how I can determine that app has been bootstrap from go test runner?
You will find various ways to unit test method with os.Exit() in "Testing os.Exit scenarios in Go with coverage information (coveralls.io/Goveralls)".
It uses a function which is:
os.Exit() when you are not testing
var osExit = os.Exit
and "yourOsExit" when you are testing.
func TestCrasher(t *testing.T) {
// Save current function and restore at the end:
oldOsExit := osExit
defer func() { osExit = oldOsExit }()
osExit = myExit

TestMain not run

I have a test package in go which tests some stuff that depend on reading a configuration. I want to read that configuration once before running all tests so I'm trying to use TestMain(m *testing.M):
main.go:
package tests
import (
...
)
var logger = logging.MustGetLogger("tests")
func TestMain(m *testing.M) {
logger.Info("Initializing test suite")
viper.SetConfigName("config")
viper.AddConfigPath("..\\..\\")
err := viper.ReadInConfig()
if err == nil {
os.Exit(m.Run())
} else {
logger.Fatal("Could not read configuration")
}
}
And I have another file in the same directory (and package) with a test.
repository_test.go:
package tests
import (
...
)
func TestCreation(t *testing.T) {
aa := myModule.CreateRepository()
assert.NotNil(t, aa)
}
My problem is that the test fails because the configuration is not read from the file. When I try to debug the test in Gogland a breakpoint inside TestMain is not hit. When I run the tests from command line I don't see any printouts from TestMain.
Is there something special I should do to make it work? From what I read online I understood that if I define TestMain(m *testing.M) then it's going to run just once for the package and that's where I'm supposed to write any setup or teardown code.
TestMain is only executed in test files (suffix _test.go).
Move the function to the repository_test.go file to fix this.
Make sure that the run configuration is set to Package not File in Run | Edit Configurations... | Go Test | Name of your configuration and this should work. If it doesn't, please post the commands the IDE runs to execute the tests.

How can stdout be captured or suppressed for Go(lang) testing?

How can stdout be captured or suppressed for Go testing?
I am trying to teach myself go(lang) testing. In the code below, myshow.LoadPath prints lots of information to stdout (which is a normal side effect). It does however make for very noisy output when I run "go test" Is there a way to suppress or capture stdout?
For comparison, I'm thinking about something like this from the python world. http://pytest.org/latest/capture.html#captures
package slideshow_test
import (
"os"
"testing"
"github.com/golliher/go-hpf/slideshow"
)
func setupTest() {
myshow := slideshow.Slideshow{Name: "This is my show"}
myshow.LoadPath("..")
}
func TestStub(t *testing.T) {
if true == false {
t.Fail()
}
}
func TestMain(m *testing.M) {
setupTest()
os.Exit(m.Run())
}
os.Stdout which is used by the fmt.Printf and others is just a variable. So you can overwrite it at any time and restore it back when necessary. https://golang.org/pkg/os/#pkg-variables
To suppress the output during the test I use the following code. I fixes output as well as logging. After test is done it resets the output streams.
func TestStartStowWrongCommand(t *testing.T) {
defer quiet()()
...
}
func quiet() func() {
null, _ := os.Open(os.DevNull)
sout := os.Stdout
serr := os.Stderr
os.Stdout = null
os.Stderr = null
log.SetOutput(null)
return func() {
defer null.Close()
os.Stdout = sout
os.Stderr = serr
log.SetOutput(os.Stderr)
}
}
The output can be suppressed
by running the tests with go test .:
$ go help test
Go test runs in two different modes: local
directory mode when invoked with no package arguments (for example,
'go test'), and package list mode when invoked with package arguments
(for example 'go test math', 'go test ./...', and even 'go test .').
In local directory mode, go test compiles and tests the package
sources found in the current directory and then runs the resulting
test binary. In this mode, caching (discussed below) is disabled.
After the package test finishes, go test prints a summary line showing
the test status ('ok' or 'FAIL'), package name, and elapsed time.
In package list mode, go test compiles and tests each of the packages
listed on the command line. If a package test passes, go test prints
only the final 'ok' summary line. If a package test fails, go test
prints the full test output. If invoked with the -bench or -v flag, go
test prints the full output even for passing package tests, in order
to display the requested benchmark results or verbose logging.
Not exactly what you are asking for but still might be helpful.
You can use t.Log (http://golang.org/pkg/testing/#T.Log) and t.Logf (http://golang.org/pkg/testing/#T.Logf) methods in the test method. The output will be printed only if the test fails or the -test.v flag is set.
I also would suggest to use log package to print to the console in myshow.LoadPath. Then you can disable (or capture) the output in the test by setting custom writer using log.SetOutput

Resources