有大量用例的单元测试

时间:2009-07-31 18:43:56

标签: unit-testing

我正在研究一个有很多用例的java应用程序。对应用程序的输入是在不同时间发生的不同类型的事件。这种输入引发了数百个测试用例。有人遇到过这种情况吗?在向QA团队发布之前,您是否确保涵盖所有测试用例? 所以我的问题是:测试具有大量测试用例的程序的最佳方法是什么?

10 个答案:

答案 0 :(得分:14)

不要试图从一开始就覆盖整个应用程序的单元测试。以小的增量步骤进行。设置一个小里程碑,在一到两周内到达,然后开始为该里程碑的第一个功能编写测试。然后开始实现该功能。它应该是这样的:

小的增量步骤

  1. 将应用程序分解为较小的功能里程碑,您可以在那一刻看到
  2. 选择当时必须实施的最紧迫功能
  3. 将该功能分解为较小的任务
  4. 为其中一项任务编写测试
  5. 运行测试。它应该失败( RED )。如果它通过你的测试就会被打破。
  6. 开始编写最少量的代码,以便通过该测试。允许使用硬编码值。
  7. 运行测试(绿色)。它们应该通过(特别是在使用硬编码值时)。现在你知道你有一个安全网用于未来的重构。
  8. 如有需要,请开始重构代码( REFACTOR ),否则请转到第4步。
  9. 准备变更

    这种方法的优点是将一项巨大的任务分解为可管理的部分,它使您有机会在一两周内完成一些任务。稍后,管理层可能会重新考虑他们的优先级,您必须从上面的第一点重新组织列表。另一个优点是,每一步都有一个支持你的单元测试让你有信心,你实际上已经完成了某些事情,而且你实际上可以比你想象的更快地向你的管理层提供一些东西,因为你的每一步都有(有点)你的程序的工作版本。他们可以看到进步,这对你和他们都非常重要。他们看到工作实际上已经完成,并且您获得了应用程序所需的反馈(需求总是在变化,让我们尽可能地保持变化)。

    正如Gren所述,您可能会将用例与单元测试混淆。用户可以对应用程序执行的操作也可以由域模型中的单个方法处理。所以情况可能不像看起来那么糟糕。

    没有前期设计,即使是单元测试

    无论如何,不​​要试图从头开始编写所有测试。这就是我这样做的方式,这是一个很大的失败。一旦你做了小的迭代(测试方法/方法实现),你就会变得更有效率和自信。在预先编写所有测试时,你可能会注意到由于你的第一次测试通过所需的因素分析,你需要重新思考你在编写测试时想象的整个API,而写一个测试,然后执行,测试,然后执行,你最终得到它所谓的紧急设计。这是最好的设计。这就是设计模式的出现方式。设计模式并非出自那些整天站着的人,并想出了解决问题的方法。

答案 1 :(得分:5)

如果您有数百个测试用例,我认为这是因为它反映了输入的可变性和应用程序的要求?

如果您没有为所有这些(已知)案例编写测试,那么您如何知道自己是否已提供所需的功能?

自动化测试的替代方案是手动测试,与自动测试相比,我无法看到手动测试数百个测试用例是否会为您节省时间。

答案 2 :(得分:4)

我广泛使用JUnit的理论来最小化测试用例:

import org.junit.Assert;
import org.junit.Assume;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import static org.hamcrest.CoreMatchers.*;

@RunWith(Theories.class)
public class D {

    @DataPoints
    public static int[] a = {1, 2, 3, 4};
    @DataPoints
    public static int[] b = {0, 1, 2, 3, 4};

    @Theory
    public void divisible(int a, int b) {
        Assume.assumeThat(b, is(not(0)));
        System.out.format("%d / %d\n", a, b);
        int c = a / b;
        Assert.assertThat(c, is(a / b));
    }
}
将使用divisiblea的任意组合调用

b

1 / 1
1 / 2
1 / 3
1 / 4
1 / 1
1 / 2
1 / 3
1 / 4
2 / 1
2 / 2
2 / 3
2 / 4
...
4 / 3
4 / 4
4 / 1
4 / 2
4 / 3
4 / 4

很好,不是吗?

Check also my hashCode/equals checker

答案 3 :(得分:1)

这一切都取决于您的时间和预算。在理想的世界中,你应该尽一切可能。但我们都知道这离现实有点远。

你说的方式,似乎是一个非常大的项目。在这种情况下,预计还需要花费大量时间进行测试。每当我们估算任何项目时,我们都应该考虑测试时间。

我建议将不同类别的测试用例分开,并根据您的时间和预算做任何事情。 尝试使用更多测试覆盖主要类别而不是次要类别。这一点至关重要,因为通常80%的时间花在20%的代码上。这是最重要的部分。

优先考虑其他工作所需的工作也很重要。假设您有一个只有订阅用户可以执行操作的应用程序。如果您希望您的应用程序有用,那么订阅部分应该经过充分测试。

最后,你应该尝试创建一些验收测试,这些测试表明出现了问题(尽管它们在找到错误的内容方面没有多大帮助)。

答案 4 :(得分:1)

在编写代码之前编写测试。这并不意味着在开始之前为每个场景编写测试,这意味着编写一个测试,通过该测试,继续下一步。老实说,它没有在开发时加上这么多,特别是考虑到你现在知道第二件事情已经破裂了。

在所有情况下都瞄准100%的测试覆盖率。

答案 5 :(得分:1)

我认为您对测试用例和单元测试感到困惑。测试用例应该尝试在方法级别或最多在类级别。在这种情况下,您应该尝试在预算/时间限制内尽可能地覆盖,并且应该在编写代码之前/编写代码时编写它们。

我认为开发人员还应该尝试运行实际用例并使用硒等自动化方法来确保产品是稳固的,但最终经过合理数量的此类测试后,应将其交付给质量保证。

答案 6 :(得分:0)

当然,最好的方法是测试所有测试用例...但是时间,金钱等使这个变得不可能......

其中一种方法是对测试用例进行分组并按组查找“超级”测试用例!

另一个是识别您的应用程序的评论模块并优先管理其测试用例。

答案 7 :(得分:0)

从新应用程序的第一步开始编写大量单元测试不是我的方法。一般来说,当我创建一个新的应用程序(从头开始)时,我首先创建一个原型,没有任何UT 。一旦我在阳光灿烂的日子里有一个工作原型,并且一些同行对它进行审查(并批准,改进等) - 我做了两件事:我编写了覆盖晴天场景的单元测试,然后我重构了我的代码。 / p>

只有这样我才继续处理应用程序,但我尝试编写我认为重要的UT。太多的UT可能会给代表完全覆盖的错误印象。在现实世界中,这种覆盖很少存在。

答案 8 :(得分:0)

对于组合的数量,能够涵盖所有场景可能是不现实的。

你能做的是:

  • 尽可能至少测试所有代码一次(接近100%代码覆盖率)

  • 专注于您认为可能存在编写额外测试问题的区域

  • 每当QA发现错误时,请在修复之前编写测试以显示错误

答案 9 :(得分:0)

如果您无法为所有内容编写测试,我建议使用 cobertura 等一些覆盖工具来衡量您的覆盖率。这将至少确保您使用一些黑盒测试覆盖大部分代码。 当代码库增长时,测量覆盖率非常重要,否则将无法跟踪测试套件的性能。