首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

精通 Grails 测试 Grails 应用程序(2)

精通 Grails 测试 Grails 应用程序(2)

编写第一个有价值的测试以上是第一个正常运行的简单测试,接下来将展示一个更加实用的测试示例。假设您的 HotelStay 类有两个字段:Date checkIn 和 Date checkOut。根据一个用户情景,toString 方法的输出应该像这样:Hilton (Wednesday to Sunday)。通过 java.text.SimpleDateFormat 类,获取正确格式的日期非常简单。您应该为此编写一个测试,但不需验证 SimpleDateFormat 是否正确工作。您的测试做两件事情:它验证 toString 方法是否按照预期运行;它证明您是否满足用户情景。
单元测试是可执行的文档用户需求常常是桌面上的某些文档。作为开发人员,您应该将这些需求转换成有效的软件。
需求文档的问题是:在进行实际软件开发时它通常已经过时。它不是可以随着软件的发展而变化的 “活动文档”。工件 一词完美地描述了这种情况 — 文档描述软件最初的、历史性的任务是什么,而不是当前实现要做什么。
要想准备一组全面的、优秀的测试,仅仅保持代码没有 bug 是不够的。这样的测试有一个附带的好处,即您可以得到 “可执行的文档”:用代码表示活动的、不断变化的项目需求。如果将测试映射到需求,则可以和用户共享某些内容。您必须保证代码的健全,保证满足了用户的需求。将这个可执行文档与 CruiseControl 等持续集成服务器(持续反复地运行测试的服务器)相结合,就可以得到一个安全保障机制,它保证新特性不会对原本良好的软件造成损害。
行为驱动的开发(Behavior-Driven Development,BDD)完全采用了可执行文档的想法。easyb 是一个用 Groovy 编写的 BDD,它允许您将测试编写成用户和开发人员都可以阅读的用户需求(参见 )。如果一些用户思想比较前卫,宁愿放弃 Microsoft® Word(例如),easyb 可以排除所有过时的需求文档。因此,项目需求从一开始就是可执行的。

将清单 5 中的代码输入到 HotelStay.groovy 和 HotelStayTests.groovy:
清单 5. 使用 assertToString
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.text.SimpleDateFormat
class HotelStay {
  String hotel
  Date checkIn
  Date checkOut
   
  String toString(){
    def sdf = new SimpleDateFormat("EEEE")
    "${hotel} (${sdf.format(checkIn)} to ${sdf.format(checkOut)})"
  }  
}


import java.text.SimpleDateFormat
class HotelStayTests extends GroovyTestCase {

    void testSomething(){...}

    void testToString() {
      def h = new HotelStay(hotel:"Hilton")
      def df = new SimpleDateFormat("MM/dd/yyyy")
      h.checkIn = df.parse("10/1/2008")
      h.checkOut = df.parse("10/5/2008")
      println h
      assertToString h, "Hilton (Wednesday to Sunday)"
    }
}




输入 grails test-app 验证第二个测试是否通过。
testToString 方法使用了新的断言方法之一 —assertToString— 它由 GroovyTestCase 引入。使用 JUnit assertEquals 方法肯定会获得相同的结果,但是 assertToString 的表达能力更强。测试方法的名称和最终的断言清楚地表明了这个测试的目的(参见  获得一个链接,它列出了 GroovyTestCase 支持的所有断言,包括 assertArrayEquals、assertContains 和 assertLength)。
添加控制器和视图到目前为止,您一直以编程的方式与 HotelStay 域类交互。添加一个 HotelStayController,如清单 6 所示,它使您能够在 Web 浏览器上使用该类:
清单 6. HotelStayController 源代码
1
2
3
class HotelStayController {
  def scaffold = HotelStay
}




您应该对 create 表单进行仔细的 UI 调试。默认情况下,日期字段包括 day、month、year、hours 和 minutes,如图 4 所示:
图 4. 默认显示日期和时间在这里,忽略日期字段的时间戳部分是安全的。输入 grails generate-views HotelStay。要创建图 5 所示的经过修改的 UI,请将 precision="day" 添加到 views/hotelStay/create.gsp 和 views/hotelStay/edit.gsp 中的 <g:datePicker> 元素:
图 5. 仅显示日期有了运行在 servlet 容器中的活动的、有效的 HotelStay 之后,就要开始讨论测试了:单元测试还是集成测试?
返回列表