- 浏览: 5134861 次
- 性别:
- 来自: 天津
博客专栏
-
实战 Groovy
浏览量:29044
文章分类
- 全部博客 (639)
- 代码之谜 (6)
- JavaScript quirks (5)
- 程序员 (92)
- Java (93)
- BT编程 (7)
- html/css (64)
- Groovy&Grails (42)
- Android (20)
- C/C++ (5)
- PHP/Perl/Python (46)
- 经典文章 (51)
- CodeIgniter (14)
- JQuery (10)
- 笑话 (4)
- 其他 (32)
- javascript (69)
- 云计算 (0)
- html5 (7)
- 面试 (8)
- google (3)
- nosql (2)
- nodejs (11)
- go (5)
- erlang (1)
- 小常识 (3)
- 冷知识 (5)
- database (4)
- web (12)
- 架构 (12)
- Exception (0)
最新评论
-
jqw1992:
https://www.chromefor.com/libra ...
[福利] 开发者必备的 Chrome 插件——ChromeSnifferPlus -
litjerk:
初步算了一下,目前最最精简的Win98版是5M,他5个小时多敲 ...
让人目瞪口呆的三位世界级电脑大师 -
379855529:
。。似乎重点没说NIO啊,前面基础只是铺垫的很好的,可是我要的 ...
Java NIO与IO的详细区别(通俗篇) -
springmvc_springjpa:
spring mvc demo教程源代码下载,地址:http: ...
一步步开发 Spring MVC 应用 -
匡建武:
Good
四个程序员的一天
测试
自动化测试被看成是Grails中一个重要部分,以 Groovy Tests 为基础执行测试。因此,Grails提供了许多方法,使不管是简单的单元测试,还是高难度的方法测试都能更容易执行。这个章节详细描述了Grails给出的各种不同的测试方法。
你要明白的第一件事是,所有create-*命令,实际上Grails最后都会自动帮它们创建集成好的全部测试实例。
比如你运行下方的create-controller 命令:
grails create-controller simple
Grails不仅在grails-app/controllers/目录下创建了SimpleController.groovy,而且在
test/integration/目录下创建了对它的集成测试实例
SimpleControllerTests.groovy。
,然而Grails不会在这个测试实例里自动生成逻辑代码,这部分需要你自己写。
当你完成这部分逻辑代码,就可以使用test-app执行所有测试实例:
grails test-app
上面的这个命令将输出如下内容:
------------------------------------------------------- Running Unit Tests… Running test FooTests...FAILURE Unit Tests Completed in 464ms … -------------------------------------------------------Tests failed: 0 errors, 1 failures
同时运行结果放在test/reports目录下。你也可以指定名字单独运行一个测试,不需要测试后缀参数:
grails test-app SimpleController
除此之外,你可以以空格隔开同时运行多个实例:
grails test-app SimpleController BookController
1 单元测试
单元测试是对单元块代码的测试。换句话说你在分别测试各个方法或代码段时,不需要考虑它们外层周围代码结构。在Grails框架中,你要特别注意单元测试和集成测试之间的一个不同点,因为在单元测试中,Grails在集成测试和测试运行时,不会注入任何被调用的动态方法。
这样做是有意义的,假如你考虑到,在Grails中各个数据库注入的各自方法(通过使用GORM),和潜在使用的Servlet引擎(通过控制器)。例如,你在
BookController调用如下的一个服务应用:
class MyService { def otherServiceString createSomething() { def stringId = otherService.newIdentifier() def item = new Item(code: stringId, name: "Bangle") item.save() return stringId }
int countItems(String name) { def items = Item.findAllByName(name) return items.size() } }
正如你看到的,这个应用调用了GORM,那么你用在单元测试中怎样处理如上这段代码呢?答案在Grails测试支持类中可以找到。
测试框架
Grails测试插件最核心部分是grails.test.GrailsUnitTestCase类。
它是
GroovyTestCase子类,为Grails应用和组件提供测试工具。这个类为模拟
特殊类型提供了若干方法,并且提供了按Groovy的MockFor和StubFor方式模拟的支持。
正常来说你在看之前所示的MyService例子和它对另外一个应用服务的依赖,以及例子中使用到的动态域类方法会有一点痛苦。你可以在这个例子中使用元类编程和“map as object”规则,但是很快你会发现使用这些方法会变得很糟糕,那我们要怎么用GrailsUnitTestCase写它的测试呢?
import grails.test.GrailsUnitTestCaseclass MyServiceTests extends GrailsUnitTestCase { void testCreateSomething() { // Mock the domain class. def testInstances = [] mockDomain(Item, testInstances)
// Mock the "other" service. String testId = "NH-12347686" def otherControl = mockFor(OtherService) otherControl.demand.newIdentifier(1..1) {-> return testId }
// Initialise the service and test the target method. def testService = new MyService() testService.otherService = otherControl.createMock()
def retval = testService.createSomething()
// Check that the method returns the identifier returned by the // mock "other" service and also that a new Item instance has // been saved. assertEquals testId, retval assertEquals 1, testInstances assertTrue testInstances[0] instanceof Item }
void testCountItems() { // Mock the domain class, this time providing a list of test // Item instances that can be searched. def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"), new Item(code: "EC-4395734", name: "Lamp"), new Item(code: "TF-4927324", name: "Laptop") ] mockDomain(Item, testInstances)
// Initialise the service and test the target method. def testService = new MyService()
assertEquals 2, testService.countItems("Laptop") assertEquals 1, testService.countItems("Lamp") assertEquals 0, testService.countItems("Chair") } }
上面代码出现了一些新的方法,但是一旦对它们进一步解释,你应该很快懂得要使用这些方法是多么容易。首先看testCreateSomething()测试方法里调用的mockDomain()方法,这是
GrailsUnitTestCase类提供的其中一个方法:
def testInstances = [] mockDomain(Item, testInstances)
这个方法可以给给定的类添加所有共同域的方法(实例和静态),这样任何使用它的代码段都可以把它当作一个真正全面的domain 类。举个例子,一旦Item类被模拟了,我们就可以在实例它的时候放心得调用save();那么这时,如果我们调用一个被模拟的domain类的这个方法,要怎么做?很简单,在testInstances数组列表里添加新的实例,这个数组被当成参数传进mockDomain()方法。
下面我们将重点讲解mockFor方法:
def otherControl = mockFor(OtherService)
otherControl.demand.newIdentifier(1..1) {-> return testId }
这段代码功能与Groovy中的MockFor类和StubFor类非常接近,你可以用这个方法模拟任何类。事实上,上述demand语法跟MockFor和StubFor使用的语法一样,所以你在用它时应该不会觉得有差别,当然你要需要频繁注入一个mock实例作为关联,但是你可以简单得调用上述的mock控制对象的createMock()方法,很容易实现。对那些熟悉EasyMock用法的人,它们知道这是otherControl强调了mockFor()返回的对象角色,它是一个控制对象而非mock对象。
testCreateSomething()方法中剩余部分应该很熟悉了,特别是你现在已经知道了save()模拟方法是往testInstances数组里添加实例。我们能确定newIdentifier()模拟方法被调用,因为它返回的值对createSomething()方法返回结果产生直接的影响。那假如情况不是这样呢?我们怎么知道它是否被调用?在MockFor类和StubFor类中,use()方法最后会做这个检查,但是testCreateSomething()方法中没有这个方法,然而你可以调用控制对象的verify()方法。在这个例子中,otherControl对象可以实现。这个方法会执行检查,在newIdentifier()应该被调用但没有被调用的情况下抛出诊断结果。
最后,这个例子中的testCountItems()向我们展示了mockDomain()方法的另外一个特性:
def testInstances = [ new Item(code: "NH-4273997", name: "Laptop"), new Item(code: "EC-4395734", name: "Lamp"), new Item(code: "TF-4927324", name: "Laptop") ] mockDomain(Item, testInstances)
通常手工模拟动态遍历器比较烦人,而且你经常不得不为每次执行设置不同的数组;除了这个之外,假如你决定使用一个不同的遍历器,你就不得不更新测试实例去测试新的方法。感谢mockDomain()方法为一组域实例的动态遍历器提供了一个轻量级的执行实现,把测试数据简单得作为这个方法的第二个参数,模拟遍历器就会工作了。
GrailsUnitTestCase - 模拟方法
你已经看过了一些介绍GrailsUnitTestCase中mock..()方法的例子。
在这部分我们将详细地介绍所有GrailsUnitTestCase中
提供的方法,首先以通用的mockFor()开始。在开始之前,有一个很重要的说明先说一下,使用这些方法可以保证对所给的类做出的任何改变都不会让其他测试实例受影响。这里有个普遍出现且严重的问题,当你尝试通过meta-class编程方法对它自身进行模拟,但是只要你对每个想模拟的类使用任何一个mock..()
方法,这个问题就会消失了。
mockFor(class, loose = false)
万能的mockFor方法允许你对你一个类设置strict或loose请求。
这个方法很容易使用,默认情况下它会创建一个strict模式的mock控制对象,它的方法调用顺序非常重要,你可以使用这个对象详细定义各种需求:
def strictControl = mockFor(MyService) strictControl.demand.someMethod(0..2) { String arg1, int arg2 -> … } strictControl.demand.static.aStaticMethod {-> … }
注意你可以在demand后简单得使用static属性,就可以mock静态方法,然后定义你想mock的方法名字,一个可选的range范围作为它的参数。这个范围决定这个方法会被调用了多少次,所以假如这个方法的执行次数超过了这个范围,偏小或偏大,一个诊断异常就会被抛出。假如这个范围没有定义,默认的是使用“1..1”范围,比如上面定义的那个方法就只能被调用一次。
demand的最后一部分是closure,它代表了这个mock方法的实现部分。closure的参数列表应该与被mock方法的数量和类型相匹配,但是同时你可以随意在closure主体里添加你想要的代码。
像之前提到的,假如你想生成一个你正在模拟类的能用mock实例,你就需要调用mockControl.createMock()。事实上,你可以调用这个方法生成你想要的任何数量的mock实例。一旦执行了test方法,你就可以调用
mockControl.verify()方法检查你想要执行的方法执行了没。
最后,如下这个调用:
def looseControl = mockFor(MyService, true)
将生成一个含有loose特性的mock控制对象,比如方法调用的顺序不重要。
mockDomain(class, testInstances = )
这个方法选一个类作为它的参数,让所有domain类的非静态方法和静态方法的mock实现都可以在这个类调用到。
使用测试插件模拟domain类是其中的一个优势。手工模拟无论如何都是很麻烦的,所以mockDomain()方法帮你减轻这个负担是多么美妙。
实际上,mockDomain()方法提供了domain类的轻量级实现,database只是存储在内存里的一组domain实例。所有的mock方法,save(),get(),findBy*()等都可以按你的期望在这组实例里运行。除了这些功能之外,save()和validate()模拟方法会执行真正的检查确认,包括对唯一的限制条件支持,它们会对相应的domain实例产生一个错误对象。
这里没什么其他要说了,除了插件不支持标准查询语句和HQL查询语句模拟。假如你想使用其中的一个,你可以简单得手工mock相应的方法,比如用mockFor()方法,或用真实的数据测试一个集成实例。
mockForConstraintsTests(class, testInstances = )
这个方法可以对domain类和command对象进行非常详细地模拟设置,它允许你确认各种约束是否按你想要的方式执行。
你测试domain约束了?如果没有,为什么没有?如果你的回答是它们不需要测试,请你三思。你的各种约束包含逻辑部分,这部分逻辑很容易产生bug,而这类bug很容易被捕捉到,特别的是save()允许失败也不会抛出异常。而如果你的回答是太难或太烦,现在这已经不再是借口了,可以用mockForConstraintsTests()解决这个问题。
这个方法就像mockDomain()方法的简化版本,简单得对所给的domain类添加一个validate()方法。你所要做的就是mock这个类,创建带有属性值的实例,然后调用validate()方法。你可以查看domain实例的errors属性判断这个确认方法是否失败。所以假如所有我们正在做的是模拟validate()方法,那么可选的测试实例数组参数呢?这就是我们为什么可以测试唯一约束的原因,你很快就可以看见了。
那么假设我们拥有如下的一个简单domain类:
class Book { String title String authorstatic constraints = { title(blank: false, unique: true) author(blank: false, minSize: 5) } }
不要担心这些约束是否合理,它们在这仅仅是示范作用。为了测试这些约束,我们可以按下面方法来做:
class BookTests extends GrailsUnitTestCase { void testConstraints() { def existingBook = new Book(title: "Misery", author: "Stephen King") mockForConstraintsTests(Book, [ existingBook ])// Validation should fail if both properties are null. def book = new Book() assertFalse book.validate() assertEquals "nullable", book.errors["title"] assertEquals "nullable", book.errors["author"]
// So let's demonstrate the unique and minSize constraints. book = new Book(title: "Misery", author: "JK") assertFalse book.validate() assertEquals "unique", book.errors["title"] assertEquals "minSize", book.errors["author"]
// Validation should pass! book = new Book(title: "The Shining", author: "Stephen King") assertTrue book.validate() } }
你可以在没有进一步解释的情况下,阅读上面这些代码,思考它们正在做什么事情。我们会解释的唯一一件事是errors属性使用的方式。第一,它返回了真实的Spring Errors实例,所以你可以得到你通常期望的所有属性和方法。第二,这个特殊的Errors对象也可以用如上map/property方式使用。简单地读取你感兴趣的属性名字,map/property接口会返回被确认的约束名字。注意它是约束的名字,不是你所期望的信息内容。
这是测试约束讲解部分。我们要讲的最后一件事是用这种方式测试约束会捕捉一个共同的错误:typos in the "constraints" property。正常情况下这是目前最难捕捉的一个bug,还没有一个约束单元测试可以直接简单得发现这个问题。
mockLogging(class, enableDebug = false)
这个方法可以给一个类增加一个mock的log属性,任何传递给mock的logger的信息都会输出到控制台的。
mockController(class)
此方法可以为指定类添加mock版本的动态控制器属性和方法,通常它和ControllerUnitTestCase一起连用。
mockTagLib(class)
此方法可以为指定类添加mock版本的动态tablib属性和方法,通常它和TagLibUnitTestCase
一起连用。
2 集成测试
集成测试与单元测试不同的是在测试实例内你拥有使用Grails环境的全部权限。Grails将使用一个内存内的HSQLDB数据库作为集成测试,清理每个测试之间的数据库的数据。
测试控制器
测试控制器之前你首先要了解Spring Mock Library。
实质上,Grails自动用 MockHttpServletRequest,MockHttpServletResponse,和 MockHttpSession 配置每个测试实例,你可以使用它们执行你的测试用例。比如你可以考虑如下controller:
class FooController {def text = { render "bar" }
def someRedirect = { redirect(action:"bar") } }
它的测试用例如下:
class FooControllerTests extends GroovyTestCase {void testText() { def fc = new FooController() fc.text() assertEquals "bar", fc.response.contentAsString }
void testSomeRedirect() {
def fc = new FooController() fc.someRedirect() assertEquals "/foo/bar", fc.response.redirectedUrl } }
在上面的实例中,返回对象是一个MockHttpServletResponse实例,你可以使用这个实例获取写进返回对象的contentAsString值,或是跳转的URL。
这些Servlet
API的模拟版本全部都很更改,不像模拟之前那样子,因此你可以对请求对象设置属性,比如contextPath等。
Grails在集成测试期间调用actions不会自动执行interceptors,你要单独测试拦截器,必要的话通过functional testing测试。
用应用测试控制器
假如你的控制器引用了一个应用服务,你必须在测试实例里显示初始化这个应用。
举个使用应用的控制器例子:
class FilmStarsController { def popularityServicedef update = { // do something with popularityService } }
相应的测试实例:
class FilmStarsTests extends GroovyTestCase { def popularityServicepublic void testInjectedServiceInController () { def fsc = new FilmStarsController() fsc.popularityService = popularityService fsc.update() } }
测试控制器command对象
使用command对象,你可以给请求对象request提供参数,当你调用没有带参数的action处理对象时,它会自动为你做command对象工作。
举个带有command对象的控制器例子:
class AuthenticationController { def signup = { SignupForm form -> … } }
你可以如下对它进行测试:
def controller = new AuthenticationController() controller.params.login = "marcpalmer" controller.params.password = "secret" controller.params.passwordConfirm = "secret" controller.signup()
Grails把signup()的调用自动当作对处理对象的调用,利用模拟请求参数生成command对象。在控制器测试期间,params通过Grails的模拟请求对象是可更改的。
测试控制器和render方法
render方法允许你在一个action主体内的任何一个地方显示一个定制的视图。例如,考虑如下的例子:
def save = { def book = Book(params) if(book.save()) { // handle } else { render(view:"create", model:[book:book]) } }
上面举的这个例子中,处理对象用返回值作这个模型的结果是不可行的,相反结果保存在控制对象的modelAndView属性当中。modelAndView属性是Spring MVC ModelAndView类的一个实例,你可以用它测试一个action处理后的结果:
def bookController = new BookController()
bookController.save()
def model = bookController.modelAndView.model.book
模拟生成请求数据
如果你测试一个action请求处理对象需要类似REST web应用的请求参数,你可以使用Spring MockHttpServletRequest对象实现。例如,考虑如下这个action,它执行一个进来请求的数据邦定:
def create = {
[book: new Book(params['book']) ]
}
假如你想把book参数模拟成一个XML请求对象,你可以按如下方法做:
void testCreateWithXML() { def controller = new BookController() controller.request.contentType = 'text/xml' controller.request.contents = '''<?xml version="1.0" encoding="ISO-8859-1"?> <book> <title>The Stand</title> … </book> '''.getBytes() // note we need the bytesdef model = controller.create() assert model.book assertEquals "The Stand", model.book.title }
同样你可以通过JSON对象达到这个目的:
void testCreateWithJSON() { def controller = new BookController() controller.request.contentType = "text/json" controller.request.content = '{"id":1,"class":"Book","title":"The Stand"}'.getBytes()def model = controller.create() assert model.book assertEquals "The Stand", model.book.title
}
使用JSON,也不要忘记对class属性指定名字,绑定的目标类型。在XML里,在book节点内这些设置隐含的,但是使用JSON你需要这个属性作为JSON包的一部分。
更多关于REST web应用的信息,可以参考REST章节。
测试Web Flows
测试Web
Flows需要一个特殊的测试工具grails.test.WebFlowTestCase,它继承Spring Web
Flow的
AbstractFlowExecutionTests
类。Testing Web Flows
requires a special test harness called grails.test.WebFlowTestCase
which sub classes Spring Web Flow's AbstractFlowExecutionTests
class.
WebFlowTestCase子类必须是集成测试实例Subclasses of
WebFlowTestCase
must be integration
tests
例如在下面的这个小flow情况下:
class ExampleController { def exampleFlow = { start { on("go") { flow.hello = "world" }.to "next" } next { on("back").to "start" on("go").to "end" } end() } }
接着你需要让测试工具知道使用什么样的flow定义。通过重载getFlow抽象方法可以实现:
class ExampleFlowTests extends grails.test.WebFlowTestCase { def getFlow() { new ExampleController().exampleFlow } … }
假如你需要指定一个flow标识,你可以通过重载getFlowId方法实现,同时默认情况下是一个测试实例:
class ExampleFlowTests extends grails.test.WebFlowTestCase { String getFlowId() { "example" } … }
一旦这在你的测试实例里实现了,你需要用startFlow方法开始启动这个flow,这个方法会返回ViewSelection对象:
void testExampleFlow() { def viewSelection = startFlow()assertEquals "start", viewSelection.viewName … }
如上所示,你可以通过使用ViewSelection对象的viewName属性,检查你是否是正确的。触发事件你需要使用signalEvent方法:
void testExampleFlow() { … viewSelection = signalEvent("go") assertEquals "next", viewSelection.viewName assertEquals "world", viewSelection.model.hello }
这里我们可以给flow发送信号执行go事件,这导致了到next状态的转变。在上面的这个例子中转变的结果把一个hello变量放进flow范围。我们可以检查如上ViewSelection的model属性测试这个变量的值。
测试标签库
其实测试标签库是一件很容易的事,因为当一个标签被当作一个方法执行时,它会返回一个字符串值。所以例如你拥有如下的一个标签库:
class FooTagLib { def bar = { attrs, body -> out << "<p>Hello World!</p>" }def bodyTag = { attrs, body -> out << "<${attrs.name}>" out << body() out << "</${attrs.name}>" } }
相应的测试如下:
class FooTagLibTests extends GroovyTestCase {void testBarTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bar(null,null) }
void testBodyTag() { assertEquals "<p>Hello World!</p>", new FooTagLib().bodyTag(name:"p") { "Hello World!" } } }
注意在第二个例子的testBodyTag中,我们传递了返回标签主体内容的代码块作为内容,把标签主体内容作为字符串比较方便。
使用GroovyPagesTestCase测试标签库
除了上述简单的标签库测试方法之外,你也可以使用grails.test.GroovyPagesTestCase类测试标签库。
GroovyPagesTestCase类是常见GroovyTestCase的子类,它为GSP显示输出提供实用方法。
GroovyPagesTestCase类只能在集成测试中使用。
举个时间格式化标签库的例子,如下:
class FormatTagLib {
def dateFormat = { attrs, body ->
out << new java.text.SimpleDateFormat(attrs.format) << attrs.date
}
}
可以按如下方法进行测试:
class FormatTagLibTests extends GroovyPagesTestCase { void testDateFormat() { def template = '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />'def testDate = … // create the date assertOutputEquals( '01-01-2008', template, [myDate:testDate] ) } }
你也可以使用GroovyPagesTestCase的applyTemplate方法获取GSP的输出结果:
class FormatTagLibTests extends GroovyPagesTestCase { void testDateFormat() { def template = '<g:dateFormat format="dd-MM-yyyy" date="${myDate}" />'def testDate = … // create the date def result = applyTemplate( template, [myDate:testDate] )
assertEquals '01-01-2008', result } }
测试Domain类
用GORM API测试domain类是一件很简单的事情,然而你还要注意一些事项。第一,假如你在测试查询语句,你将经常需要flush以便保证正确的状态持久保存到数据库。比如下面的一个例子:
void testQuery() { def books = [ new Book(title:"The Stand"), new Book(title:"The Shining")] books*.save()assertEquals 2, Book.list().size() }
这个测试实际上会失败,因为调用save方法的时候,save方法不会真的持久保存book实例。调用save方法仅仅是向Hibernate暗示在将来的某个时候这些实例应该会被保存。假如你希望立即提交这些改变,你需要flush它们:
void testQuery() { def books = [ new Book(title:"The Stand"), new Book(title:"The Shining")] books*.save(flush:true)assertEquals 2, Book.list().size() }
在这个案例中我们传递了flush的true值作为参数,更新将马上被保存,因此对此后的查询语句也有效。
3 功能测试
功能测试是测试正在运行的应用,经常自动化较难实现。Grails没有发布任何功能测试开箱即用支持,但是通过插件实现了对 Canoo WebTest 的支持。
首先按如下的命令按照Web Test:
grails install-plugin webtest
参考reference on the wiki ,它里面了解释怎么使用Web Test和Grails。 Show details
发表评论
-
实战 Groovy: 用 Groovy 打造服务器端
2010-07-10 11:07 2667Groovlet 和 GroovyServer P ... -
实战 Groovy: 用 Groovy 生成器作标记
2010-07-10 11:07 2008Groovy 生成器让您能够利用诸如 Swing 这样 ... -
实战 Groovy: for each 剖析
2010-07-10 11:07 18115在这一期的 实战 Groovy 中,Scott Davi ... -
实战 Groovy: 用 Groovy 进行 Ant 脚本编程
2010-07-10 11:07 2001Ant 和 Maven 两者在构建处理工具的世界中占统 ... -
实战 Groovy: 在 Java 应用程序中加一些 Groovy 进来
2010-07-10 11:06 4253您有没有想过在自己相对复杂的 Java 程序中嵌入 G ... -
实战 Groovy: Groovy 的腾飞
2010-07-10 11:06 2130随着 Groovy JSR-1(及其后续发行版本)的发 ... -
实战 Groovy: 用 curry 过的闭包进行函数式编程
2010-07-10 11:06 3190在 Groovy 中处处都是闭包,Groovy 闭包惟 ... -
实战 Groovy: 关于 MOP 和迷你语言
2010-07-10 11:06 2018将耳朵贴到地上仔细听 —— MOP 正在前进!了解一下 ... -
实战 Groovy: 用 Groovy 更迅速地对 Java 代码进行单元测试
2010-07-10 11:06 2260不久以前,developerWor ... -
实战 Groovy: 构建和解析 XML
2010-07-10 11:05 7070通过本文,您将了解 ... -
实战 Groovy: 用 Groovy 进行 JDBC 编程
2010-07-10 11:05 5118这个月,随着 Andrew G ... -
实战 Groovy: 美妙的操作符
2010-07-10 11:05 2243Java™ 取消了操作符重载,但是新兴的 Groovy ... -
实战 Groovy: 使用 Groovy 模板进行 MVC 编程
2010-07-10 11:04 2855视图是 MVC 编程的一个重要部分,而 MVC 编程本 ... -
实战 Groovy: 用 Groovy 减少代码冗余
2010-07-10 11:04 2008Groovy 简洁的语法将 ... -
实战 Groovy: Groovy:Java 程序员的 DSL
2010-07-10 11:04 3043Groovy 专家 Scott Davis 将重新开始 ... -
精通 Grails: 构建您的第一个 Grails 应用程序
2010-07-06 09:37 1602Java™ 程序员不需要 ... -
Grails 部署
2010-07-06 09:36 6024部署 Grails可以使用很多种方式来部署,每一种 ... -
Grails 脚手架
2010-07-05 08:20 4032脚手架 根据指定的领域类,脚手架为你自动生成 ... -
Grails Grails 与 Hibernate
2010-07-05 08:19 2655Grails 与 Hibernate 如果 GOR ... -
Grails Grails和 Spring
2010-07-05 08:19 7840Grails和 Spring 这一节适合于高级用户 ...
相关推荐
这意味着您可以使用test-app运行Cucumber功能,并且结果将包含在常规grails测试报告中。 当前,该插件仅将Cucumber测试类型注册到功能测试阶段。 要运行Cucumber功能,可以通过以下命令之一调用grails: grails ...
第1章 寻找grails之旅 1.1 java的困惑 1.2 webc2.0时代 1.3 java的力量 1.4 什么是grails 1.4.1 与java集成 1.4.2 简单而强大 1.4.3 吸取的经验教训 1.5 使用grails的原因 ...
Groovy和Grails配置方法 教你从0入手,一步一步深入安装和测试,包含环境和语言的下载地址
SwingLibrary.zip,一个用于swing-ui测试的robot-framework测试库swing-ui-framework测试库
2.7 测试Grails应用 2.8 部署Grails应用 2.9 所支持的Java EE容器 2.10 创建工件 2.11 生成Grails应用 3. 配置 3.1 基本配置 3.1.1 内置选项 3.1.2 日志 3.2 环境 3.3 数据源 3.3.1 数据源和环境 3.3.2 JNDI数据源 ...
帮我们创建domain、service 和controller等类及它们的测试类及其他。因此,我们在Grails 项目 中常常是使用这些工具帮我们创建各种类,而不是直接动手去创建它们。前面,我们已经动手将 Grails 项目集成到了Eclipse ...
Grails插件实验 定义Grails 3.0插件域类是可扩展的 SO的详细信息: 该项目包含一个名为security的插件和一个名为bookstore的应用程序以测试该插件。 插件用户: org.centerkey.grails.User 应用程序用户(扩展...
grails-test-app 目标 使用Groovy来实现RESTful API Web应用程序。 或用于RESTful API实现)或您要使用的任何框架。 使用Robotframework( )编写一个测试用例,以在Google上搜索“ Ruckus Wireless”,并检查是否...
带有基于 Spock 的测试的 Grails 项目。 有关基于 Grails 1.3.7 的示例,请查看分支 有关基于 Grails 2.2.0 的示例,请查看分支 有关基于 Grails 2.3.7 的示例,请查看分支 有关基于 Grails 2.4.0 的示例,请...
grails-perf-testapps 用于性能测试的简单 Grails 应用程序集合
然后,在分析GrailsMVC模式实现和自适应考试系统原理的基础上,采用用例分析技术和领域模型驱动模式,基于Grails框架设计实现了一个自适应测试系统;最后,还针对安全权限控制和国际化等问题充分利用Grails插件给出了相应...
功能测试实例 这是为功能测试添加单独位置的概念证明。 分离回滚(集成)和非回滚(功能,geb)测试 创建Gradle功能测试实现,以便您可以将功能测试(即不回滚的测试)与确实回滚的集成测试分开。 这种划分有点武断...
Grails 3的功能测试 Grails 3的功能测试套件 要更改用于运行功能测试的Geb驱动程序,请提供geb.env系统属性。 ./gradlew -Dgeb.env=chromeHeadless iT
Grails 插件业力测试运行器这是一个 grails 插件,用于在 grails test-app 生命周期中使用 [karma] 运行 javascript 测试。 [业力]: : [karma] 是一个正在兴起的 javascript 测试框架,支持多浏览器测试... [karma]...
9.1 Grails自动化测试基础知识 111 9.2 编写测试用例 113 9.2.1 对Domain类进行测试 113 9.2.2 对Service类进行测试 116 9.2.3 对Controller进行测试 118 9.2.4 对Taglib进行测试 120 9.3 本章小结 121 第10章 部署...
本文内容包括:ShortenUrl插件简介创建TinyUrl类测试TinyUrl类创建IsGd类创建ShortenUrl服务打包并部署插件结束语下载参考资料在这个“精通Grails”系列中,ScottDavis将向您展示如何创建您自己的Grails插件。...
我们非常欢迎您提供有关检查平台兼容性,添加更多测试和常规清理的任何帮助。 感谢几个人在整个开发过程中的建议。 值得注意的是:Brian Brian Wheeler(@bdwheeler),Rick Jensen(@cdeszaq),Bobby Warner(@...
Grails 下的 Websocket 插件带有 grails 3 和 spring boot 的默认 Websocket: 这个项目有一个关于如何配置 grails 3 应用程序以与默认 websockets 交互的简要说明。创建一个基本的聊天回声系统在这个项目中,上述...
重写ShiroFilters > ShiroInterceptor 修复损坏的进口修复损坏的测试剩下要做使用grails 3应用进行测试(运行脚本,Travis测试) 获得更多关注,检查并更正代码(希望您如此)目标短期:使此插件在Grails 3.x上可以...