String 不可变类型,StringBuilder 可变的对象。
final 不可变引用,对可变值(如StringBuilder)进行不可变引用,其值可以更改。
int count = lst.size(); lst.add(e); if (lst,isEmpty()) ...Map
map.put(key,val); map.get(key); map.containsKey(key); map.remove(key);Set
s1.contains(e); s1.containsAll(s2); s1.removeAll(s2);快速创建数组
String[] arr = {"a","b","c"};
Arrays.asList(new String[] {"a","b","c"}); //长度固定
Arrays.asList("a","b","c"); //长度固定
迭代 map
for (String key : turtles.keyset()) {
System.out.println(key + ": " + turtles.get(key));
}
Java I/O
java.io.File //表示磁盘上的文件,测试是否可读,删除文件等 java.io.FileReader // 阅读文本文件 java.io.BufferedReader // 有效阅读文本,可以一次阅读整行测试
测试希望发现程序中错误,尽早、经常进行测试,在开发时进行测试
单个功能的开发按以下顺序进行
- 编写功能说明。
- 编写符合规范的测试。
- 编写可以通过测试的代码。
原则:测试用例足够小,可以快速运行,但又足够大,可以验证程序。
方法
- 将输入空间划分为子域,每个子域由一组输入组成。从每个子域中选择一个测试用例
- 子域的划分方法:划分为使程序产生相似行为的输入集。
测试 BigInteger.multiply()
public BigInteger multiply(BigInteger val) //用法: BigInteger a = ...; BigInteger b = ...; BigInteger ab = a.multiply(b);
multiply 实际上它是两个参数的函数
- multiply : BigInteger × BigInteger → BigInteger
进行分区
- a和b均为正
- a和b均为负
- a为正,b为负
- a为负,b为正
- 特殊情况,0、1、-1
- 使用很大的整数,大于最大的整数long
设计(a,b)空间,a,b 是独立的,分别都是
- 0
- 1
- -1
- 小正整数
- 小负整数
- 巨大的正整数
- 巨大的负整数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovbuqBjo-1654449191489)(image/multiply-partition.png)]
一共 49 种情况。
在分区中包括边界错误通常发生在子域之间的边界处。
常见的边界有:
- 0是正数和负数之间的边界
- 数字类型的最大值和最小值,例如 int 和 double
- 集合类型的空性(空字符串,空列表,空数组)
- 集合的第一个和最后一个元素
测试 public static int max(int a, int b)
- (1,2) 覆盖 a 0,b> 0
- (-1,-3) 覆盖 a> b,a <0,b <0
- (0,0) 涵盖 a = b,a = 0,b = 0
- (Integer.MIN_VALUE,Integer.MAX_VALUE) 覆盖 a < b,a = minint,b = maxint
- (Integer.MAX_VALUE,Integer.MIN_VALUE) 覆盖 a > b,a = maxint,b = minint
详尽的测试包括:完整的笛卡尔积 和 覆盖每个部分。
单元测试JUnit assertEquals(expect, actual)
每个测试方法上方应有一条注释,说明如何选择其测试用例,即它涵盖分区的哪些部分:
// covers test.length() = 0,
// start = 0 = text.length(),
// text.length()-start = 0
@Test public void testEmpty() {
assertEquals("", reverseEnd("", 0));
}
黑盒和白盒测试
黑盒测试
- 仅从规范中选择测试用例,而不从功能的代码实现中选择
白盒测试
- 基于代码的测试
- 如果实现根据输入选择不同的算法,应根据这些域进行分区
- 对于未明确要求的实现行为,测试用例不需要包含。
白盒测试实例
public static void sort(Listvalues) { // choose a good algorithm for the size of the list if (values.length() < 10) { radixSort(values); } else if (values.length() < 1000*1000*1000) { quickSort(values); } else { mergeSort(values); }
测试当数组长度为 10 时的情况: values = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
这种只有知道代码的实现才知道。
- 语句覆盖: 每个语句是否都由某个测试用例运行
- 分支覆盖: 每个 if 或 while 语句,是否同时遵循正确与错误的方向
- 路径覆盖: 是否采用了分支的所有可能组合
EclEmma 的一个很好的 Eclipse 代码覆盖工具
集成测试程序可能会在模块之间的连接上失败,集成测试将测试模块组合。
自动化测试运行测试并自动检查其结果
- 在更改代码时经常运行测试可防止程序退化(在修复新错误或添加新功能时引入其他错误)。
修复错误后,把错误样例输入自动化测试中,是回归测试。因为该错误可能很容易再犯,因为它已经发生过一次
总结- 测试驱动编程。在编写代码之前,先编写测试。
- 系统地选择测试用例的分区和边界。
- 白盒测试和声明范围,用于填写测试套件。
- 尽可能孤立地对每个模块进行单元测试。
- 自动化的回归测试可防止错误再次出现。
优质程序的三个属性
- 避免错误
- 容易理解
- 准备好进行更改



