项目中如何应用单元测试-集成测试

来源:互联网 发布:电子挂历制作软件 编辑:程序博客网 时间:2024/06/07 14:06

boss要求我们先写测试,再写代码。但是对于单元测试集成测试总是没有明确的概念,分不清两者的边界。根据个人理解记录如下,如有错误,望指正:


一.单元测试


1.概念

单元测试(又称为模块测试)是指对软件中的最小可测试单元进行检查和验证。例如一个求和方法就是一个测试单元:

public int add(int a, int b) {        return a + b;    }

程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。(个人觉得要根据实际情况去判定,例如假设规定Service的一个方法就是一个单元,那么这也就是某种意义上的单元测试。)

通常来说,如果一个测试包括以下任何一个情形,它就不是一个单元测试:

1. 需要连接数据库;2. 需要网络通信;3. 需要与文件系统打交道;4. 不能和其它单元测试同时运行;5. 需要对环境进行一些配置(如编辑配置文件)才能运行它。”

2.示例

//MyMath is used to 做数学运算public class MyMath {    public int add(int a, int b) {        return a + b;    }}
//MyMathTest is used to 测试MyMathpublic class MyMathTest {    private MyMath myMath;    @Before    public void createMyMath() {        myMath = new MyMath();    }    //测试add方法    @Test    public void test_add() {        int a = 1, b = 3;        int c = myMath.add(a, b);        assertEquals(4, c);    }}

注意命名规范,MyMath–> MyMathTest,add –> test_add


补充(多读几遍就能理解了,为mock测试打下基础)

在单元测试时,如果模块不是独立的程序,需要辅助测试模块:驱动模块或桩模块。

1. 驱动模块:用来模拟被测模块的上一级模块,相当于被测模块的主程序。它接收测试数据,把这些数据传递给所测试模块,最后再输出测试结果。

2. 桩模块:为被测模块编制的模拟其下级模块功能的“替身”模块(用来代替所测模块调用的子模块),接收或传递被测模块的数据。


二.集成测试


1.概念

集成测试(组装测试或联合测试):在单元测试的基础上(集成测试的对象是已经经过单元测试的软件单元),交所有模块按照设计要求,组装成为子系统进行的测试活动。

集成测试是指一个应用系统的各个部件的联合测试,以决定他们能否在一起共同工作并没有冲突。部件可以是代码块、独立的应用、网络上的客户端或服务器端程序。这种类型的测试尤其与客户服务器和分布式系统有关。一般集成测试以前,单元测试需要完成。

例如现在有个应用方法(功能方法)A方法,A调用B方法和C方法。B和C为单元模块。示例如下:

public class FeatureA {    /**     * @Desc    功能A     * @Auth    kingboy--KingBoyWorld@163.com     * @Date    2017/6/6 16:19     * @Version V1.0     */    public void methodA() {        methodB();        methodC();        System.out.println("A Feature");    }    /**     * @Desc    单元模块B     * @Auth    kingboy--KingBoyWorld@163.com     * @Date    2017/6/6 16:18     * @Version V1.0     */    public void methodB() {        System.out.println("B Unit");    }    /**     * @Desc    单元模块C     * @Auth    kingboy--KingBoyWorld@163.com     * @Date    2017/6/6 16:18     * @Version V1.0     */    public void methodC() {        System.out.println("C Unit");    }}

个人理解1:集成测试就是对各种小的Function组合成的Feature进行测试,来确保功能组合后是没有问题的。一些单元虽然能够单独地工件,但并不能保证连接起来也能正常的工作。一些局部反映不出来的问题,在全局上可能暴露出来。

为了加强理解,来个示意图了解系统的一般架构。


2.目的

  • 发现单元之间接口的错误
  • 发现集成后的软件同软件需求不一致的地方。

3.集成测试方法

1. 自顶向下

对任何系统几乎都可以采用这一策略。该策略是从低层次的、相互之间依赖性最步的模块开始的,可以用驱动程序来测试这些模块。这种策略能用来逐步建立系统,或者首先并行地建立起子系统,然后集成为一个完整系统。这种集成可以从开发过程的早期就开始进行。当然,如果项目计划中模块提交也是采用自下而上的方式,那么采用这种方法就能够尽早检测出接口问题,而且这些接口问题也比较容易被隔离,因此解决起来成本就低。其主要缺点是需要使用许多驱动程序来执行这一策略,而且因为测试需要迭代,所以也是一种非常耗时的策略。

2. 自底而上

这种策略由系统的控制结构来引导。控制结构按照自上向下的顺序开发,这也提供了从上层控制模块开始,自上而下集成模块的能力。对每一个新的层次,位于同一层次的相关模块被集成起来并得到测试。还不存在的模块角色可以用占位来实现。采用该集成策略的一个缺点是:如果需求发生了变化,变化对底层模块产生影响,从而也将导致上层模块需要更改。这可能导致需要(部分)重新开始集成以及测试过程。另一个缺点是用于测试每个集成步骤所必须用的占位数目很大。如果在早期从上层模块开始集成测试,即使采用占位来替代系统的主要部件。仍然可以观察到整个系统的概貌以及工作方式。


个人理解2:集成测试是一个测试过程,这个过程分为自顶向下和自底而上两种方式。怎么理解呢?伪代码如下:

public void A(){    B();    C();    D();}public void B(){    E();}public void C(){}public void D(){    F();}public void E(){}public void F(){}

A调用B、C、D,B调用E,D调用F,C、E、F为单元方法(已经成功进行单元测试)。

那么集成测试按照自顶向下测试流程为:

深度优先:A-B-E-C-D-F

宽度优先:A-B-C-D-E-F

图略

那么集成测试按照自底向上测试流程为:

E-C-F-B-D-A


个人理解3(理解不对的地方,请指教):

单元测试主要针对的是一个单元(方法、java类)中的代码逻辑是否正确。而集成测试主要是针对一个功能块(或者一个子系统)和项目的需求是否一致,以及附带测试有没有代码逻辑性的错误。

参考:

如果解决测试之痛<特别是单元、集成测试之痛>

持续集成之“测试三角形与分段构建策略原则

原创粉丝点击