(叠甲:如有侵权请联系,内容都是自己学习的总结,一定不全面,仅当互相交流(轻点骂)我也只是站在巨人肩膀上的一个小卡拉米,已老实,求放过)
为什么要对软件进行测试分类?
1.明确测试目标
不同类型的测试有着不同的具体目标,例如,单元测试主要是为了验证软件中的最小单元(如函数、方法)是否正确的实现特定的功能,其目标是尽早发现代码中的错误,以便开发人员可以快速修复等,通过软件分类,测试人员可以更清楚当前的测试目标是什么,从而更有针对性的进行测试工作。
2.提高测试效率
测试人员可以根据不同阶段和需求选择合适的测试方法和技术,避免不必要的重复测试,从而提高测试效率。
3.保证软件质量
每种类型的测试都是从不同的角度对软件进行检查,可以更全面的保证软件质量。
4.便于测试管理
对软件测试进行分类有助于测试团队进行有效的测试管理,测试管理人员可以根据不同类型的测试制定相应的测试计划,安排测试资源,跟踪测试进度和评估测试结果等。
具体的测试分类
按测试目标分类
界面测试、功能测试、性能测试、安全测试、易用性测试、兼容性测试等。
按照执行方式分类
静态测试
静态测试就是不实际运行被测试的软件,而只是静态的检查程序代码,界面或者是文档中可能存在错误的过程。不以测试数据的执行而是对测试对象的分析过程,常见的静态测试方式有代码走查,代码扫描工具等。
动态测试
动态测试指的是实际运行被测程序,输入相应的测试数据,检查实际输出结果是否与预期相符,大部分的软件测试工作都属于动态测试。
按照测试方法分类
白盒测试
白盒测试又称结构测试,透明盒测试,逻辑驱动测试或基于代码的测试,白盒测试是一种基于对程序内部结构和代码的了解来设计测试用例的测试方法。
白盒测试的特点
1.可以深入了解程序内部结构,白盒测试运行测试人员查看程序源代码,了解程序的逻辑结构,控制流和数据流,从而更有针对性的设计测试用例。
2.能够发现代码中的潜在问题,如:逻辑错误、边界值错误、内存泄漏等。
3.测试用例设计比较复杂,需要测试人员具备一定的编程和代码分析能力。
白盒测试的具体方法
语句覆盖
设计测试用例,使得程序中的每一条语句至少被执行一次。
例:
if (a > b):
c = a + b
else:
c = a - b
print(c)
测试用例可以是,令a = 5,b = 3,此时程序会执行c = a + b这条语句;再令令a = 5,b = 3,此时程序会执行c = a - b这条语句,这样就实现了语句覆盖。
判定覆盖
设计测试用例,使得程序中每个判定的取真分支和假分支至少被执行一次。
例:
if (a > b && c > d):
e = a + b + c + d
else:
e = a - b - c - d
print(e)
测试用例可以是,令a = 5,b = 3,c = 4,d = 2,此时程序会执行判定为真的分支;再令a = 1,b = 3,c = 4,d = 2,程序会执行判定为假的分支,这样就实现了判定覆盖。
条件覆盖
设计测试用例,使得程序中每个判定中的每一个条件的可能取值至少被满足一次。
例:
if (a > b && c > d):
e = a + b + c + d
else:
e = a - b - c - d
print(e)
测试用例可以是,令a = 5,b = 3,c = 4,d = 2,满足 a > b 和 c > d 两个条件;再令a = 1,b = 3,c = 1,d = 2,满足 a <= b 和 c <= d 两个条件,这样就实现了条件覆盖。
路径覆盖
设计测试用例,使得程序中的所有可能的路径都至少被执行一次。
function foo(int a,int b)
{
if (a > 0)
{
if (b > 0)
{
eturn a + b;
}
else
{
return a - b;
}
else
{
if (b > 0)
{
eturn -a + b;
}
else
{
return -a - b;
}
}
这个函数有四条可能的路径,a>0
且b>0
、a>0
且b<=0
、a<=0
且b>0
、a<=0
且b<=0
。设计测试用例分别覆盖这四条路径,比如令 a = 5
,b = 3
;a = 5
,b = -3
;a = -5
,b = 3
;a = -5
,b = -3
,这样就实现了路径覆盖。
条件组合覆盖
条件组合覆盖要求设计测试用例,使得每个判定中条件的各种可能组合都至少出现一次。其目的是更全面地测试程序中各种条件组合的情况,以发现可能存在的逻辑错误和缺陷。
例:
if A > 0 and B < 10:
# 执行某些操作
else:
# 执行其他操作
这里有两个条件:A(A > 0)和条件B(B < 10)。
1.条件 A 有两种可能的取值:真(A > 0)和假(A <= 0)。
2.条件 B 也有两种可能的取值:真(B <10)和假(B>= 10)。
这样条件覆盖就有四种情况:
情况一:A 为真且 B 为真(A > 0 且 B < 10)。
测试用例可以是:令 A = 5,B = 5,满足此组合条件。
情况二:A 为真且 B 为假(A > 0 且 B >= 10)。
测试用例可以是:令 A = 5,B = 10,满足此组合条件。
情况三:A 为假且 B 为真(A <= 0 且 B < 10)。
测试用例可以是:令 A = 0,B = 5,满足此组合条件。
情况四:A 为假且 B 为假(A <= 0 且 B>= 10)。
测试用例可以是:令 A = 0,B = 10,满足此组合条件。
判定条件覆盖
判定条件覆盖要求设计测试用例,使得判定中的每个条件的所有可能结果至少出现一次,并且每个判定本身的所有可能结果也至少出现一次。其目的是同时满足条件覆盖和判定覆盖,更全面地测试程序的逻辑。
例:
if A > 0 and B < 10:
# 执行操作 1
else:
# 执行操作 2
对于条件覆盖部分:
条件 A(A > 0)有两种结果:真和假。
条件 B(B < 10)也有两种结果:真和假。
测试用例可以是:令 A = 5,B = 5,满足 A > 0 和 B <10 为真的情况;令 A = -5,B = 15,满足 A> 0 和 B < 10 为假的情况。这样就覆盖了条件 A 和条件 B 的所有可能结果。
对于判定覆盖部分:
判定本身有两种结果:条件为真时执行操作 1,条件为假时执行操作 2。
上述两个测试用例也使得判定的两种结果都得到了覆盖。
小结
1.白盒测试主要 应用于单元测试阶段;
2.先执行静态设计用例的方法,再执行动态设计测试用例的方法;
3.设计用例一般使用路径测试,重点模块追加使用逻辑覆盖方法;
黑盒测试
黑盒测试就是完全不考虑程序内部逻辑和内部结构的情况下,检查系统功能是否按照需求规格说明书的规定正常使用、是否能适当的输入数据而输出正确的结果,满足规范需求。所以,黑盒测试又称为数据驱动测试,只注重软件的功能。
黑盒测试的特点
1.不需要了解程序内部的代码实现,不关注软件内部的实现;
2.从用户角度出发设计测试用例,很容易知道用户用到哪些功能,会遇到哪些问题,锻炼测试人员的产品思维;
3.测试用例是基于软件需求开发文档,不容易遗漏软件需求文档中需要测试的功能;
4.黑盒测试不能覆盖所有代码;
5.黑盒测试用到的测试方法有等价类、边界值、错误猜想法、场景法、正交法、判定表法等;
灰盒测试
是一种介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅仅关注输出,输入的正确性,同时也关注程序内部的情况。
黑盒/白盒/灰盒之间的关系以及使用人员
灰盒测试没有白盒测试完整和详细,也没有黑盒测试覆盖产品范围广的特点,因此这三种测试不能彼此代替。开发人员多用白盒测试和灰盒测试,测试人员主要使用白盒测试和黑盒测试,对于测试人员来说,黑盒测试要比白盒测试用的更多一些。
按照测试阶段来分类
单元测试
与编码同步进行,针对软件最小组成单元进行测试,主要采用白盒测试方法,从被测对象的内部结构设计测试用例,确保每个单元在独立的情况下能够正确的执行其特定的功能。最小单元可以是一个方法、一个函数,一个类等
单元测试的特点
1.独立性:单元测试是独立的,不依赖于其他单元或外部系统;
2.可重复性:单元测试应该是可重复的,无论何时运行都应该得到同样的结果;
3.可自动化:单元测试通常是自动化的,可以使用专门的测试框架来编写和运行测试用例。
例:
假设我们有一个简单的 Python 函数,用于计算两个数的和:
def add_numbers(a, b):
return a + b
我们可以使用 Python 的内置测试框架 unittest 来编写单元测试。以下是一个单元测试的示例:
import unittest
class TestAddNumbers(unittest.TestCase):
def test_add_positive_numbers(self):
result = add_numbers(5, 3)
self.assertEqual(result, 8)
def test_add_negative_numbers(self):
result = add_numbers(-5, -3)
self.assertEqual(result, -8)
def test_add_zero(self):
result = add_numbers(5, 0)
self.assertEqual(result, 5)
if __name__ == '__main__':
unittest.main()
在这个例子中,我们定义了一个测试类 TestAddNumbers,继承自 unittest.TestCase。在这个测试类中,我们定义了三个测试方法,分别测试了不同情况下的加法运算。每个测试方法中,我们调用被测试的函数 add_numbers,并使用 assertEqual 方法来验证函数的返回值是否与预期结果一致。
通过运行这个单元测试,我们可以快速地发现 add_numbers 函数中的问题,例如计算错误或者逻辑错误。如果函数的实现发生了变化,我们只需要再次运行单元测试,就可以确保新的实现仍然能够正确地执行其功能。
集成测试
集成测试是将多个经过单元测试的模块组合在一起进行测试,以验证这些模块能否正确地协同工作。其目的是检测各个模块之间的接口是否正确,数据在模块之间的传递是否符合预期,以及整个系统在集成后的功能和性能是否满足要求。主要采用黑盒和白盒混合的方式。
集成测试的特点
1.逐步集成:集成测试通常采用逐步集成的方式,从较小的模块开始组合,逐步扩大集成的范围,直到整个系统被集成完成,这样更容易定位和解决问题;
2.关注接口:重点关注模块之间的接口,包括参数传递,返回值,异常处理等方面,确保接口的正确性是集成测试的关键任务之一;
3.可能需要模拟环境:某些情况下,集成测试可能需要模拟一些外部系统或环境,以便更好的测试系统的集成情况;
例:
假设我们正在开发一个在线购物系统,该系统由多个模块组成,包括用户管理模块、商品管理模块、购物车模块和订单管理模块。
首先,我们对每个模块进行单元测试,确保它们各自的功能正确。
然后,进行集成测试。例如,我们可以测试用户登录后将商品添加到购物车,再从购物车生成订单的流程。
测试用例可以包括:用户成功登录系统,选择商品并添加到购物车,检查购物车中的商品信息是否正确;然后从购物车生成订单,验证订单的信息是否与购物车中的一致,以及订单状态是否正确更新。
如果在这个过程中发现问题,可能是用户管理模块与购物车模块之间的接口有问题,或者购物车模块与订单管理模块之间的数据传递出现错误。
系统测试
对通过集成测试的系统进行整体测试,验证系统功能性和非功能性需求的实现。这是黑盒测试,主要测试的内容具体是,功能、界面、可靠性、性能、兼容性、安全性等。
系统测试的特点
1.全面性:系统测试会对整个软件系统进行全面的测试,涵盖了很多方面;
2.复杂性:由于软件系统通常由多个组件和模块组成,涉及不同的技术栈和复杂的逻辑业务,这使得系统测试变得非常复杂。
3.协同性:系统测试通常需要多个部门和人员的协同合作,包括开发人员、测试人员、项目经理、产品经理等。开发人员需要提供可测试的软件版本,测试人员需要设计和执行测试用例,项目经理和产品经理需要协调资源和确定测试的重点。
例:以一个企业级管理系统为例
功能测试:
测试用户登录功能,验证不同用户角色(管理员、普通员工)是否能够正确登录,密码错误时是否有相应提示。
测试项目管理模块,创建项目、编辑项目信息、删除项目等操作是否正常。
检查报表生成功能,验证生成的报表是否准确,格式是否符合要求。
性能测试:
使用性能测试工具模拟 100 个用户同时登录系统,观察系统的响应时间是否在可接受范围内。
测试在大量数据导入和导出时,系统的处理速度和资源利用率。
安全测试:
尝试使用 SQL 注入攻击手段,检查系统是否能够防范此类攻击;
测试用户权限管理,确保不同用户角色只能访问其被授权的功能;
兼容性测试:
在不同的操作系统(Windows、Linux、Mac OS)上安装和运行系统,检查是否存在兼容性问题;测试系统在不同的浏览器(Chrome、Firefox、IE)上的显示效果和功能是否正常。
可靠性测试:
让系统连续运行一周,观察是否会出现死机、数据丢失等问题;模拟网络中断等异常情况,检查系统的恢复能力。
按照是否手工测试
手工测试
手工测试就是由人去一个一个的输入用例,然后去观察结果,和机器测试相对应,属于一个原始但必要的步骤。
自动化测试
利用特定的工具和技术,通过编写脚本或使用测试框架,自动执行测试用例,以提高测试效率、准确性和可重复性。(由于这是一个重点,这里不再赘述,后续会有专门的文章来介绍,敬请关注【抱拳抱拳】)
其他
冒烟测试、内测、公测、国际测试等。