你需要用单元测试来测试什么?

6

我对单元测试很陌生。假设我正在构建一个 Web 应用程序。我该如何知道要测试什么?你看到的所有示例都是某种基本的求和函数,它们实际上没有任何真正的价值,或者至少我从来没有编写过一个将输入相加然后返回结果的函数!

那么,我的问题是......在 Web 应用程序中,需要测试哪些方面呢?

我知道这是一个宽泛的问题,但任何有用的信息都会对我有所帮助。我对现实生活中的示例感兴趣,而不是那些没有任何实际用途的概念示例。如果您提供链接或任何其他内容,我会非常感激。

8个回答

2
测试的第一步是编写可测试的应用程序。尽可能将功能与UI分离。重构成较小的方法。学习依赖注入,并尝试使用它来创建可以接受简单、一次性输入并产生已知结果(因此可测试)的方法。查看模拟工具。
基础设施和数据层代码最容易测试。
同时查看行为驱动测试和测试驱动设计。对我来说,行为测试比纯单元测试更好;您可以跟随用例,使测试与预期的使用模式匹配。

2
看看你的代码,特别是其中有循环、条件等复杂逻辑的部分,问问自己:我怎么知道这个是否有效呢?
如果你需要改变复杂逻辑以考虑其他情况,那么你如何确保引入的更改不会破坏现有的情况?这正是单元测试旨在解决的问题。
因此,回答你关于它如何应用于Web应用程序的问题:假设你有一些代码,根据浏览器不同而以不同方式布局页面。你的一个客户拒绝升级IE6,并坚持要求你支持它。所以,通过模拟来自IE6的连接字符串并检查布局是否符合预期,对你的布局代码进行单元测试。
一个客户告诉你他们发现了一个安全漏洞,其中使用特定的cookie将给你管理员访问权限。你如何知道你已经修复了错误并且不会再次发生?为其创建一个单元测试,并每天运行单元测试,以便在失败时获得早期警报。
你发现一个错误,其中具有重音符号的用户名在数据库中被损坏。将Web表单输入从数据库层中抽象出来,并添加单元测试以确保(例如)UTF8编码数据正确存储在数据库中并可以检索。
你懂的。任何过程中具有明确定义的输入和输出部分都非常适合进行单元测试。任何没有这样的部分都非常适合重构,直到它被定义为明确的。看看像WebUnit、HTMLUnit、XMLUnit、CSSUnit这样的项目。

1

单元测试意味着测试任何工作单元,最小的工作单元是方法和函数。单元测试的艺术在于为无法通过检查来验证的函数定义测试,单元测试的目的是测试方法的每个可能的功能要求。

例如,考虑您有一个登录函数,那么您可以编写以下失败测试: 1. 函数是否在用户名和密码为空时失败 2. 函数是否在正确的用户名但错误的密码时失败 3. 函数是否在正确的密码但错误的用户名时失败

然后,您还将编写函数将通过的测试: 1. 函数是否在正确的用户名和密码上通过

这只是一个基本示例,但这就是单元测试试图实现的内容,测试可能在开发过程中被忽视的事物。

然后还有一种纯粹主义的方法,即开发人员首先应编写测试,然后编写代码以通过这些测试(也称为测试驱动开发)。

Resources: http://devzone.zend.com/article/2772 http://www.ibm.com/developerworks/library/j-mocktest.html


+1 给那些非常好的链接。我最喜欢 devzone.zend.com 上的文章。 - Icode4food

1

如果你是TDD的新手,我可以建议你快速了解BDD的世界吗?我的经验是,这种语言真的可以帮助人们更快地掌握TDD。特别是,我向你指出这篇文章,在其中Dan North建议“测试什么”:

http://blog.dannorth.net/introducing-bdd/

为了透明度,请注意:我可能会深度参与BDD运动。

关于在Web应用程序中进行单元测试的类,我建议从控制器、如果它们具有复杂行为的域对象开始,并查找任何名为“service”、“manager”、“helper”或“util”的内容。还请尝试将此类名称重新命名,使其不那么通用,并实际反映它们的功能。名为“calculator”或“converter”的类也是很好的选择,您可能会在同一包/文件夹中找到更多这样的类。

这里有几本不错的书籍可以帮助您:

  • Martin Fowler,《重构》
  • Michael Feathers,《有效处理遗留代码》

祝好运!


1

如果你一开始就说,“我该如何测试我的 Web 应用程序?”那么这将一次性解决很多问题,很难看到单元测试提供任何好处。我通过从小的、独立的部分开始入手,先编写库的测试,然后再构建可测试的整个应用程序来进行单元测试。

通常,Web 应用程序具有领域模型,具有执行数据库查询并返回领域对象的数据访问对象,具有调用数据访问对象的服务,以及接受 HTTP 请求并调用服务的控制器。

控制器的测试将检查它们是否使用正确的参数调用正确的服务方法。服务对象可以在测试设置期间注入模拟对象。

服务的测试将检查它们是否调用了正确的数据访问对象并执行它们需要执行的任何逻辑。数据访问对象可以在测试设置期间注入模拟对象。

数据访问对象的测试将检查它们是否通过检查数据库的内容(查询或更新等)执行了正确的数据库操作。对于 DAO 测试,您需要一个数据库和像 DBUnit 这样的工具,在测试之前预先填充它。此外,此测试将使用您的领域对象的 getter 和 setter,因此您不需要单独的测试。

对域模型的测试将检查您在其中编码的任何领域逻辑是否有效(有时您可能没有)。如果您设计域模型,使其不与数据库耦合,则在域模型中放置更多逻辑越好,因为很容易进行测试。您不应该需要任何模拟来进行这些测试。


0

对于 Web 应用程序,您需要进行的测试类型略有不同。单元测试是测试程序的特定组件的测试。对于 Web 应用程序,您需要测试表单是否接受/拒绝正确的输入,所有链接是否指向正确的位置,它是否能够处理意外的输入等。如果我是您,我会看一下 Selenium,我已经广泛地在测试许多网站时使用了它:Selenium HQ


0

我没有测试Web应用程序的经验,但一般来说:您应该尽可能地对程序中最小的“块”进行单元测试。这意味着您需要逐个测试每个函数。任何规模较大的测试都将成为集成测试。

当然,有些方法非常简单,不值得花时间编写测试,但总体上,您应该尽可能地测试代码的大部分。


0
一条经验法则是,如果不值得测试,那么就不值得编写。
但是,有些东西非常难以测试,因此您需要对您测试的内容进行成本效益分析。如果您最初的目标是70%的代码覆盖率,那么您将走上正确的道路。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接