单元测试_单元测试框架 - CSDN
单元测试 订阅
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在像C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。 展开全文
单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在像C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。
信息
性    质
概念
外文名
unit testing
释    义
对最小可测试单元进行检查和验证
中文名
单元测试
单元测试详解
单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,你可能把一个很大的值放入一个有序list 中去,然后确认该值出现在list 的尾部。或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。我认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈我的看法。一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以我的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。
收起全文
精华内容
参与话题
  • 单元测试

    千次阅读 2018-12-26 20:58:09
    什么是单元测试单元测试是开发人员编写,用于测试自己的代码在特定条件下的检测,验证代码的正确性。 单元测试作用。 单元测试是为了保证代码的正确性,代码开发比较复杂,没有人可以保证自己的代码没有任何问题...


    什么是单元测试?
    单元测试是开发人员编写,用于测试自己的代码在特定条件下的检测,验证代码的正确性。
    单元测试作用。
    单元测试是为了保证代码的正确性,代码开发比较复杂,没有人可以保证自己的代码没有任何问题,功能也完整可用,需要通过不同的途径来验证代码的正确性。单元测试就是其中的方式之一。
    单元测试自我总结技巧

    我最近使用的单元测试的框架是testNg
    1. mock的使用

    Mock可以用来mock类,也可以用来mock方法。Mock类有常规的类,还静态类,mock的方法有啥,现在想想也忘记了,感觉没啥区别。其他待补充
    Mock常规的类,例如:
    ProceedingJoinPoint point  = PowerMockito.mock(ProceedingJoinPoint.class);
    MethodSignature signature  = PowerMockito.mock(MethodSignature.class);
    静态类:
    PowerMockito.mockStatic(AnnotationParseUtil.class);
    Mock静态类需要加注解@PrepareForTest({AnnotationParseUtil.class }),如果一个测试类有多个静态类需要mock,那需要mock的静态类用逗号分割就可以了,比如这个注解为@PrepareForTest({AnnotationParseUtil.class,TimeUtil.class})

    Mockito方法:Mockito.when(类实例.方法名(参数)) .thenReturn(返回值实例);
    其中返回值的实例就是原方法的返回值类型的一个实例。
    如果在mock过程中,遇到一些需要特殊参数的方法,或者无法手动编造的参数,可用Mockito.any() 或Mockito.anyString() 或 Mockito.anyList() 等等,具体用什么参数代替,可以去Mockito的父类Matchers里面去找一下,可以说大部分都能找到。

    2. 私有方法的单元测试
    使用反射来调用私有化方法,
    //获取被测试类的class对象
    Class clazz = healthCheckService.getClass();
    try {
    //getDeclaredMethod() :获取需要被测试的函数名 && getMethod():只可获取公共的方法
    Method addMethod = clazz.getDeclaredMethod("sendSmsAndUpdateAlarmStatus", String.class, String.class);
    // 对所有属性设置访问权限 当类中的成员变量为private时 必须设置此项true
    addMethod.setAccessible(true);//设置该方法可见
    //调用被测试函数
    addMethod.invoke(healthCheckService, deviceId, alertSendContent);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }

    3. 对于try catch 的覆盖

    在@Test后面加上类似的(expectedExceptions = NullPointerException.class),catch到什么异常就在注解里抛什么异常。多写几个同样的方法(不同名),抛出不同的异常,那所有的异常都可以覆盖了。

    展开全文
  • 菜鸟学Java——如何更好的进行单元测试——JUnit

    万次阅读 多人点赞 2018-10-05 11:22:31
    从软件开发的过程分为:单元测试、集成测试、确认测试、验收、回归等。   在众多的分类中,与开发人员关系最紧密的莫过于单元测试了。像其他种类的测试基本上都是由专门的测试人员来完成,只有单元测试是完全由...

    测试在软件生命周期中的重要性,不用我多说想必大家也都非常清楚。软件测试有很多分类,从测试的方法上可分为:黑盒测试、白盒测试、静态测试、动态测试等;从软件开发的过程分为:单元测试、集成测试、确认测试、验收、回归等。

     

    在众多的分类中,与开发人员关系最紧密的莫过于单元测试了。像其他种类的测试基本上都是由专门的测试人员来完成,只有单元测试是完全由开发人员来完成的。那么今天我们就来说说什么是单元测试,为什么要进行单元测试,以及如更好的何进行单元测试。

     

    什么是单元测试?

    单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。比如我们可以测试一个类,或者一个类中的一个方法。

     

    为什么要进行单元测试?

    为什么要进行单元测试?说白了就是单元测试有什么好处,其实测试的好处无非就是减少bug、提高代码质量、使代码易于维护等。单元测试有什么好处请看一下百度百科中归纳的四条:

     

    1、它是一种验证行为。
    程序中的每一项功能都是测试来验证它的正确性。它为以后的开发提供支援。就算是开发后期,我们也可以轻松的增加功能或更改程序结构,而不用担心这个过程中会破坏重要的东西。而且它为代码的重构提供了保障。这样,我们就可以更自由的对程序进行改进。


    2、它是一种设计行为。
    编写单元测试将使我们从调用者观察、思考。特别是先写测试(test-first),迫使我们把程序设计成易于调用和可测试的,即迫使我们解除软件中的耦合。


    3、它是一种编写文档的行为。
    单元测试是一种无价的文档,它是展示函数或类如何使用的最佳文档。这份文档是可编译、可运行的,并且它保持最新,永远与代码同步。


    4、它具有回归性。
    自动化的单元测试避免了代码出现回归,编写完成之后,可以随时随地的快速运行测试。

     

    如何更好的进行单元测试?

     

    在讨论如何更好的进行单元测试之前,先来看看我们以前是怎么测试代码的。

    以前是这样测试程序的:

    public int add(int x,int y) {
    	return x + y;
    }
    	
    public static void main(String args[]) {
    	int z = new Junit().add(2, 3);
    	System.out.println(z);
    }

     

    如上面所示,在测试我们写好的一个方法时,通常是用一个main方法调用一下我们要测试的方法,然后将结果打印一下。现在看来这种方式已经非常out了,所以出现了很多单元测试的工具,如:JUnit、TestNG等。借助它们可以让我们的单元测试变得非常方便、高效。今天就说说如何利用JUnit进行单元测试。

     

     

    我们新建一个Java Project以便进行演示,至于Java Project怎么创建我就不在此赘述了,如果连怎么建Java Project,那你还不适合看这篇文章。建好以后在该项目的“src”目录上右击,选择new——》JUnit Test Case,然后按下图填写必要信息:

     

    填写好包名和类名(选择New JUnit 4 Test),点击最下面的那个“Browse”按钮来选择需要测试的类:

     

    手动输入我们要测试的类,选择该类,点击“OK”,回到第一张图的界面,然后点击“Next”,来到下图:

     

    勾选要测试的方法,点击“Finish”,这样我们的JUnit测试实例就建好了。然后就可以写具体的测试了:

    package com.tgb.junit.test;
    
    //静态引入
    import static org.junit.Assert.*;
    import static org.hamcrest.Matchers.*;
    
    import org.junit.Test;
    
    import com.tgb.junit.Junit;
    
    public class JUnitTest {
    
    	@Test
    	public void testAdd() {
    		int z = new  Junit().add(2, 3);
    		assertThat(z , is(5));
    	}
    
    	@Test
    	public void testDivide() {
    		int z = new Junit().divide(4, 2);		
    		assertThat(z, is(2));
    	}
    }
    


    写好以后,右击该类选择“Run As”——》“JUnit Test”,出现下图代表测试通过:

     

    到这里,可能有人会有疑问,JUnit跟用main方法测试有什么区别呢?

    首先,JUnit的结果更加直观,直接根据状态条的颜色即可判断测试是否通过,而用main方法你需要去检查他的输出结果,然后跟自己的期望结果进行对比,才能知道是否测试通过。有一句话能够很直观的说明这一点——keeps the bar green to keeps the code clean。意思就是说,只要状态条是绿色的,那么你的代码就是正确的。

    第二点,JUnit让我们同时运行多个测试变得非常方便,下面就演示一下如何进行多实例测试:

    首先我们要再建一个待测试类,然后再建一个对应的JUnit测试实例,步骤略。然后在我们测试实例的包上右击选择“Run As”——》“Run Configurations”,如下图;

     

    选择第二项“Run all tests in the selected project, package or source folder”,然后点击“Run”效果如下:

     

    可以看到,我们本次测试了两个类,共三个方法,这种方便的效果在测试实例越多的情况下,体现的越明显。至于main方法运行多个测试,想想就觉得非常麻烦,这里就不演示了。

     

    JUnit除了可以测试这些简单的小程序,还可以测试Struts、JDBC等等,这里只是用这个小程序做过简单的介绍。本实例使用的是hamcrest断言,而没有使用老的断言,因为hamcrest断言更加接近自然语言的表达方式,更易于理解。

     

    本实例需要引入以下三个jar包:

    hamcrest-core-1.3.jar
    hamcrest-library-1.3.jar
    junit-4.10.jar

     

    最后附上常用hamcrest断言的使用说明:

    数值类型
    //n大于1并且小于15,则测试通过
    assertThat( n, allOf( greaterThan(1), lessThan(15) ) );
    //n大于16或小于8,则测试通过
    assertThat( n, anyOf( greaterThan(16), lessThan(8) ) );
    //n为任何值,都测试通过
    assertThat( n, anything() );
    //d与3.0的差在±0.3之间,则测试通过
    assertThat( d, closeTo( 3.0, 0.3 ) );
    //d大于等于5.0,则测试通过
    assertThat( d, greaterThanOrEqualTo (5.0) );
    //d小于等于16.0,则测试通过
    assertThat( d, lessThanOrEqualTo (16.0) );
    
    字符类型
    //str的值为“tgb”,则测试通过
    assertThat( str, is( "tgb" ) );
    //str的值不是“tgb”,则测试通过
    assertThat( str, not( "tgb" ) );
    //str的值包含“tgb”,则测试通过
    assertThat( str, containsString( "tgb" ) );
    //str以“tgb”结尾,则测试通过
    assertThat( str, endsWith("tgb" ) ); 
    //str以“tgb”开头,则测试通过
    assertThat( str, startsWith( "tgb" ) ); 
    //str忽略大小写后,值为“tgb”,则测试通过
    assertThat( str, equalToIgnoringCase( "tgb" ) ); 
    //str忽略空格后,值为“tgb”,则测试通过
    assertThat( str, equalToIgnoringWhiteSpace( "tgb" ) );
    //n与nExpected相等,则测试通过(对象之间)
    assertThat( n, equalTo( nExpected ) ); 
    
    collection类型
    //map中包含key和value为“tgb”的键值对,则测试通过
    assertThat( map, hasEntry( "tgb", "tgb" ) );
    //list中包含“tgb”元素,则测试通过
    assertThat( iterable, hasItem ( "tgb" ) );
    //map中包含key为“tgb”的元素,则测试通过
    assertThat( map, hasKey ( "tgb" ) );
    //map中包含value为“tgb”的元素,则测试通过
    assertThat( map, hasValue ( "tgb" ) );

     

     

     

    展开全文
  • 单元测试的目的及使用

    千次阅读 2019-07-05 14:46:06
    如何编写单元测试 燕双龙 一 单元测试简介 单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节。也是唯一需要编写代码才能进行测试的一种测试方法。在标准的开发过程中,单元测试的代码与实际...

    如何编写单元测试

    燕双龙

    一 单元测试简介
    单元测试是代码正确性验证的最重要的工具,也是系统测试当中最重要的环节。也是唯一需要编写代码才能进行测试的一种测试方法。在标准的开发过程中,单元测试的代码与实际程序的代码具有同等的重要性。每一个单元测试,都是用来定向测试其所对应的一个单元的数据是否正确。

    单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。

    单元测试还具有一下几个好处:

    能够协助程序员尽快找到BUG的具体位置

    能够让程序员对自己的程序更有自信

    能够让程序员在提交项目之前就将代码变的更加健壮

    能够协助程序员更好的进行开发

    能够向其他程序员展现你的程序该如何调用

    能够让项目主管更了解系统的当前状况

    1.1 能够协助程序员尽快找到BUG的具体位置
    在没有单元测试的时代,我们大多数的错误都是通过操作页面的时候发现的。当我们发现一个错误的时候,会根据异常抛出的地点来确定是哪段代码出现了问题。但是大多数时候,我们不会所有方法中都使用Try块去处理异常(这一也是低效的)。因此一旦发现一个异常通常都是最顶层代码抛出的,但是错误往往又是在底层很深层次的某个对象中出现的。当我们找到了这个最初抛出异常的方法的时候,我们可能无法得知这段代码到底是哪里出了问题。只能逐行代码的去查找,一旦这个方法中使用的某个对象在外部有注册事件或者有其他的操作正在与当前方法同步进行,那么就更难发现错误真正的原因了。

    有经验的程序员也会知道,大多数的时候,我们并不是真正的在编写新的代码,而是在修改旧的代码出现的错误。通常这个比例会大于2比8,这也是编写代码的时候的二八现象——编写代码的时间是二,而为这段代码找错误、修改错误所花费的时间却是八。

    在这种状态之下,我们在找错误的时候会直接编译整个程序,然后通过界面逐步的操作到错误的地方然后再去查找代码中是否有错误。这样的找错误的方法效率非常低。但是当我们拥有单元测试的时候,我们就不需要通过界面去一步一步的操作,而是直接运行这个方法的单元测试,将输入的条件模拟成出现错误的时候输入的信息和调用的方法的形式,这样就可能很快的还原出错误。这样解决起来速度就提高了很多,每次找到错误都去修改单元测试,那么下次就不会再出现相同的错误了。

    如果通过模拟,单元测试也没有出现任何异常,这时也可以断定,并非该代码出现的错误,而是其他相关的代码出现的错误。我们只需再调试其他几个相关的代码的单元测试即可找到真正的错误。

    1.2 能够让程序员对自己的程序更有自信
    很多时候,当主管问我们程序会不会再出问题的时候,我们会很难回答。因为我们没法估计到系统还可能出现什么问题。但是如果这时我们为所有代码都编写了单元测试,而且测试代码的编写是按照标准去写的,这些测试又都能够成功的通过测试。那么我们就完全有自信说出我们的把握有多大。因为在测试代码中,我们已经把所有可能的情况都预料到了,程序代码中也将这些可能预料到的问题都解决了。因此我们会对自己的程序变得越来越自信。

    1.3 能够让程序员在提交项目之前就将代买变得更加健壮
    大多数程序员在编写代码的时候,都会先考虑最理想化情况下的程序该如何写,写完之后在理想状态下编译成功,然后输入理想的数据发现没有问题。他们就会自我安慰的说“完成了”。然后可能为了赶进度,就又开始作另外的程序了。时间久了这种理想化的程序就越来越多。一旦提交测试,就发现这里有错误那里有错误,然后程序员们再拿出时间来这里补个漏洞那里补个漏洞。而且在补漏洞的过程中,也可能继续沿用这种理想化的思路,就导致了补了这里又导致那里出问题的情况。

    但是如果在初期,我们就为每段代码编写单元测试,而且根据一些既定的标准去写,那么单元测试就会提前告诉程序员哪些地方会出现错误。那么他们可能在编写过程中就提前处理了那些非理想状态下的问题。这样我们的代码就会健壮很多。

    1.4 能够协助程序员更好的进行开发
    “码未动,测试现行。”这是极限编程中倡导的一种编程模式,为什么要这样呢?因为我们在编写单元测试的过程中,其实就是在设计我们的代码将要处理哪些问题。单元测试写的好,就代表你的代码写的好。而且你会根据单元测试的一些预先设想的情况去编写代码,就不会盲目的添加一个属性、添加一个方法了。

    1.5 能够向其他程序员展现你的程序该如何调用
    通常情况下,单元测试代码中写的都是在各种情况下如何调用那段待测试的代码。因此这个单元测试同时也向其他人员展示了我们的代码该如何调用?在什么情况下会抛出什么异常?等等。这样一个单元测试就变成了一个代码性的帮助文档了。

    1.6 能够让项目主管更了解系统当前的状况
    传统的管理中,项目的进度、代码的质量都只是通过口头的形式传递到主管那里的。因此有时候主管获得的反馈可能事实。但是如果通过一个完善的单元测试系统,那么主管就可以通过查看单元测试的运行结果和单元测试的代码覆盖率来确定开发人员的工作是否真正完成。

    二 如何编写单元测试
    Microsoft Visual Studio 2005中集成了一个专门用来进行测试的组件,该组件能够提供给我们单元测试、压力测试、代码覆盖率等等的测试相关的功能。我们无须借用第三方的测试工具来进行这些测试。

    2.1 创建单元测试
    该工具可以对任何类、接口、结构等实体中的字段、属性、构造函数、方法等进行单元测试。创建单元测试大致可以分为两类:

    整体测试,整体测试是在类名称上右击鼠标,在下拉菜单中点击创建单元测试选项。这样就可以为整个类创建单元测试了,这时他会为整个类可以被测试的内容全部添加测试方法。开发人员直接在这些自动生成的测试方法中添加单元测试代码就可以了。

    单独测试,如果只想单独对某个方法、属性、字段进行测试,则可以将鼠标焦点放在这个待测试的项目名称之上,然后点击鼠标右键,在右键菜单中选择创建单元测试选项。这样就可以单独为某个方法创建单元测试了。

    2.2 编写单元测试代码
    创建完单元测试之后,就可以为单元测试编写测试代码了。具体的测试代码的编写标准会在第三章中介绍。

    2.3 运行单元测试
    单元测试代码编写完毕,就可以通过运行单元测试来进行测试了。需要运行单元测试的时候,需要打开测试管理器窗口。该窗口可以通过菜单中的“测试”-“窗口”——“测试管理器”来打开。打开该窗口之后,就可以在该窗口中看到我们所建立的单元测试的列表。我们可以在列表中勾选某个单元测试前面的复选框。然后右击鼠标在右键菜单中点击“调试选中的测试”或者“运行选中的测试”。

    调试选中的测试的时候,我们可以在测试代码中或者我们自己的代码中添加断点并逐步运行以看其状态。

    运行选中的测试只会运行测试并不能够进行测试,这时代码的运行是模拟真实软件运行的时候的情况执行的。我们可以根据我们的实际情况来选中执行哪种测试。

    2.4 测试结果
    运行了测试之后,我们需要查看这次测试的结果。我们可以通过点击菜单中的“测试”——“窗口”——“测试结果”来打开一个测试结果窗口。每次测试都会在测试结果中向我们显示一些记录。我们也可以通过双击这个测试结果,来查看详细的结果信息。

    2.5 代码覆盖率
    单元测试写的是否合理或者是否达到了要求的一个唯一的标准就是整个测试的代码覆盖率。代码覆盖率其实就是测试代码所运行到的实际程序路径的覆盖率。在实际程序中可能会有很多的循环、判断等分支路径。一个好的单元测试应该能够将所有可能的路径都将走到,这样就可以保证大多数情况都测试过了。

    VS2005中也提供了查看代码覆盖率的工具。我们可以通过点击菜单中的“测试”——“窗口”——“代码覆盖率结果”来打开代码覆盖率查看的窗口。

    若要进行代码覆盖率的检查,我们必须进行设置,因为系统默认情况下是不进行代码覆盖率检测的。若要打开某个测试的代码覆盖率测试,我们必须点击菜单中的“测试”——“编辑测试运行配置”——“本地测试运行。。。。。。”来打开一个测试配置窗口。在该窗口左侧的列表中选中“代码覆盖率”就会显示代码覆盖率的设置。在这个配置中会显示当前解决方案中可以用来检测代码覆盖率的程序集,我们将需要进行覆盖率检测的程序集选中然后点击“应用”按钮就可以了。

    设置完毕之后,我们就可以直接运行单元测试,测试通过后。我们就可以打开代码覆盖率结果窗口,在这里我们就能够看到这些测试覆盖了多少代码。当我们在这里双击某个类的时候,就可以看到VS已经将代码背景改变了颜色。显示为深棕色的代码就是没有覆盖到的代码,我们可以通过在单元测试代码中添加代码来想办法覆盖这些代码。这样一个单元测试的全过程就完成了。

    三 单元测试的标准
    虽然要进行单元测试的代码会是各种各样的,但是编写单元测试代码还是有规律可循的。测试的对象一般情况下分为方法(包含构造函数)、属性,因此我们按照这两个方向来确定单元测试的标准。

    由于现在大多数开发人员还没有真正使用过.NET的单元测试工具,对于单元测试的了解程度也不高。因此我们这里也不便于制定非常多的标准。我们当前主要针对两大方面进行规范:

    l 哪些代码需要添加单元测试?

    l 单元测试代码的写法?

    3.1 哪些代码需要添加单元测试
    当前项目正处在一个最后冲刺阶段,主要的大部分编码工作已经基本完成。因此要全面的添加单元测试,其实是比较大的投入。所以单元测试不能一次性的全部加上,我们只能通过一步一步的来进行测试。

    第一步,应该对所有程序集中的公开类以及公开类里面的公开方法添加单元测试。

    第二步,对于构造函数和公共属性进行单元测试。

    第三步,添加全面单元测试。

    在产品全面提交之前可以先完成第一步的工作,二三步可以待其他所有功能完成之后再进行添加。由于第二三步的添加工作其实于第一步类似,只是在量上的累加,因此我们先着重讨论第一步的情况。

    在作第一步单元测试添加的时候,也需要有选择性的进行,我们要抓住重点进行测试。首先应该针对属于框架技术中的代码添加单元测试。这里就包含操作数据库的组件、操作外部WebService的组件、邮件接收发送组件、后台服务与前提程序之间的消息传递的组件等等。通过为这些主要的可复用代码进行测试,可以大大加强底层操作的正确性和健壮性。

    其次为业务逻辑层对界面公开的方法添加单元测试。这样可以让业务逻辑保持正确,并且能够将大部分的业务操作都归纳到单元测试中,保证以后产品发布之后,一旦出现问题可以直接通过业务逻辑的单元测试来找到BUG。

    剩下的代码大部分属于代码生成器生成的,而且大多数的操作都是类似的,因此我们可以先针对某一个业务逻辑对象做详细的单元测试。通过这样的规定,单元测试添加的范围就减少了很多。

    3.2 单元测试代码的写法
    在编写单元测试代码的时候需要认真的考虑以下几个方面:

    l 所测试的方法的代码覆盖率必须达到100%。

    l 所测试的代码内部的状态,例如执行了某个方法之后,该方法所在的类中某个属性或者返回值是否与预期相同。

    l 被测试代码所使用的外部设备的状态,如数据库是否可读、网络是否可用、打印机是否可用、WebService是否可用等等。

    每一段单元测试代码,必须考虑到以上的三个问题,并且对于这些问题都要有相应的测试。

    3.2.1 代码覆盖率要求
    在2.5小节中已经讲了什么是代码覆盖率和代码覆盖率查看的方法。在这里我们着重来讲怎样将代码覆盖率提升到100%。

    一般情况下,代码覆盖率低,说明测试代码中没有过多的考虑某些特殊情况。特殊情况包括:

    l 边界条件数据,比如值类型数据的最大值、最小值、DBNull,或者是方法中所使用的条件边界,例如a>100那么100就变成了这个数据的边界。而且在测试的时候还必须把超出边界的数据作为测试条件进行测试。

    l 空数据,一般空数据对应于引用类型的数据,也就是Null值。

    l 格式不正确数据,对于引用类型的数据或者结构对象,类型虽然正确但是其内部的数据结构不正确的数据。例如一个数据库实体对象,数据库中要求其某个属性必须为非空,但是这时我们可以属于一个空。这样这个对象就属于一个不正确数据库。

    这三种数据都是针对被测试方法中所使用的外部数据来说的。方法中使用的外部数据无非就是方法参数传入的数据和方法所在的对象的属性或者字段的数据。因此在编写测试代码的时候就必须将这些使用到的数据设置为上面这几种情况的数据来检测方法执行的情况。这才能保证方法编写是正确的。

    在编写单元测试代码的时候先了解到被测试方法可能会使用的外部数据,然后将这些外部数据一次设置为上面规定的这几种情况,然后再执行方法。这样就基本可以达到外部数据所有情况都能够正确测试到了。

    通过这种方法编写的单元测试代码覆盖率一般可以超过80%。

    3.2.2 预期值是否达到
    在编写单元测试的时候,不能单纯的追求代码覆盖率。有时候代码覆盖率已经达到了100%,程序也能正常运行,但是可能会出现方法执行完毕之后某些数据并非预期的数值。这时就必须对执行的结果进行断言。在.NET提供的单元测试模块中,可以在单元测试中直接使用一个类的一些静态方法来判断某个值是否达到了预期的情况。这个类是Assert。在这个类中公开了很多判断等效性、判断开关性、判断非空性等一系列方法。这些方法可以让你提前做出预测,一旦程序执行之后,如果这些断言不能通过,就代表代码有错误。

    在使用断言的时候,我们要求要达到平均5行测试代码就要有一个断言。

    通过添加断言,我们就可以对程序执行过程中数据的正确性做一个检测,保证我们的程序不出现写错数据的情况或者出现错误状态的情况。

    3.2.3 外部设备状态更改时测试是否正常通过
    当代码覆盖率和预期值都达到了我们的要求之后,整个程序其实就基本达到了质量标准。但是这样还不全面,因为很多程序都要使用到外部的设备或者程序,例如数据库、打印机、网络、串行口、并行口等等。当这些设备发生改变或者不可用的时候,程序就可能出现一些不可预知的错误。因此一个健壮的程序也必须考虑到这些情况,这时通常都是通过将这些设备确定的设置为这些不正常状态来检测程序可能会出现的问题。然后再在测试程序中将这些条件加上。

    附录
    中科永联高级技术培训中心(www.itisedu.com)关于单元测试的一些解释
    单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,你可能把一个很大的值放入一个有序list 中去,然后确认该值出现在list 的尾部。或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。

      单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。
    
      工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。
    

    其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,老纳把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。

    对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。

    要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。老纳认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈老纳的看法。

    一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以老纳的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。

    有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。

    为什么要使用单元测试

    我们编写代码时,一定会反复调试保证它能够编译通过。如果是编译没有通过的代码,没有任何人会愿意交付给自己的老板。但代码通过编译,只是说明了它的语法正确;我们却无法保证它的语义也一定正确,没有任何人可以轻易承诺这段代码的行为一定是正确的。
    
    幸运,单元测试会为我们的承诺做保证。编写单元测试就是用来验证这段代码的行为是否与我们期望的一致。有了单元测试,我们可以自信的交付自己的代码,而没有任何的后顾之忧。
    

    什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。

    由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。

    关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。

    在一种传统的结构化编程语言中,比如C,要进行测试的单元一般是函数或子过程。在象C++这样的面向对象的语言中, 要进行测试的基本单元是类。对Ada语言来说,开发人员可以选择是在独立的过程和函数,还是在Ada包的级别上进行单元测试。单元测试的原则同样被扩展到第四代语言(4GL)的开发中,在这里基本单元被典型地划分为一个菜单或显示界面。
    

    单元测试不仅仅是作为无错编码一种辅助手段在一次性的开发过程中使用,单元测试必须是可重复的,无论是在软件修改,或是移植到新的运行环境的过程中。因此,所有的测试都必须在整个软件系统的生命周期中进行维护。

    经常与单元测试联系起来的另外一些开发活动包括代码走读(Code review),静态分析(Static analysis)和动态分析(Dynamic analysis)。静态分析就是对软件的源代码进行研读,查找错误或收集一些度量数据,并不需要对代码进行编译和执行。动态分析就是通过观察软件运行时的动作,来提供执行跟踪,时间分析,以及测试覆盖度方面的信息。

    一些流行的误解

    在明确了什么是单元测试以后,我们可以进行"反调论证"了。在下面的章节里,我们列出了一些反对单元测试的普遍的论点。然后用充分的理由来证明这些论点是不足取的。

      它浪费了太多的时间
    

    一旦编码完成,开发人员总是会迫切希望进行软件的集成工作,这样他们就能够看到实际的系统开始启动工作了。 这在外表上看来是一项明显的进步,而象单元测试这样的活动也许会被看作是通往这个阶段点的道路上的障碍, 推迟了对整个系统进行联调这种真正有意思的工作启动的时间。

    在这种开发步骤中,真实意义上的进步被外表上的进步取代了。系统能够正常工作的可能性是很小的,更多的情况是充满了各式各样的Bug。在实践中,这样一种开发步骤常常会导致这样的结果:软件甚至无法运行。更进一步的结果是大量的时间将被花费在跟踪那些包含在独立单元里的简单的Bug上面,在个别情况下,这些Bug也许是琐碎和微不足道的,但是总的来说,他们会导致在软件集成为一个系统时增加额外的工期, 而且当这个系统投入使用时也无法确保它能够可靠运行。

    在实践工作中,进行了完整计划的单元测试和编写实际的代码所花费的精力大致上是相同的。一旦完成了这些单元测试工作,很多Bug将被纠正,在确信他们手头拥有稳定可靠的部件的情况下,开发人员能够进行更高效的系统集成工作。这才是真实意义上的进步,所以说完整计划下的单元测试是对时间的更高效的利用。而调试人员的不受控和散漫的工作方式只会花费更多的时间而取得很少的好处。

    使用AdaTEST和Cantata这样的支持工具可以使单元测试更加简单和有效。但这不是必须的,单元测试即使是在没有工具支持的情况下也是一项非常有意义的活动。

      它仅仅是证明这些代码做了什么
    

    这是那些没有首先为每个单元编写一个详细的规格说明而直接跳到编码阶段的开发人员提出的一条普遍的抱怨, 当编码完成以后并且面临代码测试任务的时候,他们就阅读这些代码并找出它实际上做了什么,把他们的测试工作基于已经写好的代码的基础上。当然,他们无法证明任何事情。所有的这些测试工作能够表明的事情就是编译器工作正常。是的,他们也许能够抓住(希望能够)罕见的编译器Bug,但是他们能够做的仅仅是这些。

    如果他们首先写好一个详细的规格说明,测试能够以规格说明为基础。代码就能够针对它的规格说明,而不是针对自身进行测试。这样的测试仍然能够抓住编译器的Bug,同时也能找到更多的编码错误,甚至是一些规格说明中的错误。好的规格说明可以使测试的质量更高,所以最后的结论是高质量的测试需要高质量的规格说明。

    在实践中会出现这样的情况: 一个开发人员要面对测试一个单元时只给出单元的代码而没有规格说明这样吃力不讨好的任务。你怎样做才会有更多的收获,而不仅仅是发现编译器的Bug?第一步是理解这个单元原本要做什么, — 不是它实际上做了什么。 比较有效的方法是倒推出一个概要的规格说明。这个过程的主要输入条件是要阅读那些程序代码和注释, 主要针对这个单元, 及调用它和被它调用的相关代码。画出流程图是非常有帮助的,你可以用手工或使用某种工具。 可以组织对这个概要规格说明的走读(Review),以确保对这个单元的说明没有基本的错误, 有了这种最小程度的代码深层说明,就可以用它来设计单元测试了。

      我是个很棒的程序员, 我是不是可以不进行单元测试?
    

    在每个开发组织中都至少有一个这样的开发人员,他非常擅长于编程,他们开发的软件总是在第一时间就可以正常运行,因此不需要进行测试。你是否经常听到这样的借口?

    在真实世界里,每个人都会犯错误。即使某个开发人员可以抱着这种态度在很少的一些简单的程序中应付过去。 但真正的软件系统是非常复杂的。真正的软件系统不可以寄希望于没有进行广泛的测试和Bug修改过程就可以正常工作。

    编码不是一个可以一次性通过的过程。在真实世界中,软件产品必须进行维护以对操作需求的改变作出反应, 并且要对最初的开发工作遗留下来的Bug进行修改。你希望依靠那些原始作者进行修改吗? 这些制造出这些未经测试的原始代码的资深专家们还会继续在其他地方制造这样的代码。在开发人员做出修改后进行可重复的单元测试可以避免产生那些令人不快的负作用。

      不管怎样, 集成测试将会抓住所有的Bug
    

    我们已经在前面的讨论中从一个侧面对这个问题进行了部分的阐述。这个论点不成立的原因在于规模越大的代码集成意味着复杂性就越高。如果软件的单元没有事先进行测试,开发人员很可能会花费大量的时间仅仅是为了使软件能够运行,而任何实际的测试方案都无法执行。

    一旦软件可以运行了,开发人员又要面对这样的问题: 在考虑软件全局复杂性的前提下对每个单元进行全面的测试。 这是一件非常困难的事情,甚至在创造一种单元调用的测试条件的时候,要全面的考虑单元的被调用时的各种入口参数。在软件集成阶段,对单元功能全面测试的复杂程度远远的超过独立进行的单元测试过程。

    最后的结果是测试将无法达到它所应该有的全面性。一些缺陷将被遗漏,并且很多Bug将被忽略过去。

    让我们类比一下,假设我们要清洗一台已经完全装配好的食物加工机器!无论你喷了多少水和清洁剂,一些食物的小碎片还是会粘在机器的死角位置,只有任其腐烂并等待以后再想办法。但我们换个角度想想,如果这台机器是拆开的, 这些死角也许就不存在或者更容易接触到了,并且每一部分都可以毫不费力的进行清洗。

      它的成本效率不高
    

    一个特定的开发组织或软件应用系统的测试水平取决于对那些未发现的Bug的潜在后果的重视程度。这种后果的严重程度可以从一个Bug引起的小小的不便到发生多次的死机的情况。这种后果可能常常会被软件的开发人员所忽视(但是用户可不会这样),这种情况会长期的损害这些向用户提交带有Bug的软件的开发组织的信誉,并且会导致对未来的市场产生负面的影响。相反地,一个可靠的软件系统的良好的声誉将有助于一个开发组织获取未来的市场。

    很多研究成果表明,无论什么时候作出修改都要进行完整的回归测试,在生命周期中尽早地对软件产品进行测试将使效率和质量得到最好的保证。Bug发现的越晚,修改它所需的费用就越高,因此从经济角度来看, 应该尽可能早的查找和修改Bug。在修改费用变的过高之前,单元测试是一个在早期抓住Bug的机会。

    相比后阶段的测试,单元测试的创建更简单,维护更容易,并且可以更方便的进行重复。从全程的费用来考虑, 相比起那些复杂且旷日持久的集成测试,或是不稳定的软件系统来说,单元测试所需的费用是很低的。

    结论

    经验表明一个尽责的单元测试方法将会在软件开发的某个阶段发现很多的Bug,并且修改它们的成本也很低。在软件开发的后期阶段,Bug的发现并修改将会变得更加困难,并要消耗大量的时间和开发费用。无论什么时候作出修改都要进行完整的回归测试,在生命周期中尽早地对软件产品进行测试将使效率和质量得到最好的保证。 在提供了经过测试的单元的情况下,系统集成过程将会大大地简化。开发人员可以将精力集中在单元之间的交互作用和全局的功能实现上,而不是陷入充满很多Bug的单元之中不能自拔。

    使测试工作的效力发挥到最大化的关键在于选择正确的测试策略,这其中包含了完全的单元测试的概念,以及对测试过程的良好的管理,还有适当地使用象AdaTEST和Cantata这样的工具来支持测试过程。这些活动可以产生这样的结果:在花费更低的开发费用的情况下得到更稳定的软件。更进一步的好处是简化了维护过程并降低了生命周期的费用。有效的单元测试是推行全局质量文化的一部分,而这种质量文化将会为软件开发者带来无限的商机。

    参考出处:http://www.docin.com/p-557363928.html
    原文链接:https://www.cnblogs.com/mq0036/p/4100084.html

    展开全文
  • JAVA单元测试的用法和要点(入门篇)

    万次阅读 多人点赞 2018-09-25 14:13:51
    一、单元测试的目的?  单元测试是编写测试代码,用以检测特定的、明确的、细颗粒的功能! 严格来说,单元测试只针对功能点进行测试,不包括对业务流程正确性的测试。现在一般公司都会进行业务流程的测试,这也要求...

    一、单元测试的目的?
          单元测试是编写测试代码,用以检测特定的、明确的、细颗粒的功能!  严格来说,单元测试只针对功能点进行测试,不包括对业务流程正确性的测试。现在一般公司都会进行业务流程的测试,这也要求测试人员需要了解需求! 测试人员也不好过啊~~

          目前开发所用的单元是Junit框架,在大多数java的开发环境中已经集成,可以方便开发自己调用!

    注意:单元测试不仅仅是要保证代码的正确性,一份好的单元测试报告,还要完整地记录问题的所在和缺陷以及正确的状态,方便后面代码的修复,重构和改进!


    二、单元测试做什么?

    一般来说,一份单元测试主要包括以下几个方面:

    ==============================================================================================
    1.接口功能性测试: 接口功能的正确性,即保证接口能够被正常调用,并输出有效数据!

    ------------------> 是否被顺利调用

    ------------------> 参数是否符合预期

    ==============================================================================================
    2.局部数据结构测试:保证数据结构的正确性
    ------------------> 变量是否有初始值或在某场景下是否有默认值
    ------------------> 变量是否溢出
    ==============================================================================================
    3.边界条件测试:测试
    ------------------> 变量无赋值(null)
    ------------------> 变量是数值或字符
    ------------------> 主要边界:最大值,最小值,无穷大
    ------------------> 溢出边界:在边界外面取值+/-1
    ------------------> 临近边界:在边界值之内取值+/-1
    ------------------> 字符串的边界,引用 "变量字符"的边界
    ------------------> 字符串的设置,空字符串
    ------------------> 字符串的应用长度测试
    ------------------> 空白集合
    ------------------> 目标集合的类型和应用边界
    ------------------> 集合的次序
    ------------------> 变量是规律的,测试无穷大的极限,无穷小的极限
    ==============================================================================================

    4.所有独立代码测试:保证每一句代码,所有分支都测试完成,主要包括代码覆盖率,异常处理通路测试
    ------------------> 语句覆盖率:每个语句都执行到了
    ------------------> 判定覆盖率:每个分支都执行到了
    ------------------> 条件覆盖率:每个条件都返回布尔
    ------------------> 路径覆盖率:每个路径都覆盖到了

    ==============================================================================================
    5.异常模块测试,后续处理模块测试:是否包闭当前异常或者对异常形成消化,是否影响结果!


    三、JAVA的单元测试JUNIT4

    (1):业务流程的一般是按照需求的预期效果,跑完整个业务流程,包括以前开发的流程
    -----------------> 是否实现了预期
    -----------------> 是否影响到了以前的流程
    -----------------> 全流程是否顺利
    -----------------> 数据是否符合预期

    ==============================================================================================

    (2):代码测试:

    @BeforeClass 全局只会执行一次,而且是第一个运行
    @Before 在测试方法运行之前运行
    @Test 测试方法
    @After 在测试方法运行之后允许
    @AfterClass 全局只会执行一次,而且是最后一个运行
    @Ignore 忽略此方法

    JUNIT4是以org.junit为框架进行的测试,以注解的形式来识别代码中需要测试的方法!

    注意:

    对于每一个测试,我们都应该保持独立测试,以确保测试结果是有意义的。在程序中,经常会出现,当测试完一个方法后,其参数已经被系统保持或持久化下来。无疑会造成下一次的测试测试数据或者状态的不合理性!为了解决问题,对于此类场景,我们的测试代码必须具备初始化和收尾的能力。也即是@Before和@After的意义所在!

    同理@AfterClass和BeforeClass即是为了满足测试中,那些体积非常大,但只要一次初始化的代码块!

    (3):断言测试与及常用断言:

       ---------->assertEquals:

    Assert.assertEquals("此处输出提示语", 5, result);
    
    ===================================================================================================================
    解析:"此处输出提示语" 为错误时你个人想要输出的错误信息; 5  是指你期望的值;result 是指你调用程序后程序输出给你的结果
    
    @Test(expected = NullPointerException.class)  
    解析:在注解的时候添加expected 为忽略此异常
    @Test(timeout  =   5000 ):超时设置
    @Test(expected  =  XXXXException. class):期望出现异常,如果出现该异常则成功,否则测试失败
    @Ignore() :用户方法之上,被注解的方法会被成功需忽略
    ===================================================================================================================
    
    fail("Not yet implemented")
    解析:放在方法中,如果我顺利地执行,我就报失败出来。就是说按道理不应该执行到这里的,但是偏偏执行了,说明程序有问题
    ===================================================================================================================
    Assert.assertTrue("msg",boolean)与Assert.assertFalse("msg",boolean)
    解析:如果和预期一样为true则成功,否则失败输出msg;如果和预期一样为false则成功,否则失败并输出
    

      ----------> assertNull("msg",boolean)与assertNotNull("msg",boolean)

    解析:assertNull与assertNotNull可以验证所测试的对象是否为空或不为空,如果和预期的相同则测试成功,否则测试失败!

    ========================================主要常用方法============================================

    断言列表:
    -------------->assertTrue(String message, boolean condition)             要求condition == true
    -------------->assertFalse(String message, boolean condition)            要求condition == false
    -------------->assertEquals(String message, XXX expected,XXX actual) 要求expected期望的值能够等于actual
    -------------->assertArrayEquals(String message, XXX[] expecteds,XXX [] actuals) 要求expected.equalsArray(actual)
    -------------->assertNotNull(String message, Object object)          要求object!=null
    -------------->assertNull(String message, Object object)             要求object==null
    -------------->assertSame(String message, Object expected, Object actual)     要求expected == actual
    -------------->assertNotSame(String message, Object unexpected,Object actual) 要求expected != actual
    -------------->assertThat(String reason, T actual, Matcher matcher)  要求matcher.matches(actual) == true

    -------------->fail(String message) 要求执行的目标结构必然失败,同样要求代码不可达,即是这个方法在程序运行后不会成功返回,如果成功返回了则报错

    (4):运行器指定?

    单元测试中,每个类都是由于JUNIT4框架中的Runner运行器来执行的。一般情况下,在没有指定运行器的时候,是由系统默认选择(TestClassRunner)的运行器执行。包括类中的所有方法都是由该运行器负责调用和执行。当我们需要指定的时候,则通过类级别注解 @Run Wirth(xxxxxx)进行选择,一般是根据不同类型选择不同执行器,可以提高效率也可以应用于某种特殊场景!

    (5):参数化测试?

     @RunWith(Parameterized. class )
     public   class  TestParam {
    
          private   static  Calculator calculator  =   new  Calculator(); //需要测试的类
          private   int  param; 
          private   int  result;
     
    @Parameters
    public   static  Collection data(){
    
       return  Arrays.asList(new  Object[][] {{ 11 ,  17 } , { xx1 ,  xx} } );
     
    } 
     
    //有参构造,在实例的时候实现参数初始化
    public  TestParam( int  param,  int  result){
       this .param  =  param;
       this .result  =  result;
    } 
    
    @Test
    public  void  TestResult(){
       calculator.square(param);
       assertEquals(result, calculator.getResult()); 
    } 
    
    } 
    

    解说:参数化测试的目标是为了一次性完成同类型测试,将相同类型的数据按照一定的顺序批量地传入测试方法,并得出结论!其本质是一个批量的化的操作,只是为了方便我们测试而进行了封装。我们只有提供测试的方法以及按照一定的顺序进行设置则可以。

    --------->进行类注解:@RunWith(Parameterized.class),为了测试类指定一个ParameterizedRunner运行器

    --------->进行参数设置:将测试结果和期望结果,以每一组都是一个数组的形式存放以形成二维数组,转化为list返回并注解。

    --------->参数初始化:设置测试方法要入参的参数,并按照"参数设置"的顺序利用构造方法进行初始化的赋值!

    --------->测试调用:写一个测试方法进行调用,将参数传递到要测试的类的方法中并返回数据

    注意:参数化测试需要创建一单独用于测试的测试类。并定义两个变量用于接受测试结果和预期目标。数据存放以二维数组的方式,两个为一组。接着便是通过构造方法进行数据初始化。 构造方法入参的顺序要和二维数组中国每一组存放的数据顺序保持一致。


    (6):打包测试?

    @RunWith(Suite. class )
    @Suite.SuiteClasses( {CalculatorTest. class ,SquareTest. class } )
    public   class  AllCalculatorTests  {
        //to do something;
    } 
    ==========================================================================================================================
    解析:将有需要的一起执行程序一起打包,然后执行
    运行器:Suite. class

    解析:我们把需要打包一起测试的测试类作为参数传递给该注解。然后直接运行代码,此处的测试类可以直接设置为空,只需要添加注解便OK;

     

    展开全文
  • 什么是单元测试

    千次阅读 2019-01-30 16:04:24
    百度百科 对于单元测试 的定义 如下 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,...
  • 单元测试是什么 单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确,通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为1。 单元测试的好处 ...
  • .net 我的单元测试之路

    千次阅读 2019-01-07 22:53:34
    单元测试上,我走了很多的弯路,我写这篇文章,希望其他的还没有找到单元测试的小伙伴能够了解一下单元测试,并且知道怎样使用,不用像我当初那样在走很多不必要的弯路。  大学毕业后,我进入的是一个小型的创业...
  • 关于单元测试的总结

    千次阅读 2018-08-21 14:40:49
    开发人员必备的技能——单元测试 说起软件测试四个字,想必大家脑海中浮现的有集成测试、系统测试、黑盒测试、白盒测试等,可能就是没想到会有单元测试。 对于大学是学习软件工程专业出身的同学来说可能会听过这四...
  • 作者:coolhappy ...来源:知乎 ...介绍怎么做单元测试的书很多,这里主要解答:为什么单元测试。 客观来说,单元测试和使用版本控制系统(GIT,SVN)是一样重要的。 为什么单元测试如此重要,但你却感...
  • 软件测试一般分为4个阶段:单元测试、集成测试、系统测试、验收测试。 一、单元测试  单元测试是对软件中的最小可验证单元进行检查和验证。比如对Java中的类和方法的测试。 测试原则:  1、尽可能保证测试...
  • 单元测试时针对每个单元的测试,是
  • 从系统上来说,软件测试的方法主要包括单元测试,集成测试,系统测试,确认测试。(重点说单元测试和集成测试) 单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否...
  • 单元测试、集成测试和功能测试

    万次阅读 2017-09-19 19:20:20
    一、单元测试 Unit Tests单元测试用于测试最小功能单元,比如单个方法(给定一个指定状态的类,然后调用该类的x方法,最后检查状态是否符合预期)。单元测试应该聚焦在一个特定的功能上(比如,在一个空的stack上调...
  • Maven单元测试

    万次阅读 2020-03-01 09:42:22
    Maven单元测试, maven配置,使用单元测试
  • 单元测试  1、什么是单元测试单元测试是对程序中的单个子程序、子程序或过程进行测试,也就是说一开始的时候不是对整个程序进行测试,而是先将注意力集中构成整个程序的各个小单元的测试上。单元测试是编写一小...
  • IDEA中创建单元测试过程 JUnit

    万次阅读 热门讨论 2018-03-15 16:30:00
    1、在src同级别下创意一个test目录2、右键这个test文件夹,设置为测试专用文件夹,然后在在下面创建一个java目录,根据你的需求,多级建目录3、选择一个...可参考:IDEA 单元测试入门百度:如何使用JUnit编写测试类...
  • idea 的SpringBoot项目做单元测试

    万次阅读 2018-02-02 18:20:02
    SpringBoot项目的一个功能开发完成之后,需要对功能做单元测试,需要项目有单元测试的功能,这个项目是一个新建的项目,所以需要自己弄,下面记载一下步骤。 首先,我们使用点击需要做单元测试的类名,右击使用idea...
  • 单元测试之关键问题解答

    万次阅读 2007-05-04 01:17:00
    这篇博文的重点: 单元测试的目的是什么; 单元测试测试什么; 在敏捷开发中,如何进行单元测试; 测试的分配与配合; 如何设计好的单元测试案例; 因为我的打字不快,外加国内对知识产权的轻视,我不准
  • Visual Studio 2010 单元测试目录

    万次阅读 2011-02-10 14:15:00
    单元测试的重要性这里我就不多说了,以前大家一直使用NUnit来进行单元测试,其实早在Visual Studio 2005里面,微软就已经集成了一个叫Test的专门测试插件,经过几年的发展,这个工具现在已经比较强大了,下面我就以...
  • 最近,在网上看到过一个调查,调查的内容是“程序员在项目开发中编写单元测试的情况”。当然,至于调查的结果,我想聪明的你已经可以猜到了。高达 58.3% 的比例,一般情况下不写单元测试,只有偶尔的情况才会写写。...
1 2 3 4 5 ... 20
收藏数 469,621
精华内容 187,848
关键字:

单元测试