这是我参加「第五届青训营 」伴学笔记创造活动的第 4 天

前语

记载参加青训营的每一天的日笔记

背景

测验的呈现是为了防止项目中呈现重大事端

测验是防止事端的最终一道屏障

测验

Go语言工程实践之测试 | 青训营笔记

单元测验的掩盖率在必定程度上而言,决议了代码的质量

单元测验

Go语言工程实践之测试 | 青训营笔记

经过测验单元的输出与期望值进行校正从而验证代码的正确性,从而确保新旧代码的互不影响与程序的正常运转。

从而单元测验较于编译更易于在较短的周期内发现和定位代码中的过错使丢失最小化从而提升效率。所以写单元测验是很有必要的。

Golang单元测验对文件名和办法名,参数都有很严格的要求

  • 文件名有必要以xx_test.go命名
  • 办法有必要是Test[^a-z]最初
  • 办法参数有必要t *testing.T
  • 初始化逻辑放到TestMain中
  • 使用go test履行单元测验

演示

经过第三方包assert演示单元测验

判断函数测验值与期望值是否一致

import(
    "github.com/stretchr/testify/assert"
    "testing"
)
​
func TestHelloTom(t *testing.T) {
  output := HelloTom()
  expectOutput := "Tom"
  assert.Equal(t, expectOutput, output)
}
​
func HelloTom() string {
  return "Tom"
}

掩盖率

掩盖率呈现的目的:

  • 衡量代码是否经过了足够的测验
  • 点评项目的测验水准
  • 评估项目是否达到了高水准测验等级

经过go test指令测验函数的掩盖率

// judgment.go
func JudgePassLine(score int16) bool {
  if score >= 60 {
    return true
   }
  else {
    return false
   }
}
​
// judgment_test.go
func TestJudgePassLineTrue(t *testing.T) {
  isPass := JudgeePassLine(70)
  assert.Equal(t, true, isPass)
}
​
func TestJudgePassLineFalse(t *testing.T) {
  isPass := JudgeePassLine(50)
  assert.Equal(t, false, isPass)
}
​
/*
 经过go test 指令测验掩盖率
 go test judgment_test.go judgment.go --cover
*/
  • 一般掩盖率:50%~60%,较高掩盖率:80%+

  • 测验分支彼此独立、全面掩盖

    对于上述事例代码而言

    应呈现成果大于等于60 和小于60的测验用力

  • 测验单元粒度足够小,函数单一责任

依靠

Go语言工程实践之测试 | 青训营笔记

  • 幂等:重复运转同一个case,结果与之前一致
  • 稳定:指单元测验彼此阻隔,能够独立运转

文件处理

当测验文件被修改后,可能会导致测验失败或过错率增高

从而呈现了Mock函数

func ReadFirstLine() string {
    open, err := os.Open("log") // 打开一个文件
    defer open.Close()
    if err != nil {
        return ""
    }
    scanner := bufio.NewScanner(open) // 对每行进行遍历
    for scanner.Scan() {
        return scanner.Text()
    }
    return ""
}
​
func ProcessFirstLine() string {
    line := ReadFirstLine()
    destLine := strings.ReplaceAll(line, "11", "00") // 替换11为00
    return destLine
}
​
func TestProcessFirstLine(t *testing.T) { // 履行单元测验
    firstLine := ProcessFirstLine()
    assert.Equal(t, "line00", firstLine)
}

Mock

monkey: github.com/bouk/monkey 这是一个开源的mock测验库,能够对method或许实例的办法进行mock

Monkey Patch的作用域在Runtime, 运转时经过Go的unsafe包能够将内存中函数的地址替换为运转时函数的地址,将待打桩函数或办法的完成跳转。

Mock函数不只可认为一个函数打桩 也可认为一个办法打桩

// 用函数A去替换函数B,B便是原函数,A便是打桩函数func Patch(target, replacement interface{}) *PatchGuard {
  // target便是原函数,replacement便是打桩函数
    t := reflect.ValueOf(target)
    r := reflect.ValueOf(replacement)
    patchValue(t, r)
    return &PatchGuard{t, r}
}
​
func Unpatch(target interface{}) bool {
  // 确保了在测验完毕之后需要把这个包卸载掉
    return unpatchValue(reflect.ValueOf(target))
}
​
func TestProcessFirstLineWithMock(t *testing.T) {
    monkey.Patch(ReadFirstLine, func() string {
        return "line110"
    })
    defer monkey.Unpatch(ReadFirstLine)
    line := ProcessFirstLine()
    assert.Equal(t, "line000", line)
}
// 经过patch对ReadFirstLine进行打桩mock,默认回来line110,经过defer卸载mock
// 这样整个测验函数就摆脱了本地文件的捆绑和依靠

基准测验

基准测验是指测验一段程序的功能及耗费CPU的程度;

在实践的项目开发中,经常会遇到代码功能瓶颈,为了定位问题,经常要对代码做功能分;

这时就用到了基准测验,其使用办法与单元测验类似。

  • 优化代码,需要对当时代码分析
  • 内置的测验结构供给了基准测验的能力

小结

对于今日课程而言,我将其划分红测验的重要性与分类。 当时课程余下部分为项目实战,该部分内容挑选了放置于项目笔记。 假如笔记中有过错的地方也期望掘友们能够及时的提出纠正。