如何轻松测试代码?

时间:2010-08-23 21:39:54

标签: java unit-testing testing code-testing

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

7 个答案:

答案 0 :(得分:4)

这是对的 - 您知道会发生什么,并编写测试用例来涵盖这些知识。在许多方面,这是正常的 - 你想测试你写的东西,以便你知道它按预期工作。

现在,您需要将它带到下一步:找到一个可以正常工作的系统(即将其与其他位置整合在一起),看看它是否仍然可以根据您的假设和知识运行。

然后你需要把它交给其他人来测试你 - 他们会很快发现你从未想过的那些。

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

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

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

和:Dilbert's take on testing

答案 1 :(得分: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. 白盒:使用实现的知识来驱动代码覆盖率。调整输入以强制代码向下移动特定路径。例如,如果yoiu知道代码具有“if negative rate”条件路径,那么这是包含负速率测试的线索。

答案 2 :(得分:1)

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

此外,一些比较流行的单元测试框架(如jUnit)将允许您测试某些内容是否有效或显式不起作用(即您可以断言抛出某种类型的异常)。这对于检查错误输入,拐角情况等非常有用。

要从斯蒂芬科维那里偷走一条线,只需从头脑开始,然后编写尽可能多的测试。对于非常简单的代码来说,这似乎是微不足道的,但是当你转向更复杂的问题时,这个想法变得很有用。

答案 3 :(得分:1)

该网站有很多测试代码的帮助资源。 SoftwareTestingHelp

答案 4 :(得分:1)

首先,您需要确保编写代码以进行单元测试。外部类的依赖性应该是显式的(如果可能的话,构造函数需要),这样就不可能在没有确定每种可能的方法来破解事物的情况下编写单元测试。如果您发现依赖项太多,或者每个依赖项的使用方式并不明显,那么您需要使用单一责任原则,这将使您的类更小,更简单,更模块化。

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

一旦您认为自己已覆盖所有基础,您可能还希望将代码放在QuickCheck之类的工具上,以帮助您找出可能错过的可能性。

答案 5 :(得分:0)

  

测试驱动

不,您应该编写JUnitTestNG个测试。

答案 6 :(得分:0)

正确完成后,您的测试就是您的规格。它定义了您的代码应该执行的操作。每个测试都定义了应用程序的新方面。因此,您永远不会编写测试来查找无法正常工作的测试,因为您的测试指定了应该正常工作的方式。

一旦您认为自己已完成单元测试并对组件进行编码,那么提高信誉以确保工作正常的最佳和最简单的方法之一就是使用一种称为Exploratory Testing的技术,可以将其视为根据您的直觉和经验(以及狡猾!)对您编写的应用程序部分进行无缺陷的探索,寻找错误。

Pair Programming是防止和清除代码中的错误的另一种好方法。两个人的思想比一个人好,经常有人会想到你没有的东西(反之亦然)。