06单元测试

不写测试的开发不是好程序员,我个人非常崇拜TDD Test Driven Development 的,然而可惜的是国内的程序员

都不太关注测试这一部分,这篇文章主要介绍下在Go语言中如何做单元测试和基准测试。

go test 工具

Go 语言中的测试依赖go test 命令。编写测试代码和编写普通的Go代码过程是类似的,并不需要学习新的语法。

规则或工具

go test 命令是一个按照一定约定和组织的测试代码的驱动程序,在包目录内,所有以——test,go 为后缀名

的源代码文件都是 go test 测试的一部分,不会被go build 编译到最终的可执行文件中。

在 *_test.go 文件中有三种类型的函数,单元测试函数、基准测试函数和示例函数。

测试函数 函数名前缀为Test 测试程序的一些逻辑行为是否正确

基准函数 函数名前缀为Benchmark 测试函数的性能

示例函数 函数名前缀为Example 为文档提供示例

go test 命令会遍历所有的*_test.go文件汇总符合上述命名规则的函数,然后生成一个临时的main包用于

调用相应的测试函数,然后构建并运行,报告测试结果,最后清理测试中生成的临时文件

Conytext 初识

Go1.7加入了一个新的标准库context,它定义了 Context类型,专门用来简化对于处理单个请求的多个goroutine之间

与请求域的数据,取消信号。截止时间等相关操作,这些操作可能涉及多个API调用。

对服务器传入的请求应该创建上下文,而对服务器的传出调用应该接受上下文。他们之间的函数调用链必须传递上下文,或者可以使用WithCancel WithDeadline 

WithTimeout 或WithValue创建的派生上下文,当一个上下文被取消时,它派生的所有上下文也被取消

Context接口

contexty.Context 是一个接口,改接口定义了四个需要实现的方法,具体签名如下:

type Context interface {

  Deadline() (deadline time.Time, ok bool)

  Done() <- chan struct{}

  Err() error

  Value(key interface{}) interface{}

}

其中

Deadline 方法需要返回当前Context被取消的时间,也就是完成工作的截止时间deadline

Done方法需要返回一个Channel ,这个Channel会在当前工作完成或者上下文被取消之后关闭,多次调用

Done方法会范湖同一个Channel;

Err方法会返回当前Context结束的原因,它只会在Done返回的Channel被关闭时才会返回非空的值;

如果当前的Context被取消就会返回Canceled错误;

如果当前Context超时就会返回DeadlineExceeded错误;

Value方法会从Context中返回键对应的值,对于同一个上下文来说,多次调用Value并传入相同的Key

会返回相同的结果,该方法仅用于传递跨API和进程间跟请求域的数据;

Background() 和TODO()

Go内置两个函数:Background()和TODO(),这两个函数分别返回了一个实现了Context接口的background

和todo.我们代码中最开始都是以这两个内置的上下文对象作为最顶层的partent context ,衍生出更多的子

上下文对象。

Background() 主要用于main函数,初始化以及测试代码中,作为Context这个树结构的最顶层的Context,也就是

Context.

TODO() 它目前还不知道具体的使用场景,如果我们不知道该使用什么Context的时候,可以使用这个

background 和 todo 本质上都是emptyCtx 结构体类型,是一个不可取消,没有设置截止时间,没有携带任何值得

Context。

With系列函数

此外,context 包中还定义了四个With系列函数。

WithCancel 

返回带有新Done通道的父节点的副本。当调用返回的cancel函数或当关闭父上下文的Done通道时,将关闭返回上下文的Done通道,无论先发生什么情况。

取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel

WithDeadline

返回父上下文的副本,并将deadline调整为不迟于d,如果父上下文的deadline已经早于d,则WithDeadline(

parent,d)在语义上等同于父上下文。当截止日过期时,调用返回的cancel函数时,或者当父上下文的Done

通道关闭时,返回上下文的Done通道即将关闭,以最先发生的情况为准。

取消此上下文将释放与其关联的资源,因此代码应该在此上下文中运行的操作完成后立即调用cancel

WithTimeout

取消此上下文将释放与其相关的资源,因此代码应该在此上下文中运行的操作完成后理解调用

cancel,通常用于数据库或者网络连接的超时控制。

WithValue

返回父节点的副本,其中与key关联的值为val.

仅对api和进程间传递请求域的数据使用上下文,而不是使用它来传递可选参数给函数。

所提供的健必须是可以比较的,并且不应该是string类型或任何其他内置类型,以避免使用上下文在包之间

发生冲突。withValue 的用户应该为健定义自己的类型。为了避免在分配给interface {} 时进行分配,上下文

健通常具有具体类型struct{} 。或者,导出的上下文关键变量的静态类型应该是指针或接口。

使用Context的注意事项

推荐以参数的方式显示传递Context

以Context作为参数的函数方法,应该把Context作为第一个参数。

给一个函数方法传递Context的时候,不要传递nil,如果不知道传递什么,就是用context.TODO()

Context的Value相关方法应该传递请求域的必要参数,不应该用于传递可选参数

Context 是线程安全的,可以放心的在多个goroutine 中传递

Zookeeper

是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的

实现,它是集群的管理者,监视者集群中各个节点的状态根据节点提交的反馈进行

下一步合理操作。最终,将简单易用的接口和性能高效、功能稳定的系统提供给用户

 

posted @ 2021-01-20 16:07  zhangsima  阅读(83)  评论(0编辑  收藏  举报