5

我通过阅读“Head First Java”以及做所有的谜题和练习来学习 Java。在书中,他们建议编写 TestDrive 类来测试我编写的代码和类,这是一件非常简单的事情,但是这样做我认为我无法完全测试我的代码,因为我正在编写测试代码知道我想得到什么,我不知道这是否有意义,但我想知道是否有任何方法可以以一种简单的方式测试我的代码,它告诉我什么不能正常工作。谢谢。

4

7 回答 7

4

没错-您知道会发生什么,并编写测试用例来涵盖该知识。在许多方面这是正常的——你想测试你写的东西,这样你就知道它按你期望的那样工作。

现在,你需要把它带到下一步:找到一个可以工作的系统(即将它与完整拼图的其他部分集成),看看它是否仍然根据你的假设和知识工作。

然后你需要把它交给其他人为你测试——他们会很快找到你从未想过的部分。

然后你把它交给一个真正的用户,他们不仅会找到你和你的测试人员从未想过的东西,而且还会找到需求分析师从未想过的东西。

这就是软件的工作方式,可能也是它从未完成的原因。

PS。关于您的测试代码的一件事比任何事情都重要 - 一旦您完成了一次并发现它按预期工作,您可以向您的应用程序添加更多内容,然后再次运行您的测试代码以确保它仍然按预期工作. 这称为回归测试,我认为这是编写自己的单元测试的唯一原因。

和:呆伯特对测试的看法

于 2010-08-23T21:45:32.633 回答
2

我们所说的代码是什么意思?当我认为我们在这里谈论的单元测试时,我们正在测试特定的方法和类。

我认为我无法完全测试我的代码,因为我在编写测试代码时知道我想要得到什么

换句话说,您正在调查某些代码是否履行合同。考虑这个例子:

 int getInvestvalue( int depositCents, double annualInterestRate, int years) {

 }

你可以设计什么测试?如果你设计了一套好的测试,你可以对这个例程有一些信心。所以我们可以尝试这些类型的输入:

  deposit 100, rate 5.0, years 1 : expected answer 105
  deposit 100, rate 0, years 1 : expected answer 100
  deposit 100, rate 10, years 0 : expected anwer 100

还有什么?负利率怎么办?

更有趣的是,如果像 1,000,000.50 和 100,000 年这样的非常高的利率,结果会发生什么,它是否适合整数 - 设计这个测试的事情是它挑战接口 - 为什么没有记录例外?

那么问题来了:我们如何找出那些测试用例。我认为没有一种方法可以导致构建一个全面的集合,但这里有几件事需要考虑:

  1. 边缘:零,一,二,许多。在我的示例中,我们不只是执行 5% 的比率。我们特别考虑特殊情况。零是特殊的,一是特殊的,负数是特殊的,大数是特殊的......
  2. 角落案例:边缘的组合。在我的例子中,这是一个很大的比率和很多年。选择这些是一门艺术,并且得益于我们对实施的了解:在这里我们知道利率和年份之间存在“乘数”效应。
  3. 白盒:使用实现知识来驱动代码覆盖率。调整输入以强制代码进入特定路径。例如如果你知道代码有一个“ifnegative rate”条件路径,那么这是一个包含负利率测试的线索。
于 2010-08-23T22:03:43.153 回答
1

首先,您需要确保您的代码是为进行单元测试而编写的。应该明确对外部类的依赖(如果可能,构造函数需要),这样就不可能在没有识别出所有可能的破坏方式的情况下编写单元测试。如果您发现依赖项太多,或者每个依赖项的使用方式不明显,则需要遵循单一职责原则,这将使您的类更小、更简单和更模块化。

一旦编写了代码以便您可以根据依赖项和输入参数预见可能发生的情况,您应该编写测试以从各种可预见的情况中寻找正确的行为。我发现单元测试的最大优势之一是它实际上迫使我思考“如果……怎么办”,并弄清楚每种情况下的正确行为是什么。例如,我必须决定在某些错误的情况下是抛出异常还是返回空值更有意义。

一旦你认为你已经掌握了所有的基础,你可能还想把你的代码扔给一个像QuickCheck这样的工具来帮助你识别你可能错过的可能性。

于 2010-08-23T22:32:10.930 回答
1

“测试驱动开发”的原则之一是首先编写测试(即在您编写代码之前)。显然这个测试最初会失败(你的程序甚至可能无法编译)。如果测试没有失败,那么您就知道测试本身有问题。一旦测试失败,目标就会变成继续编写代码,直到测试通过。

此外,一些更流行的单元测试框架,如 jUnit 将允许您测试某些东西是否有效或明确无效(即您可以断言某种类型的异常被抛出)。这对于检查错误输入、极端情况等非常有用。

要从 Stephen Covey 那里窃取一句台词,请从结尾开始,并编写尽可能多的测试。对于非常简单的代码,这可能看起来微不足道,但是当您处理更复杂的问题时,这个想法会变得有用。

于 2010-08-23T21:44:38.033 回答
1

这个站点有很多测试代码的帮助资源。软件测试帮助

于 2010-08-23T22:07:20.507 回答
0

试驾

不,您应该编写JUnitTestNG测试。

于 2010-08-23T22:01:34.563 回答
0

正确完成,您的测试就是您的规范。它定义了您的代码应该做什么。每个测试都定义了应用程序的一个新方面。因此,您永远不会编写测试来寻找不能正常工作的东西,因为您的测试指定了事情应该如何正常工作。

一旦你认为你已经完成了单元测试和对你的组件进行编码,提高对事情正常工作的信心的最好和最简单的方法之一就是使用一种称为探索性测试的技术,这可以被认为是对部件的无脚本探索根据您的直觉和经验(以及狡猾!),您编写的应用程序寻找错误。

结对编程是防止和清除代码中的错误的另一种好方法。两个头脑比一个头脑好,而且经常有人会想到你没有想到的东西(反之亦然)。

于 2010-08-23T22:04:28.017 回答