写点什么

learn go with tests 学习笔记(一) hello world

用户头像
半亩房顶
关注
发布于: 2020 年 08 月 07 日
learn go with tests 学习笔记(一) hello world

引言

终于开始学习golang细节了,此系列笔记旨在记录学习路上遇到的一些坑,还有一些感觉需要特别注意的知识点



环境准备

IDE:goland

go version: go version go1.14.1 darwin/amd64



遇到问题

(一)cannot find main module

运行 go test 报错 `go: cannot find main module; see 'go help modules'`

  • 问题分析:其根本原因是我使用了go mod进行依赖管理,然而使用项目根目录没有go.mod文件

  • 解决办法:添加go.mod 文件,方法有二

(1)在目录中运行 go mod init

(2)如果使用的是goland ide,可以通过配置完成 https://goproxy.io,direct



知识点

(一)如何编写单元测试:

编写测试和函数很类似,其中有一些规则

  • 程序需要在一个名为 xxx_test.go 的文件中编写

  • 测试函数的命名必须以单词 Test 开始

  • 测试函数只接受一个参数 t *testing.T

现在这些信息足以让我们明白,类型为 *testing.T 的变量 t 是你在测试框架中的 hook(钩子),所以当你想让测试失败时可以执行 t.Fail() 之类的操作。



hello.go

package main

import "fmt"

func Hello() string {
return "Hello, world"
}

func main() {
fmt.Println(Hello())
}

hello_test.go

package main

import "testing"

func TestHello(t *testing.T) {
got := Hello()
want := "Hello, world"

if got != want {
t.Errorf("got '%q' want '%q'", got, want)
}
}

此时,运行go test 或者 go test hello_test.go hello.go(go test -v 则打印完整信息)即可:

// go test
PASS
ok learnGoWithTest/hello 0.005s
// go test -v
=== RUN TestHello
--- PASS: TestHello (0.00s)
PASS
ok learnGoWithTest/hello 0.006s

或者测试失败时如下:

=== RUN TestHello
TestHello: hello_test.go:10: got '"Hello, world"' want '"Hello, world11"'
--- FAIL: TestHello (0.00s)
FAIL
exit status 1
FAIL learnGoWithTest/hello 0.010s



(二)t.Helper()

hello.go

package main

import "fmt"

const englishHelloPrefix = "Hello, "

func Hello(name string) string {
if name == "" {
name = "World"
}
return englishHelloPrefix + name
}

func main() {
fmt.Println(Hello("world"))
}

hello_test.go

package main

import "testing"

func TestHello(t *testing.T) {

assertCorrectMessage := func(t *testing.T, got, want string) {
t.Helper()
if got != want {
t.Errorf("got '%q' want '%q'", got, want)
}
}

t.Run("saying hello to people", func(t *testing.T) {
got := Hello("Chris")
want := "Hello, Chris1"
assertCorrectMessage(t, got, want)
})

t.Run("empty string defaults to 'world'", func(t *testing.T) {
got := Hello("")
want := "Hello, World1"
assertCorrectMessage(t, got, want)
})
}

t.Helper() 需要告诉测试套件这个方法是辅助函数(helper)。通过这样做,当测试失败时所报告的行号将在函数调用中而不是在辅助函数内部。这将帮助其他开发人员更容易地跟踪问题。如果你仍然不理解,请注释掉它,使测试失败并观察测试输出。

输出对比:

注释掉 t.Helper()时,错误提示的行号为19,是真正抛出错误的代码行号:

=== RUN TestHello
--- FAIL: TestHello (0.00s)
=== RUN TestHello/saying_hello_to_people
TestHello/saying_hello_to_people: hello_test.go:19: got '"Hello, Chris"' want '"Hello, Chris1"'
--- FAIL: TestHello/saying_hello_to_people (0.00s)
=== RUN TestHello/empty_string_defaults_to_'world'
TestHello/empty_string_defaults_to_'world': hello_test.go:19: got '"Hello, World"' want '"Hello, World1"'
--- FAIL: TestHello/empty_string_defaults_to_'world' (0.00s)
FAIL

未注释掉 t.Helper()时,错误提示的行号为26和32,是调用包含t.Helper()代码的函数的代码行号:

=== RUN TestHello
--- FAIL: TestHello (0.00s)
=== RUN TestHello/saying_hello_to_people
TestHello/saying_hello_to_people: hello_test.go:26: got '"Hello, Chris"' want '"Hello, Chris1"'
--- FAIL: TestHello/saying_hello_to_people (0.00s)
=== RUN TestHello/empty_string_defaults_to_'world'
TestHello/empty_string_defaults_to_'world': hello_test.go:32: got '"Hello, World"' want '"Hello, World1"'
--- FAIL: TestHello/empty_string_defaults_to_'world' (0.00s)
FAIL



(三)return & switch

func Hello(name string, language string) string {
if name == "" {
name = "World"
}

return greetingPrefix(language) + name
}

func greetingPrefix(language string) (prefix string) {
switch language {
case french:
prefix = frenchHelloPrefix
case spanish:
prefix = spanishHelloPrefix
default:
prefix = englishHelloPrefix
}
return
}

一些新的概念:

* 在我们的函数签名中,我们使用了 命名返回值(prefix string)。

* 这将在你的函数中创建一个名为 prefix 的变量。它将被分配「零」值。这取决于类型,例如 int 是 0,对于字符串它是 ""。你只需调用 return 而不是 return prefix 即可返回所设置的值。

* 这将显示在 Go Doc 中,所以它使你的代码更加清晰。

* 如果没有其他 case 语句匹配,将会执行 default 分支。

* 函数名称以小写字母开头。在 Go 中,公共函数以大写字母开始,私有函数以小写字母开头。我们不希望我们算法的内部结构暴露给外部,所以我们将这个功能私有化。



引用






欢迎大家关注我的公众号,一起探讨技术



发布于: 2020 年 08 月 07 日阅读数: 60
用户头像

半亩房顶

关注

人生那么长,能写多少bug? 2018.11.16 加入

我希望,自己永远是自己。我希望,远离bug。

评论

发布
暂无评论
learn go with tests 学习笔记(一) hello world