How to run tests and get coverage in a golang application with a particular structure?/ [duplicate] - unit-testing

This question already has answers here:
How to detect code-coverage of separated folders in GO?
(3 answers)
Closed 1 year ago.
Let's say my golang project has a directory structure like this:
├── go.mod
├── main.go
├── pack
│   └── runner.go
└── test
└── pack
└── runner_test.go
How do I run the tests and get the coverage?
Simply running go test -cover does not work with this directory strucure. I get [no test files]. It only works when runner_test.go and runner.go are in the same directory.

It's recommended for the code and its tests to be in the same directory, because they're typically in the same package.
Moreover, you can run all tests in a module from its root directory with go test ./... -- this will run tests of all packages in the module.
I'd modify your code structure slightly to be:
├── go.mod
├── main.go
├── pack
└── runner.go
└── runner_test.go
Assuming the code in runner.go is in package pack (note that in Go the package name is the containing dir's name).
See Testing in the official "How to Write Go Code", and Add a test in the Go tutorial.

Related

How do I run unit tests from smaller applications inside of a parent directory?

I'm working in a repository with multiple smaller applications for various lambdas. I'd like to be able to run cargo test from the top level directory, but I can't seem to find a way to get this to work since the files aren't nested within a top level src directory.
├── cloudformation
├── apps
│ ├── app1
│ │ └── src
│ └── app2
│ └── src
└── otherStuff
Ideally I could run cargo test from the top level and it would dig into apps and run tests from the src directory nested within each individual app. Is there a way to accomplish this?

Django & coverage - .coveragerc omit not working

I have a Django project with multiple applications. In one application, I have a library already tested using unittest + coverage.
When I run the test of the django project, I would like to omit this folder.
My project architecture is :
project/
├── application1/
│ ├── tests.py
│ ├── views.py
│ ├── ...
│ └── my_lib/ << The lib I want to omit
│ ├── tests.py
│ ├── script.py
│ ├── __init__.py
│ └── ...
├── application2/
│ ├── tests.py
│ ├── views.py
│ └── ...
├── application3/
│ ├── tests.py
│ ├── views.py
│ └── ...
├── .coveragerc
├── runtest.bat
├── manage.py
└── ...
runtest.bat is :
CALL activate ./venv
coverage erase
coverage run manage.py test
coverage html
PAUSE
Based on several tutorials and SO questions, I've tried several .coveragerc files but none of them properly skipped the library. Testing it creates a fail because it tries to load with the incorrect relative path.
.coveragerc is :
[run]
omit =
*/application1/my_lib/*
[report]
exclude_lines =
if __name__ == .__main__.:
show_missing = True
I also tried :
[run]
source = .
omit =
/application1/my_lib/*
[run]
source = project/*
omit =
*/application1/my_lib/*
[run]
source = .
omit =
*/application1/my_lib/*
Do you have any clue what am I doing wrong ?
For information :
Django version is 2.2.5
Coverage version is 4.5.4
Python version is 3.7
Few sources :
Django Coverage
Coverage Documentation
SO question
Thanks in advance
EDIT 1:
Just as a background. my_lib is mainly a file containing a class. This code is just embedded in the application to be used "like" a standard library.
In application1/views.py, I simply have a from . import my_lib.
In application1/my_lib/__init__.py, I have from .script import MyClass
The objective is simply to be able then to use in my view with my_lib.MyClass.do_something()
Now the reason why I would like to exclude this "library" from the coverage is because this was developped out of the application. It has his own unittest in applications1/my_lib/tests/py starting with from script import MyClass.
When I run the coverage in the root of the project, Python cannot find script.py in the root of the project so it triggers the error
File "path_to/project/application1/my_lib/tests.py", line 3
from script import MyClass
ModuleNotFoundError: No module named script.
In the worst case scenario, I could put this library to site-packages of my virtual environment bu I would like to avoid it (there will be probably multiple similar my_lib with at most 1 per application)
EDIT 2:
As a temporary solution, I simply renamed application1/my_lib/tests.py by application1/my_lib/script_tests.py. There is no file starting by test so the coverage does not care about this folder anymore.
The other alternative to run the test at the same time as the project required quite a lot of updates due to relative path used to several files

How to generate coverage for multiple packages using go test in custom folders?

We have following project structure:
├── Makefile
├── ...
├── src
│   ├── app
│   │   ├── main.go
│ │ ├── models
│ │ ├── ...
│ │ └── dao.go
│   │   ├── ...
│   │   └── controllers
│ │ ├── ...
│ │ └── pingController.go
│   └── test
│   ├── all_test.go
│   ├── ...
│   └── controllers_test.go
└── vendor
└── src
├── github.com
├── golang.org
└── gopkg.in
I want to measure coverage of packages in src/app by tests in src/test. And currently generating coverage profile by running custom script that runs coverage for each package in app and then merges all coverage profiles into one file. Recently I heard that in go1.10 we are able to generate coverage for multiple packages.
So I tried to replace that script with oneliner, and tried running
GOPATH=${PROJECT_DIR}:${PROJECT_DIR}/vendor go test -covermode count -coverprofile cover.out -coverpkg all ./src/test/...
It gives me "ok test 0.475s coverage: 0.0% of statements in all"
When I do
cd src/test/
GOPATH=${PROJECT_DIR}:${PROJECT_DIR}/vendor go test -covermode count -coverprofile cover.out -coverpkg all
Logs show that specs are runned and tests are successfull, but still I have "coverage: 0.0% of statements in all" and empty cover.out.
What am I missing to properly compute coverage of packages in app by tests in test?
You can't with the current state of go test but you can always use third party scripts.
https://github.com/grosser/go-testcov
Short answer:
go test -race -coverprofile=coverage.txt -covermode=atomic ./... # Run all the tests with the race detector enabled
go test -bench=. -benchmem ./... # Run all the benchmark for 3s and print memory information
In order to create a test for a Go code, you have to create a file (in the same folder of the root code) that have the same name of the code, and append "_test" to the name. The package have to be the same too.
So, if I have a GO Code called strings.go, the relative test suite have to be named: strings_test.go.
After that, you have to create a method that have in input the t *testing.T
struct, and the name of the method have to start with Test or Benchmark word.
So, if the strings.go contains a method called "IsUpper", the related test-case is a method called TestIsUpper(t *testing.T).
If you need the Benchmark, than you need to substitute the Test word with Benchmark, so the name of the method will be BenchmarkIsUpper, and the struct that the method take in input is b *testing.B.
You can have a look at the following link in order to see the tree-structure necessary for execute the test in GO: https://github.com/alessiosavi/GoGPUtils.
There you can find Benchmark and TestCase.
Here an example of tree-struct
├── string
│ ├── stringutils.go
│ └── stringutils_test.go

Integrating jquery-csv into Rails app, ES15 syntax causing issues

I have already implemented a csv import feature in my app using this plugin, and it works great! But recently I had to reinstall some of my assets and it appears the plugin has some recent additions that include ES15 syntax. My Rails 4 app isn't ready to digest ES15 so I'm looking for a way to exclude the offending files if I can.
The plugin's directory structure looks like this (with some items omitted for brevity).
├── src
│   ├── jquery.csv.js
│   └── jquery.csv.min.js
└── test
├── csv.from_array.js
├── csv.from_arrays.js
├── csv.parsers.js
├── csv.to_array.js
├── etc ...
The ES15 code only appears in the test/ files. In my assets pipeline I include jquery.csv.js, which apparently includes the test/ files, as it's choking on the ES15 when I precompile assets. (If I don't require jquery.csv.js, assets precompile fine.)
This illustrates the errors I'm seeing when I precompile.
Seems like I should be able to do without the test files, but looking in jquery.csv.js it's not obvious to me how they're being included.
I know I should probably focus on getting Rails upgraded or use webpack/babel/whatever to integrate ES15 but I'm hoping for a short-term fix so I can move forward.
Thanks for any tips!

How to deploy a Go web application in Beanstalk with custom project folder structure

I'm new to Go.
I am trying to deploy a simple web project to EB without success.
I would like to deploy a project with the following local structure to Amazon EB:
$GOPATH
├── bin
├── pkg
└── src
├── github.com
│   ├── AstralinkIO
│   │   └── api-server <-- project/repository root
│   │   ├── bin
│   │   ├── cmd <-- main package
│   │   ├── pkg
│   │   ├── static
│   │   └── vendor
But I'm not sure how to do that, when building the command, Amazon is treating api-server as the $GOPATH, and of course import paths are broken.
I read that most of the time it's best to keep all repos under the same workspace, but it makes deployment harder..
I'm using Procfile and Buildfile to customize output path, but I can't find a solution to dependencies.
What is the best way to deploy such project to EB?
Long time has past since I used Beanstalk, so I'm a bit rusty on the details. But basic idea is as follows. AWS Beanstalk support for go is a bit odd by design. It basically extracts your source files into a folder on the server, declares that folder as GOPATH and tries to build your application assuming that your main package is at the root of your GOPATH. Which is not a standard layout for go projects. So your options are:
1) Package your whole GOPATH as "source bundle" for Beanstalk. Then you should be able to write build.sh script to change GOPATH and build it your way. Then call build.sh from your Buildfile.
2) Change your main package to be a regular package (e.g. github.com/AstralinkIO/api-server/cmd). Then create an application.go file at the root of your GOPATH (yes, outside of src, while all actual packages are in src as they should be). Your application.go will become your "package main" and will only contain a main function (which will call your current Main function from github.com/AstralinkIO/api-server/cmd). Should do the trick. Though your mileage might vary.
3) A bit easier option is to use Docker-based Go Platform instead. It still builds your go application on the server with mostly same issues as above, but it's better documented and possibility to test it locally helps a lot with getting configuration and build right. It will also give you some insights into how Beanstalk builds go applications thus helping with options 1 and 2. I used this option myself until I moved to plain EC2 instances. And I still use skills gained as a result of it to build my current app releases using docker.
4) Your best option though (in my humble opinion) is to build your app yourselves and package it as a ready to run binary file. See second bullet point paragraph here
Well, which ever option you choose - good luck!