Golang: Compile all tests across a repo without executing them - unit-testing

Context
I have a repo in which multiple teams contribute integration tests.
All these tests are hidden behind //go:build integration flags, so if I want go to see or run them, I need to pass the -build integration flag to the test command.
Purpose
What I’m trying to accomplish is to compile all tests across the entirety of this repo without actually executing them (would take a long time) so I can catch build errors introduced by PRs that the default go test compilation and execution would not catch.
I see the -c flag:
-c
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.
However… one cannot use the -c flag with the -build flag:
$ go test -build=integration -c ./integrationtests/client/admin-api
go: unknown flag -build=integration cannot be used with -c
Also... one cannot use the -c flag across multiple packages:
$ go test -c ./...
cannot use -c flag with multiple packages
Any ideas?

You can use the go test -run flag and pass it a pattern you know will never match:
go test -run=XXX_SHOULD_NEVER_MATCH_XXX ./...
ok mypkg 0.731s [no tests to run]
this will catch any test compilation errors - and if there are none - no tests will be run.
If you need to pass any build tags that are typically passed during your go build process (e.g. go build -tags mytag), you can do the same during go test:
go test -tags mytag -run=XXX_SHOULD_NEVER_MATCH_XXX ./...
Full details on the -run flag from the inline (go help testflag) docs:
-run regexp
Run only those tests, examples, and fuzz tests matching the regular
expression. For tests, the regular expression is split by unbracketed
slash (/) characters into a sequence of regular expressions, and each
part of a tests identifier must match the corresponding element in
the sequence, if any. Note that possible parents of matches are
run too, so that -run=X/Y matches and runs and reports the result
of all tests matching X, even those without sub-tests matching Y,
because it must run them to look for those sub-tests.

Related

ninja run specific test [duplicate]

If I have a bunch of tests for my project, I can run them - after cmakeing and makeing to build, building - with make test.
But what if I only want to run one of my tests? That is, one of the items for which I have a add_test() in the tests CMakeFile.txt ?
tl;dr - Do this:
cd $YOUR_BUILD_DIRECTORY
ctest -R name_of_your_test
Explanation
Here is how you likely got confused:
You were trying to do this with make, since make test runs all the tests for you. This won't work for a single test (although there's a workaround - see #danger89's answer). ctest is the cross-platform way to do it.
You started using ctest, e.g. in your main project directory, and you probably got something like:
*********************************
No test configuration file found!
*********************************
Usage
ctest [options]
which wasn't helpful.
... So you thought "Ok, maybe ctest has a -C switch, like CMake and GNU Make" - and indeed, it has a -C switch! but that didn't do what you expected:
[joeuser:/home/joeuser/src/myproj]$ ctest -C build
Test project /home/joeuser/src/myproj
No tests were found!!!
What you actually need to do:
cd $YOUR_BUILD_DIRECTORY
ctest -R name_of_your_test
(note that -R matches a regular expression.) This should work. Note that you can list the tests to be run rather than actually run them by passing -N to ctest.
Thanks goes to #RTsyvarev for pointing me in the right direction
einpoklum is not fully correct. Actually you can use make test if you like. CMake will generate a Makefile and I found out that it accepts an ARGS variable.
Meaning you are able run specific tests via for example the -R (regex) parameter. Which will look like this when using make test:
make test ARGS="-R '^test_'"
This will run only the testcases files that starts with test_ in their filename.
Note: -R above is just an example, it will accept all the arguments that ctest command will accept as well.
Anyway the make test example above will do exactly the same as running:
ctest -R '^test_'

Temporarily get jest coverage to show only files in a specific folder

For my reactjs app, I'm adding integration tests to a view and want to keep an eye on coverage along the way. I'm currently getting all files on every run.
Question
While adding tests to increase coverage, how can I get jest coverage to show only files in a specific folder?
Examples tried
$ yarn test --collectCoverageFrom=src/app/components/Tools
Test run, bu no coverage is showing here.
$ yarn test Tools --coverage --collectCoverageFrom=src/app/components/Tools
I get Ran all test suites matching "Tools".
$ yarn test src/app/components/Tools --coverage
Here I see the coverage percentage is smaller but still lists all files.
$ yarn test -o --coverage
Again as the previous, I see the coverage percentage is smaller but still lists all files.
It would be best to have an argument in the CLI, but you can add a temporary script in your package.json:
"tools-coverage": "react-app-rewired test --env=jsdom src/app/components/Tools --coverage --collectCoverageFrom=src/app/components/Tools/**/*.js"
Running the full command in the terminal just doesn't work.
Now you can instead run $ yarn tools-coverage to just test your Tools folder you targeted in your package.json.
An example shown here in the create-react-app issue:
https://github.com/facebook/create-react-app/issues/1455#issuecomment-277010725

Build single test in go

I have two tests in my project, I would like to build a single test, place the resulting binary in a container, run it, and then attach a debugger.
Is this possible?
package dataplatform
import "testing"
func TestA(t *testing.T) {
// test A
}
func TestRunCommand(t *testing.T) {
// Test B
}
You may use -run <regexp> to limit (filter) the tests to run. So for example if you want to run only the TestA() test, you may do it like this:
go test -run TestA
Actually the above will run all tests whose names contain TestA, so to be explicit, it would be:
go test -run ^TestA$
To not run the tests but generate the test binary, you may use the -c option:
go test -c
This won't run the tests, but compile a binary which when executed will run the tests.
The problem is that you can't combine these options, e.g. running
go test -c -run TestA
Will generate a binary which when executed will run all tests.
The truth is that the generated binary accepts the same parameters as go test, so you may pass -run TestA to the generated binary, but you must prefix the params with test:
Each of these flags is also recognized with an optional 'test.' prefix, as in -test.v. When invoking the generated test binary (the result of 'go test -c') directly, however, the prefix is mandatory.
So if the name of the generated test binary is my.test, run it like:
./my.test -test.run TestA
For more options and documentation, run go help test, or visit the official documentation:
Command Go
And the relevant section:
Command Go: Testing flags

get output of bash autocompletion for testing

I would like to make a unit test that tests that a bash autocompletion script correctly expands a certain string (let's assume the cursor is at the end).
(I think) I would like to be able to input a string and capture the output of COMPREPLY.
For example, suppose I would like to test that when I put git b<TAB><TAB> it offers bisect blame branch bundle. How can I get that output from a bash function?
In case that is confusing, I would like to be able to do something like:
output=$(get_compreply "git b")
echo "$output"
> bisect blame branch bundle
Here you are:
compgen -c YOUR_INPUT_BEFORE_TAB
Firstly, do you have defined completions for git? (What is the output of running complete -p?)
This page describes building compspecs: http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2
Here is a simplified example:-
$ output=$(compgen -W "bisect blame branch bundle" b)
$ echo $output
bisect blame branch bundle

How to measure test coverage in Go

Has anyone succeeded in generating code coverage for Go unit tests? I can't find a tool for that on the web.
Note that Go 1.2 (Q4 2013, rc1 is available) will now display test coverage results:
One major new feature of go test is that it can now compute and, with help from a new, separately installed "go tool cover" program, display test coverage results.
The cover tool is part of the go.tools subrepository. It can be installed by running
$ go get golang.org/x/tools/cmd/cover
The cover tool does two things.
First, when "go test" is given the -cover flag, it is run automatically to rewrite the source for the package and insert instrumentation statements. The test is then compiled and run as usual, and basic coverage statistics are reported:
$ go test -coverprofile fmtcoverage.html fmt
ok fmt 0.060s coverage: 91.4% of statements
$
Second, for more detailed reports, different flags to "go test" can create a coverage profile file, which the cover program, invoked with "go tool cover", can then analyze.
Frank Shearar mentions:
The latest versions of Go (2013/09/19) use:
go test -coverprofile <filename> <package name>
Details on how to generate and analyze coverage statistics can be found by running the commands
$ go help testflag
$ go tool cover -help
Ivan Black mentions in the comments:
go test -coverprofile cover.out and then
go tool cover -html=cover.out opens cover.out in your default browser
I don't even want to wait for the browser to open, so I defined this alias:
alias gc=grep -v -e " 1$" cover.out
That I just type gc, and have a list of all the lines not yet covered (here: with a coverage.out line not ending with " 1").
Update 2022, possibly for Go 1.19
proposal: extend Go's code coverage testing to include applications
While the existing "go test" based coverage workflow will continue to be supported, the proposal is to add coverage as a new build mode for "go build".
In the same way that users can build a race-detector instrumented executable using "go build -race", it will be possible to build a coverage-instrumented executable using "go build -cover".
Merging coverage profiles produced in different GOOS/GOARCH environments will be supported.
Go comes with awesome tool for testing and coverage. Although all Go tools are well documented go tool cover -help I would suggest reading The cover story article on the official Go blog. It has plenty of examples and I strongly recommend it!
I have this function in my ~/.bash_profile. (you can just paste it in the terminal to give it a try).
cover () {
t="/tmp/go-cover.$$.tmp"
go test -coverprofile=$t $# && go tool cover -html=$t && unlink $t
}
Then just cd into a go project/package folder and type cover.
This opens a visual tool in browser which shows you the tested and untested code for each file in the current package. Very useful command! I strongly recommend it for finding what is not 100% tested yet! The shown results are per file. From a drop down in top-left you can see results for all files.
With this command you can also check the coverage of any package for example:
cover fmt
The output in terminal from this command would be:
ok fmt 0.031s coverage: 91.9% of statements
In addition to that in your browser you will see this tool showing in red all lines of code which are not covered with tests:
It is also possible to just save the html coverage file instead of opening it in a browser. This is very useful in cases when your tests + coverage is run by CI tool like Jenkins. That way you can serve the coverage files from a central server and the whole team will be able to see the coverage results for each build.
In addition to the good answers above, I find these three lines to be the simplest way to get it (which includes all packages):
go test -v -coverprofile cover.out ./YOUR_CODE_FOLDER/...
go tool cover -html cover.out -o cover.html
open cover.html
Note that in the HTML file you will find a dropdown button that will direct you to all files.
See go tool cover -help for additional options.
Simply run
go test -cover
or
go test -cover ./...
or
go test -coverprofile=coverage.out ./... ; go tool cover -func=coverage.out
or to check the source code
go test -coverprofile=coverage.out ./... ; go tool cover -html=coverage.out
I can't find a tool for that on the web.
Actually... there is now (2022) such a tool on the web, from Nikolay Dubina's project go-cover-treemap-web:
https://go-cover-treemap.io/
Nothing it uploaded (the processing remains local), but by dragging/dropping your coverprofile, the Web UI (using Go WASM) will run go-cover-treemap and display:
(gocovergage for https://github.com/gohugoio/hugo)
Coverage Report:
a) Run all the tests and enable coverage --> go test ./... -coverprofile coverage.out
b) Get coverage for individual functions as well as overall coverage → go tool cover -func coverage.out
c) See the lines covered and the ones not covered by your tests → go tool cover -html=coverage.out -o coverage.html. Open the coverage.html file hereby generated in the browser and analyze the detailed coverage info.
Already built-in in VSCode
Ctrl+Shift+P to Open Command Palette
Go: Toggle Test Coverage ...
The Green part is tested and Red is not
It's right here, some docs here.
$ go tool
6a
6c
6g
6l
addr2line
api
cgo
cov
dist
ebnflint
fix
gotype
nm
objdump
pack
pprof
prof
vet
yacc
$ go tool cov -h
usage: cov [-lsv] [-g substring] [-m minlines] [6.out args...]
-g specifies pattern of interesting functions or files
go tool cov: exit status 1
$
I haven't used it, this is all I know.
If you like to see the uncovered lines by function directly in a terminal I rewrote the cover tool for this purpose. It's available at https://github.com/gregoryv/uncover.
Usage
go get -u github.com/gregoryv/uncover/...
go test -coverprofile /tmp/c.out
uncover /tmp/c.out
Screenshot
If you are using VSCode this functionality is supported out the box ( But disabled by default )
Just turn on test on save + coverage reporting
https://github.com/microsoft/vscode-go/wiki/On-Save-features
It will even show in your editor which lines are not covered which is super handy.
If you want to find test coverage in Windows, just go to the desired folder in command prompt and type the following command:
go test -coverprofile=coverage.out && go tool cover -html=coverage.out
This is perfectly easy and works reliably.
Inspired by the help menus and other answers to this question, just run:
f=cover.out
if [ -f $f ]; then
rm $f
fi
go test ./... -coverprofile $f && \
go tool cover -html $f && \
rm $f
A quick and easy way is to use the coverage tool that comes with built-in go :
$ go test -coverprofile cp.out
// Emits the coverage in one liner percentage wise
After you execute the above command, if you wish to visually see the code coverage (like covered statements and missed etc)
$ go tool cover -html=cp.out
Note : You need to execute the above commands in the folder where you wish to see coverage
Try using gaia-docker/base-go-build Docker Image.
This is a Docker image that contains all you need in order to build and test coverage.
Running test coverage inside a Docker container creates .cover folder with test coverage results of your project.
docker run --rm -v "$PWD":$PROJECT_PATH -w $PROJECT_PATH $BUILDER_IMAGE_NAME /go/script/coverage.sh
The test coverage script running on all projects' folders and generates, inside .cover folder junit and coverage reports for each folder, and a combine coverage report of all projects' tests.
Codecov also suggests a script that collect coverage results: multiple files
Test Coverage for Golang
go get github.com/axw/gocov/gocov
go get -u gopkg.in/matm/v1/gocov-html
Check It is Installed Correctly And you have access from your Terminal
Run the Test Case
If you run the test case it will Reder the .json File Based on the file you will get the Code Coverage Report in .html file
gocov test >your_Coverage_report.json
Once Your Test case is done Generate a Report in .html File using .json
gocov-html your_Coverage_report.json >your_Coverage_report.html
Reference
GoTest Coverage Tool for go lang
Go Test Report Tool
Alternate Method
Go Native Test coverage
go test -coverprofile=coverage.out
go tool cover -html=coverage.out