我是单元测试的新手。假设我正在构建一个Web应用程序。我怎么知道要测试什么?您看到的所有示例都是某种基本的和函数,它实际上没有任何实际价值,或者至少我从未写过函数来添加到输入然后返回!
所以,我的问题......在Web应用程序上,有哪些需要测试的东西?
我知道这是一个广泛的问题,但任何事情都会有所帮助。我会对链接或任何提供现实生活示例的内容感兴趣,而不是没有任何实际用途的概念示例。
答案 0 :(得分:2)
测试的第一部分是编写可测试的应用程序。从UI中分离出尽可能多的功能。重构为更小的方法。了解依赖注入,并尝试使用它来创建可以采用简单的丢弃输入的方法,这些输入可以产生已知的(以及可测试的)结果。看看嘲弄工具。
基础架构和数据层代码最容易测试。
观察行为驱动的测试以及测试驱动的设计。对于我的钱,行为测试比纯单元测试更好;您可以关注用例,以便测试与预期的使用模式匹配。
答案 1 :(得分:2)
看看你的代码,特别是那些你有循环,条件等复杂逻辑的部分,并问问自己:我如何知道这是否有效?
如果您需要更改复杂逻辑以考虑其他极端情况,那么您如何知道您引入的更改不会破坏现有案例?这正是单元测试旨在解决的问题。
因此,要回答有关它如何应用于Web应用程序的问题:假设您有一些代码根据浏览器以不同方式布局页面。您的一位客户拒绝从IE6升级并坚持要求您支持。因此,您可以通过模拟IE6中的连接字符串并检查布局是否符合预期来对布局代码进行单元测试。
客户告诉您,他们找到了一个安全漏洞,使用特定的cookie可以让您获得管理员访问权限。你怎么知道你已经修复了这个bug并且它不会再发生?为它创建一个单元测试,并每天运行单元测试,以便在失败时获得预警。
您发现了一个错误,其中名称中带有重音符号的用户在数据库中被损坏。从数据库层抽象出webform输入并添加单元测试,以确保(例如)UTF8编码数据正确存储在数据库中并可以检索。
你明白了。过程的一部分具有明确定义的输入和输出的任何地方都是单元测试的理想选择。任何不适合重构的东西,直到它被明确定义。看看WebUnit,HTMLUnit,XMLUnit,CSSUnit等项目。
答案 2 :(得分:1)
单元测试意味着测试任何工作单元,最小的工作单元是方法和功能。单元测试的艺术是定义一个不能通过检查检查的功能的测试,单元测试的目标是测试方法的每个可能的功能要求。
例如,考虑一下你有一个登录功能,然后可能会有以下可以为失败写的测试: 1.该功能是否因空用户名和密码而失败 2.该功能是否在正确的用户名上失败,但密码错误 3.函数是否因正确的密码失败,但用户名错误
您还可以编写函数将传递的测试: 1.该功能是否传递正确的用户名和密码
这只是一个基本的例子,但这是单元测试试图实现的,测试在开发过程中可能被忽略的事情。
然后还有一种纯粹的方法,开发人员首先应该编写测试,然后是代码来传递这些测试(也就是测试驱动的开发)。
资源: http://devzone.zend.com/article/2772 http://www.ibm.com/developerworks/library/j-mocktest.html
答案 3 :(得分:1)
如果您是TDD的新手,我是否可以建议您快速进入BDD世界?我的经验是,该语言真正帮助人们更快地获得TDD。特别是,我在这篇文章中指出了你,Dan North建议“测试什么”:
http://blog.dannorth.net/introducing-bdd/
注意透明度:我可能会参与BDD运动。
关于在web-app中进行单元测试的类,我考虑从控制器,域对象(如果它们具有复杂行为)开始,以及任何称为“service”,“manager”,“helper”或“util”的东西。还请尝试重命名这样的类,以便它们不那么通用,并且实际上说出它们的作用。被称为“计算器”或“转换器”的类也是很好的候选者,你可能会在同一个包/文件夹中找到更多。
还有一些好书可以帮到你:
答案 4 :(得分:1)
如果您开始说“我如何测试我的网络应用程序?”这种情况很快就会被咬掉,而且单位测试很难提供任何好处。我从单独的小块开始进行单元测试,然后先编写测试库,然后再构建可测试的整个应用程序。
通常,Web应用程序具有域模型,它具有对数据库进行查询并返回域对象的数据访问对象,具有调用数据访问对象的服务,并且具有接受http请求并调用服务的控制器
控制器的测试将检查他们是否使用正确的参数调用了正确的服务方法。服务对象可以是在测试设置期间注入的模拟。
对服务的测试将检查他们是否调用了正确的数据访问对象并执行他们需要执行的任何逻辑。数据访问对象可以在测试设置期间注入模拟。
数据访问对象的测试将通过检查数据库之前和之后的内容来检查它们是否执行了正确的数据库操作(查询或更新或其他)。对于dao测试,您需要一个数据库,以及像DBUnit这样的工具在测试之前预先填充它。此外,您的域对象的getter和setter也将通过此测试进行练习,因此您无需为它们单独进行测试。
域模型的测试将检查您编码的域逻辑是否有效(有时您可能没有)。如果您设计域模型以使其不与数据库耦合,那么您在域模型中放置的逻辑越多越好,因为它很容易测试。你不应该为这些测试需要任何模拟。
答案 5 :(得分:0)
对于Web应用程序,您需要进行的测试类型略有不同。单元测试是测试程序特定组件的测试。对于Web应用程序,您需要测试表单接受/拒绝正确的输入,所有链接指向正确的位置,它可以应对意外的输入等。如果我是你,我会看看Selenium,我在测试多个网站时广泛使用它:Selenium HQ
答案 6 :(得分:0)
我没有测试网络应用程序的经验,但通常会说:您可以对程序中最小的“块”进行单元测试。这意味着您可以单独测试每个功能。任何大规模的东西都会成为集成测试。
当然,有些方法会如此简单,以至于不值得花时间为它们编写测试,但总的来说,我们的目标是尽可能多地测试代码。
答案 7 :(得分:0)
根据经验,如果不值得测试则不值得写。
但是,有些事情很难测试,因此您可以对所测试的内容进行一些成本效益分析。如果您最初的目标是70%的代码覆盖率,那么您将走上正确的道路。