Head First Go -第14部分自动化测试


前言

自动化测试能够测试一个程序是否能正常运行,避免程序上线之后出现的各种问题


提示:以下是本篇文章正文内容,下面案例可供参考

1. 一个应该有自动化测试的函数

首先我们来写一个函数,这个函数的作用是把几个字符串连接成一个大的字符串

//join.go
package prose

import "strings"

func JoinWithCommas(phrases []string) string {
	result := strings.Join(phrases[:len(phrases)-1], ", ")	//对于第一个集合里面的参数使用第二个参数进行连接
	result += ", and " //在最后一个单词之前插入and
	result += phrases[len(phrases)-1]
	return result
}

package main

import (
	"fmt"
	"mycode/prose"
)

func main() {
	phrases := []string{"my parents", "a rodeo clown"}
	fmt.Println("A photo of", prose.JoinWithCommas(phrases))
	//A photo of my parents, and a rodeo clown
	
	phrases = []string{"my parents", "a rodeo clown", "a prize bull"}
	fmt.Println("A photo of", prose.JoinWithCommas(phrases))
	//A photo of my parents, a rodeo clown, and a prize bull
}

其实对于三个的情况是没问题的,但是对于两个参数,就有问题了,我举个例子:比如传入的参数是a,b,c,那么组成的string就是 this is a, b, and c,而传入a,b的时候组成的参数是this is a and b,但是上面的例子很明显不符合两个参数的需求,因为多了一个逗号,但是去掉逗号又不满足三个参数的需求,所以我们可以通过自动化测试来测试出这些问题



2. 编写测试

Go包含一个testing包,可以用来进行自动化测试,还有一个go test命令。

package main

import "testing"

func TestTwoElements(t *testing.T){
	t.Error()
}

func TestThreeElements(t *testing.T){
	t.Error("no test here either")
}
  • go 的Test函数以Test开头
  • 不需要把测试和正在测试的代码放在一个包中,但是如果需要导出,就要放到同一个包
  • 测试需要使用testing包中的类型,需要导入
  • 测试函数应该接收单个参数:一个执行testing.T的指针
  • 可以通过testing.T值调用方法例如(Error)来报告测试失败



3. 使用 go test

go test + 包名可以测试go root下面某个包的go测试文件

package main

import "testing"

func TestTwoElements(t *testing.T){
	t.Error()
}

func TestThreeElements(t *testing.T){
	t.Error("no test here either")
}

在这里插入图片描述

删除掉Error,就可以看到测试成功了
在这里插入图片描述



4. 现在使用test来测试我们的拼接函数

package main

import (
	"mycode/prose"
	"testing"
)

func TestTwoElements(t *testing.T) {
	list := []string{"apple", "orange"}
	s := prose.JoinWithCommas(list)
	if s != "apple and orange" {
		t.Error("didn't match expected value - 1")
	}
}

func TestThreeElements(t *testing.T) {
	list := []string{"apple", "orange", "pear"}
	s := prose.JoinWithCommas(list)
	if s != "apple, orange, and pear" {
		t.Error("didn't match expected value - 2")
	}
}

在这里插入图片描述
可以看到经过测试,第一个方法就发生了错误,这样我们就可以看到传入两个参数是不符合我们的要求的。



5. 使用Errorf获取更详细的测试失败信息

Errorf 函数接收一个带格式化动词的字符串,就像fmt.Printf 和 fmt.Sprintf 函数一样。

package main

import (
	"mycode/prose"
	"testing"
)

func TestTwoElements(t *testing.T) {
	list := []string{"apple", "orange"}
	want := "apple and orange"
	got := prose.JoinWithCommas(list)
	if got != want {
		t.Errorf("TestTwoElements(%#v) = \"%s\", want \"%s\"", list, got, want)
	}
}

func TestThreeElements(t *testing.T) {
	list := []string{"apple", "orange", "pear"}
	want := "apple, orange, and pear"
	got := prose.JoinWithCommas(list)
	if got != want {
		t.Errorf("TestTwoElements(%#v) = \"%s\", want \"%s\"", list, got, want)
	}
}

我们使用这个来替换原来的t.Error("didn't match expected value - 2"),这样就可以看到详细的详细了
在这里插入图片描述


6. 抽离出函数

其实对于test里面那些方法,我们希望将具体Error内容抽离出来形成一个函数,这样调用起来就方便一点

package main

import (
	"mycode/prose"
	"testing"
	"fmt"
)

func TestTwoElements(t *testing.T) {
	list := []string{"apple", "orange"}
	want := "apple and orange"
	got := prose.JoinWithCommas(list)
	if got != want {
		t.Error(errString(list, got, want))
	}
}

func TestThreeElements(t *testing.T) {
	list := []string{"apple", "orange", "pear"}
	want := "apple, orange, and pear"
	got := prose.JoinWithCommas(list)
	if got != want {
		t.Error(errString(list, got, want))
	}
}

func errString(list[] string, got string, want string) string{
	return fmt.Sprintf("JoinWithCommas(%#v) = \"%s\", want \"%s\"", list, got, want)
}

在这里插入图片描述



7. 修复字符串拼接函数

而对于这个错误,要修复也很简单,我们只需要判断当len(list) == 2的时候单独处理就行了,同样的你会发现当长度只有1的时候也会出问题,这时候我们也是只需要单独处理len(list) == 1的情况

package prose

import "strings"

func JoinWithCommas(phrases []string) string {
	if len(phrases) == 1{
		return phrases[0]
	}else if len(phrases) == 2{
		return phrases[0] + " and " + phrases[1]
	}else{
		result := strings.Join(phrases[:len(phrases)-1], ", ")	//对于第一个集合里面的参数使用第二个参数进行连接
		result += ", and " //在最后一个单词之前插入and
		result += phrases[len(phrases)-1]
		return result
	}
	
}



8. 运行特定的测试集

有时候我们不需要测试整个集合,而是只想运行几个特定的测试,go test 也提供了对应的指令来帮我们测试。首先我们另外创建一个测试文件:记住文件名以test结尾,否则go不认为这是一个测试文件

package test

import (
	"fmt"
	"testing"
)

func TestFirstLarger(t *testing.T) {
	want := 2
	got := Larger(2, 1)
	if got != want {
		t.Error(myError(want, got))
	}
}

func TestSecondLarger(t *testing.T) {
	want := 8
	got := Larger(4, 8)
	if got != want {
		t.Error(myError(want, got))
	}
}

func myError(want int, got int) string {
	return fmt.Sprintf("预测结果: %v, 实际结果: %v", want, got)
}

func Larger(a int, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

首先,-v 表示输出详细的测试信息
在这里插入图片描述

然后,-v -run 名称 表示运行方法中包括指定名称的方法,所以运行某个特定的方法就 go run 文件夹 -v -run 方法名
在这里插入图片描述
在这里插入图片描述





如有错误,欢迎指出!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《Head First设计模式-深入浅出设计模式》是一本以简单有趣的方式介绍设计模式的书籍。设计模式是在软件开发中解决特定问题的一种经验总结,它们提供了在实际开发中可重用、可靠、灵活的解决方案。 该书的主要特点是通过生动有趣的讲解和丰富多样的图表、示例来帮助读者更好地理解和应用设计模式。作者采用了大量的图形和实例来解释设计模式的概念,使读者能够迅速理解并应用这些概念。 这本书涵盖了23种常用的设计模式,如工厂模式、单例模式、适配器模式、装饰器模式等。每一种设计模式都以一个实际的例子开始,引出该模式解决的问题,然后详细解释其结构和应用,最后通过示例代码展示如何使用该模式。 此外,该书还介绍了设计模式之间的关系和如何选择合适的设计模式。它教授了读者如何在具体问题中识别出适用的设计模式,并提供了一些实际的应用建议。 《Head First设计模式-深入浅出设计模式》以其独特的教学风格和简洁明了的讲解深受读者喜爱。这本书不仅适合初学者了解设计模式,也适合有一定经验的开发人员进一步提高他们的软件设计和编程能力。 总之,这本书以其生动有趣的讲解方式和大量的图表、实例为读者介绍了设计模式的基本概念和具体应用,是学习和理解设计模式的一本不可或缺的指南。 ### 回答2: 《Head First设计模式:深入浅出设计模式》是一本主要介绍软件设计模式的书籍。设计模式是在软件开发中经常出现的问题的解决方案,可以帮助开发人员更好地构建可重用、可扩展、可维护的代码。 这本书以深入浅出的方式介绍了23种常见的设计模式,通过生动有趣的讲解和大量的图形和实例,使读者能够更加轻松地理解和掌握设计模式。它采用了非传统的学习方式,通过讲故事、练习、谜题等方式将设计模式的概念和使用方法娓娓道来。 该书首先从简单的设计模式开始,引导读者逐步理解和掌握基础的设计原则和模式,如单例模式、工厂模式等。然后,逐渐深入介绍更复杂的模式,如装饰器模式、观察者模式、策略模式等。每个模式都通过具体的案例和代码示例进行讲解,帮助读者理解模式的思想和应用场景。 除了具体的设计模式之外,这本书还关注了如何将设计模式应用到现实的软件开发中。它探讨了如何根据不同的需求选择合适的设计模式,以及如何通过设计模式提高代码的质量和可维护性。 总的来说,《Head First设计模式:深入浅出设计模式》是一本非常有趣、易懂且实用的设计模式入门书籍。无论是初学者还是有一定经验的开发人员,都能从中获得有益的知识和经验,提高软件开发的能力和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值