发布新日志

  • 【zz】白盒测试实例——单元测试的步骤

    2010-08-24 12:47:54

    白盒测试黑盒测试的过程和方法是有一些区别的。

      单元测试的步骤:

      1、 理解需求和设计

      理解设计是很重要的,特别是要搞清楚被测试模块在整个软件中所处的位置,这对测试的内容将会有很大的影响。需要记住的一个原则就是:好的设计,各模块只负责完成自己的事情,层次与分工是很明确的。在单元测试的时候,可以不用测试不属于被测试模块所负责的功能,以减少测试用例的冗余,集成测试的时候会有机会测试到的。

      举例:

      1. /*

      2.

      3. * 判断三条边是否能够组成三角形

      4.

      5. * 返回值:true-是; false-否

      6.

      7. */

      8.

      9. bool isTriangle(int a, int b, int c);

      测试该函数的时候,只需要测试三条边(在合法的取值范围内的整数)是否能够满足两边之和是否大于第三边的功能,而不需要测试三条边是否在合法的范围(0, 200)之间的整数,因为调用该函数之前,一定要先通过下面函数的检查,要是检查不通过,就不会执行isTriangle函数。

      1. /*

      2.

      3. * 判断三条边是否合法(即:判断三条边都在合法的范围内)

      4.

      5. * 返回值:true-是; false-否

      6.

      7. */

      8.

      9. bool isLegal(int a, int b, int c);

      所以,单元测试主要是关注本单元的内部逻辑,而不用关注整个业务的逻辑,因为会有别的模块去完成相关的功能。

    2、 概览源代码

      浏览一下源代码,主要任务:

      (1)初步检查源代码的编码风格与规范

      (2)大致估算测试工作量,比如:需要多少的测试用例、需要写多少的驱动模块和装模块等。

      (3)确定模块的复杂程度,初步制定测试的优先级等。

      3、 精读源代码

      认真阅读和分析代码,主要任务:

      (1)理解代码的业务逻辑。

      (2)检查代码与设计是否相符,如果详细设计没有该模块的流程图的话,先去画出流程图。

      (3)仔细研究逻辑复杂的模块

      (4)可以采用一些检查列表来检查程序可能会出现的问题。如果没有检查列表,那么,可以根据程序的特点,有针对性地检查容易出问题的地方(记得把经验总结下来供下次使用)。

      4、 设计测试用例

      综合运用白盒测试方法(和结合黑盒测试方法)来设计测试用例,包括功能测试、性能测试等,要达到一定的测试覆盖率。在设计测试用例的过程中,流程图或控制流图是分析的好帮手。

      5、 搭建单元测试环境

      使用XUnit或自己写的框架将有助于单元测试的实施。在这个阶段主要就是写桩模块和驱动模块,第4步所设计的测试用例是通过驱动模块传递给被测试模块的,然后驱动模块想办法获取被测试模块对数据的处理结果,并判定返回的实际结果与测试用例的预期结果是否一致,通过测试框架来记录执行的结果,对于出现的错误,还需要统计错误的信息,供执行完之后分析。

      搭建单元测试环境要避免在main函数中使用printf和scanf函数来跟测试人员交互来达到获取测试用例数据的信息。这样的测试还是没有摆脱手工测试方式,效率是低下的。同时,对于测试结果是否通过测试也不要使用printf方式打印被测试函数的返回结果值,避免要人工去检查结果。

      6、 执行测试

      运行写好的驱动模块完成对被测试模块的测试。

      7、 补充和完善测试用例

      单元测试也是个循序渐进的过程,可能一开始考虑的不够全面,或预期的覆盖标准太低,需要在测试过程中不断补充测试用例,直到满足要求为止。

      8、 分析结果,给出评价

      根据测试的结果分析、查找错误的原因,并找到解决的办法。测试结束之后,根据测试过程的数据统计,给出被测试对象评价。

    原文地址:http://yinhe2726.javaeye.com/blog/495114

  • 【zz】白盒测试动态测试之白盒单元测试

    2010-08-01 22:44:56

     

      白盒单元测试体现了几个概念,第一是知道程序里面的实现逻辑;第二是进行单元测试,这些单元可以是一个方法,一个类。介入的时机程序员开发完一个方法或者一个类的时候,往往需要检测我们的代码是否排除错误并按照预期运行。这个时候就需要进行白盒单元测试。

      工作的内容根据代码里面的实现逻辑,测试代码是否对非法输入进行控制,测试代码是否按照预期的进行了工作。在jtest工具中,它认为重点在于输入数据,尽可能在所有的路径上运行程序,并尽可能的压垮程序。如果程序能够经受考验,那么认为这个关是通过的。至于代码是否按照需求定义那样运行,在这个阶段并不关心,而是在黑盒测试阶段。

      目前很多实践中,并没有严格区分单元的白盒和黑盒测试。

      白盒单元测试,是尽量的保证所有的路径都覆盖,同时包括合法的和非法的。但是并不关心实现逻辑是否按照需求预期的逻辑进行。所以,基于这种思想,可以完全实现用例的自动化生成、自动化执行。预期输入、预期输出都可以通过判断程序内部逻辑来生成,所以完全可以自动化。

      黑盒单元测试,是尽量的保证所有的路径都覆盖,同时重点关注输出的预期是按照需求预期来输出的。所以,数据驱动测试在这里可以应用,根据输入输出数据用来生成测试用例。测试用例设计工具测试用例,说白了就是调用被测的代码,检查结果是否正确,程序是否崩溃。

      Xunit框架可以很方便的实现测试用例的设计和执行。

      用例的生成,可以手工开发,也可以使用自动化工具自动生成。

      衡量测试用例的质量:

      测试用例是否已经充分了,我们往往是通过覆盖率指标来统计的,理想的情况下是达到100%。现在也很多统计的自动化工具可以嵌入到开发工具,或者运行测试用例中后台收集。(

  • 【转】白盒测试静态检查——Java经典Bug

    2010-08-01 22:43:59

     

      经过一段时间白盒静态扫描,目前已经扫了两个包,发现了100多个bug。

      值得欣慰的是,自己开发的工具也扫描出了一些bug,这段时间熬夜的开发没有白费。总结一下,主要问题的分类。随着这些经验的积累,可以作为日后人工审查和开发学习的。

      经典案例:

      Type headline demo Comment
    1 多线程 单例action里面包含有属性并且允许读写 public class XxxAction extends Action{

    private StringBuffer vo = new StringBuffer();


    public void setVo(StringBuffer invo){
    vo=invo;
    }
    public StringBuffer getVo(){
    return this.vo;
    }
    .................
    单例action里面包含有属性进行读写
    会引起数据错乱
    2 Bad
    practice
    字符串比较用==或者= if(dao.getADTerminalByServiceCode(serviceCode).getServicecode() == serviceCode){ String类型的比较不要用==或者!=,应该用equal方法
    就上面的代码永远都为false,因为==表示在同一常量区才会为true
    3   字符串分割正则表达式使用不对 String[] area = areaSize.split("*"); 正则表达式使用不对,会一直抛出异常
    应该使用转义字符
    4   字符串比较的空点异常 vo.getVirtualFlag().equals("NO") 建议修改为"NO".equals(vo.getVirtualFlag())
    5   对象比较不对
    if (this == obj) {
    return true;
    }
    对象必须重再了hashcode方法,比较才有意义
    6   流没关闭 InputStream input = new BufferedInputStream(file.getInputStream()); 流没有关闭
    会造成文件句柄资源耗尽,那么就无法再打开新的流
    7   connection statement rs等没关闭 try{
    .....
    } catch(..){

    }finally
    if(rs!=null){
    rs.close();
    }
    if(stmt!=null){
    stmt.close();
    }
    if(conn!=null){
    conn.close();
    }

    }
    在rs有异常会关闭不了statement conn
    在statement有异常会关闭不了conn
    8 Performance 循环中创建字符串 String children = "" ;
    ClassSpecVO[] t = cs.getTree();
    if ( t == null )
    return "";

    for ( int i = 0 ; i < t.length ; i ++ )
    {
    if ( children.length() != 0 )
    children += ",";
    children += constructJsonString(t[i]);
    }

    children会循环创建对象,必须改为StringBuffer对象。用append进行连接字符串
    9   不应该创建字符串对象 String vsplist=new String();  
  • 【转】白盒测试之静态检查--检测循环判断体重复计算

    2010-08-01 22:43:07

     

    在编写循环结构的程序很多程序会犯一个错误,就是在循环判断体中做重复计算。

    例如:for(int i = 0;i <list.size; i ++) {

              

    }

    应替换为:

    for(int i = 0,int len = list.size();i < len; i ++) {

               

    }

    在循环的语句结构中,每次跳转都需要比较,判断是否进行继续循环,但是最好不要在比较之前有

    计算的语句,尽量避免。否则循环中重复计算,效率会非常低。

        今天开发的静态扫描检测器就是检查这个问题,

    时刻提醒程序员注意该问题。

    扫描器运行结果如图:

     

     

    该检测器详细介绍:

    1.1.1       PERFORMANCE_LOOP_CALCULATE

    循环中重复计算

    1.1.1.1      版本

    Verson:1.2.0

     

    1.1.1.2      作者

    Author: River.liu

    Date : 2010.4.17

    Email :  liuhanhong@yahoo.com.cn

    1.1.1.3      原理

    在循环的语句结构中,每次跳转都需要比较,判断是否进行继续循环,但是最好不要在比较之前有

    计算的语句,尽量避免。否则循环中重复计算,效率会非常低。

    例如:for(int i = 0;i &lt; list.size; i ++) {

               

    }

    应替换为:

    for(int i = 0,int len = list.size();i < len; i ++) {

               

    }

    1.1.1.4      开发原理

     

    当遇到循环指令,就查找之前保存的preDirectCount个指令,判断是否存在includeMethordsDirect指定的指令,同时判断是否调用了includeMethords指定的方法,如果存在就表示存在循环计算。

     

     

    1.1.1.5      配置说明

    配置文件pluginConfig.properties在插件的jar包里面,直接修改里面的配置项目,再放回jar包就可以了。

    1.1.1.5.1     isOpen

    是否启用该检测器。

     

    PERFORMANCE_LOOP_CALCULATE.isOpen=true

    1.1.1.5.2     includeMethords

     

    在循环中进行计算的方法的名字,比如list.size()szie

    每个方法名以逗号分隔

    PERFORMANCE_LOOP_CALCULATE.includeMethords=size

     

    1.1.1.5.3     preDirectCount

    循环指令保存的前preDirectCount个指令,

    也就是循环指令的前preDirectCount指令中调用了指定的方法就算匹配了

    PERFORMANCE_LOOP_CALCULATE.preDirectCount=3

    1.1.1.5.4     includeMethordsDirect

    循环指令的前preDirectCount个指令中调用的指令的列表

    # all methord direct:INVOKEVIRTUAL = 182;INVOKESPECIAL = 183;INVOKESTATIC = 184;INVOKEINTERFACE = 185;

    PERFORMANCE_LOOP_CALCULATE.includeMethordsDirect=182,185

     

    1.1.1.6      误报说明

    1、可能会把循环体里面的计算当作条件判断的计算

    如果preDirectCount参数的值过大

    可能会把aa.size();当作循环计算

     for(int i = 0,int len = list.size();i < len; i ++) {

               aa.size();

    }

  • 【转】白盒测试静态检查——规划篇

    2010-07-31 01:20:47

     

      经过一段时间的准备,结合平时的开发经验,已经开发出了一系列的自定义检测器。现在需要规划好静态检查的可操作方案。

      一、初步积累期

      静态扫描工具由于会出现误报,以及自行开发的检测插件也是需要经过一定时间的考验。同时,也需要积累一些常见的问题,共享给开发以免再次犯同样的错误。所以,需要一个初步积累的阶段。

      1)手工分析扫描结果

      取得class和对应的源代码,可以先挑一些包,使用Findbugs的GUI工具进行扫描。

      对扫描的结果我们先进行分析。

      2)每天发送分析报告给开发

      报告的特点,必须是转换我们自己的语言,指明会导致的问题,代码的具体位置。

      同时让开发每天对报告进行反馈。

      3)积累bug库

      对于每天扫描出的问题,整理成文档,可以作为原始积累。这些积累,可以作为开发以后学习的文档,乃至日后人工代码评审的文档。

      二、正式使用期

      随着大家都对扫描工具对发现问题的价值的认可,我们会很迫切的要求需要贯彻到我们日常的工作中。

      1)开发阶段

      把插件安装到开发的eclipse环境中,让开发提交代码之前就对代码进行静态扫描。

      让bug消灭在萌芽阶段。

      2)构建阶段

      构建完成之后,我们使用ANT增加一个扫描任务。

      扫描出结构之后,形成报告,并自动发送到开发、测试等人员中。

      让漏网之鱼无处可逃。

      3)完善阶段

      我们需要不断的开发我们的检测器来构筑更加强调的扫描体系。

      可以从开发、以及其它资料找到容易出现问题的代码,然后开发成检测器。

      构筑更加强大、坚固的质量堡垒。

Open Toolbar