如何编写测试用例:
- 等价类划分和边界值分析进行测试用例设计
- Assertion的使用
- 测试用例对代码的覆盖度分析
- 测试种类
通过分区选择测试用例:
将可能输入空间分成不同的域,希望每个域中的输入代表的是会产生类似结果的参数输入,每个域称为一个子域。
对边界值进行考虑时,我们有如下经验:
- -1、0、1
- 数字类型的最大最小值
- 空集,如空的字符串、空的列表、空的数组
- 集合类中的第一、最后一个元素
覆盖分区的两个极限情况:
完全笛卡尔积:根据对输入空间的思考情况,测试所有的等价类
每一分区覆盖:在分析出来的取值组合的情况下,要求输入对每组合都覆盖,同时,对单个输入参数的所有取值分区也完成覆盖。
以max()函数为例:
通过等价类划分,将情况分成了a<b、a=b、a>b三种
结合边界情况分析,选出了五种特殊取值,分别为=0,>0,<0,MIN_INT,MAX_INT五种。
最终选出五组测试值,分别覆盖了三种等价类,并完成对两个数五种特殊取值的全覆盖。
代码覆盖度测试:
1.函数覆盖:是否每个函数都被测试到了
2.语句覆盖:是否每个声明都被测试到了
3.条件覆盖:是否每一个if/while/for/switch-case分支都被测试到了
4.路径覆盖:是否每一种分支组合都被测试到了
测试效果:路径覆盖>条件覆盖>语句覆盖
测试难度:同上
回归测试思想要求一旦程序被修改,就重新执行之前的所有测试
Test的书写格式
测试策略:写在测试类之前
测试规约:写在测试方法之前
内容:覆盖了测试策略中的哪一个部分?测试用例如何选取的?
健壮性与正确性
释义:
健壮性:系统在不正常输入或不正常外部环境下仍能够表现正常的程度
正确性:系统在不正常输入或不正常环境下直接报错,以保证不会给出错误结果
比较:
健壮性:倾向容错、让client使用更容易、对外接口倾向健壮
正确性:倾向报错、让implementor变得容易、对内接口倾向正确
异常类型:
Throwable类及其子类
Exception声明:
只声明Checked Exception,使用throws表示,method告诉调用者(甩锅)该方法可能抛出的异常类型有哪些,编译器会要求调用者必须捕获or抛出那些异常。
子类型override方法的Exception抛出原则(LSP原则的一部分)
Exception的spec书写格式:
Exception的抛出:异常一经抛出,不会再返回
构造字符串,利用构造函数传入String的参数来展示信息并抛出异常。
除了字符串,也可以直接将传入的异常对象作为参数,再传入另一个异常构造函数
Exception的创建:利用继承来创造新的类
如果允许client随意抛出异常,而不强制对其进行处理,可以将新建类声明为RuntimeException的子类
定义:
声明(不必使用throws进行声明):不强制要求client进行处理
Exception的处理:
方法一:try-catch-finally
Try所囊括的语句含义是捕获这段代码运行时抛出的异常
Catch囊括的语句是对
Finally囊括的语句块无论是否碰到异常都会被执行
方法二:rethrowing exceptions
最好保留根原因:
这么做一般是为了更改exception的类型,更方便client端获取错误信息并处理,如根据不同系统自定义的一个exception类。
子方法由于override产生的异常必须被处理,有LSP准则,不允许抛出更宽泛的异常
如果某一个语句throw了一个异常(主动抛出或被动抛出),但找不到它的handler,会终止执行程序,在控制台上打印出stack trace
常用的异常:NullParameterException、IOException、Exception、FileNotFoundException、InterruptedException、Runtime exception
常见unchecked异常:NullPointerException、IllegalArgumentException、IlleagalStateException
只想看到异常信息:
如何使用断言(Assert):
一般匹配符
1、assertThat( testedNumber,
allOf( greaterThan(8), lessThan(16) ) );
注释: allOf匹配符表明如果接下来的所有条件必须都成立测试才通过,相当于“与”(&&)
2、assertThat( testedNumber, anyOf( greaterThan(16), lessThan(8) ) );
注释:anyOf匹配符表明如果接下来的所有条件只要有一个成立则测试通过,相当于“或”(||)
3、assertThat( testedNumber, anything() );
注释:anything匹配符表明无论什么条件,永远为true
4、assertThat( testedString, is( "developerWorks" ) );
注释: is匹配符表明如果前面待测的object等于后面给出的object,则测试通过
5、assertThat( testedString, not( "developerWorks" ) );
注释:not匹配符和is匹配符正好相反,表明如果前面待测的object不等于后面给出的object,则测试通过
软件复用级别:
源码级别:包括代码,甚至spec、test和doc
模块级别:类、抽象类、接口
使用技术:继承与委托、继承与重写
库 级别:API、包
系统级别:框架
软件复用分类:
黑盒复用:源码不可见,不能修改,仅能通过API来使用
白盒复用:源码可见,可修改可扩展
如何设计复用类:
OOP知识:封装与隐藏、继承与重写、多态的三种形式、泛型编程
LSP目的:使客户端可用统一的方式处理不同类型对象
LSP内容:
子类型中可以增加method,但不可删除method
子类型需要实现抽象类型(接口、抽象类)中所有未实现的方法
子类型中重写方法时,方法返回值更严格(必须有相同或子类型的返回值 or 符合协变的参数)
子类型覆盖或实现父类方法时,方法形参更宽松(重写的方法必须使用同样类型的参数或者符合逆变的参数)
子类型中重写的方法不能抛出额外的异常
更强的不变量、更弱的前置条件、更强的后置条件
数组是协变的:一个实例帮助理解
泛型是类型不变的
一个例子体现泛型不变
泛型的类型擦除
JVM中没有泛型类型对象,所有泛型类都属于普通类
类型参数的限定和无限定: