Why `go test` complains undefined _test - go

I am new to Go. Why go test complains about the undefined test, while go test countdown_test.go main.go is fine?
❯ go test
# main.test
/var/folders/1z/p_x3q6b53mdf7_536x8_8h2h0000gn/T/go-build2418758029/b001/_testmain.go:13:2: cannot import "main"
/var/folders/1z/p_x3q6b53mdf7_536x8_8h2h0000gn/T/go-build2418758029/b001/_testmain.go:21:20: undefined: _test
FAIL main [build failed]
In the directory where I run the command has three files,
main.go:
package main
import (
"bytes"
"fmt"
)
func Countdown(out *bytes.Buffer) {
fmt.Fprint(out, "3")
}
countdown_test.go:
package main
import (
"bytes"
"testing"
)
func TestCountdown(t *testing.T) {
buffer := &bytes.Buffer{}
Countdown(buffer)
got := buffer.String()
want := "3"
if got != want {
t.Errorf("got %q want %q", got, want)
}
}
go.mod:
module main
go 1.17

Passed after changing the module name in go.mod file to:
module Countdown
go 1.17
Before change:
PS D:\##\##\##> go test
# main.test
C:\##\##\AppData\Local\Temp\go-build2311367811\b001\_testmain.go:13:2: cannot import "main"
C:\##\##\AppData\Local\Temp\go-build2311367811\b001\_testmain.go:21:20: undefined: _test
FAIL main [build failed]
After changing the module name:
PS D:\##\##\##> go test
PASS
ok Countdown 0.037s
Please check this refrence.
I will quote the important thing form it:
Even if you’re not at first intending to make your module available for use from other code, using its repository path is a best practice that will help you avoid having to rename the module if you publish it later.

Related

Go local module import can't be resolved by IDE linter

The code compiles fine, but when using the replace directive for mapping package name to a local directory, the Go linter can't pick this up.
I've tried this on both VSCode & Goland, both has the lint error as shown below. The image is extra information, all code & error messages are shown below in text format.
Repository: https://github.com/webberwang/go-lint-error
This is the folder structure:
/core
/calc
math.go
go.mod
/main
app.go
go.mod
// main/app.go
package main
import (
"fmt"
"github.com/codelabstudios/core/calc" <- ERROR "Cannot resolve directory 'core'"
)
func main() {
result := calc.Add(1, 2) <- ERROR "Unresolved reference 'Add'"
fmt.Println("calc.Add(1, 2) => ", result)
}
// main/go.mod
module github.com/codelabstudios/main
go 1.14
require github.com/codelabstudios/core v0.0.0-00010101000000-000000000000
replace github.com/codelabstudios/core => ../core
// core/calc/math.go
package main
import (
"fmt"
"github.com/codelabstudios/core/calc"
)
func main() {
result := calc.Add(1, 2)
fmt.Println("calc.Add(1, 2) => ", result)
}
// core/calc/go.mod
module github.com/codelabstudios/core
go 1.14
After some digging, I found out that the "replace" directive is part of the Vgo proposal (the V stands for versioning). This was merged with Go in 1.11.
To fix the local module import error, we just need to enable "Vgo Integration" in the IDE.

go test error : import path contains backslash; use slash

I got the following output upon running test in my golang project (truncated. see the complete output down below) :
import path contains backslash; use slash: "gitlab.com\\group-name\\project-name/vendor/..."
project-name is the name of the project I'm working on. The project itself run smoothly, only the test was error.
I have no idea how such an import path (containing \\) generated, who could be responsible for generating that import (is it go test?), and how should I do about fixing it?
I tried to run the test after upgrading go version from 1.6.x to 1.8, if this matter.
environment :
go version go1.8 windows/amd64
goconvey v1.6.2
glide package manager
command :
go test api_test.go
output :
# command-line-arguments
.\api_test.go:6: import path contains backslash; use slash: "gitlab.com\\group-name\\project-name/vendor/github.com/smartystreets/assertions"
.\api_test.go:6: cannot import "gitlab.com\\group-name\\project-name/vendor/github.com/smartystreets/goconvey/convey"
due to version skew - reinstall package (bad package path "gitlab.com\\group-name\\project-name/vendor/github.com/smartystreets/assertions" for package assertions)
FAIL command-line-arguments [build failed]
api_test.go : (just a random sample of goconvey for now, and still produce the error)
package test
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestIntegerStuff(t *testing.T) {
Convey("Given some integer with a starting value", t, func() {
x := 1
Convey("When the integer is incremented", func() {
x++
Convey("The value should be greater by one", func() {
So(x, ShouldEqual, 2)
})
})
})
}

My main.go file cannot see other files

I need some help understanding what is wrong with my file layout in a simple web application.
$GOPATH/src/example.com/myweb
I then have 2 files:
$GOPATH/src/example.com/myweb/main.go
$GOPATH/src/example.com/myweb/api.go
Both files have:
package main
The api.go file looks like:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
type API struct {
URI string
Token string
Secret string
client *http.Client
}
...
My main.go file looks like:
package main
import (
"github.com/gorilla/mux"
"html/template"
"net/http"
)
var (
templates = template.Must(template.ParseFiles("views/home.html", "views/history.html", "views/incident.html"))
api = API{
URI: "http://localhost:3000",
Token: "abc",
Secret: "123",
}
)
func renderTemplate(w http.ResponseWriter, tmpl string, hp *HomePage) {
..
..
}
func WelcomeHandler(w http.ResponseWriter, r *http.Request) {
..
..
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", WelcomeHandler)
r.PathPrefix("/assets/").Handler(
http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/"))))
http.ListenAndServe(":9000", r)
}
In the code I excluded, I basically use structs that are defined in my api.go file, and I get this error when doing:
go run main.go
# command-line-arguments
./main.go:16: undefined: API
./main.go:23: undefined: User
What exactly am I doing wrong here?
I tried changing the package name in api.go to myweb but that didn't help.
Am I suppose to use the package name myweb? Is just 1 file suppose to have main?
You're compiling only the main.go file. You should use:
go run main.go api.go
Or:
go run *.go
If you're writing a complex application, you might add everything to packages in subdirectories and have a single main.go file. For instance, etcd has an etcdmain subdirectory/package along with other subdirectories/packages. Something like:
/alarm
/auth
/cmd
/etcdmain
...
And the main.go file is simply:
package main
import "github.com/coreos/etcd/etcdmain"
func main() {
etcdmain.Main()
}
You are using golang workspace project, which is good for the structure for your application and it also standardize.
When we use the golang workspace, you can not run single go file. You need to call go build / go install.
Install
go install example.com/myweb
The command above will compile your main package on example.com/myweb. And the myweb executable binary will be placed on the GOPATH/bin. And you can run it manually.
Build
go build example.com/myweb
The command is similar to go install but the binary executable file will be placed on the current directory when you call the command, instead of on GOPATH/bin (unless your current directory is GOPATH/bin).
For more information please check this link.

is it possible to place test files in subfolder

When I have module and its test in the same directory it works ok.
- module1.go
- module1_test.go
But when number of files and test files grows it is hard to navigate through code.
Is it possible to place go tests to subfolder for cleaner code structure?
When I try to do it I got namespace error.
I placed file module1_test.go to folder ./test
- module1.go
- test/module1_test.go
Now I got error on testing:
test/module1_test.go:8: undefined: someFunc
My module1.go code:
package package1
func someFunc() {
}
My module1_test.go code:
package package1
import (
"testing"
)
func TestsomeFunc(t *testing.T) {
someFunc()
}
You can put the tests in another directory, but it is not common practice. Your tests will need to import the subject package and will not have access unexported methods in the subject package. This will work:
File $GOPATH/src/somepath/package1/module1.go
package package1
func SomeFunc() {
}
File $GOPATH/src/somepath/package1/test/module1_test.go
package test
import (
"testing"
"somepath/package1"
)
func TestSomeFunc(t *testing.T) {
package1.SomeFunc()
}
A couple of notes:
I changed SomeFunc to an exported method so that the test can access it.
The test imports the subject package "somepath/package1"

Golang Package Import

I am attempting to get the following code to compile:
package main
import (
"fmt"
"code.google.com/p/go.text/unicode/norm"
)
func main() {
fmt.Println(norm.IsNormalString("ŋ̊"))
}
I have installed the unicode/norm package. I compile with the command:
go build -o ipa ipa.go
Unfortunately, I get the following error:
# command-line-arguments
./ipa.go:9: undefined: norm.IsNormalString
make: *** [ipa] Error 2
It seems that the package is being imported correctly, but I cannot access any of its members. I have tried changing the method from being called to another from norm, but I still get the error. This leads me to believe that I'm fundamentally misunderstanding something about go's package system.
func (Form) IsNormalString
func (f Form) IsNormalString(s string) bool
IsNormalString returns true if s == f(s).
IsNormalString is not a function, it's a method on type Form. For example,
package main
import (
"code.google.com/p/go.text/unicode/norm"
"fmt"
)
func main() {
fmt.Println(norm.NFC.IsNormalString("ŋ̊"))
}
Output:
true

Resources