知识点
1、测试
知名的第三方测试包 github.com/stretchr/testify/assert
1.1 测试文件标识:
后缀名 _test 告知 Go 编译器和工具链这是一个测试文件 Go 编译器在编译时会跳过这些文件
1.2 cmd 运行(项目目录下)
go test ./测试文件目录
-v
显示详细信息-count=1
测试的次数,官方推荐的清除缓存的方式
1.3 testify 的常用断言函数:
//assert.
// 相等
func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool
// 是否为 nil
func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
// 是否为空
func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool
// 是否存在错误
func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool
func Error(t TestingT, err error, msgAndArgs ...interface{}) bool
// 是否为 0 值
func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool
func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool
// 是否为布尔值
func True(t TestingT, value bool, msgAndArgs ...interface{}) bool
func False(t TestingT, value bool, msgAndArgs ...interface{}) bool
// 断言长度一致
func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool
// 断言包含、子集、非子集
func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool)
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool)
// 断言文件和目录存在
func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool
func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool
1.4 testing.T
混脸熟
// 获取测试名称
method (*T) Name() string
// 打印日志
method (*T) Log(args ...interface{})
// 打印日志,支持 Printf 格式化打印
method (*T) Logf(format string, args ...interface{})
// 反馈测试失败,但不退出测试,继续执行
method (*T) Fail()
// 反馈测试失败,立刻退出测试
method (*T) FailNow()
// 反馈测试失败,打印错误
method (*T) Error(args ...interface{})
// 反馈测试失败,打印错误,支持 Printf 的格式化规则
method (*T) Errorf(format string, args ...interface{})
// 检测是否已经发生过错误
method (*T) Failed() bool
// 相当于 Error + FailNow,表示这是非常严重的错误,打印信息结束需立刻退出。
method (*T) Fatal(args ...interface{})
// 相当于 Errorf + FailNow,与 Fatal 类似,区别在于支持 Printf 格式化打印信息;
method (*T) Fatalf(format string, args ...interface{})
// 跳出测试,从调用 SkipNow 退出,如果之前有错误依然提示测试报错
method (*T) SkipNow()
// 相当于 Log 和 SkipNow 的组合
method (*T) Skip(args ...interface{})
// 与Skip,相当于 Logf 和 SkipNow 的组合,区别在于支持 Printf 格式化打印
method (*T) Skipf(format string, args ...interface{})
// 用于标记调用函数为 helper 函数,打印文件信息或日志,不会追溯该函数。
method (*T) Helper()
// 标记测试函数可并行执行,这个并行执行仅仅指的是与其他测试函数并行,相同测试不会并行。
method (*T) Parallel()
// 可用于执行子测试
method (*T) Run(name string, f func(t *T)) bool
2、重构
项目目录结构
go 没有明确的目录推荐
在实际 Go 项目开发中,要灵活运用,不需要太纠结于某个目录应该怎么设计。以项目的大小、业务的复杂度、个人及团队专业技能认知的广度和深度、时间的紧迫度为准。不一定要选最好的,而是要选择最适用的方案。
Go 社区里推荐阅读下这个项目 —— golang-standards/project-layout
注意循环引用!!!
- main 包里面引入 goblog/pkg/route ,调用 route.Initialize 进行路由初始化;
- goblog/pkg/route 里 Initialize 函数加载了 goblog/routes 注册路由 routes.RegisterWebRoutes(Router);
- goblog/routes 包里加载了控制器的包 goblog/app/http/controllers
- 控制器包里再次使用了路由工具包 goblog/pkg/route !!出现循环引用问题了!!
我的理解:main包引用的项目自身写的包,不能被其他包使用,需独立出来,只供main包调用
- 贵在坚持,保持进步