欢迎大家光临我的空间,希望能跟大家成为好朋友。

发布新日志

  • 常回来看看

    2010-10-08 17:02:20

    今天上了一下51testing,突然想起了我的空间,就上来看看。

    发现最近的一篇日志竟然是去年的了...哎,一年时间又这样过去了,我这一年收获了什么呢?

    最近的半年可以过的说是比较郁闷+烦躁的,觉得自己的精神变得越来越脆弱了,一点小事都可以让自己生气。

    新接手了一个项目的测试,开始了将近有半年时间了。由于开发人员是半路出家,代码的质量不敢恭维,不仅这样,而且他们的思想好像也没有跟上公司的潮流。竟然觉得在公司还有这样小视QA team的开发team,而且不尊重QA team的劳动成果,无语了...HKG的PM 也是软弱的很,项目管理一团糟,下面的人做事也是乱乱的。

    我现在才深刻的认识到流程的重要性,如果一个项目在立项之初没有确定一个流程,后果会是多么的严重。感觉tl也不是很想管这个项目的事情,自己又觉得自己的力量是多么的微弱,没有力挽狂澜的能力。大家都知道有问题,谁也不想去解决问题,烫手的山芋没人愿意碰...为了自己以后工作的幸福感,我想改变也愿意接受改变,但是没有领导的支持,我能做些什么呢?

    如果你不能改变环境,就只能适应环境了。我不知道该怎么选择?未来是哪条路?

    路漫漫其修远兮,吾将上下而求索...

    头痛,国庆长假刚结束,又开始想休息了,感觉每天都工作的好累...

     

     

  • QTP使用EXCEL对象(转)

    2009-07-31 11:16:16

    最近想用QTP 写一段对excel进行读写和比较的代码,在网上找到一些资料,拿出来跟大家share一下。是转帖的哦,呵呵!

    一、Excel对象模型

      为了在VB应用程序中调用Excel,必须要了解Excel对象模型。Excel对象模型描述了Excel的理论结构,所提供的对象很多,其中最重要的对象,即涉及VB调用Excel最可能用到的对象有:



      二、调用Excel

      在VB应用程序中调用Excel,实质是将Excel作为一个外部对象来引用,由Excel对象模型提供能从VB应用程序内部来程序化操纵的对象以及相关的属性、方法和事件。

      1、在VB工程中添加对Excel类型库的引用

      为了能从VB应用程序中访问Excel丰富的内部资源,使Excel应用程序运行得更快,需要在VB工程中添加对Excel类型库的引用。具体步骤如下:

      a)从VB5“工程”菜单中选择“引用”;

      b) 在“引用”对话框中选择Excel类型库:"Microsoft Excel9.0 Object Library";

      c)单击左边小方框,使之出现“√”符号;

      d)按“确定”退出。

      注:要想在VB应用程序中调用Excel,你的计算机系统中必须安装Excel。

      2、引用Application对象

      Application对象是Excel对象模型的顶层,表示整个Excel应用程序。在VB应用程序中调用Excel,就是使用Application对象的属性、方法和事件。为此,首先要声明对象变量:

    Dim VBExcel As Object

      或直接声明为Excel对象:

    Dim VBExcel As Excel.Application

      在声明对象变量之后,可用CreateObject函数或GetObject函数给变量赋值新的或已存在的Application对象引用。

      a)用CreateObject函数生成新的对象引用:

    Set VBExcel=CreateObject ("Excel.Application")

      字符串“Excel.Application”是提供Excel应用程序的编程ID,这个变量引用Excel应用程序本身。

      b)用GetO场ect函数打开已存在的对象引用:

    Set AppExcel=GetObject("SAMP.XLS")

      上面语句打开文件SAMP.XLS。

      3、Application对象常用的属性、方法

    属性、方法 方法
    Visible属性 取True或False,表明Excel应用程序是否可见。
    Left,Top属性 Excel窗口的位置;
    Height, Width属性 Excel窗口的大小;
    WindowState属性 指定窗口的状态,取:XIMaximized(最大化)X1 Minimized(最小化)x1 Normal(缺省)。
    Quit方法 退出Microsoft Excel;
    Calculate方法 重新计算所有打开的工作簿、工作表或单元格。
    Evaluate方法 求值数学表达式并返回结果。

      示例1:求值数学表达式:

    Dim VBExcel As Object
    Set VBExcel=CreateObject ("Excel.Application")
    X=VBExcel. Evaluate ("3+5*(cos (1/log (99. 9)))")

    三、使用Excel应用程序

      如前所述,在VB应用程序中调用Excel应用程序,就是使用Application对象的属性、方法和事件。下面分类给出其中常用的属性和方法。

      1、使用工作薄

      Workbook对象代表Excel应用程序中当前打开的一个工作簿,包含在Workbooks集合中。可以通过Workbooks集合或表示当前活动工作簿的Active Workbook对象访问Workbook对象。

      常用的方法有:

    属性、方法 意义
    Add方法 创建新的空白工作簿,并将其添加到集合中。
    Open方法 打开工作簿。
    Activate方法 激活工作簿,使指定工作簿变为活动工作簿,以便作为Active Workbook对象使用。
    Save方法 按当前路径和名称保存现有工作簿(如是首次保存,则将其保存到缺省名称中,如BOOK1.XLS)。
    SaveAs方法 首次保存工作簿或用另一名称保存工作簿。
    Close方法 关闭工作簿。
    PrintOut方法 打印工作簿,语法为:

    PrintOut (from, To, Copies, Preview, Printer, ToFile, Collate)

      可选参数:

     From:打印的起始页号。如省略将从起始位置开始打印。
     To:打印的终止页号。如省略将打印至最后一页。
     Copies:要打印的份数。如省略将只打印一份。
     Preview:如果为True则Excel打印指定对象之前进行打印预览。如果为False,或省略则立即打印该对象。
     Printer:设置活动打印机的名称。
     ToFile:如果为True则打印输出到文件。
     Collate:如果为True则逐份打印每份副本。

      下面语句将活动工作簿的2到5页打印3份:

    ActiveWorkbook.PrintOut From:=2 To 5 Copies:=3

      示例2:生成、保存、关闭工作簿

    Dim VBExcel As Excel.Application
    Set VBExcel== CreateObject("Excel.Application")
    With VBExcel
    .Workbooks.Add
    With ActiveWorkbook
    .Save As"C: \Temp \OUTPUT.XLS"
    .Close
    End With
    .Quit
    End With

      2、使用工作表

      Sheets集合表示工作簿中所有的工作表。可以通过Sheets集合来访问、激活、增加、更名和删除工作表。一个Worksheet对象代表一个工作表。

      常用的属性、方法有:

    属性、方法 意义
    Worksheets属性 返回Sheets集合。
    Name属性 工作表更名。
    Add方法 创建新工作表并将其添加到工作簿中。
    Select方法 选择工作表。
    Copy方法 复制工作表。
    Move方法 将指定工作表移到工作簿的另一位置。
    Delete方法 删除指定工作表。
    PrintOut方法 打印工作表。

      示例3:将C盘工作簿中的工作表复制到A盘工作簿中:

    Dim VBExcel As Excel.Application
    Set VBExcel=CreateObject("Excel.Application")
    With VBExcel
     .Workbooks.Open "C:\Temp\OUTPUT.XLS"
     .Workbooks.Open"A:\OUTPUT1.XLS"
     .Workbooks("OUTPUT.XLS").Sheets ("Sales").Copy
     .Workbooks("OUTPUT1.XLS)
     .Workbooks("OUTPUT1.XLS").Save
     .Workbooks("OUTPUT.XLS").Close
     .Workbooks("OUTPUTI.XLS").Close
     .Quit
    End With

      3、使用单元范围

      Range对象代表工作表的某一单元格、某一行、某一列、某一选定区域或者某一三维区域。

      常用的属性、方法有:

    属性、方法 意义
    Range属性 Range (arg)其中arg为A1--样式符号,表示单个单元格或单元格区域。
    Cells属性 Cells (row, col )(其中row为行号,col为列号)表示单个单元格。
    ColumnWidth属性 指定区域中所有列的列宽。
    Rowl3eight属性 指定区域中所有行的行宽。
    Value属性 指定区域中所有单元格的值(缺省属性)。
    Formula属性 指定单元格的公式,由A1--样式引用。
    Select方法 选择范围。
    Copy方法 将范围的内容复制到剪贴板。
    C1earContents方法 清除范围的内容。
    Delete方法 删除指定单元范围。

      4、使用图表

      Chart对象代表工作簿中的图表。该图表既可为嵌人式图表(包含于ChartObject对象中)也可为分立的图表工作表。

      常用方法有:

    方法

    意义

    Add方法 新建图表工作表。返回Chart对象。
    PrineOut方法 打印图表。
    ChartWizard方法 修改给定图表的属性,其语法为:
     
    ChartWizard(Source, Gallery, Format, P1otBy, CategoryLabels,
    SeriesLabels, HasLegend, Title, CategoryTitle, ValueTitle, ExtraTitle)

      其中:

      Source:包含新图表的源数据的区域。如省略,将修改活动图表工作表或活动工作表中处于选定状态的嵌人式图表。

      Gallery:图表类型。其值可为下列常量之一:xlArea, x1Bar, xlColumn, xlLine, x1Pie, xlRadar,x1XYScatter, xlCombination, x13DArea, x13DBar、x13DColumn, x13DLine, x13DPie、x13 DSurface、xlDoughnut或xlDefaultAutoFormat。

      Format:内置自动套用格式的编号。如省略,将选择默认值。

      P1otBy:指定系列中的数据是来自行(xlRows)还是列(xlColumns)。

      CategoryLabels:表示包含分类标志的源区域内行数或列数的整数。

      SeriesLabels:表示包含系列标志的源区域内行数或列数的整数。

      HasLegend:若指定True,则图表将具有图例。

      Title:图表标题文字。

      CategoryTitle:分类轴标题文字。

      ValueTitle:数值轴标题文字。

      ExtraTitle:三维图表的系列轴标题,或二维图表的第二数值轴标题。

      可组合使用Add方法和ChartWizard方法,以创建包含工作表中数据的图表工作表。下例基于工作表“Sheetl”中单元格区域“A1:A20”中的数据生成新的折线图并打印。

    With Charts.Add
     .ChartWizard source:=Worksheets ("sheet1").Range ("a1:a20"),gallery:=xlLine, title:=“折线图表”
     .Printout
    End With


      5、使用Excel工作表函数

      在VB语句中可使用大部分的Excel工作表函数,可通过WorksheetFunction对象调用Excel工作表函数。下面的Sub过程用Min工作表函数求出指定区域中单元格的最小值,并通过消息框显示结果值。

    Sub UseFunction()
    Dim myRange As Range
    Set myRange=Worksheets ("Sheet1").Range("B2:F10")
    answer=Application.WorksheetFunction.Min(myRange)
    MsgBox answer
    End Sub

      如果使用以区域引用为参数的工作表函数,必须指定一个Range对象。如可用Match工作表函数对A1:A10区域的所有单元格进行搜索。

    Sub FindFirst()
    my Var=Application.WorksheetFunction.Match (9, Worksheets( 1).Range("A1:A10"),0)
    MsgBox myVar
    End Sub

      要在单元格中插人工作表函数,可将该函数指定为对应于Range对象的Formula属性值。在以下示例中,将当前工作簿Sheetl内A1:B3区域的Formula属性指定为RAND工作表函数(此函数产生二个随机数)。

    Sub InsertFormula()
    Worksheets ("Sheet1" ).Range("A1:B3").Formula="RAND()"
    End Sub
  • 几种性能测试常用的方法

    2009-03-17 14:15:54

       今天在《软件性能测试过程详解与案例剖析》中看到对几种性能测试常用方法的概念定义,觉得写的很清晰,特贴出来和大家共享:

    性能测试(performance testing)方法是通过模拟生产运行的业务压力量和使用场景组合,测试系统的性能是否满足生产性能要求。主要目的是验证系统是否有系统宣称具有的能力。

    负载测试(load testing)方法通过在被测系统上不断增加压力,直到性能指标。主要目的是找到系统处理能力的极限。

    压力测试(stress testing)方法测试系统在一定饱和状态下,例如CPU、内存等在饱和使用情况下,系统能够处理的会话能力,以及系统是否会出现错误。主要目的是检查系统处于压力情况下,应用的表现。

     

    配置测试(configuration testing)方法通过被测系统的软/硬件环境的调整,了解各种不同环境对系统性能影响的程度,从而找到系统各项资源的最优分配原则。主要目的是了解各种不同因素对系统性能影响的程度,从而判断出最值得进行的调优操作。

     

    并发测试(concurrency testing)方法通过模拟用户的并发访问,测试多用户并发访问同一个应用、同一个模块或者数据记录时是否在死锁或者其他性能问题。主要目的时发现系统中可能隐藏的并发访问时的问题。

     

    可靠性测试(reliability testing)方法通过给系统加载一定的业务压力(例如资源在70%~90%的使用率)的情况下,让应用持续运行一段时间,测试系统在这种条件下是否能够稳定运行。主要目的时验证系统是否支持长期稳定的运行。

     

    失效恢复测试(failover testing)方法是针对有冗余备份和负载均衡的系统设计的。这种测试方法可以用来检验如果系统局部发生故障,用户是否能够继续使用系统;以及如果这种情况发生,用户将受到多大程度的影响。主要目的是验证在局部故障情况下,系统能否继续使用。

  • [转]在QTP中使用描述性编程(实例)

    2009-03-06 13:29:32

    QTP中使用描述性编程是一个提高QTP脚本利用率的很好的方式。
            通常QTP是通过对象库来识别不同的对象,而描述性编程是QTP另外一种能够识别对象的途径,它不依赖于对象库,通过增加一些对象的描述来识别对象的。
     
            说明:本例子是以Flight飞机订票系统的登陆界面为测试页面进行描述的。
     
            步骤一:录制脚本
    Dialog("Login").WinEdit("Agent Name:").Set "Holly"
    Dialog("Login").WinEdit("Password:").SetSecure "46ef0dc7efe5834c73673898279af1204fea51a7"
    Dialog("Login").WinButton("Cancel").Click
    共录制3步操作,输入Agent Name, Password, 点击Cancel按钮
     
            步骤二:初级描述性编程
    Dialog("Regexpwndtitle:=Login").WinEdit("Attached text:=Agent Name:").Set "Holly"
    Dialog("Regexpwndtitle:=Login").WinEdit("Attached text:=Password:").Set “Mercury
    Dialog("Regexpwndtitle:=Login").WinButton("Class Name:=WinButton", "text:=Cancel").Click
            在这里要注意有三点:
            1)如果需要两个以上特性来描述一个对象,需要使用逗号(,)对描述性语言进行分割
            2)使用:=来连接属性和属性值,并且:=两边不能有空格
            3)使用SPY查看对象的属性名和属性值(Tools -> Object Spy)
     
            步骤三:描述性编程提高
    Dim descEditLogin
    Set descEditLogin = Description.Create()
    descEditLogin("Class Name").Value = "Dialog"
    descEditLogin("Regexpwndtitle").Value = "Login"
     
    Dialog(descEditLogin).WinEdit("Attached text:=Agent Name:").Set "Holly"
    Dialog(descEditLogin).WinEdit("Attached text:=Password:").Set "Mercury"
    Dialog(descEditLogin).WinButton("Class Name:=WinButton", "text:=Cancel").Click
            在这里需要注意有两点:
            1)把经常使用到的对象定义为一个对象变量,方便以后调用,减少代码工作量和错误
            2)使用SPY获取对象的属性和属性值
     
            步骤四:使用自定义的环境变量
            在File>>Settings>>Environment中选择user-defined,增加一个变量
    dlgLogin = “Login”
     
            这样脚本可以被修改为:
    Dim descEditLogin
    Set descEditLogin = Description.Create()
    descEditLogin("Class Name").Value = "Dialog"
    descEditLogin("Regexpwndtitle").Value = Environment.Value("dlgLogin")
     
    Dialog(descEditLogin).WinEdit("Attached text:=Agent Name:").Set "Holly"
    Dialog(descEditLogin).WinEdit("Attached text:=Password:").Set "Mercury"
    Dialog(descEditLogin).WinButton("Class Name:=WinButton", "text:=Cancel").Click
            当然,参数化的方式很多,这边介绍的是使用环境变量
     
            步骤五:从XML文件导入环境变量
    <Enviroment>
           <Variable>
                  <Name>dlgLogin</Name>
                  <Value>Login</Value>
           </Variable>
    </Environment>
    可以使用手工导入,也可以使用LoadFromFile自动导入
     
            总结:
            优点是当对象的一些属性变更后,脚本更容易维护。
            比如说对于一个通用对象,比如save, reset, cancel等按钮,一个页面有3个,30个页面就有90个对象,
            假如save变成保存,reset变成重置,cancel变成取消,那么对象库就会产生很大的变动。
            而使用了描述性编程只需要在导入的XML文件中修改一个值就可以了。
            当然描述性编程的作用远远不止这些,这次只是抛砖引玉,希望大家共同进步。
  • 坚持“折腾”的测试理念

    2009-03-06 09:12:24

        最近在测的一个项目真是让我觉得很迷茫,才发现原来软件的流程是这么的重要。

    需求在测试的前一个星期还在修改,导致了项目开发的延迟。在讨论测试用例的时候才发现有些需求根本就是错误的,开发人员埋怨测试人员为什么没有早发现问题,作为这个系统唯一的一名兼职的测试人员,我真的很无语。手上的两个系统时间衔接很紧,基本上是测完一个就开始另一个了,这样才导致我在测试的前一个星期才有时间分析需求,写测试用例。仔细分析业务需求不是应该需求分析者,开发人员,测试人员都要做的吗?为什么开发人员会埋怨测试人员呢?难道只是因为测试人员提出的需求错误导致他们要重新写代码吗?现在已经测试一个星期了,其中发现了一些问题,但是开发人员不想改,可能认为问题不算严重,改代码的代价大于实现功能的代价吧。这些我都可以理解,但是开发人员的一句话让我的心凉到极点“少折腾!!”,难道我提出问题就是为了折腾大家么?真是想不到公司里面现在还存在这样混乱的项目组?这也让我深思了是否需要从另一种视角来考虑这个系统的测试,是否按照他们的说法“不折腾”的来测试?想到我们是公司的“质量保证”部门,保证软件的质量就是我们的工作,我决定继续折腾,提出问题。把问题都摆在台面上,大家一起分析,哪些需要改进,哪些可以以后再做。也许有人会在背后说我“一跟筋,傻瓜“,but I am a Quality Assurance, that’s my job.希望我的坚持能唤起他们对流程和质量的重视!

  • 【转】EMMA:测试覆盖率工具(2)

    2008-06-26 10:54:20

    本文主要通过一个示例项目介绍如何在集成了 Ant 和 Junit 的基础上,利用 EMMA 来收集单元测试对代码的覆盖率。

    介绍测试代码覆盖率的重要性

    测试驱动开发(TDD)是极限编程的一个重要特点,它具有很多优点,并被越来越多的开发人员所接受。在测试驱动开发过程中,程序员经历了编写测试用例,实现功能,重构代码这个不断迭代的过程。实践证明,这个过程能显著提高我们的生产效率,并产生高质量的代码。它还能给我们以自信,让我们放心的重构自己的代码。

    测试代码确实能够保证代码的质量,但如果你以为自己已经写了一堆测试用例,并都能运行通过时,就能高枕无忧了,那么你错了。隐藏的 Bug 也许只是在等待时机让你的系统崩溃。这是什么原因呢?聪明的你肯定已经想到,测试代码是用来保证功能代码的质量的,但测试代码的质量如何,我们不得而知。我们需要知道,我们辛苦编写的测试代码到底覆盖了多少功能代码,这就是我写这篇文章的出发点,我将介绍一种测试代码覆盖率的工具 - EMMA。


    介绍 EMMA

    EMMA 是一个用于检测和报告 JAVA 代码覆盖率的开源工具。它不但能很好的用于小型项目,很方便得得出覆盖率报告,而且适用于大型企业级别的项目。

    EMMA 有许多优点,首先你能免费得到它,并把它用于自己项目的开发。它支持许多种级别的覆盖率指标:包,类,方法,语句块(basic block)和行,特别是它能测出某一行是否只是被部分覆盖,如条件语句短路的情况。它能生成 text,xml,html 等形式的报告,以满足不同的需求,其 html 报告提供下钻功能,我们能够从 package 开始一步步链接到我们所关注的某个方法。EMMA 能和 Makefile 和 Ant 集成,便于应用于大型项目。特别还须指出的一点是,EMMA 的效率很高,这对于大型项目来说很重要。

    EMMA 是通过向 .class 文件中插入字节码的方式来跟踪记录被运行代码信息的。EMMA 支持两种模式:On the fly 和 Offline 模式。

    On the fly 模式往加载的类中加入字节码,相当于用 EMMA 实现的 application class loader 替代原来的 application class loader。

    Offline 模式在类被加载前,加入字节码。

    On the fly 模式比较方便,缺点也比较明显,如它不能为被 boot class loader 加载的类生成覆盖率报告,也不能为像 J2EE 容器那种自己有独特 class loader 的类生成覆盖率报告。这时,我们能求助于 Offline 模式。

    EMMA 也支持两种运行方式:Command line 和 Ant。

    本文后面提供的实例主要是演示如何集成 EMMA 和 Ant,通过 Offline 模式产生覆盖率报告。

    示例工程 SampleProject 是个小型的项目,有一个类 NumberParser,主要功能是把一个字符串解析成 float 型。下面是整个工程的目录结构。

    图1. 示例项目的目录结构
    图1. 示例项目的目录结构 

    下面,我们开始来为我们的工程编写 Ant 脚本。


    清单1设置一些属性,包括源文件,二进制文件,JUnit 报告,覆盖率报告等的路径
                <!-设置Java类被注入字节码后存放的路径-->
                <property name="bin.instrument.dir" location="../instrbin" />
                <!-设置覆盖率元数据和报告的路径-->
                <property name="coverage.dir" location="../coverage" />
                <!--设置junit报告的路径 -->
                <property name="junitReport.dir" location="../junitReport" />
                <!-设置主题代码bin路径-->
                <property name="bin.main.dir" location="../srcbin" />
                <!-设置测试代码bin路径-->
                <property name="bin.test.dir" location="../testbin" />
                <!--设置主题代码源路径-->
                <property name="src.main.dir" location="../../SampleProject/src" />
                <!--设置测试代码源路径-->
                <property name="src.test.dir" location="../../SampleProjectTest/test"
                />
                <!-指示需要注入字节码的Java类的路径-->
                <path id="classpath.main">
                <pathelement location="${bin.main.dir}" />
                </path>
                <!-指示 emma.jar 和emma_ant.jar 的路径-->
                <path id="emma.lib">
                <pathelement location="${libs}/emma.jar" />
                <pathelement location="${libs}/emma_ant.jar" />
                </path>
                <!-允许emma-->
                <property name="emma.enabled" value="true" />
                

    其中目录${ bin.instrument.dir }存放被注入字节码的类,"emma.lib" 指向 emma 资源所在的位置。
    清单2为 ANT 定义 EMMA 任务

    	<!-为ANT添加EMMA任务-->
                <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
                

    清单3编译源代码和测试代码
    		<target name="compile-src.main">
                <mkdir dir="${bin.main.dir}" />
                <javac destdir="${bin.main.dir}" debug="on">
                <src path="${src.main.dir}" />
                </javac>
                <copy todir="${bin.main.dir}">
                <fileset dir="${src.main.dir}">
                <exclude name="**/*.java" />
                </fileset>
                </copy>
                </target>
                <target name="compile-src.test">
                <mkdir dir="${bin.test.dir}" />
                <javac destdir="${bin.test.dir}" debug="on">
                <src path="${src.test.dir}" />
                <classpath location="${bin.main.dir}" />
                </javac>
                <copy todir="${bin.test.dir}">
                <fileset dir="${src.test.dir}">
                <exclude name="**/*.java" />
                </fileset>
                </copy>
                </target>
                

    编译分两阶段,先编译源代码,然后再编译测试用例代码。

    清单4在所要测试类的代码中插入字节码
    		<!-对编译在路径bin.main.dir中的Java类注入字节码,
                并且把注入字节码的新Java类存放到路径bin.instrument.dir-->
                <!-覆盖率的元数据存放在路径coverage.dir中-->
                <target name="instrument">
                <mkdir dir="${bin.instrument.dir}" />
                <mkdir dir="${coverage.dir}" />
                <emma enabled="${emma.enabled}">
                <instr instrpathref="classpath.main"
                destdir="${bin.instrument.dir}"
                metadatafile="${coverage.dir}/metadata.emma"
                merge="true">
                </instr>
                </emma>
                <copy todir="${bin.instrument.dir}">
                <fileset dir="${bin.main.dir}">
                <exclude name="**/*.java" />
                </fileset>
                </copy>
                </target>
                

    当${emma.enabled}为 true 时,才生成插入字节码的类。<instr>中指定了要 instrument 的类的地址, instrumented 后类存放的地址,以及 metadata 存放的地址。
    清单5运行测试用例,得到一些生成报告的元数据

                <!-执行测试用例同时生成junit测试报告和emma代码覆盖率报告-->
                <target name="test">
                <mkdir dir="${junitReport.dir}" />
                <junit fork="true" forkmode="once"
                printsummary="withOutAndErr"
                errorproperty="test.error"
                showoutput="on">
                <!-指明代码覆盖率的元数据的存放位置-->
                <jvmarg
                value="-Demma.coverage.out.file=${coverage.dir}/metadata.emma" />
                <jvmarg value="-Demma.coverage.out.merge=true" />
                <classpath location="${bin.instrument.dir}" />
                <classpath location="${bin.test.dir}" />
                <classpath refid="emma.lib" />
                <formatter type="xml" />
                <!-执行所有以Test结尾的junit测试用例-->
                <batchtest todir="${junitReport.dir}" haltonfailure="no">
                <fileset dir="${bin.test.dir}">
                <include name="**/*Test.class" />
                </fileset>
                </batchtest>
                </junit>
                </target>
                

    在运行测试用例前,需要设置 jvmarg。所有的测试用例都跑在 instrumented 的类上面。
    清单6生成 JUnit 报告
     

                <target name="gen-report-junit">
                <!-生成junit测试报告-->
                <junitreport todir="${junitReport.dir}">
                <fileset dir="${junitReport.dir}">
                <include name="*" />
                </fileset>
                <report format="frames" todir="${junitReport.dir}" />
                </junitreport>
                </target>
                

     清单7生成覆盖率报告
    		<!-生成代码覆盖率报告-->
                <target name="gen-report-coverage">
                <!-如果属性emma.enabled的值是true,就生成代码覆盖率报告 -->
                <emma enabled="${emma.enabled}">
                <report sourcepath="${src.main.dir}"
                sort="+block,+name,+method,+class"
                metrics="method:70,block:80,line:80,class:100">
                <fileset dir="${coverage.dir}">
                <include name="*.emma" />
                </fileset>
                <html ōutfile="${coverage.dir}/coverage.html"
                depth="method" columns="name,class,method,block,line" />
                </report>
                </emma>
                </target>
                

    指明源代码所在的位置,以便能够显示每行代码的覆盖情况。Sort指明生成列表的排列顺序,"+"表示升序,"-"表示降序。Metrics 可为每个度量指明一个覆盖率阈值,若未达到该阈值,则该行会被标记出来(前提是报告的形式支持这个功能,如 HTML)。<html>指明以 HTML 形式生成报告,Depth 指明报告的详细程度,columns 指明生成列表列名的排列顺序。


    显示报告

    我们已经写好了Ant脚本,接下来你就可以运行该脚本了。这里假设你已经搭好了运行 Ant 和 JUnit 的环境,直接到脚本所在目录,在命令行敲入 Ant 即可。
    图2整个项目层次的报告
    图2整个项目层次的报告 
    图3包层次的报告
    图3包层次的报告
    图4类层次的报告
    图4类层次的报告 图5用颜色标记的源代码

    你会发现有三种颜色,绿色,红色和黄色,它们分别表示该行:被测试到,未被测试到,以及部分被测试到。红色或黄色的部分是需要引起你注意的,bug 也许就隐藏在这部分代码中,你所需做的就是设计一些测试用例,使它们运行以前未被执行到的语句。如上面那张图给出了我们一些信息,String 中含有"+"号的情况未被测试到,还有"isPositive"只被测试到 true 或 false 的一种情况,你需要相应的增加一些测试用例。运行新加的测试用例,你也许会发现一些新的 bug,并修正这些 bug。TestAge 中国软件测试时代

    藏在报告背后的问题

    对于这个简单的例子,你会发现,我们很容易达到 100% 的测试覆盖率,你也许会松口气说:啊,我把所有情况都测试到了,这下放心了。在这里很遗憾的告诉你,EMMA 的功能是有限的,它不支持决策覆盖和路径覆盖。事实上,对于一个稍复杂的工程进行穷尽的测试是不可能的。


    清单8决策覆盖和路径覆盖的代码示例
                /**
                * Parses the given string to a float number
                *
                * @param number
                *            the given string
                * @return the float number related with the string
                *
                * @throws IllegalArgumentException
                *             if the string is empty, null or can not parse to a float
                */
                public float parse(String number) {
                if (number.equals("")||number == null ) {
                throw new IllegalArgumentException(
                "Number string should not be empty or null");
                }
                StringIterator stringIterator = new StringIterator(number);
                getSign(stringIterator);
                int integer = getInteger(stringIterator);
                float fraction = getFraction(stringIterator);
                float total = integer + fraction;
                return isPositive ? total : (-1) * total;
                }
                

     清单9决策覆盖和路径覆盖的测试用例
                public void test_parse () {
                NumberParser np = new NumberParser();
                String number ="";
                try {
                np.parse(number);
                fail("should throw IAE");
                } catch (IllegalArgumentException e) {
                // pass
                }
                number = "22.010";
                float parsedNumber = np.parse(number);
                assertEquals((float) 22.010, parsedNumber);
                number = "-22.010";
                parsedNumber = np.parse(number);
                assertEquals((float) 22.010, parsedNumber);
                }
                

    运行 Ant 脚本,生成报告,你会发现,测试用例都运行通过了,测试覆盖报告也表明代码所有的行都被执行到了。但细心的读者肯定早已看到上面代码存在 Bug。若传进 parse 的 string 为 null 的话,并不是如我们所愿,得到 IllegalArgumentException,而是抛出了 NullPointerException。

    虽然下面那行是绿色的,但它只表明每个条件语句都被执行到了,并不能说明每个条件都取到true和false两种情况。在我们设计的测试用例中,"null == number"只取到 false 一种情况。我们需要在我们的测试用例中加入对 string 情况是 null 的测试。


    图6 决策覆盖和路径覆盖率报告
    图6 决策覆盖和路径覆盖率报告 
    清单10 修正代码的 Bug
     
                    if (null == number || "".equals(number)) {
                

    为你的项目生成覆盖率报告,EMMA 是个不错的选择。通过覆盖率报告,我们能发现并修复一些隐藏的 bug,我们的软件会变得更强壮。

  • 【转】EMMA:测试覆盖率工具(1)

    2008-06-26 10:40:46

    以前在做过的一个项目上面应用过EMMA,不过当时不是很清楚原理,今天又重新学习了一下。找了两篇不错的帖子跟大家共享一下,呵呵。

    在讨论EMMA的使用之前,我首先简要介绍几个相关的概念。

     测试覆盖率(Code Coverage)
      测试覆盖率,简单的说,就是评价测试活动覆盖产品代码的指标。测试的目的,是确认产品代码按照预期一样工作,也可以看作是产品代码工作方式的说明文档。进一步考虑,测试覆盖率可以看作是产品代码质量的间接指标--之所以说是间接指标,因为测试覆盖率评价的是测试代码的质量,并不是产品代码的质量。

     代码覆盖率是一种白盒测试,因为测试覆盖率是评价产品代码类内部的指标,而不是评价系统接口或规约。测试覆盖率尤其用于评价测试代码是否已经覆盖了产品代码所有的路径。

     衡量测试覆盖率的指标很多,常用的指标有:

     Statement coverage,也称作Line coverage,用于评价测试的代码语句覆盖率。

     Basic block coverage,是Statement coverage的一个变种,它把没有一个分支的代码区域作为一个计量单位,而不是简单的代码行,用于一个if-else分支代码行数远远大于另一个的情况,在这种情况下,statement coverage指标并不适用。

     Decision coverage(也称作Branch coverage),用于评价代码分支地测试覆盖率。

     Path coverage,和Decision coverage相似,用于评价代码从开始到结束所有路径的测试覆盖率。

     Function coverage,用于评价代码方法的测试覆盖率。

     EMMA目前支持四种Coverage类型:class、method、line和basic block。

     测试覆盖率的实现方式

      实现测试服务覆盖率的技术通常分为两种:

     1、Instrumentation

     Instrumentation技术在产品代码的关键位置插入统计代码。事实上,Instrumentation技术可以分为两种方式:Class Instrumentation和Source Instrumentation。前者把统计代码插入编译好的.class文件,而后者则把统计代码插入源代码并编译成新的.class文件。大多数测试覆盖率工具采用这两种Instrumentation技术。

       2、Custom JVM

     另一种方式是在JVM中把统计代码插入.class。测试覆盖率分析可以在JVM执行测试代码的过程中完成。

     测试覆盖率工具的典型特性
      1、和Ant集成
      2、多种报告输出格式
      3、源代码链接
      4、覆盖率历史报告

     EMMA的特点

     Instrumentatiton方式:EMMA使用两种模式来实现覆盖率的统计,它称作“offline”和“on-the-fly”。EMMA使用Instrumentation .class文件的方式。EMMA通过byte instrumentation生成.class文件的增强版本,加入了统计测试覆盖率的代码Hook。对于“offline”模式,它从硬盘读入.class文件,然后输出经过Instrumented的增强版本;对于“on-the-fly”模式,这些操作发生在JVM内部(即增强版本的.class文件不写入硬盘)。前者是通用的模式,而后者用于简单的Java应用程序。

      支持的覆盖率指标:EMMA支持class,method,line和basic block coverage指标。
      优越的性能和可伸缩性。
      Java平台支持:EMMA支持Java 1.2或更高版本的JVM,不依赖于任何第三方类库。
      CPL License。
      使用EMMA:命令行方式

     安装EMMA的jar文件到类路径-最简单的方法是,把emma.jar复制到/lib/ext/。注意,不要复制emma_ant.jar,否则使用Ant脚本会出错。
    on-the-fly模式:使用emmarun-使用-g选项编程java源代码,javac -g -d out ,然后执行java emmarun -cp out 。本方法把instrumentation和执行过程合而为一。
    offline模式:分开instrumentation过程和执行过程-首先使用-g选项编译java源代码,javac -g -d out ;然后是instrumentation,java emma instr -d outinstr -ip out,注意,经过instrumentation的class目标目录是outinstr;最后是执行过程,java -cp outinstr;out ,注意,把经过instrumentation的类路径放在前面,并在后面加上原来的类路径,因为instr命令没有处理properties文件和interface,这些都是执行过程需要的。
    使用EMMA:Ant

     设置instrumentation属性

    <property name="coverage.dir" value="${basedir}/coverage" />
    <property name="out.instr.dir" value="${basedir}/outinstr" />
    <property name="emma.enabled" value="true" />
    <property name="javac.debug" value="on" />
    <!-- path element used by EMMA taskdef below: -->
    <path id="emma.lib" >
    <pathelement location="${libs}/emma.jar" />
    <pathelement location="${libs}/emma_ant.jar" />
    </path>

    在Ant脚本中加入EMMA task
    <!-- this loads <emma> and <emmajava> custom tasks: -->
    <taskdef resource="emma_ant.properties" classpathref="emma.lib" />

    在编译Task中打开debug选项
    <target name="compile">
    <mkdir dir="${classes.main}" />
    <javac srcdir="${src.main}" destdir="${classes.main}" debug="${javac.debug}">
    <classpath refid="classpath.lib" />
    </javac>
    <copy todir="${classes.main}">
    <fileset dir="${src.main}" includes="**/*.xml, **/*.vm" />
    </copy>
    </target>

    instrumentation task
    <target name="instrument" depends="compile">
    <mkdir dir="${out.instr.dir}" />
    <mkdir dir="${coverage.dir}" />
    <emma enabled="${emma.enabled}" >
    <instr instrpathref="classpath.main"
    destdir="${out.instr.dir}"
    metadatafile="${coverage.dir}/metadata.emma"
    merge="true"
    >
    <filter excludes="com.talent.fw.formula.test.*Test*,com.talent.fw.esb.*Test*,com.talent.fw.message.test.*,com.
    talent.fw.entityengine.*Test*,com.talent.fw.integration.*Test*,com.talent.fw.security.impl.*Test*,testdomain.*" />
    </instr>
    </emma>
    </target>

    JUnit测试
    <target name="test" depends="compile, instrument">
    <mkdir dir="${reports.junit.data}" />
    <mkdir dir="${classes.main}/maps" />
    <mkdir dir="${classes.main}/scrīpts" />

    <copy todir="${classes.main}/maps">
    <fileset dir="${src.main}/maps" />
    </copy>
    <copy todir="${classes.main}/scrīpts">
    <fileset dir="${src.main}/scrīpts" />
    </copy>
    <copy todir="${classes.main}">
    <fileset dir="${src.main}" includes="*.xml, *.properties, **/*.vm, **/*.dtd" />
    </copy>

    <rmic classname="com.talent.fw.message.test.RMITestServer" base="${classes.main}"/>

    <junit printsummary="yes" haltonfailure="no" failureproperty="tests.failed">
    <classpath location="${out.instr.dir}" />
    <classpath location="${classes.main}" />
    <classpath location="${src.main}" />
    <classpath refid="classpath.lib" />
    <jvmarg value="-Demma.coverage.out.file=${coverage.dir}/coverage.emma" />
    <jvmarg value="-Demma.coverage.out.merge=true" />
    <formatter type="xml" />
    <batchtest fork="yes" todir="${reports.junit.data}" failureproperty="tests.failed">
    <fileset dir="${classes.main}">
    <include name="**/*Test.class" />
    <exclude name="**/AllTests.class" />
    <exclude name="**/Base*Test.class" />
    </fileset>
    </batchtest>
    </junit>
    </target>

    生成报告并复制到Tomcat的发布目录下
    <target name="coverage.report" depends="instrument">
    <!-- if enabled, generate coverage report(s): -->
    <emma enabled="${emma.enabled}" >
    <report sourcepath="${src.main}"
    sort="+block,+name,+method,+class"
    metrics="method:70,block:80,line:80,class:100"
    >
    <fileset dir="${coverage.dir}" >
    <include name="*.emma" />
    </fileset>

    <!-- <xml ōutfile="${coverage.dir}/coverage.xml" depth="package" /> -->
    <html ōutfile="${coverage.dir}/coverage.html" depth="method"
    columns="name,class,method,block,line"
    />
    </report>
    </emma>

    <mkdir dir="${coverage.publish.dir}" />
    <copy todir="${coverage.publish.dir}">
    <fileset dir="${coverage.dir}">
    <include name="**/*.html" />
    </fileset>
    </copy>
    </target>

      和CruiseControl集成
      最简单的集成方式是在cruisecontrol的navigation.jsp文件下方加入EMMA测试覆盖率报告的超链接。如下图:



      进一步的集成方式是,在生成HTML报告的同时,生成XML格式的报告,并为XML格式报告编写XSL文件,并加入到CruiseControl的buildresults.jsp文件中。

     

  • 【转】EMMA:测试覆盖率工具(1)

    2008-06-26 10:40:40

    以前在做过的一个项目上面应用过EMMA,不过当时不是很清楚原理,今天又重新学习了一下。找了两篇不错的帖子跟大家共享一下,呵呵。

    在讨论EMMA的使用之前,我首先简要介绍几个相关的概念。

     测试覆盖率(Code Coverage)
      测试覆盖率,简单的说,就是评价测试活动覆盖产品代码的指标。测试的目的,是确认产品代码按照预期一样工作,也可以看作是产品代码工作方式的说明文档。进一步考虑,测试覆盖率可以看作是产品代码质量的间接指标--之所以说是间接指标,因为测试覆盖率评价的是测试代码的质量,并不是产品代码的质量。

     代码覆盖率是一种白盒测试,因为测试覆盖率是评价产品代码类内部的指标,而不是评价系统接口或规约。测试覆盖率尤其用于评价测试代码是否已经覆盖了产品代码所有的路径。

     衡量测试覆盖率的指标很多,常用的指标有:

     Statement coverage,也称作Line coverage,用于评价测试的代码语句覆盖率。

     Basic block coverage,是Statement coverage的一个变种,它把没有一个分支的代码区域作为一个计量单位,而不是简单的代码行,用于一个if-else分支代码行数远远大于另一个的情况,在这种情况下,statement coverage指标并不适用。

     Decision coverage(也称作Branch coverage),用于评价代码分支地测试覆盖率。

     Path coverage,和Decision coverage相似,用于评价代码从开始到结束所有路径的测试覆盖率。

     Function coverage,用于评价代码方法的测试覆盖率。

     EMMA目前支持四种Coverage类型:class、method、line和basic block。

     测试覆盖率的实现方式

      实现测试服务覆盖率的技术通常分为两种:

     1、Instrumentation

     Instrumentation技术在产品代码的关键位置插入统计代码。事实上,Instrumentation技术可以分为两种方式:Class Instrumentation和Source Instrumentation。前者把统计代码插入编译好的.class文件,而后者则把统计代码插入源代码并编译成新的.class文件。大多数测试覆盖率工具采用这两种Instrumentation技术。

       2、Custom JVM

     另一种方式是在JVM中把统计代码插入.class。测试覆盖率分析可以在JVM执行测试代码的过程中完成。

     测试覆盖率工具的典型特性
      1、和Ant集成
      2、多种报告输出格式
      3、源代码链接
      4、覆盖率历史报告

     EMMA的特点

     Instrumentatiton方式:EMMA使用两种模式来实现覆盖率的统计,它称作“offline”和“on-the-fly”。EMMA使用Instrumentation .class文件的方式。EMMA通过byte instrumentation生成.class文件的增强版本,加入了统计测试覆盖率的代码Hook。对于“offline”模式,它从硬盘读入.class文件,然后输出经过Instrumented的增强版本;对于“on-the-fly”模式,这些操作发生在JVM内部(即增强版本的.class文件不写入硬盘)。前者是通用的模式,而后者用于简单的Java应用程序。

      支持的覆盖率指标:EMMA支持class,method,line和basic block coverage指标。
      优越的性能和可伸缩性。
      Java平台支持:EMMA支持Java 1.2或更高版本的JVM,不依赖于任何第三方类库。
      CPL License。
      使用EMMA:命令行方式

     安装EMMA的jar文件到类路径-最简单的方法是,把emma.jar复制到/lib/ext/。注意,不要复制emma_ant.jar,否则使用Ant脚本会出错。
    on-the-fly模式:使用emmarun-使用-g选项编程java源代码,javac -g -d out ,然后执行java emmarun -cp out 。本方法把instrumentation和执行过程合而为一。
    offline模式:分开instrumentation过程和执行过程-首先使用-g选项编译java源代码,javac -g -d out ;然后是instrumentation,java emma instr -d outinstr -ip out,注意,经过instrumentation的class目标目录是outinstr;最后是执行过程,java -cp outinstr;out ,注意,把经过instrumentation的类路径放在前面,并在后面加上原来的类路径,因为instr命令没有处理properties文件和interface,这些都是执行过程需要的。
    使用EMMA:Ant

     设置instrumentation属性

    <property name="coverage.dir" value="${basedir}/coverage" />
    <property name="out.instr.dir" value="${basedir}/outinstr" />
    <property name="emma.enabled" value="true" />
    <property name="javac.debug" value="on" />
    <!-- path element used by EMMA taskdef below: -->
    <path id="emma.lib" >
    <pathelement location="${libs}/emma.jar" />
    <pathelement location="${libs}/emma_ant.jar" />
    </path>

    在Ant脚本中加入EMMA task
    <!-- this loads <emma> and <emmajava> custom tasks: -->
    <taskdef resource="emma_ant.properties" classpathref="emma.lib" />

    在编译Task中打开debug选项
    <target name="compile">
    <mkdir dir="${classes.main}" />
    <javac srcdir="${src.main}" destdir="${classes.main}" debug="${javac.debug}">
    <classpath refid="classpath.lib" />
    </javac>
    <copy todir="${classes.main}">
    <fileset dir="${src.main}" includes="**/*.xml, **/*.vm" />
    </copy>
    </target>

    instrumentation task
    <target name="instrument" depends="compile">
    <mkdir dir="${out.instr.dir}" />
    <mkdir dir="${coverage.dir}" />
    <emma enabled="${emma.enabled}" >
    <instr instrpathref="classpath.main"
    destdir="${out.instr.dir}"
    metadatafile="${coverage.dir}/metadata.emma"
    merge="true"
    >
    <filter excludes="com.talent.fw.formula.test.*Test*,com.talent.fw.esb.*Test*,com.talent.fw.message.test.*,com.
    talent.fw.entityengine.*Test*,com.talent.fw.integration.*Test*,com.talent.fw.security.impl.*Test*,testdomain.*" />
    </instr>
    </emma>
    </target>

    JUnit测试
    <target name="test" depends="compile, instrument">
    <mkdir dir="${reports.junit.data}" />
    <mkdir dir="${classes.main}/maps" />
    <mkdir dir="${classes.main}/scrīpts" />

    <copy todir="${classes.main}/maps">
    <fileset dir="${src.main}/maps" />
    </copy>
    <copy todir="${classes.main}/scrīpts">
    <fileset dir="${src.main}/scrīpts" />
    </copy>
    <copy todir="${classes.main}">
    <fileset dir="${src.main}" includes="*.xml, *.properties, **/*.vm, **/*.dtd" />
    </copy>

    <rmic classname="com.talent.fw.message.test.RMITestServer" base="${classes.main}"/>

    <junit printsummary="yes" haltonfailure="no" failureproperty="tests.failed">
    <classpath location="${out.instr.dir}" />
    <classpath location="${classes.main}" />
    <classpath location="${src.main}" />
    <classpath refid="classpath.lib" />
    <jvmarg value="-Demma.coverage.out.file=${coverage.dir}/coverage.emma" />
    <jvmarg value="-Demma.coverage.out.merge=true" />
    <formatter type="xml" />
    <batchtest fork="yes" todir="${reports.junit.data}" failureproperty="tests.failed">
    <fileset dir="${classes.main}">
    <include name="**/*Test.class" />
    <exclude name="**/AllTests.class" />
    <exclude name="**/Base*Test.class" />
    </fileset>
    </batchtest>
    </junit>
    </target>

    生成报告并复制到Tomcat的发布目录下
    <target name="coverage.report" depends="instrument">
    <!-- if enabled, generate coverage report(s): -->
    <emma enabled="${emma.enabled}" >
    <report sourcepath="${src.main}"
    sort="+block,+name,+method,+class"
    metrics="method:70,block:80,line:80,class:100"
    >
    <fileset dir="${coverage.dir}" >
    <include name="*.emma" />
    </fileset>

    <!-- <xml ōutfile="${coverage.dir}/coverage.xml" depth="package" /> -->
    <html ōutfile="${coverage.dir}/coverage.html" depth="method"
    columns="name,class,method,block,line"
    />
    </report>
    </emma>

    <mkdir dir="${coverage.publish.dir}" />
    <copy todir="${coverage.publish.dir}">
    <fileset dir="${coverage.dir}">
    <include name="**/*.html" />
    </fileset>
    </copy>
    </target>

      和CruiseControl集成
      最简单的集成方式是在cruisecontrol的navigation.jsp文件下方加入EMMA测试覆盖率报告的超链接。如下图:



      进一步的集成方式是,在生成HTML报告的同时,生成XML格式的报告,并为XML格式报告编写XSL文件,并加入到CruiseControl的buildresults.jsp文件中。

     

  • [转]在Eclipse中使用JUnit

    2008-06-13 11:16:49

    看到一篇很不错的Junit的帖子,打算先转到自己空间来,有时间的时候自己去试试,呵呵。
     
    这篇文章将向你介绍Junit,一个用来在项目中进行测试和调试的工具。在介绍完TDD(以测试驱动开发)理论后,将进一步讲解怎样在流行的Eclipse中建立你自己的JUnit测试。向你展示如何测试Hello World这样简单的程序。

       

        许多书上都讨论了自动测试,但是只有很少的著作注意到这么一个问题,那就是怎样把这些测试组织起来。随着测试的增加,放置和调用这些测试却变得更加麻烦。这将成为一个重要问题,以至于出现了TDD,极限编程(XP)使TDD得以普及。另外,你可以这样理解TDD:通过测试来开发。

       

        TDD的主要规范:

       

        在编写程序代码之前,与之对应的自动测试必须被写好。甚至程序代码并不存在,那也要看见一个失败的测试结果。

        在测试通过后,副本代码必须被丢弃。

       

        有一个具体步骤(可能指的是《Extreme Programming》)可以被任何一个程序员来参考,而不需要特殊的其他方法。在我们开始写测试之前,这些步骤(章节)应该被首先阅读——怎样组织自动测试。

       

        讲解一下不同种类的测试:

       

        单元测试检测模块(也就是类)的正确性。如果对象需要访问外部的数据资源,例如数据库,就需要模拟一个mock objects,但在实际中真实数据与测试环境是不同的。

        客户测试:这是功能性、系统、和验收测试。用来测试整体的系统特性。在XP中,这些测试由用户编写。

        综合测试:介于用户测试和单元测试之间的桥梁。综合测试帮助测试应用程序的交互性。一般情况下,mock objects不被用于综合测试,它会增加测试时间。同样,综合测试经常依赖特殊的测试环境,例如数据库送来的测试数据。综合测试也需要用到外部类库。例如为J2EE应用程序进行综合测试的类库Cactus。解释这些测试超出了本文的范围,需要更加详细的信息请参考http://jakarta.apache.org/cactus/

        开发人员测试:这是用来让开发人员检验自己代码或新函数的。对于每一个开发人员,只要有可能,就需要有更多的测试来检验代码。组织这些测试和组织程序代码一样重要。

       

        在以下章节,只要提到“测试”,那就指的是开发人员测试。

        

        我们几乎准备好开始建立测试了,先应该为我们的测试选择名字。你也许会说,“这不是问题:把‘Test’这个字放在类名前面,就好了!”不会这么快!让我来说一下这个步骤存在的问题:

       

        在TDD中,被测试的类或者方法还不存在。

        一个测试能够覆盖多个方法,甚至多个类,这是可能的。

       

        以上只是一些普遍问题;还存在更多的问题。

       

        让我来提一个建议,在测试命名时:测试类的名字应该让人一眼就知道这是一个测试类,且能说明它要测试什么,注意是否和其他类重名。按照以上建议做,就很简单了,也不用担心名字太长或难听。

       

        即将在Eclipse中用JUnit工具创建我们第一个测试了。假设你已经下载了一个最新的Eclipse版本。如果还没有,你应该去官方站点http://www.eclipse.org下载。还需要JUnit,也可以从http://www.junit.org/下载。

       

        运行Eclipse。新建一个workplace项目,点击文件->新建->项目,选择Java项目,点击下一步。起一个项目名称,例如ProjectWithJUnit。点击完成。这样就完成新项目的建立了。再来配置一下Eclipse,在构建路径中添加JUnit类库。在工具条上点击项目->属性,选择Java构建路径,选择添加外部JAR,浏览Junit被存储的目录,选择junit.jar,点击打开。你将会看见JUnit出现在库的列表中。点击确定,让Eclipse重建路径。

       

        现在开发我们的“Hello World”例子。按照TDD的规则,应该在代码建立以前先把测试写好。为了能够在某出开始,我们假设未来的类名是HelloWorld,并且有一个方法Say(),这个方法返回String的值(例如“Hello World!”)。

       

        建立测试,在ProjectWithJUnit的标题上面点击右键,选择新建->其他,展开“Java”选项,选择JUnit。在右边的栏目对话框中选择测试案例,然后下一步。参考图1。

     

           

                        1. 在Eclipse中建立JUnit测试

       

        在测试类这一栏中,写上将要被测试的类名HelloWorld。选择一个测试案例的名字,例如TestThatWeGetHelloWorldPrompt(是的,看上去很长,但是很清楚它的行为。)点击完成

       

        TestThatWeGetHelloWorldPrompt的代码如下:

     

        import junit.framework.TestCase;

     

        public class TestThatWeGetHelloWorldPrompt

        extends TestCase {

            public TestThatWeGetHelloWorldPrompt(

                String name) {

                super(name);

            }

            public void testSay() {

                HelloWorld hi = new HelloWorld();

                assertEquals("Hello World!", hi.say());

            }

            public static void main(String[] args) {

                junit.textui.TestRunner.run(

                    TestThatWeGetHelloWorldPrompt.class);

            }

        }

     

        代码并不复杂;只是有点与众不同。然而,让我们考察一下细节。我们继承了JUnit的TestCase类,它在JUnit的javadocs定义为“运行众多测试的夹具。”JUnit也有TestSuite类,它是一组测试案例的集合,但在本文中不做讨论。

       

        建立测试案例的步骤如下:

       

        1、建立一个junit.framework.TestCase的实例。

        2、定义一些以“test”开头的无返回方法(例如testWasTransactionSuccessful(),testShow(),等等)。

       

        TestThatWeGetHelloWorldPrompt.java包含这些:TestCase的子类和一个叫做testSay()的方法。这个方法调用了assertEquals()函数,它用来比较我们预期的值和由say()返回的值。

       

        main()方法用来运行测试和显示输出的。JUnit的TestRunner处理测试,提供基于图像和文本的输出表现形式。我们使用基于文本的版本,因为Eclipse支持它,且也适合我们。当开始运行后,基于文本的版本测试会以文本形式输出,Eclipse会把这些输出自动变成图像界面的输出。

       

        按照TDD规范,首次运行测试,应该故意让它失败。点击运行->运行为->Junit测试(记住TestThatWeGetHelloWorldPrompt.java应该被突出的显示在包资源管理器中)。在左边窗口,应该看见JUnit窗口而不是包资源管理器,它显示一个红条,一次失败的测试,具体的失败原因参看图2。如果没有自动显示这些内容,点击JUnit标签(在底部的左边)。

     

              

                        2. JUnit中失败的测试

       

        很好!的却失败了。现在我们来建立被测试代码:在包资源管理器窗口的ProjectWithJUnit标题上右击,选择新建->。选择类名,我们已经假设了它叫HelloWorld,然后直接点击完成。为HelloWorld.java填入下列代码:

     

            public class HelloWorld {

                public String say() {

                    return("Hello World!");

                }

            }

           

        这段代码很简单,甚至不需要注解,我们再来看看结果。按照上面描述过的方式,在JUnit的窗口中显示了一个绿条,参看图3。绿条证明测试成功。

     

              

                         3. JUnit中成功的测试

                                  

        现在,我们想再让测试失败一次,但原因不同。这有助于展示JUnit测试中不同的报错信息。修改assertEquals()代码,把“Hello World!”变成“Hello Me!”。当再次运行JUnit时,结果变成了红条,在JUnit窗口的底部输出了失败原因,参看图4。

     

               

                        4. JUnit中的ComparisonError

                                 

        最后,我想说一下关于测试是开发过程中的必要部分的话题。测试代码一直是开发中的重要部分。经过近几年的发展,已得到了很大的提高,这要归功于强大的理论研究(比如“expectations-based development”等等),和快速发展的测试工具包,还有测试过程的改进。如果你对这篇文章感兴趣,那请你花一些时间来正式的学习一下测试理论吧,这对你的工作很有用。

       

        关于作者:

        Alexander Prohorenko 一名UNIX系统管理员、网络安全管理员。

        Olexiy Prohorenko    一名Java开发者居住在乌克兰的Dniepropetrovsk。

  • 『傻瓜版2』用QTP连接Oracle DB

    2008-05-30 16:24:38

    方法2: 用代码实现QTP与Oracle DB的连接。

    Dim Cnn
    Dim Rst
    Dim strCnn
    strCnn="Provider=OraOLEDB.Oracle.1;Data Source=数据库名;Password=登录密码;User ID=登录用户名;Persist Security Info=True;"

    (得出方法参考一下链接:

    http://bbs.51testing.com/viewthread.php?tid=107598&highlight=DB%2B%CA%FD%BE%DD%BF%E2

    Set Cnn = CreateObject("ADODB.Connection")
    Cnn.Open strCnn
    Set Rst =CreateObject("ADODB.Recordset")
    Rst.open "select column_name  from table_name where **** ", Cnn
    i=1 
    While not Rst.eof       '//循环取出DB里面的数据并导到Global table里面
         dim1=Rst("para1").value
         dim2=Rst("para2").value   
         DataTable.GlobalSheet.SetCurrentRow(i)
         DataTable("Dim1",dtGlobalSheet)=dim1
         DataTable("Dim2",dtGlobalSheet)=dim2     
    i=i+1
        Rst.movenext                 
    wend

  • 『傻瓜版1』用QTP 连接Oracle DB

    2008-05-30 16:13:27

    今天终于成功用QTP连接到数据库了,用的是比较傻瓜的方法,特写出来跟大家分享^_^

    方法1:

    用insert DB checkpoint 的方法:这个方法的关键是创建data resource。

    详细步骤:

    1.Start->All Programs->Orcal OraClient9->Configuration and Migration Tools->Microsoft ODBC Administor 添加你要连接的数据库的data resource 文件,如图1所示。

    2.打开QTP, Insert->check point ->DataBase checkpoint,会出现Database query wizard窗口(图2)。

    3.根据向导一步一步如下图往下做,最后完成之后即可以连接数据库成功添加一个database checkpoint了(图3,图4)。

  • 转载:如何有效的对测试人员进行业绩考核?(08-04-11)

    2008-05-28 17:03:40

    Q:随着企业对软件测试的不断重视,测试团队的规模也越来越大,测试相关的岗位也在逐渐增多,测试工程师、测试leader、高级性能测试工程师等等。如何对不同岗位的测试人员实施科学、合理、公正的考核,已成为测试管理工作的一个重点和难点。如果你是测试经理,你是如何对你的团队进行业绩考核的?如果你是测试工程师,你现在被考核的标准是什么?而你期望的标准又是什么?

    最佳答案由 “godn_1981”提供:

    鄙人从事软件测试好几年了,也一直为该问题困扰,每次项目作完了,感觉大家都表现还马马虎虎。但是项目却感觉总不是那么完美,既然存在问题,说明测试人员的考核做的不到位,所以最近痛定思痛,也咨询了一些在微软和IBM做测试的朋友,结合自己多年来的实践,得出如下核心考核指标,和大家共享。
    测试人员主要是三个方面。
    第一,整体工作效率。第二,工作结果。第三,过程控制。(针对测试主管或组长)

    1.整体工作效率
    1.1有效工作时间
    主要check指标是每日实际工作时间,按照Ms的标准,一个测试工程师的每天的有效工作时间应该在70%以上。如果只有50%或以下的有效工作时间,那么不能成为好的测试工程师,因为他有能力做得更好。
    1.2是否在制定时间内完成工作任务
    主要check指标是进度偏离度。主要是和测试计划相比,有多少的延期。这个指标计算是:计划时间/实际需用时间。
    当然,本指标未考虑其他因素,如开发人员窝工导致的delay。
    2.工作结果
    2.1测试用例的数量和质量
    a,测试用例的数量
    主要考核指标是用例编写速度,考核办法是测试用例的个数/写用例所用时间。
    b,测试用例的质量
    主要考核指标是用例编写质量,用于考察文档是由有效的指导了测试工作。考核办法是来自用例的bug数目/总bug数目,应该是70%以上才算是质量比较好的用例。
    2.2bug的数量和质量
    a,bug提交的数量
    主要考核指标是提交bug的数量,这个指标根据项目不同而定,不好给出固定经验值。
    b,bug的质量
    主要考核指标是提交bug的质量,即提交的bug,严重程度和,发现路径的复杂程度
    c,发现bug的阶段
    主要考核指标是提交bug的时间段,具体执行是统计在测试的每个阶段,发现bug的比例,特别是严重的bug发现的早晚
    2.3是否及时验证关闭bug
    主要考核指标是验证关闭bug的及时度
    2.4测试自动化程度及收效
    主要考核指标是,测试中自动化运用的含量,也就是测试技术含量,成果如何?
    2.5所负责模块的产品总体质量以及用户反馈
    这个总体质量是产品发布之后一段时间才能得出结论,主要是市场,用户对产品的质量、稳定性、性能的反馈。
    考核的主要指标是两个。
    a,根据市场反馈(由经理定性考核)
    b,根据测试人员提交的bug和用户反馈的bug之间的比例,比例越大,说明测试质量相对越高。当然前提是必须划清楚客户的新需求,或者对spec设计方面的抱怨。
    3.过程改进
    考核点,是纵向对比,相比上一个项目,在质量控制上和测试进度进程上有否进步。包括测试方法,提升质量的手段,测试数据记录,用例更新等等有没有改进。
    该项具体考核方法也是经理来根据测试组在过程中具体表现,来定性打分。
    还包括测试人员在测试过程中的学习能力。这个也是定性。
    4.考核注意事项
    4.1统计bug的注意事项
    5.其它注意事项
    作为考核者要注意以下比例,也许有些没有列入考核内容,但是如下这些点可以指导测试。
    a,测试团队发现的bug和所有bug之间的比例
    b,spec设计造成的bug
    c,重复或者误提交的bug所占的比例
    d,每周发现的bug的趋势图
    e,Bug严重等级的构成比例
    f,Bug从提交到解决的平均需要时间
    g,Bug从解决到关闭的平均需要时间
  • 转载:在网站测试中如何做好安全性测试?(08-05-16)

    2008-05-28 16:57:07

    随着网络发展的趋势,对于网站的安全性的要求也越来越高,很多网站都存在被黑客攻击的漏洞,你在网站测试中有做到安全性测试吗?你觉得安全测试应该从哪些方面来检查?

    最佳答案由“卖烧烤的鱼”提供:

    安全性测试(security testing)是有关验证应用程序的安全服务和识别潜在安全性缺陷的过程。

    注意:安全性测试并不最终证明应用程序是安全的,而是用于验证所设立策略的有效性,这些对策是基于威胁分析阶段所做的假设而选择的。


    以下是我读<<软件评测试教程>>中的Web安全性测试章节内容,并进行修改的笔记,前面看了好多朋友写的,不过不是很全,希望对大家有所帮助,建议大家还是买本<<软件评测试教程>>此书绝对物超所值^_^

    WEB安全性测试
    一个完整的WEB安全性测试可以从部署与基础结构、输入验证、身份验证、授权、配置管理、敏感数据、会话管理、加密。参数操作、异常管理、审核和日志记录等几个方面入手。
    1.        安全体系测试
    1)        部署与基础结构
    l        网络是否提供了安全的通信
    l        部署拓扑结构是否包括内部的防火墙
    l        部署拓扑结构中是否包括远程应用程序服务器
    l        基础结构安全性需求的限制是什么
    l        目标环境支持怎样的信任级别
    2)        输入验证
    l        如何验证输入
    A.        是否清楚入口点
    B.        是否清楚信任边界
    C.        是否验证Web页输入
    D.        是否对传递到组件或Web服务的参数进行验证
    E.        是否验证从数据库中检索的数据
    F.        是否将方法集中起来
    G.        是否依赖客户端的验证
    H.       应用程序是否易受SQL注入攻击
    I.        应用程序是否易受XSS攻击
    l        如何处理输入
    3)        身份验证
    l        是否区分公共访问和受限访问
    l        是否明确服务帐户要求
    l        如何验证调用者身份
    l        如何验证数据库的身份
    l        是否强制试用帐户管理措施
    4)        授权
    l        如何向最终用户授权
    l        如何在数据库中授权应用程序
    l        如何将访问限定于系统级资源
    5)        配置管理
    l        是否支持远程管理
    l        是否保证配置存储的安全
    l        是否隔离管理员特权
    6)        敏感数据
    l        是否存储机密信息
    l        如何存储敏感数据
    l        是否在网络中传递敏感数据
    l        是否记录敏感数据
    7)        会话管理
    l        如何交换会话标识符
    l        是否限制会话生存期
    l        如何确保会话存储状态的安全
    8)        加密
    l        为何使用特定的算法
    l        如何确保加密密钥的安全性
    9)        参数操作
    l        是否验证所有的输入参数
    l        是否在参数过程中传递敏感数据
    l        是否为了安全问题而使用HTTP头数据
    10)        异常管理
    l        是否使用结构化的异常处理
    l        是否向客户端公开了太多的信息
    11)        审核和日志记录
    l        是否明确了要审核的活动
    l        是否考虑如何流动原始调用这身份
    2.        应用及传输安全
    WEB应用系统的安全性从使用角度可以分为应用级的安全与传输级的安全,安全性测试也可以从这两方面入手。
    应用级的安全测试的主要目的是查找Web系统自身程序设计中存在的安全隐患,主要测试区域如下。
    l        注册与登陆:现在的Web应用系统基本采用先注册,后登录的方式。
    A.        必须测试有效和无效的用户名和密码
    B.        要注意是否存在大小写敏感,
    C.        可以尝试多少次的限制
    D.        是否可以不登录而直接浏览某个页面等。
    l        在线超时:Web应用系统是否有超时的限制,也就是说,用户登陆一定时间内(例如15分钟)没有点击任何页面,是否需要重新登陆才能正常使用。
    l        操作留痕:为了保证Web应用系统的安全性,日志文件是至关重要的。需要测试相关信息是否写进入了日志文件,是否可追踪。
    l        备份与恢复:为了防范系统的意外崩溃造成的数据丢失,备份与恢复手段是一个Web系统的必备功能。备份与恢复根据Web系统对安全性的要求可以采用多种手段,如数据库增量备份、数据库完全备份、系统完全备份等。出于更高的安全性要求,某些实时系统经常会采用双机热备或多级热备。除了对于这些备份与恢复方式进行验证测试以外,还要评估这种备份与恢复方式是否满足Web系统的安全性需求。
    传输级的安全测试是考虑到Web系统的传输的特殊性,重点测试数据经客户端传送到服务器端可能存在的安全漏洞,以及服务器防范非法访问的能力。一般测试项目包括以下几个方面。
    l        HTTPS和SSL测试:默认的情况下,安全HTTP(Soure HTTP)通过安全套接字SSL(Source Socket Layer)协议在端口443上使用普通的HTTP。HTTPS使用的公共密钥的加密长度决定的HTTPS的安全级别,但从某种意义上来说,安全性的保证是以损失性能为代价的。除了还要测试加密是否正确,检查信息的完整性和确认HTTPS的安全级别外,还要注意在此安全级别下,其性能是否达到要求。
    l        服务器端的脚本漏洞检查:存在于服务器端的脚本常常构成安全漏洞,这些漏洞又往往被黑客利用。所以,还要测试没有经过授权,就不能在服务器端放置和编辑脚本的问题。
    l        防火墙测试:防火墙是一种主要用于防护非法访问的路由器,在Web系统中是很常用的一种安全系统。防火墙测试是一个很大很专业的课题。这里所涉及的只是对防火墙功能、设置进行测试,以判断本Web系统的安全需求。

    另推荐安全性测试工具:
    Watchfire AppScan:商业网页漏洞扫描器(此工具好像被IBM收购了,所以推荐在第一位)
    AppScan按照应用程序开发生命周期进行安全测试,早在开发阶段就进行单元测试和安全保证。Appscan能够扫描多种常见漏洞,例如跨网站脚本、HTTP应答切开、参数篡改、隐藏值篡改、后门/调试选项和缓冲区溢出等等。


    Acunetix Web Vulnerability Scanner:商业漏洞扫描器(目前用的比较多,不过这东东N占内存)
    Acunetix WVS自动检查您的网页程序漏洞,例如SQL注入、跨网站脚本和验证页面弱密码破解。Acunetix WVS有着非常友好的用户界面,还可以生成个性化的网站安全评估报告。

    另附我以前在51testing上发过“Yeepay网站安全测试漏洞之跨站脚本注入
    http://bbs.51testing.com/thread-113784-1-1.html
    Sql注入和跨站脚本这种漏洞比较常见,另在支付宝网站注册页面也存在跨站脚本情况,希望能早点发现^_^

  • 【原创】系统接口测试有感

    2008-01-24 22:47:37

        最近忙于两个系统间的测试。现在将近测试尾期了,自己觉得在测试过程中收获了很多,也有一些值得改进的地方。所以把感触写出来,希望给自己和别人以后的测试工作有所帮助。

        接口是基于两个不同的系统,进行的信息交互。因为是不同的系统,所以各个系统间的很多的设置和业务逻辑是不一样的。可以肯定的一点是系统间还是有部分相同的操作和信息的,要不然也不用做接口了。

        首先,业务分析人员会给出系统间接口的业务逻辑和需求,以及两个系统间的一些字段的mapping表。(就是A系统的某个字段对应到B系统的某个字段,都应该在这个文档中清晰正确的给出)

        QA在拿到需求和匹配文档之后,就应该结合自己所测系统的逻辑跟接口逻辑比较(有些系统的接口逻辑和应用软件的逻辑不一样,接口会增加或放开某些逻辑限制 )。QA应该仔细比较异同处,因为文档当中也有可能有错误。

        在编写测试用例初期,QA应仔细分析需求和进行静态测试。对于mapping表里面的字段,如果是真正系统实施的时候,有些字段是需要做同步的。mapping表里面的系统下拉菜单的字段要特别留意,像下拉菜单里面的value是不是完全匹配的,而且不能只是凭UI上的值去判断,一定要用DB里面的code去判断。因为有些字段,虽然在两个系统UI上的值是一样的,但是在DB里面的code是不一样的,而接口测试肯定是用code来传递参数值的。(我在测试初期就犯了这个错误,只在UI上判断两个系统里面的菜单value。忽略了code,导致在测试过程中很多defect是因为这种原因产生的,而这些其实是可以在测试前发现并提出的。)测试用例的设计基本上采用"End-To-End" 流程模式。

       一般在测试的第一,二个版本上系统都是不稳定的,可能只是实现了需求中的部分功能。所以在测试初期我们不需要去测试很具体的东西,只需要走大概的流程。去确认一下在这个测试版本上实现了哪些功能,哪些功能还没有实现。

       在第三、四个版本上功能基本上都实现了,这个时候我们就需要仔细的测试各个"End-To-End"的flow了,一般还会有挺多的defect的。这两个版本测试过程中,我们应该注意要插入对于mapping表里面所有字段的测试,看是不是所有的字段都能正常显示,某些特殊字段我们还需要去xml文件里面核对一些code。(在这次测试过程中,我的失误就是对于字段的测试进行的太晚,以至于到测试后期出现某个字段的defect导致function flow走不下去的情况。) 这个阶段还有一个值得注意的问题就是,有些字段在第一次从接口传送的时候是可以成功发送的。但是一旦修改后,即使没有修改的一些字段再次发送的时候都有可能被miss掉的。

      在第五、六个版本上,基本上就比较稳定了。但是此时也不能掉以轻心,还是要把所有的flow都仔细的走一遍,可能还会有漏网之鱼呢,呵呵。

      以上就是我这次接口测试的心得,希望对大家的测试有帮助。^_^

      

     

     

     

     

     

     

  • Mysql日期和时间函数

    2007-10-12 17:59:18

    对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。

    这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:

    mysql> SELECT something FROM table
    WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;

    DAYOFWEEK(date)
    返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。这些索引值对应于ODBC标准。
    mysql> select DAYOFWEEK('1998-02-03');
    -> 3

    WEEKDAY(date)
    返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。
    mysql> select WEEKDAY('1997-10-04 22:23:00');
    -> 5
    mysql> select WEEKDAY('1997-11-05');
    -> 2

    DAYOFMONTH(date)
    返回date的月份中日期,在1到31范围内。
    mysql> select DAYOFMONTH('1998-02-03');
    -> 3

    DAYOFYEAR(date)
    返回date在一年中的日数, 在1到366范围内。
    mysql> select DAYOFYEAR('1998-02-03');
    -> 34

    MONTH(date)
    返回date的月份,范围1到12。
    mysql> select MONTH('1998-02-03');
    -> 2

    DAYNAME(date)
    返回date的星期名字。
    mysql> select DAYNAME("1998-02-05");
    -> 'Thursday'

    MONTHNAME(date)
    返回date的月份名字。
    mysql> select MONTHNAME("1998-02-05");
    -> 'February'

    QUARTER(date)
    返回date一年中的季度,范围1到4。
    mysql> select QUARTER('98-04-01');
    -> 2

    WEEK(date)
     
    WEEK(date,first)
    对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数,范围在0到52。2个参数形式WEEK()允许
    你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,
    从星期一开始。
    mysql> select WEEK('1998-02-20');
    -> 7
    mysql> select WEEK('1998-02-20',0);
    -> 7
    mysql> select WEEK('1998-02-20',1);
    -> 8

    YEAR(date)
    返回date的年份,范围在1000到9999。
    mysql> select YEAR('98-02-03');
    -> 1998

    HOUR(time)
    返回time的小时,范围是0到23。
    mysql> select HOUR('10:05:03');
    -> 10

    MINUTE(time)
    返回time的分钟,范围是0到59。
    mysql> select MINUTE('98-02-03 10:05:03');
    -> 5

    SECOND(time)
    回来time的秒数,范围是0到59。
    mysql> select SECOND('10:05:03');
    -> 3

    PERIOD_ADD(P,N)
    增加N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
    mysql> select PERIOD_ADD(9801,2);
    -> 199803

    PERIOD_DIFF(P1,P2)
    返回在时期P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
    mysql> select PERIOD_DIFF(9802,199703);
    -> 11

    DATE_ADD(date,INTERVAL expr type)
     
    DATE_SUB(date,INTERVAL expr type)
     
    ADDDATE(date,INTERVAL expr type)
     
    SUBDATE(date,INTERVAL expr type)
    这些功能执行日期运算。对于MySQL 3.22,他们是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。
    在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的
    DATETIME或DATE值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以
    一个“-”开始表示负间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type FROM date)函数从日期
    中返回“type”间隔。下表显示了type和expr参数怎样被关联: type值 含义 期望的expr格式
    SECOND 秒 SECONDS
    MINUTE 分钟 MINUTES
    HOUR 时间 HOURS
    DAY 天 DAYS
    MONTH 月 MONTHS
    YEAR 年 YEARS
    MINUTE_SECOND 分钟和秒 "MINUTES:SECONDS"
    HOUR_MINUTE 小时和分钟 "HOURS:MINUTES"
    DAY_HOUR 天和小时 "DAYS HOURS"
    YEAR_MONTH 年和月 "YEARS-MONTHS"
    HOUR_SECOND 小时, 分钟, "HOURS:MINUTES:SECONDS"
    DAY_MINUTE 天, 小时, 分钟 "DAYS HOURS:MINUTES"
    DAY_SECOND 天, 小时, 分钟, 秒 "DAYS HOURS:MINUTES:SECONDS"

    MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅
    包含YEAR、MONTH和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。

    mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
    -> 1998-01-01 00:00:00
    mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
    -> 1998-01-01
    mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
    -> 1997-12-31 23:59:59
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    INTERVAL 1 SECOND);
    -> 1998-01-01 00:00:00
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    INTERVAL 1 DAY);
    -> 1998-01-01 23:59:59
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
    INTERVAL "1:1" MINUTE_SECOND);
    -> 1998-01-01 00:01:00
    mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
    INTERVAL "1 1:1:1" DAY_SECOND);
    -> 1997-12-30 22:58:59
    mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
    INTERVAL "-1 10" DAY_HOUR);
    -> 1997-12-30 14:00:00
    mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
    -> 1997-12-02
    mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
    -> 1999
    mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
    -> 199907
    mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
    -> 20102

    如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,
    如果你指定一个type是DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,
    MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10" DAY_SECOND以它等价于"1:10" MINUTE_SECOND
    的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,
    结果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。

    mysql> select DATE_ADD('1998-01-30', Interval 1 month);
    -> 1998-02-28

    注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。
    TO_DAYS(date)
    给出一个日期date,返回一个天数(从0年的天数)。
    mysql> select TO_DAYS(950501);
    -> 728779
    mysql> select TO_DAYS('1997-10-07');
    -> 729669

    TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。

    FROM_DAYS(N)
    给出一个天数N,返回一个DATE值。
    mysql> select FROM_DAYS(729669);
    -> '1997-10-07'

    TO_DAYS()不打算用于使用格列高里历(1582)出现前的值。

    DATE_FORMAT(date,format)
    根据format字符串格式化date值。下列修饰符可以被用在format字符串中: %M 月名字(January……December)
    %W 星期名字(Sunday……Saturday)
    %D 有英语前缀的月份的日期(1st, 2nd, 3rd, 等等。)
    %Y 年, 数字, 4 位
    %y 年, 数字, 2 位
    %a 缩写的星期名字(Sun……Sat)
    %d 月份中的天数, 数字(00……31)
    %e 月份中的天数, 数字(0……31)
    %m 月, 数字(01……12)
    %c 月, 数字(1……12)
    %b 缩写的月份名字(Jan……Dec)
    %j 一年中的天数(001……366)
    %H 小时(00……23)
    %k 小时(0……23)
    %h 小时(01……12)
    %I 小时(01……12)
    %l 小时(1……12)
    %i 分钟, 数字(00……59)
    %r 时间,12 小时(hh:mm:ss [AP]M)
    %T 时间,24 小时(hh:mm:ss)
    %S 秒(00……59)
    %s 秒(00……59)
    %p AM或PM
    %w 一个星期中的天数(0=Sunday ……6=Saturday )
    %U 星期(0……52), 这里星期天是星期的第一天
    %u 星期(0……52), 这里星期一是星期的第一天
    %% 一个文字“%”。

    所有的其他字符不做解释被复制到结果中。

    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
    -> 'Saturday October 1997'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
    -> '22:23:00'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00',
    '%D %y %a %d %m %b %j');
    -> '4th 97 Sat 04 10 Oct 277'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00',
    '%H %k %I %r %T %S %w');
    -> '22 22 10 10:23:00 PM 22:23:00 00 6'
    MySQL3.23中,在格式修饰符字符前需要%。在MySQL更早的版本中,%是可选的。

    TIME_FORMAT(time,format)
    这象上面的DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。
    其他修饰符产生一个NULL值或0。
    CURDATE()
     
    CURRENT_DATE
    以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
    mysql> select CURDATE();
    -> '1997-12-15'
    mysql> select CURDATE() + 0;
    -> 19971215

    CURTIME()
     
    CURRENT_TIME
    以'HH:MM:SS'或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
    mysql> select CURTIME();
    -> '23:50:26'
    mysql> select CURTIME() + 0;
    -> 235026

    NOW()
     
    SYSDATE()
     
    CURRENT_TIMESTAMP
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的
    上下文被使用。
    mysql> select NOW();
    -> '1997-12-15 23:50:26'
    mysql> select NOW() + 0;
    -> 19971215235026

    UNIX_TIMESTAMP()
     
    UNIX_TIMESTAMP(date)
    如果没有参数调用,返回一个Unix时间戳记(从'1970-01-01 00:00:00'GMT开始的秒数)。如果UNIX_TIMESTAMP()用一
    个date参数被调用,它返回从'1970-01-01 00:00:00' GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME
    字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。
    mysql> select UNIX_TIMESTAMP();
    -> 882226357
    mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
    -> 875996580

    当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。

    FROM_UNIXTIME(unix_timestamp)
    以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串
    还是或数字上下文中被使用。
    mysql> select FROM_UNIXTIME(875996580);
    -> '1997-10-04 22:23:00'
    mysql> select FROM_UNIXTIME(875996580) + 0;
    -> 19971004222300

    FROM_UNIXTIME(unix_timestamp,format)
    返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条
    目同样的修饰符。
    mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
    '%Y %D %M %h:%i:%s %x');
    -> '1997 23rd December 03:43:30 x'

    SEC_TO_TIME(seconds)
    返回seconds参数,变换成小时、分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字
    上下文中被使用。
    mysql> select SEC_TO_TIME(2378);
    -> '00:39:38'
    mysql> select SEC_TO_TIME(2378) + 0;
    -> 3938

    TIME_TO_SEC(time)
    返回time参数,转换成秒。
    mysql> select TIME_TO_SEC('22:23:00');
    -> 80580
    mysql> select TIME_TO_SEC('00:39:38');
    -> 2378

  • 软件测试术语中英文对照(部分)

    2007-10-11 14:40:16

    Acceptance testing : 验收测试
    Acceptance Testing:可接受性测试
    Accessibility test : 软体适用性测试
    actual outcome:实际结果       
    Ad hoc testing     : 随机测试
    Algorithm analysis : 算法分析
    algorithm:算法       
    Alpha testing      : α测试
    analysis:分析       
    anomaly:异常       
    application software:应用软件       
    Application under test (AUT) : 所测试的应用程序
    Architecture       : 构架
    Artifact           : 工件
    ASQ:自动化软件质量(Automated Software Quality)
    Assertion checking : 断言检查
    Association        : 关联
    Audit              : 审计
    audit trail:审计跟踪       
    Automated Testing:自动化测试       
    Backus-Naur Form:BNF范式       
    baseline:基线       
    Basic Block:基本块       
    basis test set:基本测试集       
    Behaviour          : 行为
    Bench test         : 基准测试
    benchmark:标杆/指标/基准       
    Best practise      : 最佳实践
    Beta testing       : β测试
    Black Box Testing:黑盒测试       
    Blocking bug       : 阻碍性错误
    Bottom-up testing  : 自底向上测试
    boundary value coverage:边界值覆盖       
    boundary value testing:边界值测试       
    Boundary values    : 边界值
    Boundry Value Analysis:边界值分析       
    branch condition combination coverage:分支条件组合覆盖       
    branch condition combination testing:分支条件组合测试       
    branch condition coverage:分支条件覆盖       
    branch condition testing:分支条件测试
    branch condition:分支条件 
    Branch coverage    : 分支覆盖
    branch outcome:分支结果       
    branch point:分支点       
    branch testing:分支测试       
    branch:分支       
    Breadth Testing:广度测试       
    Brute force testing: 强力测试
    Buddy test         : 合伙测试
    Buffer             : 缓冲
    Bug                : 错误
    Bug bash           : 错误大扫除
    bug fix            :  错误修正
    Bug report         : 错误报告
    Bug tracking system: 错误跟踪系统
    bug:缺陷
    Build              : 工作版本(内部小版本)
    Build Verfication tests(BVTs): 版本验证测试
    Build-in           : 内置
    Capability Maturity Model (CMM):   能力成熟度模型
    Capability Maturity Model Integration (CMMI): 能力成熟度模型整合
    capture/playback tool:捕获/回放工具       
    Capture/Replay Tool:捕获/回放工具       
    CASE:计算机辅助软件工程(computer aided software engineering)
    CAST:计算机辅助测试       
    cause-effect graph:因果图       
    certification        :证明       
    change control:变更控制       
    Change Management  :变更管理
    Change Request     :变更请求
    Character Set      : 字符集
    Check In           :检入
    Check Out          :检出
    Closeout           : 收尾
    code audit        :代码审计       
    Code coverage      : 代码覆盖
    Code Inspection:代码检视       
    Code page          : 代码页
    Code rule          : 编码规范
    Code sytle         : 编码风格
    Code Walkthrough:代码走读       
    code-based testing:基于代码的测试       
    coding standards:编程规范       
    Common sense       : 常识
    Compatibility Testing:兼容性测试       
    complete path testing        :完全路径测试       
    completeness:完整性       
    complexity        :复杂性       
    Component testing     : 组件测试
    Component:组件       
    computation data use:计算数据使用       
    computer system security:计算机系统安全性       
    Concurrency user      : 并发用户
    Condition coverage    : 条件覆盖
    condition coverage:条件覆盖       
    condition outcome:条件结果       
    condition:条件       
    configuration control:配置控制       
    Configuration item    : 配置项
    configuration management:配置管理       
    Configuration testing : 配置测试
    conformance criterion: 一致性标准       
    Conformance Testing: 一致性测试       
    consistency        : 一致性       
    consistency checker: 一致性检查器       
    Control flow graph    : 控制流程图
    control flow graph:控制流图       
    control flow:控制流       
    conversion testing:转换测试       
    Core team             : 核心小组
    corrective maintenance:故障检修       
    correctness        :正确性       
    coverage        :覆盖率       
    coverage item:覆盖项       
    crash:崩溃       
    criticality analysis:关键性分析       
    criticality:关键性       
    CRM(change request management): 变更需求管理
    Customer-focused mindset : 客户为中心的理念体系
    Cyclomatic complexity : 圈复杂度
    data corruption:数据污染       
    data definition C-use pair:数据定义C-use使用对       
    data definition P-use coverage:数据定义P-use覆盖       
    data definition P-use pair:数据定义P-use使用对       
    data definition:数据定义       
    data definition-use coverage:数据定义使用覆盖       
    data definition-use pair        :数据定义使用对       
    data definition-use testing:数据定义使用测试       
    data dictionary:数据字典       
    Data Flow Analysis    : 数据流分析
    data flow analysis:数据流分析       
    data flow coverage:数据流覆盖       
    data flow diagram:数据流图       
    data flow testing:数据流测试       
    data integrity:数据完整性       
    data use:数据使用       
    data validation:数据确认       
    dead code:死代码       
    Debug                 : 调试
    Debugging:调试       
    Decision condition:判定条件       
    Decision coverage     : 判定覆盖
    decision coverage:判定覆盖       
    decision outcome:判定结果       
    decision table:判定表       
    decision:判定       
    Defect                : 缺陷
    defect density        : 缺陷密度
    Defect Tracking       :缺陷跟踪
    Deployment            : 部署
    Depth Testing:深度测试 
    design for sustainability :可延续性的设计     
    design of experiments:实验设计       
    design-based testing:基于设计的测试       
    Desk checking         : 桌前检查
    desk checking:桌面检查   
    Determine Usage Model : 确定应用模型  
    Determine Potential Risks : 确定潜在风险
    diagnostic:诊断       
    DIF(decimation in frequency) : 按频率抽取
    dirty testing:肮脏测试       
    disaster recovery:灾难恢复       
    DIT (decimation in time): 按时间抽取 
    documentation testing        :文档测试       
    domain testing:域测试       
    domain:域       
    DTP  DETAIL TEST PLAN详细确认测试计划
    Dynamic analysis      : 动态分析
    dynamic analysis:动态分析       
    Dynamic Testing:动态测试       
    embedded software:嵌入式软件       
    emulator:仿真       
    End-to-End testing:端到端测试       
    Enhanced Request      :增强请求
    entity relationship diagram:实体关系图  
    Encryption Source Code Base: 加密算法源代码库    
    Entry criteria        : 准入条件
    entry point        :入口点       
    Envisioning Phase     :  构想阶段
    Equivalence class     : 等价类
    Equivalence Class:等价类       
    equivalence partition coverage:等价划分覆盖       
    Equivalence partition testing : 等价划分测试
    equivalence partition testing:参考等价划分测试
    equivalence partition testing:等价划分测试       
    Equivalence Partitioning:等价划分       
    Error                 :  错误
    Error guessing        :  错误猜测
    error seeding:错误播种/错误插值       
    error:错误       
    Event-driven          :  事件驱动
    Exception handlers    :  异常处理器
    exception:异常/例外       
    executable statement:可执行语句       
    Exhaustive Testing:穷尽测试       
    exit point:出口点       
    expected outcome:期望结果       
    Exploratory testing   :  探索性测试
    Failure              : 失效
    Fault                : 故障
    fault:故障       
    feasible path:可达路径       
    feature testing:特性测试       
    Field testing        : 现场测试
    FMEA:失效模型效果分析(Failure Modes and Effects Analysis)
    FMECA:失效模型效果关键性分析(Failure Modes and Effects Criticality Analysis)
    Framework            : 框架
    FTA:故障树分析(Fault Tree Analysis)
    functional decomposition:功能分解       
    Functional Specification        :功能规格说明书       
    Functional testing   : 功能测试
    Functional Testing:功能测试       
    G11N(Globalization)  : 全球化
    Gap analysis         : 差距分析
    Garbage characters   : 乱码字符
    glass box testing:玻璃盒测试       
    Glass-box testing    : 白箱测试或白盒测试
    Glossary             : 术语表
    GUI(Graphical User Interface): 图形用户界面
    Hard-coding          : 硬编码
    Hotfix               : 热补丁
    I18N(Internationalization): 国际化
    Identify Exploratory Tests – 识别探索性测试
    IEEE:美国电子与电器工程师学会(Institute of Electrical and Electronic Engineers)
    Incident      事故    
    Incremental testing  : 渐增测试
    incremental testing:渐增测试       
    infeasible path:不可达路径       
    input domain:输入域       
    Inspection           : 审查
    inspection:检视       
    installability testing:可安装性测试       
    Installing testing   : 安装测试
    instrumentation:插装       
    instrumenter:插装器       
    Integration          :集成
    Integration testing  : 集成测试
    interface            : 接口
    interface analysis:接口分析       
    interface testing:接口测试       
    interface:接口       
    invalid inputs:无效输入       
    isolation testing:孤立测试       
    Issue                : 问题
    Iteration            : 迭代
    Iterative development: 迭代开发
    job control language:工作控制语言       
    Job:工作       
    Key concepts         : 关键概念
    Key Process Area     : 关键过程区域
    Keyword driven testing : 关键字驱动测试
    Kick-off meeting     : 动会议
    L10N(Localization)   : 本地化
    Lag time             : 延迟时间
    LCSAJ:线性代码顺序和跳转(Linear Code Sequence And Jump)
    LCSAJ coverage:LCSAJ覆盖       
    LCSAJ testing:LCSAJ测试       
    Lead time            : 前置时间
    Load testing         : 负载测试
    Load Testing:负载测试       
    Localizability testing: 本地化能力测试
    Localization testing : 本地化测试
    logic analysis:逻辑分析       
    logic-coverage testing:逻辑覆盖测试       
    Maintainability      : 可维护性
    maintainability testing:可维护性测试       
    Maintenance          : 维护
    Master project schedule :总体项目方案
    Measurement          : 度量
    Memory leak          : 内存泄漏
    Migration testing    : 迁移测试
    Milestone            : 里程碑
    Mock up              : 模型,原型
    modified condition/decision coverage:修改条件/判定覆盖       
    modified condition/decision testing        :修改条件/判定测试       
    modular decomposition:参考模块分解
    Module testing       : 模块测试
    Monkey testing       : 跳跃式测试
    Monkey Testing:跳跃式测试  
    mouse over:鼠标在对象之上
    mouse leave:鼠标离开对象    
    MTBF:平均失效间隔实际(mean time between failures)
    MTP    MAIN TEST PLAN主确认计划
    MTTF:平均失效时间        (mean time to failure)
    MTTR:平均修复时间(mean time to repair)
    multiple condition coverage:多条件覆盖       
    mutation analysis:变体分析       
    N/A(Not applicable)  : 不适用的
    Negative Testing     : 逆向测试, 反向测试, 负面测试
    negative testing:参考负面测试
    Negative Testing:逆向测试/反向测试/负面测试  
    off by one:缓冲溢出错误    
    non-functional requirements testing:非功能需求测试
    nominal load:额定负载
    N-switch coverage:N切换覆盖       
    N-switch testing:N切换测试       
    N-transitions:N转换       
    Off-the-shelf software : 套装软件
    operational testing:可操作性测试       
    output domain:输出域
    paper audit:书面审计      
    Pair Programming     :  成对编程
    partition testing:分类测试       
    Path coverage        :  路径覆盖
    path coverage:路径覆盖       
    path sensitizing:路径敏感性       
    path testing:路径测试       
    path:路径       
    Peer review          :  同行评审
    Performance          :  性能
    Performance indicator:  性能(绩效)指标
    Performance testing  :  性能测试
    Pilot                :  试验
    Pilot testing        :  引导测试
    Portability          :  可移植性
    portability testing:可移植性测试      
    Positive testing     :  正向测试
    Postcondition        :  后置条件
    Precondition         :  前提条件
    precondition:预置条件       
    predicate data use:谓词数据使用       
    predicate:谓词       
    Priority             :  优先权
    program instrumenter:程序插装       
    progressive testing:递进测试       
    Prototype            :  原型
    Pseudo code          :  伪代码
    pseudo-localization testing:伪本地化测试
    pseudo-random:伪随机       
    QC:质量控制(quality control)
    Quality assurance(QA):  质量保证
    Quality Control(QC)  :  质量控制
    Race Condition:竞争状态       
    Rational Unified Process(以下简称RUP):瑞理统一工艺
    Recovery testing     :  恢复测试
    recovery testing:恢复性测试       
    Refactoring          :  重构
    regression analysis and testing:回归分析和测试       
    Regression testing   :  回归测试
    Release              :  发布
    Release note         :  版本说明
    release:发布       
    Reliability          :  可靠性
    reliability assessment:可靠性评价       
    reliability:可靠性       
    Requirements management tool: 需求管理工具
    Requirements-based testing : 基于需求的测试
    Return of Investment(ROI): 投资回报率
    review:评审       
    Risk assessment      :  风险评估
    risk:风险       
    Robustness           :   强健性
    Root Cause Analysis(RCA): 根本原因分析
    safety critical:严格的安全性       
    safety:(生命)安全性       
    Sanity testing       :   健全测试
    Sanity Testing:理智测试       
    Schema Repository    :   模式库
    Screen shot          :   抓屏、截图
    SDP:软件开发计划(software development plan)
    Security testing     :   安全性测试
    security testing:安全性测试       
    security.:(信息)安全性       
    serviceability testing:可服务性测试       
    Severity             :   严重性
    Shipment             :   发布
    simple subpath:简单子路径       
    Simulation           :  模拟
    Simulator            :  模拟器
    SLA(Service level agreement): 服务级别协议
    SLA:服务级别协议(service level agreement)
    Smoke testing        :   冒烟测试
    Software development plan(SDP): 软件开发计划
    Software development process: 软件开发过程
    software development process:软件开发过程       
    software diversity:软件多样性       
    software element:软件元素       
    software engineering environment:软件工程环境       
    software engineering:软件工程       
    Software life cycle  :   软件生命周期
    source code:源代码       
    source statement:源语句       
    Specification        : 规格说明书
    specified input:指定的输入       
    spiral model        :螺旋模型       
    SQAP   SOFTWARE QUALITY ASSURENCE PLAN 软件质量保证计划
    SQL:结构化查询语句(structured query language)
    Staged Delivery:分布交付方法
    state diagram:状态图       
    state transition testing        :状态转换测试       
    state transition:状态转换       
    state:状态       
    Statement coverage   : 语句覆盖
    statement testing:语句测试       
    statement:语句       
    Static Analysis:静态分析       
    Static Analyzer:静态分析器       
    Static Testing:静态测试       
    statistical testing:统计测试       
    Stepwise refinement  : 逐步优化
    storage testing:存储测试       
    Stress Testing       : 压力测试
    structural coverage:结构化覆盖       
    structural test case design:结构化测试用例设计       
    structural testing:结构化测试       
    structured basis testing:结构化的基础测试       
    structured design:结构化设计       
    structured programming:结构化编程       
    structured walkthrough:结构化走读       
    stub:桩 
    sub-area:子域     
    Summary:  总结
    SVVP  SOFTWARE Vevification&Validation  PLAN: 软件验证和确认计划
    symbolic evaluation:符号评价       
    symbolic execution:参考符号执行
    symbolic execution:符号执行       
    symbolic trace:符号轨迹       
    Synchronization      : 同步
    Syntax testing       : 语法分析
    system analysis:系统分析       
    System design        : 系统设计
    system integration:系统集成       
    System Testing       : 系统测试
    TC   TEST CASE 测试用例
    TCS  TEST CASE SPECIFICATION 测试用例规格说明
    TDS   TEST DESIGN SPECIFICATION 测试设计规格说明书
    technical requirements testing:技术需求测试       
    Test                 : 测试
    test automation:测试自动化       
    Test case            : 测试用例
    test case design technique:测试用例设计技术       
    test case suite:测试用例套     
    test comparator:测试比较器       
    test completion criterion:测试完成标准       
    test coverage:测试覆盖       
    Test design          : 测试设计
    Test driver          : 测试驱动
    test environment:测试环境       
    test execution technique:测试执行技术       
    test execution:测试执行       
    test generator:测试生成器       
    test harness:测试用具       
    Test infrastructure  : 测试基础建设
    test log:测试日志       
    test measurement technique:测试度量技术
    Test Metrics :测试度量      
    test procedure:测试规程       
    test records:测试记录       
    test report:测试报告       
    Test scenario        : 测试场景
    Test scrīpt:测试脚本       
    Test Specification:测试规格       
    Test strategy        : 测试策略
    test suite:测试套       
    Test target          : 测试目标
    Test ware             :  测试工具
    Testability          : 可测试性
    testability:可测试性       
    Testing bed          : 测试平台
    Testing coverage     : 测试覆盖
    Testing environment  : 测试环境
    Testing item         : 测试项
    Testing plan         : 测试计划
    Testing procedure    : 测试过程
    Thread testing       : 线程测试
    time sharing:时间共享       
    time-boxed           : 固定时间
    TIR    test incident report    测试事故报告
    ToolTip:控件提示或说明
    top-down testing:自顶向下测试       
    TPS TEST PEOCESS SPECIFICATION 测试步骤规格说明
    Traceability         : 可跟踪性
    traceability analysis:跟踪性分析       
    traceability matrix:跟踪矩阵       
    Trade-off            : 平衡
    transaction:事务/处理 
    transaction volume:交易量   
    transform analysis:事务分析       
    trojan horse:特洛伊木马       
    truth table:真值表       
    TST  TEST SUMMARY REPORT 测试总结报告
    Tune System : 调试系统
    TW TEST WARE :测试件
    Unit Testing         :单元测试       
    Usability Testing:可用性测试       
    Usage scenario       : 使用场景
    User acceptance Test : 用户验收测试
    User database        :用户数据库
    User interface(UI)   : 用户界面
    User profile         : 用户信息
    User scenario        : 用户场景
    V&V (Verification & Validation) : 验证&确认
    validation           :确认       
    verification         :验证       
    version              :版本       
    Virtual user         : 虚拟用户
    volume testing:容量测试  
    VSS(visual source safe) :
    VTP   Verification  TEST PLAN验证测试计划
    VTR  Verification TEST REPORT验证测试报告
    Walkthrough          : 走读
    Waterfall model      : 瀑布模型
    Web testing          : 网站测试
    White box testing    : 白盒测试
    Work breakdown structure (WBS) : 任务分解结构
    Zero bug bounce (ZBB) : 零错误反弹
  • [转]QTP的基本使用函数:

    2007-10-11 14:25:14

     

    今天在网上找一些东东的时候,无意间发现这个帖子,觉得还不错特贴出来跟大家share一下。

    QTP的基本使用函数:

    1,获取对话框相应的文字: GetVisible Text

    2,查找相应的字符串: instr (1,查找目标字符串,所查找的字符串)

    3,随机数的获取: Randomnumber.Value() 或cstr(int(Rnd*10)+1)

    4,等待函数: Wait(秒数)

    5,获取数组下标: UBound (数组名)

    6,拆分数组:Split(MyString, ",", -1, 1)

    7,可执行步骤:OptionalStep

    8,报告信息: Reporter.ReportEvent 3, "Save Step", "Out of cycle!"

    9,判断对话框是否存在: .exist

    10,事件过滤函数:Reporter.Filter=过滤条件(0123)0代表显示所有的errorwarning,1,显示error,2,显示waining,3,任何errorwarning都不显示。

    11,循环函数:do … loop untilfor…to… then next,while.

    12数据表格:DataTable,向外赋值,Dim aa = DataTable.value(“CellingName”,”ActionName”).

    13,获得对象属性的三种方法GetTOPropertyGetTOProperties,GetROProperty,GetTOProperty获得程序中对象当前的属性,GetTOProperties获得当前属性所有集合,GetROProperty获得的是录制时对象所获得的属性。

    14,检查点方法check和输出指定属性值output

    15,函数Descrīption,可以获得某页面同标签的属性进行操作。

    16,函数nagative可以随便跳转页面到指定的URL

    17,函数Object可以获得当前页面同属性的控件。

    18,函数Focus可以让控件获得焦点,函数Blur则是失去焦点,click单击,dbclick双击。

    19,函数setAttribute可以设置控件属性,getAttribute可以获得属性。

    添加数据:

    1.       在每个要覆盖的域添加checkpoint

    2.       在不能同名的必填字段里,添加随机函数,循环增加。

    查询数据:

    1.      先添加数据,再查询数据更新,更新成功时设置checkpoint

    2.        最后删除成功时设置checkpoint

Open Toolbar