电子科大~软件测试期末复习完整版

本文详细介绍了软件测试的不同方面,包括软件测试的定义、SQA与软件测试的关系、TDD流程、测试驱动开发的重要性、软件缺陷和质量保证活动。讨论了单元测试、集成测试、系统测试、验收测试的步骤和方法,如静态测试、动态测试、边界值分析、正交实验、语句覆盖等。此外,还涉及了测试自动化、软件本地化测试、测试需求分析和测试计划,以及软件质量保证的关键点。
摘要由CSDN通过智能技术生成

第一章 引论

软件测试(Software Testing)是一种检测软件的正确性、完整性、安全性和评估其质量的活动过程。换句话说,软件测试是一种以发现程序错误、衡量软件质量为目的,并对其是否满足用户需求进行评估的活动过程。

软件质量保证(Software Quality Assurance,SQA)是指通过对软件产品进行有计划的评审与审计,来确保软件开发按照产品质量过程标准实施项目的管理活动。

软件质量保证与软件测试的关系:

SQA指导软件测试的计划与执行,监督测试工作结果的客观性、准确性与有效性,并协助软件测试的工作流程改进。

软件测试是SQA工作落实的重要手段,它为SQA提供所需的质量数据,作为软件质量评价的客观依据。

SQA是一项软件质量管理性工作,侧重于对软件开发流程进行评审与监控。

软件测试是一项技术性工作,侧重于对软件质量特性进行检测与验证。

测试驱动开发(Test-Driven Development,简称TDD)是一种不同于传统软件开发流程的过程模型。它要求在编写某个功能的代码之前先编写测试代码,然后编写功能代码,通过测试来推动整个软件开发工作的进行。

下面哪项活动不是软件测试范畴

A.需求文档评审 B.设计评审 C.代码测试 D.过程评审

过程评审是质量保证活动的一部分,用于评估软件开发过程是否符合既定标准和流程。

编程完成后才进行测试存在哪些问题?

测试的时间很有限,很难达到测试的覆盖率要求和测试的质量要求。同时,假如在项目开发的后期,发现一些软件需求阶段和概要设计阶段的错误和问题,修改这些缺陷导致的成本将是非常高的。

第二章 软件测试基本概念

缺陷(Defect)是指欠缺或不够完备的地方。因为缺陷是相对质量要求而存在的,任何违背了质量要求、违背了客户的意愿,不能满足用户的要求,都可以认为是缺陷。

IEEE STD729关于软件质量定义:软件产品或服务满足用户需求的程度。

①软件缺陷在开发早期出现的概率大,在早期进行缺陷修复的成本低。

②软件在开发后期出现缺陷的概率小,但修复成本高。

③软件测试工作应尽早开展。

在代码审查中,静态测试可发现如下编程缺陷:

变量在初始化前使用、变量声明后未使用、变量在两次赋值之间从未使用

数组访问越界

存在不可到达代码

循环中无条件分支

接口参数类型或数目不匹配

空指针或指针类型错误

存在未被调用的函数和过程

案例一

for(int i=0;i<(int)attributeList.length();i++){
        }

如果把判断条件放在for语句内,每一次判断都要重新计算length, 浪费资源

正确代码

int tmp_iListLength=attributeList.length()
for(int i=O;i<tmp_iListLength; i++)
{
......
}

案例二

int i ;
...
printf("i= %d \n",i) ;

正确代码

int i=0 ;
printf ("i= %d \n",i) ;

案例三

public class ArrayDemo {
    public static void main(String args[]) {
        int array[] = null; //声明数组
        array = new int[3];//为数组开辟空间,大小为3
        for (int i = 0; i <= array.length; i++) {
            System.out.println("array[" + i + "]=" + array[i]);
        }
    }
}

缺陷应该是数组下标可能越界

个人修改的代码

public class ArrayDemo {
    public static void main(String args[]) {
        int array[] = null; //声明数组
        array = new int[3];//为数组开辟空间,大小为3
        for (int i = 0; i < array.length; i++) {
            System.out.println("array[" + i + "]=" + array[i]);
        }
    }
}

案例四

public class ExceptionDemo {
    public static void main(String args[]) {
        System.out.println("**********计算开始***********");
        int i = 0;      // 定义整型变量
        int j = 0;      //定义整型变量
        try {
            String str1 = args[0];  // 接收第一个参数
            String str2 = args[1];  // 接收第二个参数
            i = Integer.parseInt(str1);//将第一个参数由字符串变为整型
            j = Integer.parseInt(str2);//将第二个参数由字符串变为整型
            int temp = i / j;           //进行除法计算
            System.out.println("两个数字相除的结果:" + temp);
        } catch (ArithmeticException e) {// 捕获算术异常System.out.println("出现异常了: " + e);
        }
        System.out.println("**********计算结束***********");
    }
}

可能的缺陷:

  • 在try块中,使用args数组来接收命令行参数。然而,没有对args数组的长度进行检查或验证。如果没有传递足够的参数,将会导致ArrayIndexOutOfBoundsException(数组索引越界异常)。
  • 在try块中,将args数组的元素作为字符串参数传递给parseInt()方法进行整数转换。然而,如果传递的参数无法解析为整数,将会导致NumberFormatException(数字格式异常)。
  • 在catch块中,捕获了ArithmeticException异常,但是该异常只能捕获除以0导致的算术异常。如果出现其他类型的异常,将无法被捕获和处理。

正确代码:

public class ExceptionDemo {
    public static void main(String args[]) {
        System.out.println("********** 计算开始 ***********");
        try {
            if (args.length < 2) {
                throw new IllegalArgumentException("缺少必要的参数");
            }
            
            int i = Integer.parseInt(args[0]);
            int j = Integer.parseInt(args[1]);
            
            int temp = i / j;
            System.out.println("两个数字相除的结果: " + temp);
        } catch (NumberFormatException e) {
            System.out.println("参数格式错误: " + e);
        } catch (ArithmeticException e) {
            System.out.println("除数不能为0: " + e);
        } catch (IllegalArgumentException e) {
            System.out.println("参数错误: " + e);
        } finally {
            System.out.println("********** 计算结束 ***********");
        }
    }
}

动态测试是通过运行被测软件程序,观察该程序在运行过程中的系统行为、变量结果、内存、堆栈等运行数据,来判断软件系统是否存在缺陷的测试活动。
动态测试可发现的主要缺陷:

程序逻辑错误

异常输入的功能失效

空指针使用

内存没有及时释放关闭的对象资源

Session失效

没有处理在空输入时点取Enter键情况

案例一

class Person {
    String name; // 声明姓名属性
    int age; // 声明年龄属性

    public void tell() { // 取得信息
        System.out.println("姓名: " + name + ",年龄: " + age);
    }
}

public class ClassDemo {
    public static void main(String args[]) {
        Person per = null; // 声明对象
        per.name = "张三"; // 为姓名赋值
        per.age = 30; // 为年龄赋值
        per.print(); // 调用方法,打印信息
    }
}

在ClassDemo类的main方法中,创建了一个Person对象per,但没有实际实例化该对象,而是将其初始化为null。这意味着per对象没有被正确地创建和初始化,因此在尝试为per对象的name和age属性赋值时会导致NullPointerException(空指针异常)。
在Person类的tell()方法中,打印信息的语句使用了per.print(),但实际上应该调用的是per.tell(),因为tell()方法是定义在Person类的。

案例二

OutputStream os=null;
try{
    os=new OutputStream();
      //Do something with os here.
    os.close();
}catch(Exception e){
        if(os!=null)
         os.close();
}

正确代码:

OutputStream os=null;
try{
    os=new OutputStream();
      //Do something with os here.
}finally{
    if(os!=null)
     os.close();
}

修改后的代码使用了 finally 块来确保在无论是否发生异常的情况下都能关闭输出流。

软件验证((verification)是指在开发软件过程中,检验软件是否已正确地实现了产品规格说明书所定义的系统功能和特性。
软件确认(validation)是指在开发软件完成后,检查软件产品是否符合用户的真实需求。

验证:我们正确地构造了产品吗?

确认:我们构造了正确的产品吗?

黑盒测试是指在测试中,把程序看作一个不能打开的黑盒子。在完全不考虑程序内部结构和内部特性的情况下,对程序功能进行测试,检查程序功能是否按照需求规格说明进行有效实现、是否能适当地接收输入数据而产生正确的输出信息。

黑盒测试是从用户观点出发开展的测试,其目的是尽可能发现软件的外部行为错误。黑盒测试常用于发现以下缺陷:

检测软件是否有错误的功能或有功能遗漏
不能正确地接收输入数据、输出错误的结果
功能操作不够方便
界面出错、扭曲或不美观
安装过程中出现问题,安装步骤不清晰、不灵活
系统初始化存在问题

白盒测试是指在了解被测程序内部逻辑结构情况下,对该程序的内部变量、逻辑结构、运行路径进行测试,检验被测程序的内部动作或运行功能是否符合设计规格要求。

白盒测试常用于发现以下缺陷:

程序逻辑错误
程序状态异常
程序路径无法跳转
变量遗漏初始化

单元测试

单元测试针对软件程序中的最小功能单元代码(类、函数、模块或组件)进行测试。
主要采用白盒测试方法,从程序的内部结构出发设计测试用例,检查单元程序已实现功能与设计规格是否一致、以及编码中是否存在逻辑错误。
单元测试一般由编程人员和测试人员共同完成,而以开发人员为主。通常需要编写驱动模块桩模块
单元测试还采用代码评审方法(走读、静态分析、评审)检查程序错误,代码评审可以发现程序**50%~70%**代码的缺陷。

集成测试(也称组装测试、联合测试)是一种在单元测试的基础上,将若干单元模块按照设计要求组装起来所进行的测试,其目标是发现模块接口相关问题。

系统测试是在集成测试之后,在系统层面所进行的功能特性测试和非功能特性测试。

验收测试是在软件提交用户前,在实际用户环境中,验证软件系统功能、性能及其它特性是否符合用户需求。

  • α测试——软件公司在其产品推向市场前,采用实际运行环境和真实数据在软件公司内部进行的验收测试。
  • β测试——软件公司在其产品推向市场前,还需要在公司外部用户中进行试用测试。通过收集试用户的反馈意见,对该版本软件进行修正与完善,最终得到正式发布的版本。

第三章 软件测试方法

基于直觉和经验的方法

Ad-hoc测试方法强调测试人员更多根据自己的专业经验,不受测试用例约束,放开思路、灵活地进行各种测试。
ALAC ( Act-like-a-customer,像客户那样做)测试方法是一种基于客户使用产品的经验知识进行系统测试,其出发点是应用帕累托(Pareto)二八法则进行重点测试。
错误推测法是测试者根据自己的工作经验、专业知识和直觉来来推测出软件中可能存在的各种错误,从而对被测软件采用针对性的测试。

基于输入域方法(数据驱动测试)

等价类划分法:

一个程序P有两个整型输入变量I1、I2,输出变量为Out,其计算函数为Out=P(l1,I2),假定在字长32位计算机上运行。所有输入数据组合有多少? 2³²x 2³²=2⁶⁴

例:采购收货单报表系统,要求用户输入处理报表的日期。假定日期限定在2000年1月1日到2023年12月30日。请设计“日期”输入数据验证的等价类。

有效日期的等价类:2000年1月1日到2023年12月30日的日期值
无效日期的等价类:小于2000年1月1日的日期值
无效日期的等价类:大于2023年12月30日的日期值

例:采购收货单报表系统,对于商品数量输入数据,应为大于0的整数,才能符合业务要求。请设计“数量”输入数据验证的等价类。

有效“数量”字段输入等价类:大于0的整数。
无效“数量”字段输入等价类:小于等于0的整数。

例:航班计划系统,对于某航班设定是否为往返航班,其输入数据应采用布尔数值,才能符合业务要求。请设计“来回程”输入数据验证的等价类。

有效的“来回程”字段数据输入等价类:真/假布尔值。
无效的“来回程”字段数据输入等价类:其它任何值。

例:对于计算器软件的加法运算功能进行测试。请设计“+”功能测试的等价类。

有效的数据输入等价类:整型数值
有效的数据输入等价类:实数数值
有效的数据输入等价类:负数数值
无效的数据输入等价类:非数字符号

例:四川地税发票查询页面的发票金额字段输入检查功能测试。

有效的“发票金额”字段数据输入等价类:大于0的数值数据。
无效的“发票金额”字段数据输入等价类:非数值数据。
无效的“发票金额”字段数据输入等价类:小于等于0的数值

边界值分析法就是在某个输入变量范围的边界上,输入一些特定数据,分析验证系统功能是否正常运行的测试方法。

例:酒店预订系统业务规定客户最多可提前20天预订酒店客房。请按边界值分析法设计酒店搜索功能的测试用例。

假定客人在2023-3-12进行订房操作,预订后面10到20天内入住客房,其测试边界值可设置为:2023-3-21、2023-3-31、2023-4-1

等价类划分法和边界值分析法仅适用于单因素(单变量)输入的数据测试。

基于组合及其优化方法(多变量)

判定表方法是一种借助表格方式完成多条件输入组合下测试用例设计,达至完全覆盖输出结果的测试方法。其表格组成样式如下:

序号12345678
条件正确输入年YYYYYNNNN
条件正确输入月MYYNNYYNN
条件正确输入日DYNYNYNYN
动作函数运行成功
动作函数运行失败

因果图法是一种利用图解法分析输入的各种组合情况,从而设计测试用例的形式化方法。它适合于检查程序输入、输出错误,还能判定程序规范中的二义性、不完全性等错误。

因果图PPT上面举了好几页例子,肯定很重要哒~

Snipaste_2023-06-02_15-46-16.png

Snipaste_2023-06-02_15-46-38.png

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TtFyJqQp-1686183955026)(null)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ner5mFyt-1686183955067)(null)]

Snipaste_2023-06-02_15-47-10.png

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OB34Do3e-1686183955001)(null)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zCelfcTO-1686183955091)(null)]

Snipaste_2023-06-02_15-50-08.png

Snipaste_2023-06-02_15-50-14.png

Snipaste_2023-06-02_15-50-20.png

当有多个输入变量、每个变量又有多个取值。若要执行全覆盖组合测试,其工作量非常大。为了有效地减少测试组合数,可以采用成对组合测试方法,其基本思想是每两个输入变量所有取值组合形成不同测试用例。

例:

测试一个登录页面在不同浏览器和语言下的功能正确性,其输入条件如下:

1)输入项(账号、密码)

2)浏览器(IE、chrome、FireFox、360)

3)语言(中文、英文)

成对组合测试用例表

用例账号密码浏览器语言
1空值空值IE中文
2空值有值chrome英文
3有值空值FireFox中文
4有值有值360英文
5空值空值360中文
6空值有值FireFox英文
7有值空值chrome中文
8有值有值IE英文

正交实验测试法是一种依据伽罗华(Galois)理论,从大量实验数据中挑选适量的、具有代表性的数据进行实验,以达到降低实验成本的方法。

正交表构成

行数:正交表中的行个数,即实验的次数,也是我们通过正交实验法设计的测试用例个数。行数(即>测试用例次数)=∑(每列水平数-1)+1

因素数:正交表中列的个数,即测试功能点的因子数。

水平数:任何单个因素能够取值的个数。正交表中包含值为从0到“水平数-1”或从1到“水平数”。即要测试功能点的输入取值数。

L代表正交表,它是运用数学理论在拉丁方和正交拉丁方基础上构造的规格化数据表格,常用的有L₈(2⁷)、L₉(3⁴)、L₁₆(4⁵)等。

正交表特性

1)每一列中各数字出现的次数都一样多;
2)任何两列所构成的各有序数对出现的次数都一样多。
例如在两水平正交表中,任何两列(同一横行内)有序对子共有4种:(1,1)、 (1,2)、(2,1)、 (2,2)。每种对数出现次数相等。在三水平情况下,任何两列(同一横行内)有序对共有9种,1.1、1.2、1.3、
2.1、2.2、2.3、
3.1、3.2、3.3,且每对出现数也均相等。

在一个客户信息查询界面中,输入条件有“姓名”、“身份证号”、“手机”,采用正交表方式设计该界面查询功能的测试用例。

针对本测试有3个输入条件,每个输入有2种取值情况,可以选择L₄(2³)正交表,其正交表值如下表所示:

实验数\列号姓名身份证号手机
1111
2100
3010
4001

测试用例:

测试用例/查询条件姓名身份证号手机
测试用例1填写填写填写
测试用例2填写
测试用例3填写
测试用例4填写

基于逻辑覆盖方法

语句覆盖法的基本思想是设计若干测试用例,使得被测程序中的每个可执行语句至少被执行一次。如果是顺序结构,就是让测试从头执行到尾。如果有分支、条件和循环,则需要执行足够的测试用例覆盖全部语句。

语句覆盖测试能解决的问题:发现程序中一些永远不能被执行的语句缺陷,但不能发现程序中语句逻辑错误。

语句覆盖测试即使覆盖了程序中每个语句,但并不一定测试覆盖所有分支。试图覆盖程序中所有路径的测试方法称为路径覆盖。路径测试的最简单形式就是判定覆盖测试
判定覆盖测试基本思想:设计若干用例,运行被测程序,使得程序中每个判断语句的取真分支和取假分支至少执行一次,即判断真假值均可被满足。一个判定往往代表程序的一个分支,所以判定覆盖测试也称为分支覆盖测试

判定覆盖测试能发现程序中一些永远不能被执行的分支缺陷,可以发现部分逻辑缺陷。

条件覆盖的基本思想是设计若干测试用例,使其对被测程序进行测试,使每个判断中每个条件的可能取值至少满足一次。

符合条件覆盖的测试用例并不一定满足判定覆盖要求,反之,符合判定覆盖的测试用例也不一定满足条件覆盖要求。因此,需要找出符合两者的测试用例交集,该方法称为判定-条件覆盖

条件组合覆盖的基本思想是设计足够的测试用例,使得判断中每个条件的所有取值情况至少出现一次,并且每个判断本身的判定结果也至少出现一次。条件组合测试不一定能覆盖所有路径。

基本路径覆盖就是设计测试用例,覆盖程序中所有可能的基本分支路径。
基本路径覆盖局限:不能保证覆盖所有条件组合

基本路径覆盖测试用例设计步骤:

依据代码绘制流程图
确定流程图的环路复杂度
确定各个独立路径的基本集合
设计测试用例覆盖每条基本路径

计算环路复杂度:

(1)流图中的区域数等于环形复杂度。
(2)流图G的环形复杂度V(G)=E-N+2,其中,E是流图中边的条数,N是结点数。
(3)流图G的环形复杂度V(G)=P+1,其中,P是流图中判定结点的数目。

第四章 测试流程和规范

软件测试过程:

软件工程角度
需求评审→设计评审→单元测试→集成测试→系统测试→验收测试

项目管理角度
测试计划→测试设计→执行与监控→结果分析与评估→项目总结

敏捷测试(自动化测试)是一种遵从敏捷软件开发原则,支持敏捷软件开发实现质量控制的测试实践。
TMap (Test Management Approach,测试管理方法)是一种业务驱动的、基于风险策略的、结构化的测试管理方法,其目标是尽早地发现缺陷,以最小的成本、有效地、彻底地完成测试任务,以减少软件发布后的支持成本。

基于脚本测试(Scripted Testing,ST),无论是手工测试,还是自动化测试,都需要先设计用例,生成测试脚本,然后执行脚本实施测试。
探索式测试(Exploratory Testing,ET),不需要设计用例,一边思考,一边测试。
在敏捷测试中,则主要采用探索式测试,基于脚本测试则作为补充;而在传统测试中,主要采用基于脚本测试,探索式测试作为补充。

第五章 单元测试与集成测试

单元静态测试是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。主要采用互查、走查、评审方法进行测试,也可通过代码缺陷扫描工具进行分析处理。

代码示例1:

/**
 * 通过用户UI界面输入的用户名,传递到Action层,进行用户角色识别操作
 * 
 * @param request HttpServletRequest对象
 * @return String 用户角色,如管理员/普通用户/...
 */
public String getUserRole(HttpServletRequest request) {
    String userRole = "";
    String userName = request.getParameter("userName");
    
    if (userName.equals("schadmin")) {
        // 这是系统初始化时默认的管理员账号,如果是,则进行以下验证操作...      
    } else {
        // 非系统初始化的账号,进行以下验证操作...

    }
    
    return userRole;
}

userName可能会出现空指针情况

修改:

/**
 * 通过用户UI界面输入的用户名,传递到Action层,进行用户角色识别操作
 * 
 * @param request HttpServletRequest对象
 * @return String 用户角色,如管理员/普通用户/...
 */
public String getUserRole(HttpServletRequest request) {
    String userRole = "";
    String userName = request.getParameter("userName");
    
    if ("schadmin".equals(userName)) {
        // 这是系统初始化时默认的管理员账号,如果是,则进行以下验证操作...      
    } else {
        // 非系统初始化的账号,进行以下验证操作...

    }
    
    return userRole;
}

代码示例2

/**
 * 通过用户输入的年龄,转换为数值型
 *
 * @param request HttpServletRequest对象
 * @return Integer 用户年龄
 */
public int getUserAge(HttpServletRequest request) {
    int age = 0;
    String userAge = request.getParameter("userAge");
    
    if (userAge != null) {
        age = Integer.parseInt(userAge);
    }
    
    return age;
}

userAge可能不是字符型数字。

建议写一个Util工具类,实现一些常见的数据转换方法,以供调用:

/**
 * 传入的字符串转换为整型
 *
 * @param intStr String
 * @return Integer
 */
public static int getIntValue(String intStr) {
    int parseInt = 0;
    
    if (isNumeric(intStr)) {
        parseInt = Integer.parseInt(intStr);
    }
    
    return parseInt;
}

示例代码3

/**
 * 假设电话号码字符串设计的标准格式为: 国家编码-区位号码-电话号码-分机号
 *
 * @param strPhoneNumber String
 * @return String 电话号码 (如: 例子中的2313222)
 */
public static String getPhoneNumber(String strPhoneNumber) {
    if (strPhoneNumber == null || "".equals(strPhoneNumber)) {
        return "";
    }
    
    String[] arrPhone = strPhoneNumber.split(",");
    
    return arrPhone[2];
}

可能出现数组越界错误。

修改:

public static String getPhoneNumber(String strPhoneNumber) {
    if (strPhoneNumber == null || "".equals(strPhoneNumber)) {
        return "";
    }
    
    String[] arrPhone = strPhoneNumber.split(", ");
    
    if (arrPhone.length > 2) {
        return arrPhone[2];
    }
    
    return "";
}

示例代码4

public static void writeString(File file, String writeContent, String encoding) throws FileOperatorException {
    FileOutputStream fos = null;
    try {
        if (!file.exists()) {
            file.createNewFile();
        }
        fos = new FileOutputStream(file);
        fos.write(writeContent.getBytes(encoding));
    } catch (Exception ex) {
        throw new FileOperatorException(ex);
    } 
}

修改代码:

public static void writeString(File file, String writeContent, String encoding) throws FileOperatorException {
    FileOutputStream fos = null;
    try {
        if (!file.exists()) {
            file.createNewFile();
        }
        fos = new FileOutputStream(file);
        fos.write(writeContent.getBytes(encoding));
    } catch (Exception ex) {
        throw new FileOperatorException(ex);
    } finally {//如果没有finally下面的段语句,就无法释放文件资源
         if (fos != null){
             try {
                fos.close();
        } catch (IOException e) {
            throw new FileOperatorException(e);
             }
        }
    }
}

为了确保代码在运行可靠、功能正确并且能够有良好的性能响应,仅仅进行静态测试是不够的,必须将该单元代码运行起来,验证代码业务逻辑合理性,并了解单元代码的实际表现,即对单元代码进行动态测试

动态测试实现原理

驱动程序(Driver)
被测单元(Unit)
桩程序(Stub)

桩模块和驱动模块的概念搞不清楚,那么下面来介绍这两个概念:

假设现在项目组把任务分给了7个人,每个人负责实现一个模块。你负责的是B模块,你很优秀,第一个完成了编码工作,现在需要开展单元测试工作,先分析结构图:
  1、由于B模块不是最顶层模块,所以它一定不包含main函数(A模块包含main函数),也就不能独立运行。
  2、B模块调用了D模块和E模块,而目前D模块和E模块都还没有开发好,那么想让B模块通过编译器的编译也是不可能的。
  那么怎样才能测试B模块呢?需要做:
  1、写两个模块Sd和Se分别代替D模块和E模块(函数名、返回值、传递的参数相同),这样B模块就可以通过编译了。Sd模块和Se模块就是桩模块。
  2、写一个模块Da用来代替A模块,里面包含main函数,可以在main函数中调用B模块,让B模块运行起来。Da模块就是驱动模块。
  桩模块的使命除了使得程序能够编译通过之外,还需要模拟返回被代替的模块的各种可能返回值(什么时候返回什么值需要根据测试用例的情况来决定)。
  驱动模块的使命就是根据测试用例的设计去调用被测试模块,并且判断被测试模块的返回值是否与测试用例的预期结果相符

集成测试模式:

非渐增式集成测试
先分别测试每个模块,再把所有模块按设计要求组装在一起,然后再进行集成程序的测试。
渐增式集成测试
把下一个待测试的模块同已经测试好的模块结合起来进行测试,测试完以后再把下一个待测试模块结合进来测试。

HU3PI_3`VKVH_46F9W_GL_4.png

E_Y5_DZ_B7D_8_Y_B__R_Q8.png

以上两种测试模式都属于渐增式集成测试。

针对叶节点模块进行单元测试,下面哪项不是必须的?
A.测试数据 B.被测单元 C.驱动程序 D.桩程序

然而,对于叶节点模块的单元测试而言,通常不需要使用桩程序。叶节点模块是指在软件系统中没有其他依赖的最底层模块,也被称为叶子节点或叶子模块。由于它们不依赖其他模块或外部系统,所以不需要模拟或替代任何外部依赖项的行为。

第六章 系统测试

功能测试就是对软件系统的各功能进行验证,根据系统功能需求,逐项测试系统功能是否达到用户要求。

回归测试是指修改了源代码后,重新进行系统功能测试以确认修改没有引入新的错误或导致其他代码产生错误(回归缺陷)。

性能测试是一种为了发现系统性能问题或获取系统性能相关指标而进行的测试。一般在真实环境、特定负载条件下,通过测试工具模拟实际软件系统的运行及其操作,同时监控性能各项指标,最后对测试结果进行分析来确定系统的性能状况。

常见系统性能问题

资源耗尽:CPU使用率达到100%
资源泄露:内存泄露导致资源耗尽
资源瓶颈:缺少可用线程、DB连接资源

负载测试(Load Test):负载测试是一种性能测试,指数据在超负荷环境中运行,程序是否能够承担。 关注点:how much

压力测试(Stress Test): 压力测试(又叫强度测试)也是一种性能测试,它在系统资源特别低的情况下软件系统运行情况,目的是找到系统在哪里失效以及如何失效的地方。

容量测试(Volume Test):确定系统可处理同时在线的最大用户数 关注点:how much(而不是how fast) 容量测试,通常和数据库有关,容量和负载的区别在于:容量关注的是大容量,而不需要关注使用中的实际表现。

其中,容量测试、负载测试、压力测试的英文解释为:

Volume Testing = Large amounts of data
Load Testing = Large amount of users
Stress Testing = Too many users, too much data, too little time and too little room

假设一个业务系统有1万个注册用户,每天有1半用户会在上班时间(8小时)访问该系统,平均在线时间为1个小时。那么访问该系统的上班时间平均每分钟在线用户数为多少?
5000×60/(8×60)=625

Y_TBOAQ0UR1TJ27T2@S4SQY.png

容错性测试是检查系统容错能力,即系统在异常条件下自身是否具有防护性的措施或者某种灾难性恢复的手段。

兼容性测试是指测试软件在特定的硬件平台上、不同的应用软件之间、不同的操纵系统平台上、不同的网络等环境中是否能够很友好的运行。

软件可靠性是指软件系统在规定时间内及规定环境条件下,完成特定功能的能力。

软件可靠性评估:
MTTF (Mean Time To Failure)——系统平均无故障时间

MTTR (Mean Time To Recover)——故障平均修复时间

可用性度量= MTTF / (MTTF+MTTR)
例:如果系统每运行100个时间单位,会有1个时间单位无法提供服务,其系统的可用性是99%。

下面哪项不是系统性能降低的原因?
A.资源耗尽 B.响应时间慢 C.内存泄漏 D.网络拥挤

第七章 验收测试

验收测试是在软件产品完成了系统测试之后、产品发布之前所进行的软件测试活动,它是软件测试的最后一个阶段,也称交付测试

有些内容在第二章说到啦!

第八章 软件本地化测试

软件本地化是指将某软件产品的用户界面、文档资料、在线帮助等从其源语言向目标语言进行转化,使之适应目标语言及文化的处理过程。

软件国际化是指为保证所开发软件产品能适应国际市场需要,通过特定的系统架构设计、代码编程技术支持软件能在不同语言、不同文化的国家及地区使用,使其在进行本地化时不需要修改软件的程序代码。

软件本地化测试是根据软件本地化开发完成后,设计测试用例,并利用这些测试用例去运行被测试软件,以发现软件程序缺陷的过程。(含翻译验证

第九章 测试自动化及其框架

自动化测试是指采用测试工具实现程序驱动替代人驱动所开展的软件测试活动。测试自动化除包括自动化测试之外,还包括测试辅助工作的自动化。

自动化测试不能完成下面哪项质量指标测试?

A.正确性 B.可靠性 C.性能效率 D.易用性

自动化测试可以用于测试正确性、可靠性和性能效率等质量指标,但对于易用性的测试则相对有限。易用性通常涉及到用户界面的可操作性、用户体验和用户友好性等方面,这些特征难以完全通过自动化测试来覆盖和评估。易用性测试通常需要人工参与,通过用户实际操作和反馈来评估系统的易用性。

JUnit是一种白盒测试工具,因为它主要用于单元测试,可以直接访问和测试代码的内部结构和逻辑。它通常用于Java开发环境中,用于测试Java应用程序的各个单元和模块。UFT(Unified Functional Testing)是一种黑盒测试工具,用于功能测试和自动化测试。它主要用于测试应用程序的外部行为和用户界面,而不需要了解应用程序的内部实现。
Load Runner是一种性能测试工具,用于测试应用程序在负载和压力条件下的性能表现。它通常用于模拟多个用户同时访问应用程序,以评估其性能和可靠性。
Selenium是一种自动化测试工具,主要用于Web应用程序的功能测试和回归测试。它可以模拟用户操作和交互,并对应用程序的用户界面进行测试。由于它主要关注应用程序的外部行为,因此它也被归类为黑盒测试工具。

第十章 测试需求分析与测试计划

功能测试范围

页面链接:页面是否存在、页面是否正确跳转
控件功能:按钮功能是否正确、列表内容是否正确、光标位置移动是否顺序正确
输入文本框:数据格式、数据类型、数据长度是否检查
Web图形测试:图片文字提示是否正确、图片链接是否正确、图片在不同分辨率下显示是否正确
表单测试:请求是否响应、脚本是否正确执行

非功能测试范围。

性能测试——响应时间、吞吐量等
安全测试——用户验证、授权访问、数据安全等
容错测试——部件损坏后系统仍正常运行能力
兼容性测试——硬件兼容性、操作系统兼容性、浏览器兼容性·可伸缩性测试——增加容量的能力
可用性测试——正常运行时间/总运行时间

第十一章 软件质量保证

软件度量是根据一定规则对软件项目、软件过程、软件产品进行数据定义、数据收集及量化处理,其目的是为了清晰地理解、预测、评估、控制和改善软件质量。

NK38BB~K_3SH_VC9.png

_RF_ABD_90`8@LYLXYP4R@A.png

_Q1DGL`_SUS_P_RW~_TX6_N.png

再举个上机考试考的题吧,细思也不是不能出大题:

针对如下Java程序进行单元测试,找出该程序的缺陷。

/* 对传入参数telCode(电话号码)进行处理,从中提取该电话号码的座机号码,并将其输出返回。 
 * 例如,输入电话号码为“86,28,83202112”, 返回值应为“83202112” */
public class getPhoneNo {
	public String getPhoneNumber(String telCode) { 
	  if (telCode == null ) { 
	    return "输入了空字符串";}
      else {
		String localPhone[] = telCode.split(","); 
		return localPhone[2]; }
	}
}

设计单元测试用例表,在该表中填写测试用例的输入数据和预期结果数据。

用例telCode值预期结果
186,28,8320211283202112
2Null输入了空字符串
3空格输入电话号码格式错误
486,83202112输入电话号码格式错误
586,28,83202112%输入电话号码格式错误

缺陷如下:

  1. 电话号码为空时无法提示输入了空字符串。

  2. 电话号码输入为空格,或者其位数不符合要求,该程序报错而无法继续运行,应该提示输入电话号码格式错误。

  3. 当电话号码含有非法字符,该程序没有提示输入了非法字符,而是继续输出了非法字符,应该提示输入电话号码格式错误才对。

测试代码:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class getPhoneNoTest_83202112 {
    getPhoneNo getPhoneNo=new getPhoneNo();

    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void getPhoneNumber() {
    }

    @Test
    public void getPhoneNo1() {
        String expectedResult="83202112";
        assertEquals(expectedResult,getPhoneNo.getPhoneNumber("86,28,83202112"));
    }
    @Test
    public void getPhoneNo2() {
        String expectedResult="输入了空字符串";
        assertEquals(expectedResult,getPhoneNo.getPhoneNumber(null));
    }
    @Test
    public void getPhoneNo3() {
        String expectedResult="输入电话号码格式错误";
        assertEquals(expectedResult,getPhoneNo.getPhoneNumber(" "));
    }
    @Test
    public void getPhoneNo4() {
        String expectedResult="输入电话号码格式错误";
        assertEquals(expectedResult,getPhoneNo.getPhoneNumber("86,83202112"));
    }
    @Test
    public void getPhoneNo5() {
        String expectedResult="输入电话号码格式错误";
        assertEquals(expectedResult,getPhoneNo.getPhoneNumber("86,28,83202112%"));
    }
}

修改后的源程序:

public class getPhoneNo {
    public String getPhoneNumber(String telCode) {
        if (telCode == null) {
            return "输入了空字符串";
        } else {
            String localPhone[] = telCode.split(",");
            if (localPhone.length < 3) {
                return "输入电话号码格式错误";
            }
            String phoneNumber = localPhone[2];
            for (int i = 0; i < phoneNumber.length(); i++) {
                int c = phoneNumber.charAt(i);
                if (c < '0' ||c > '9'){
                    return "输入电话号码格式错误";
                }
            }
            return phoneNumber;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王翊珩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值