Testing golang folder structure - go

My folders are structured as follows:
src/
github.com/
hello/
hello.go
hello_test.go
integers/
integers.go
integers_test.go
hello.go/hello_test.go belong to package main
integers.go/integers_test.go belong to package integers
When runing go test from the root of folder hello, it only runs hello_test.go. How can I get it to run all tests recursively. Is this the right way to structure tests inside their respective packages?

How about having a make file? In the future if you expand your project and have more test files then you can test all of them at once by just running make test.
This link would be helpful.

Related

Understanding How to Build Go Source

I am confused about how to layout my Go project and then how to build it. I am reasonably new to Go and believe there was a time <1.13 where the GOPATH was important. I am using 1.14, so I believe I do not have to care about that and GOPATH is not set. I do not (for the moment) host my code on GitHub (which is something various articles assume). I have read a number of things, but it all leaves me more confused:
https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies
https://www.wolfe.id.au/2020/03/10/starting-a-go-project/
https://talks.golang.org/2014/organizeio.slide#1
I have laid out my project according to this: https://github.com/golang-standards/project-layout. (Except this project seems to use a Makefile. I do not want to write a Makefile. I believe this should all work without a Makefile. I really do not want to write a Makefile.)
Here is the structure:
/src
/cmd
main.go
/internal
helper.go
go.mod
go.mod looks like this:
module mycompany/mymodule
go 1.14
service.go looks as follows
package main // this has to be called 'main'
import (
"mycompany/mymodule/internal/helper"
)
func main () {
helper.greet("Jenny")
}
So, if I am in /src and I run build cmd/service.go I get
cmd/service.go:4:2: package mycompany/mymodule/internal/helper is not in GOROOT (/usr/local/Cellar/go/1.14.5/libexec/src/mycompany/mymodule/internal/helper)
Do I have to compile helper.go first? Manually? Surely not. go build surely should be able to build my entire project, right? Including all the dependencies. Could someone please tell me what I am missing?
When you run go build without specifying file path, it will look for the main function inside any .go files at current directory to start. It doesn't build entire project. But it wouldn't be a problem in this case.
You're importing wrong package. The package name to import must be mycompany/mymodule/internal not mycompany/mymodule/internal/helper.
And to invoke a function inside another package, it must be exposed to outside.
So you have to declare the function greet() as Greet()

Any useful alternative to foo.go + foo_test.go

For unit testing a Go code base, is there any reasonable alternative to the foo.go and foo_test.go pattern? The only "concern" is having all those extra files in the same place on the filesystem. It might be nice to put the test files in a central place, but that might not work due to the way Go packages work.
When you tell the go command to test a package, e.g.
go test some/path/mypackage
Then the go tool will look for test files in the package's directory. If you put the test files elsewhere, then the go tool will not find them (it will not even look for them) in other folders, so they will not be run / executed.
This argument alone is enough to not put them elsewhere.
Package doc of testing:
To write a new test suite, create a file whose name ends _test.go that contains the TestXxx functions as described here. Put the file in the same package as the one being tested.
Command go: Testing functions:
The 'go test' command expects to find test, benchmark, and example functions in the "*_test.go" files corresponding to the package under test.
Some notes:
The go tool only expects test files to be in the same folder, but you can name them however you like, you just have to use the _test.go suffix. E.g. you may have a foo.go, and you may use my_test.go for the tests. There is also no requirement to have a separate test file for each .go source files, you may put all tests into a single test file, and you may have more test files than source files.
In the test files, you may use the same package name, and then the test files are compiled together with the package so tests have access to everything–including unexported identifiers–in the package (white-box testing). You may use the package name suffixed with _test, in which case the tests in those files will only have access to the package's exported identifiers (black-box testing). Read more about this here: How can I allow one package access to another package's unexported data only when testing?
You shouldn't worry about the number of .go files. To go tool will handle even if you have a thousand .go files in a package. Although in most cases if you have many .go files in a package, that's an indication that the package is doing too much, and it should be broken into multiple, smaller packages.

No usages found in module in Goland

I'm using struct from subpackage and it works. But on find usage of this structure IDEA doesn't see usages. The same situation on rename for the structure - IDEA renames the original structure and doesn't rename it in all places of usage.
How can I fix it, because I don't want to put all go files only in one package.
go project directory like this.
projectname:
bin/
src/
structs/
custom_types.go
main.go
pkg/
Use go build command will auto create bin/pkg directory.
src directory contains all go source files.

Go project structure to produce library and cli with the same name in single repository

How to setup project structure to produce library and cli with same name in
single repository?
Suppose my project name is project. I want to make it importable with name
project and have executable binary with name project when installed with
go get. My setup currently is like this:
host.com/project/
project/
main.go
core/
project.go
Then, when installed with:
go get host.com/project/project
it installs project as executable which pulls core as dependency. In
core/project.go file, the package has this:
package project
The problem is it is imported with:
import (
"host.com/project/core"
)
And it exports project as name space not core which violates go's convention.
How can I do this?
This isn't a convention, and you may do however you like, but it's a common practice to have a cmd folder in the project root, and all the executables go under that, each in is own folder.
So a good solution in your case could be simply:
host.com/project/
cmd/
project/
project.go
filea.go
fileb.go
In filea.go and fileb.go the package declaration should be:
package project
In cmd/project/project.go package and import declaration should be:
package main
import "host.com/project"
Of course if your project is more complex, you may create further packages under the project root, and it may have multiple commands (multiple main packages), e.g.:
host.com/project/
cmd/
project/
project.go
prjtool/
prjtool.go
packagex/
x.go
packagey/
y.go
filea.go
fileb.go
An example following this layout is the very popular Go Delve debugger (4.5k stars currently), available at https://github.com/derekparker/delve.
A very complex repository example is the golang.org/x/tools package which is a collection of multiple, essential Go tools, available at https://github.com/golang/tools/. Its cmd folder contains more than 20 subfolders (commands), many of the tools (main packages) even consist of multiple .go files (but each using package main declaration, forming a single package of the executable).
Also check out the following related question: What is a sensible way to layout a Go project

Organizing a multiple-file Go project [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Note: this question is related to this one, but two years is a very long time in Go history.
What is the standard way to organize a Go project during development ?
My project is a single package mypack, so I guess I put all the .go files in a mypack directory.
But then, I would like to test it during development so I need at least a file declaring the main package, so that I can do go run trypack.go
How should I organize this ? Do I need to do go install mypack each time I want to try it ?
I would recommend reviewing this page on How to Write Go Code
It documents both how to structure your project in a go build friendly way, and also how to write tests. Tests do not need to be a cmd using the main package. They can simply be TestX named functions as part of each package, and then go test will discover them.
The structure suggested in that link in your question is a bit outdated, now with the release of Go 1. You no longer would need to place a pkg directory under src. The only 3 spec-related directories are the 3 in the root of your GOPATH: bin, pkg, src . Underneath src, you can simply place your project mypack, and underneath that is all of your .go files including the mypack_test.go
go build will then build into the root level pkg and bin.
So your GOPATH might look like this:
~/projects/
bin/
pkg/
src/
mypack/
foo.go
bar.go
mypack_test.go
export GOPATH=$HOME/projects
$ go build mypack
$ go test mypack
Update: as of >= Go 1.11, the Module system is now a standard part of the tooling and the GOPATH concept is close to becoming obsolete.
jdi has the right information concerning the use of GOPATH. I would add that if you intend to have a binary as well you might want to add one additional level to the directories.
~/projects/src/
myproj/
mypack/
lib.go
lib_test.go
...
myapp/
main.go
running go build myproj/mypack will build the mypack package along with it's dependencies
running go build myproj/myapp will build the myapp binary along with it's dependencies which probably includes the mypack library.
I have studied a number of Go projects and there is a fair bit of variation. You can kind of tell who is coming from C and who is coming from Java, as the former dump just about everything in the projects root directory in a main package, and the latter tend to put everything in a src directory. Neither is optimal however. Each have consequences because they affect import paths and how others can reuse them.
To get the best results I have worked out the following approach.
myproj/
main/
mypack.go
mypack.go
Where mypack.go is package mypack and main/mypack.go is (obviously) package main.
If you need additional support files you have two choices. Either keep them all in the root directory, or put private support files in a lib subdirectory. E.g.
myproj/
main/
mypack.go
myextras/
someextra.go
mypack.go
mysupport.go
Or
myproj.org/
lib/
mysupport.go
myextras/
someextra.go
main/
mypack.go
mypage.go
Only put the files in a lib directory if they are not intended to be imported by another project. In other words, if they are private support files. That's the idea behind having lib --to separate public from private interfaces.
Doing things this way will give you a nice import path, myproj.org/mypack to reuse the code in other projects. If you use lib then internal support files will have an import path that is indicative of that, myproj.org/lib/mysupport.
When building the project, use main/mypack, e.g. go build main/mypack. If you have more than one executable you can also separate those under main without having to create separate projects. e.g. main/myfoo/myfoo.go and main/mybar/mybar.go.
I find very useful to understand how to organize code in Golang this chapter http://www.golang-book.com/11 of the book written by Caleb Doxsey
There doesn't seem to be a standard way of organizing Go projects but https://golang.org/doc/code.html specifies a best practice for most projects. jdi's answer is good but if you use github or bitbucket and you have additional libraries as well, you should create the following structure:
~/projects/
bin/
pkg/
src/
github.com/
username/
mypack/
foo.go
bar.go
mypack_test.go
mylib/
utillib.go
utillib_test.go
By doing it this way, you can have a separate repository for mylib that can be used for other projects and can be retrieved by "go get". Your mypack project can import your library using "github.com/username/mylib". For more information:
http://www.alexvictorchan.com/2014/11/06/go-project-structure/
Keep the files in the same directory and use package main in all files.
myproj/
your-program/
main.go
lib.go
Then run:
~/myproj/your-program$ go build && ./your-program
Let's explorer how the go get repository_remote_url command manages the project structure under $GOPATH. If we do a go get github.com/gohugoio/hugo It will clone the repository under
$GOPATH/src/repository_remote/user_name/project_name
$GOPATH/src/github.com/gohugoio/hugo
This is a nice way to create your initial project path. Now let's explorer what are the project types out there and how their inner structures are organized. All golang projects in the community can be categorized under
Libraries (no executable binaries)
Single Project (contains only 1 executable binary)
Tooling Projects (contains multiple executable binaries)
Generally golang project files can be packaged under any design principles such as DDD, POD
Most of the available go projects follows this Package Oriented Design
Package Oriented Design encourage the developer to keeps the implementation only inside it's own packages, other than the /internal package those packages can't can communicate with each other
Libraries
Projects such as database drivers, qt can put under this category.
Some libraries such as color, now follows a flat structure without any other packages.
Most of these library projects manages a package called internal.
/internal package is mainly used to hide the implementation from other projects.
Don't have any executable binaries, so no files that contains the main func.
~/$GOPATH/
bin/
pkg/
src/
repository_remote/
user_name/
project_name/
internal/
other_pkg/
Single Project
Projects such as hugo, etcd has a single main func in root level and.
Target is to generate one single binary
Tooling Projects
Projects such as kubernetes, go-ethereum has multiple main func organized under a package called cmd
cmd/ package manages the number of binaries (tools) that we want to build
~/$GOPATH/
bin/
pkg/
src/
repository_remote/
user_name/
project_name/
cmd/
binary_one/
main.go
binary_two/
main.go
binary_three/
main.go
other_pkg/

Resources