Golang测试技术

发表于:2015-5-25 11:36

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bigwhite    来源:51Testing软件测试网采编

  7、竞争检测(race detection)
  当两个goroutine并发访问同一个变量,且至少一个goroutine对变量进行写操作时,就会发生数据竞争(data race)。
  为了协助诊断这种bug,Go提供了一个内置的数据竞争检测工具。
  通过传入-race选项,go tool就可以启动竞争检测。
  $ go test -race mypkg    // to test the package
  $ go run -race mysrc.go  // to run the source file
  $ go build -race mycmd   // to build the command
  $ go install -race mypkg // to install the package
  注:一个数据竞争检测的例子
  例子代码:
//testrace.go
package main
import "fmt"
import "time"
func main() {
var i int = 0
go func() {
for {
i++
fmt.Println("subroutine: i = ", i)
time.Sleep(1 * time.Second)
}
}()
for {
i++
fmt.Println("mainroutine: i = ", i)
time.Sleep(1 * time.Second)
}
}
$go run -race testrace.go
mainroutine: i =  1
==================
WARNING: DATA RACE
Read by goroutine 5:
main.func·001()
/Users/tony/Test/Go/testrace.go:10 +0×49
Previous write by main goroutine:
main.main()
/Users/tony/Test/Go/testrace.go:17 +0xd5
Goroutine 5 (running) created at:
main.main()
/Users/tony/Test/Go/testrace.go:14 +0xaf
==================
subroutine: i =  2
mainroutine: i =  3
subroutine: i =  4
mainroutine: i =  5
subroutine: i =  6
mainroutine: i =  7
subroutine: i =  8
  8、测试并发(testing with concurrency)
  当测试并发代码时,总会有一种使用sleep的冲动。大多时间里,使用sleep既简单又有效。
  但大多数时间不是”总是“。
  我们可以使用Go的并发原语让那些奇怪不靠谱的sleep驱动的测试更加值得信赖。
  9、使用静态分析工具vet查找错误
  vet工具用于检测代码中程序员犯的常见错误:
  – 错误的printf格式
  – 错误的构建tag
  – 在闭包中使用错误的range循环变量
  – 无用的赋值操作
  – 无法到达的代码
  – 错误使用mutex
  等等。
  使用方法:
  go vet [package]
  10、从内部测试
  golang中大多数测试代码都是被测试包的源码的一部分。这意味着测试代码可以访问包种未导出的符号以及内部逻辑。就像我们之前看到的那样。
  注:比如$GOROOT/src/pkg/path/path_test.go与path.go都在path这个包下。
  11、从外部测试
  有些时候,你需要从被测包的外部对被测包进行测试,比如测试代码在package foo_test下,而不是在package foo下。
  这样可以打破依赖循环,比如:
  – testing包使用fmt
  – fmt包的测试代码还必须导入testing包
  – 于是,fmt包的测试代码放在fmt_test包下,这样既可以导入testing包,也可以同时导入fmt包。
  12、Mocks和fakes
  通过在代码中使用interface,Go可以避免使用mock和fake测试机制。
  例如,如果你正在编写一个文件格式解析器,不要这样设计函数:
  func Parser(f *os.File) error
  作为替代,你可以编写一个接受interface类型的函数:
  func Parser(r io.Reader) error
  和bytes.Buffer、strings.Reader一样,*os.File也实现了io.Reader接口。
  13、子进程测试
  有些时候,你需要测试的是一个进程的行为,而不仅仅是一个函数。例如:
  func Crasher() {
  fmt.Println("Going down in flames!")
  os.Exit(1)
  }
  为了测试上面的代码,我们将测试程序本身作为一个子进程进行测试:
func TestCrasher(t *testing.T) {
if os.Getenv("BE_CRASHER") == "1" {
Crasher()
return
}
cmd := exec.Command(os.Args[0], "-test.run=TestCrasher")
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
err := cmd.Run()
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
return
}
t.Fatalf("process ran with err %v, want exit status 1", err)
}
33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号