在测试驱动开发中,编写单元测试用例是承上(Specification)启下(Implementation)的一步:

  1. Spec: Write a specification for the function.
  2. Test: Write tests that exercise the specification.
  3. Implement: Write the implementation.

划分输入空间

  1. 什么是一组好的测试用例?
    1. 足够完备;
    2. 不至于太大;
  2. 什么是划分(Partition)?
    1. 集合划分 的数学定义;
    2. 对于输入空间而言,就是将输入空间划分为一组互不相交的子集;
  3. 划分输入空间的目的是什么?
    1. 将输入空间划分为互不相交的子集,以便为每一个子集构造一个测试用例;
    2. 可以类比为将输入空间划分为不同的等价类,每一个等价类用一个代表元素表示;
  4. 为什么要划分输入空间?背后的思想是什么?
    1. 将输入空间划分为一组互不相交的子集,每个子集都用一个测试用来进行测试。这样可以达到较高的测试覆盖率,避免随机测试时测试者因为经验不足而导致的遗漏。

边界值分析

  1. 为什么要加入边界值分析?
    1. Bug经常发生在子集之间的边界处,包含边界有助于发现这些Bug;
  2. 为什么Bug经常发生在边界处?
    1. 可能因为程序员经常犯一些偏移一的错误,例如写成<=而不是<,或将计数器初始化为0而不是1;
    2. 也可能是因为一些边界可能需要在代码中作为特殊情况处理;
  3. 举出常见的边界值例子:
    1. 0是正数和负数之间的边界;
    2. 数值类型(如int或double)的最大和最小值;
    3. 集合类型的边界值是空容器(如空字符串、空列表或空集);

结合边界值,得到无效等价类

  1. 为什么要分析无效等价类?
    1. 增加系统的鲁棒性;保证系统能够处理无效输入而不崩溃;
  2. 举出常见的无效等价类的例子:
    1. 超出边界值:如果一个输入字段的有效范围是1-10,那么任何超出这个范围的值都将被视为无效,例如负数或大于10的数字。
    2. 不符合前置条件的输入
      1. 非数字值:如果一个输入字段只能包含数字值,那么任何非数字字符,例如字母、符号或空格都将被视为无效。
      2. 空值:如果一个输入字段是必需的且不允许空或空值,那么任何空或空值都将被视为无效。
      3. 无效格式:如果一个输入字段需要特定的格式,例如日期格式或电话号码格式,那么任何不符合该格式的输入都将被视为无效。

以为Lab1的 guessFollowsGraph() 方法为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Guess who might follow whom, from evidence found in tweets.
*
* @param tweets
* a list of tweets providing the evidence, not modified by this
* method.
* @return a social network (as defined above) in which Ernie follows Bert
* if and only if there is evidence for it in the given list of
* tweets.
* One kind of evidence that Ernie follows Bert is if Ernie
* @-mentions Bert in a tweet. This must be implemented. Other kinds
* of evidence may be used at the implementor's discretion.
* All the Twitter usernames in the returned social network must be
* either authors or @-mentions in the list of tweets.
*/
public static Map<String, Set<String>> guessFollowsGraph(List<Tweet> tweets) {
throw new RuntimeException("not implemented");
}

三个指标:

  1. 借助边界值划分等价类:容器 tweets 是否为空?
  2. 前置条件:tweets 是否有提到其他人?
  3. 无效等价类:提到的方式是否合法

测试用例如下:

1
2
3
4
5
6
1.  空列表。期望返回一个空的 social network。
2. 多条 tweets,没有人被提到。期望返回一个空的 social network。
3. 多条 tweets,只有一个人被提到。期望返回一个只包含这个人的 social network。
4. 多条 tweets,有多个人被提到。期望返回一个包含这些人的 social network。
5. 多条 tweets,出现无效的 @-mention,即 @-mention 不是 authors。期望程序能够正确处理这些无效数据,返回正确的 social network。
6. 多条 tweets,出现自我 @-mention,即 author @-mention 自己。期望程序能够正确处理这些无效数据,返回正确的 social network。