白盒测试用例,代码覆盖率100%

时间:2019-03-06 01:44:33

标签: unit-testing testing code-coverage white-box-testing

我很抱歉,因为我是软件测试的新手。但是我有一个看起来很简单的代码来创建具有100%代码覆盖率的White-box测试用例:

01 public class ShapeAreas {
02
03 public double oneParameter(String shape, float x1)
04 {
05     float area;
06     if (shape.equals("A"))
07         return x1 * x1 * Math.XI;
08     else if (shape.equals("B"))
09         return x1 * x1;
10     else 
11         return -1.0;
12 }
13 
14 public double twoParameter(String shape, float x1, float x2)
15 {
16     float area;
17     if (shape.equals("N"))
18         return x1 * x2;
19     else if (shape.equals("M"))
20         return 0.5 * x1 * x2;
21     else
22         return -1.0;
23 }
24 }

我需要有关此代码上输入数据的外观的帮助,以最少的测试用例数量实现100%的代码覆盖率。

我很高兴能对此提供帮助,谢谢!

2 个答案:

答案 0 :(得分:1)

我可以自由地在代码中添加行号,以便能够给出更好的解释。您在提到的评论中对语句覆盖范围感兴趣。您的代码示例中的语句位于07、09和11行以及18、20和22行中。而且,当然if语句本身也是语句(因此称为名称),但是这些语句将被执行无论如何,每次执行各自的功能。

在执行函数oneParameter中,将恰好执行以下条件语句之一:在第07行,第09行或第11行中。这是由于{{1 }}语句。同样,在对函数if-else if-else的一次调用中,将执行第18行,第20行或第22行中的语句。

因此,要覆盖所有语句,您必须调用每个函数3次。在两种情况下,控制实际分支转移的参数都是twoParameter参数。这意味着,其他参数的值与将执行哪个语句无关。一组简单的呼叫可能是:

shape

这是一个最小的呼叫集示例,可以实现100%的语句覆盖率。可能令人惊讶的是,这些只是调用-甚至没有对结果的任何评估。当我们谈论测试覆盖率时,隐含的假设是,不仅要执行相应的代码行,而且还要将相应的结果作为测试的一部分进行评估。然后可能如下所示:

oneParameter("A", 0.0);
oneParameter("B", 0.0);
oneParameter("any other", 0.0);
twoParameter("N", 0.0, 0.0);
twoParameter("M", 0.0, 0.0);
twoParameter("any other", 0.0, 0.0);

尽管事实是现在它具有100%的语句覆盖率并且还可以对结果进行评估,但它仍然不是高质量的测试套件。原因如下:单元测试通常以发现代码中的错误为主要目标。但是,以上测试集不太适合发现任何有趣的错误。给您一些该测试套件找不到的可能错误的示例:

  • 由于错误,assertEquals(0.0, oneParameter("A", 0.0)); assertEquals(0.0, oneParameter("B", 0.0)); assertEquals(-1.0, oneParameter("any other", 0.0)); assertEquals(0.0, twoParameter("N", 0.0, 0.0)); assertEquals(0.0, twoParameter("M", 0.0, 0.0)); assertEquals(-1.0, twoParameter("any other", 0.0, 0.0)); oneParameter的函数"A"中的计算被交换。
  • "B"的函数twoParameter中,"N"错误地交换了*操作。
  • +的函数twoParameter中,表达式不是将"N"x1相乘,而是将表达式x2x1相乘。
  • x1的函数twoParameter中,常量设置为"M",而不是正确的0.05

这些只是可能的错误的示例。因此,认真对待可能发现的错误的目标需要思考的范围不仅仅限于覆盖范围。实际上,甚至有一些代码部分根本不适合通过单元测试进行测试-尽管在您的简单示例中并非如此。此类代码部分的示例是无法访问的代码(例如,为增强鲁棒性而添加的switch语句的默认分支),或仅由与其他组件的交互组成的代码,在这种情况下,集成测试是更合适的方法。因此,即使您真诚地追求高质量的单元测试套件,达到100%覆盖率的目标通常也没有意义。

但是,对于有兴趣确保开发人员已解决其代码中的所有相关方案的开发人员而言,覆盖率是宝贵的信息。可悲的是,从管理的角度判断测试套件的质量时,覆盖率的价值远不如:在这种情况下,覆盖率通常只降低到很小的百分比,开发人员被迫创建测试,直到达到某个覆盖率为止-但是经常在没有给他们足够的培训,时间和鼓励的情况下进行适当的测试。结果,要达到例如80%的覆盖率,所有琐碎的代码(getter和setter等)可能会受到“测试”以增加覆盖率。但是,由于时间不足,推迟了对最复杂,最难测试的20%代码的测试(尽管这可能是隐藏了错误的代码)。而且,即使覆盖了80%的空间,也可能会像我上面显示的最小测试套件那样进行糟糕的测试。

答案 1 :(得分:0)

您必须在每种方法中寻找分支以获得100%的覆盖率。 对于A方法,它是B的{​​{1}},XshapeoneParameterN,{{1} } M方法。

每种方法有3个测试用例将为您提供100%的覆盖率。

但是,它不会告诉您您的代码是100%正确的。

尝试例如X作为形状。 (这将导致twoParameter

您还需要定义计算所需的精度。 (null返回类型与浮点计算。)

NullpointerException