Go项目的测试代码3(测试替身Test Double)

上一篇文章介绍了项目中测试代码的写法。
Go项目的测试代码2(项目运用)

这里简单的共享一下测试替身。

当我们写测试代码的时候,经常遇到一个问题。
跟别的模块或服务有依赖性,可是功能还没开发完。
或是因为各种原因(安全,白名单,内网等等…)开发环境里无法调用相应的模块。
这时候我们应该如何去写测试代码?

因此测试替身Test Double出现了。 其功能和名字一样,做替身。

测试替身Test Double的分以下类型。 Dummy, Stub, Fake, Spy, Mock

Dummy

最简单、最原始的测试替身型别。Dummy 没有实作,最常用于需要参数值但不使用它的情况。
Null 可视为是 Dummy,但真的 Dummy 是接口或基类的衍生,且完全不包含实作。

Stub

Dummy 的上一级,Stub 是接口或基类的最低限度实作。
会传回 Void 的方法通常完全不包含实作,而会传回值的方法通常会传回硬式编码的值。

Spy

测试 Spy 类似 Stub,但除了提供客户端可叫用成员的实例,
Spy 还会记录叫用了哪些成员,好让单元测试验证所叫用的成员是否符合预期。

Fake

Fake 包含更复杂的实作,通常涉及所继承型别之不同成员之间的互动。
虽然不是完整的生产实作,但 Fake 与生产实作很相似,尽管它会采取一些快捷方式。

Mock

Mock 是由 Mock 链接库动态建立 (其他通常是由测试开发人员使用程序代码来产生)。
测试开发人员永远看不到实作接口或基类的实际程序代码,但是可以设定 Mock 以提供传回值、预期要叫用的特定成员…等等。
视其中的设定而定,Mock 的行为可能会像 Dummy、Stub 或 Spy。

以上是网上流行的概念和理论。


我在项目中的运用

我开发的是在企业微信中的应用,所以需要调用企业微信的API,
用过的人应该知道,这需要登记可信域名(简单的说不能本地调用,只能发布到服务器才能调用)。
也可以用第三方工具去模拟调试,但是这么做感觉很不方便。而且Debug也相当麻烦。

我是这么处理的。

项目初期(一阶段)

直接写硬代码hardcode

一般我们都会说尽量避免写硬代码hardcode,
但是项目初期我建议大家这么写
为什么? 其实很简单。
初期我们应该把所有的精力放在自己模块的功能和稳定性
没必要在别人的接口里耗精力, 甚至去考虑怎么和其他模块做联动。

例子:

var key string
if config.AppEnv == "test" || config.AppEnv == "dev" { //测试或是开发环境的时候直接赋值
    key = "23836728366"
} else {
    key, err = (Login{}).GetKeyForLogin(ctx, code) //实际调用的接口写在这里
    if err != nil {
        return nil, err
    }
}

项目中期(二阶段)

硬代码hardcode改写函数function

可以写根据参数或设定返回不同值的方法。满足不同场景下有不同返回值的需求。

例子:

var key string
if config.AppEnv == "test" || config.AppEnv == "dev" {
    key = GetKeyForLoginForTest(ctx, code) //测试或是开发环境的时候直接赋值
} else {
    key, err = (Login{}).GetKeyForLogin(ctx, code) //实际调用的接口写在这里
    if err != nil {
        return nil, err
    }
}
func GetKeyForLoginForTest(ctx context.Context, code string) string {
    var key string
    switch code {
    case "code1":
        key = "key1"
    case "code2":
        key = "key2"
    case :
        ......
    default:
        key = "key3"
    }
    return key
}

项目后期(三阶段)

函数function升类或package

这个阶段是可选项,因为这里开始需要耗精力去管理自己的“替身”了。
根据自己的实际情况来决定要不要这么做。

例子:

type LoginTest interface {
    GetKeyForLoginForTest(ctx context.Context, code string) string
}

type SellerTest struct {
}

func (SellerTest) GetKeyForLoginForTest(ctx context.Context, code string) string {
    //销售员业务处理...
    return "SellerKey"
}

type ManagerTest struct {
}

func (ManagerTest) GetKeyForLoginForTest(ctx context.Context, code string) string {
    //业务处理...
    return "ManagerKey"
}

func BuildManagedObject(ctx context.Context, condition string) string {
    switch condition {
    case "condition1":
        return SellerTest{}
    case "condition2":
        return ManagerTest{}
    case :
        ......
    default:
        return SellerTest{}
    }
}
var key string
if config.AppEnv == "test" || config.AppEnv == "dev" {
    var loginTest LoginTest
    loginTest = BuildManagedObject(condition)
    key = loginTest.GetKeyForLoginForTest(ctx, code) //测试或是开发环境的时候直接赋值
} else {
    key, err = (Login{}).GetKeyForLogin(ctx, code) //实际调用的接口写在这里
    if err != nil {
        return nil, err
    }
}

这么做其实能解决大部分的问题。
不知道我做的项目小或范围小,总之还没有碰到过用以上方式不能解决的问题。
有什么不太恰当的部分随时欢迎指正。 



组员不愿意写测试代码而找借口的时候你可以这么说了…^^

组员:这次项目依赖性很高, 其他模块的功能还没完善, 开发都很麻烦别说写测试代码了。
我:你用过测试替身吗?可以很简单的解决这些问题。

----------------------------------------------

欢迎大家的意见和交流

email: [email protected]

博客:https://limingxie.github.io/

原文地址:https://www.cnblogs.com/limingxie/p/9131948.html

时间: 2024-09-27 04:31:21

Go项目的测试代码3(测试替身Test Double)的相关文章

使用强大的 Mockito 测试框架来测试你的代码

原文链接 : Unit tests with Mockito - Tutorial 译文出自 : 掘金翻译计划 译者 : edvardhua 校对者: hackerkevin, futureshine 这篇教程介绍了如何使用 Mockito 框架来给软件写测试用例 1. 预备知识 如果需要往下学习,你需要先理解 Junit 框架中的单元测试. 如果你不熟悉 JUnit,请查看下面的教程: www.vogella.com/tutorials/J- 2. 使用mock对象来进行测试 2.1. 单元测

第4次作业类测试代码+105032014166+张珍珍

第4次作业:准备类测试代码 类测试代码的具体要求如下: (1)设计三角形完整程序 已经完成的方法是:  String triangle(int a,int b,int c) 现在要求继续增加新的功能: 建立界面,至少包含以下元素,但不限于此: 完成面积的方法:float triangleArea(int a,int b,int c) ,完成周长的方法:int perimeter(int a,int b,int c) 要求: 1.        画出类图: 2.        完成界面和相应的功能

测试代码高亮

测试方法 测试代码 测试方法 测试代码 源代码,按Markdown语法进行默认的代码高亮的效果: let g:octopress_path = "path/to/dir" 使用octopress的代码高亮进行显示的效果: 测试语法高亮 1 let g:octopress_path = "path/to/dir" 网上的一个例子 Discover if a number is primeSource Article 1 2 3 4 5 class Fixnum def

iOS开发:XCTest单元测试(附上一个单例的测试代码)

测试驱动开发并不是一个很新鲜的概念了.在我最开始学习程序编写时,最喜欢干的事情就是编写一段代码,然后运行观察结果是否正确.我所学习第一门语言是c语言,用的最多的是在算法设计上,那时候最常做的事情就是编写了一段代码,如何编译运行,查看结果是否正确,很多时候,还得自己想很多特殊的(比如说零值,边界值)测试数据来检测所写代码.算法是否正确.那个时候,感觉还好,比较输出只是只是控制台的一个简单的数字或者字符.在学习iOS开发中,很多时候也是要测试的,这种输出是必须在点击一系列按钮之后才能在屏幕上显示出来

JUint4 简单测试代码

=======================测试示例===================== =======================被测试类===================== package com.fengke; import org.junit.Test; public class ReadNumbers { private int a; private int b; static int c; static { int c=0; } public int max(){

入门级----黑盒测试、白盒测试、手工测试、自动化测试、探索性测试、单元测试、性能测试、数据库性能、压力测试、安全性测试、SQL注入、缓冲区溢出、环境测试

黑盒测试 黑盒测试把产品软件当成是一个黑箱子,只有出口和入口,测试过程中只要知道往黑盒中输入什么东西,知道黑盒会出来什么结果就可以了,不需要了解黑箱子里面是如果做的. 即测试人员不用费神去理解软件里面的具体构成和原理,只要像用户一样看待产品就可以了. 例如银行转账功能,不需要知道转账的具体实现代码是怎样工作的,只需要把自己想象成各种类型的用户,模拟多种转账情况看系统是否能正常转账即可. 但是仅仅像用户一样去测试又是不够的.如果只做黑盒测试,必然是存在一定的风险的. 例如某个安全性较高的软件系统,

测试代码

   编写函数或类时,还可以为其编写测试.通过测试,可确定代码面对各种输入都能够按照要求那样工作. 单元测试和测试用例:   单元测试用于核实蛮熟的某个方面没有问题:测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求. 良好的测试用例考虑到了函数可能收到的各种输入,包含针对这些所有情形的测试. 全覆盖测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式.对于大型项目,要实现覆盖可能很难.所以通常,最初只要针对 代码的重要行为编写测试即可,等项目被广泛使用率再考虑全覆

实验二:关于梭哈游戏的代码的测试

实验二:关于梭哈游戏的代码的测试 一.题目简介 Github基本源代码控制方法 利用Junit4进行程序模块的测试,回归测试 编码规范的考量 C/Java等基本程序设计语言的运用. (考虑到有些同学的基础参差不齐) 实现纸牌游戏梭哈 二.个人github地址 https://github.com/qingfengsuixin/test/blob/master/ShowHand 三.所设计的模块测试用例.测试结果截图: package com.langsin.text2; import java.

Eclipse Maven生成WebService客户端代码及测试

条件: 1. Eclipse安装Axis2插件 2. 导入Web Service相关包 创建Maven项目 导入axis2相关jar包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0