服务计算作业二——GO语言TDD实践报告
教程学习
go中只能使用for来进行循环和迭代。
为一个重复字符五次的函数编写测试,并先使用最少的代码让失败的测试先跑起来(核心概念)
在工作空间下创建一个iteration文件夹,并创建repeat_test.go和repeat.go如下:
repeat_test.go:
package iteration
import "testing"
func TestRepeat(t *testing.T) {
repeated := Repeat("a")
expected := "aaaaa"
if repeated != expected {
t.Errorf("expected '%q' but got '%q'", expected, repeated)
}
}
repeat.go:
package iteration
func Repeat(character string) string {
return ""
}
结果如下:
把代码补充完整,使得它能够通过测试
修改repeat.go如下:
package iteration
func Repeat(character string) string {
var repeated string
for i := 0; i < 5; i++ {
repeated = repeated + character
}
return repeated
}
测试结果如下:
重构
主要为了让代码更加项目化、易读化,容易对相关参数进行更方便的修改。
重构repeat.go如下:
package iteration
const repeatCount = 5
func Repeat(character string) string {
var repeated string
for i := 0; i < repeatCount; i++ {
repeated += character
}
return repeated
}
基准测试
基准测试是针对系统设计的一种压力测试。
在iteration目录下创建repeat_bench_test.go并编写代码如下:
package iteration
import "testing"
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
Repeat("a")
}
}
用 go test -bench=.
来运行基准测试。
结果如下:
完成该教程迭代章节的练习
修改测试代码,以便调用者可以指定字符重复的次数,然后修复代码
修改测试代码如下,重点在于获取go test命令行参数args,然后指定字符重复的次数。代码如下:
package iteration
import "testing"
import "os"
import "strconv"
func TestRepeat(t *testing.T) {
repeated := Repeat("a")
var expected string
var b int
s, err := strconv.ParseInt(os.Args[len(os.Args)-1], 10, 32)
if err != nil {
panic(err)
}
b = int(s)
for i := 0; i < b; i++ {
expected += "a"
}
if repeated != expected {
t.Errorf("expected '%q' but got '%q'", expected, repeated)
}
}
结果如下:
写一个 ExampleRepeat 来完善你的函数文档
ExampleRepeat:
func ExampleRepeat() {
s := Repeat("a")
fmt.Println(s)
// Output: aaaaa
}
查看函数文档:
安装godoc:
go env -w GO111MODULE=on
go env -w GOPROXY="https://goproxy.io,direct"
go get golang.org/x/tools/cmd/godoc
使用命令:
godoc -http=:6060
# 浏览器打开http://127.0.0.1:6060/pkg/github.com/zzm99/iteration
看一下 strings 包。找到你认为可能有用的函数,并对它们编写一些测试。
Compare函数
func Compare(a, b string) int
比较两个字符串,相同返回0,不相同返回1
package str
import "testing"
import "strings"
func TestRepeat(t *testing.T) {
var str0, str1 string
var flag int
str0 = "hello, world!"
str1 = "hello, world!"
flag = strings.Compare(str0, str1) // 应为0
if flag != 0 {
t.Errorf("%v compare %v get flag = %d", str0, str1, flag)
}
}
Contains函数
func Contains(s, substr string) bool
s中包含substr则返回真,否则假
package str
import "testing"
import "strings"
func TestRepeat(t *testing.T) {
var str0, str1 string
var flag bool
str0 = "hello, world!"
str1 = "hello"
flag = strings.Contains(str0, str1) // 应为真
if flag != true {
t.Errorf("%v contains %v get flag = %t", str0, str1, flag)
}
}
HasPrefix函数
func HasPrefix(s, prefix string) bool
s以prefix为前缀,返回真,否则假
package str
import "testing"
import "strings"
func TestRepeat(t *testing.T) {
var str0, str1 string
var flag bool
str0 = "hello, world!"
str1 = "world"
flag = strings.HasPrefix(str0, str1) // 应为假
if flag != false {
t.Errorf("%v contains %v get flag = %t", str0, str1, flag)
}
}
理解相关概念
TDD
测试驱动开发是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。
TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程
TDD的重要目的不仅仅是测试软件,测试工作保证代码质量仅仅是其中一部分,而且是在开发过程中帮助客户和程序员去除模棱两可的需求。TDD首先考虑使用需求(对象、功能、过程、接口等),主要是编写测试用例框架对功能的过程和接口进行设计,而测试框架可以持续进行验证。
重构
重构(Refactoring)就是通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。
测试
软件测试,描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。换句话说,软件测试是一种实际输出与预期输出之间的审核或者比较过程。软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。
基准测试
基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。
选择算法进行TDD实践
此部分选择“快排”算法进行TDD实践
先写测试并运行失败测试
qsort.go:
package qsort
func qsort(s []int){
return
}
qsort_test.go:
package qsort
import "testing"
func TestQsort(t *testing.T) {
var arr = []int{5,3,2,4,1}
var expected = []int{1,2,3,4,5}
qsort(arr)
for i:=0; i<5; i++ {
if arr[i] != expected[i] {
t.Errorf("expected '%d' but got '%d'", expected[i], arr[i])
}
}
}
结果如下:
完善代码,通过测试
qsort.go:
package qsort
func qsort(s []int){
if len(s)<=0 {
return
}
tag:=s[0]
i:=0
j:=len(s)-1
for i<j {
for s[j]>tag&&i<j {
j--
}
for s[i]<tag&&i<j {
i++
}
s[i],s[j]=s[j],s[i]
}
qsort(s[:i])
qsort(s[i+1:])
}
结果如下:
基准测试
qsort_bench_test.go:
package qsort
import "testing"
func BenchmarkRepeat(b *testing.B) {
var arr = []int{5,3,2,4,1}
for i := 0; i < b.N; i++ {
qsort(arr)
}
}