grails使用build-test-data插件准备测试数据
程序员文章站
2022-05-19 22:16:11
...
什么?!还有专门负责测试数据准备的插件?至于么,这个任务应该太简单了!没错,从单个测试来讲,准备测试数据的确简单,但是如果你拥有大量测试用例的时候,事情就变得不那么简单了。前面忘了说一声,这里所指的测试数据专指Grails应用的领域类数据。
如果你给Grails应用写过单元测试,那么应该会对在测试前初始化领域类数据这一步骤不会感到陌生。刚开始,你可能会觉得,Grails实在是太好了,比起以前直接用Spring+Hibernate时要爽多了,尤其是单元测试,提供了这么多便利的方法和配置,这次一定要好好的坚持写单元测试!慢慢地,新鲜劲过了,剩下的就是对每次重复工作(尤其是领域类的测试数据准备)的厌烦,但是这时还没有到你抓狂的时候,而且冲着测试为你应用提供的安全防线,你还是能够接受。毕竟,日子比起以前来讲要好过多了。后来,由于业务需要,领域类又增加了一个新的约束。当你稍稍改动几行程序写完测试用例之后,信心满满地输入“grails test-app”之后,许多原本没有改动,而且之前通过的测试,此时却都失败了。靠,怎么回事!
这时,你猛然记起,刚才给领域类增加了一个约束,而领域类在保存时是需要满足约束的。前面的测试看来很可能是与测试数据的准备相关了……原因找到了,但失败的测试还得让它们通过,没办法,挽起袖子,花上半个钟头把前面那100来个测试用例中与这个约束所属领域类相关的测试的数据准备部分都看看吧……
或许你会讲,不是还有setup吗,初始化工作就放在那里就行了。没错,这确实可以起到一部分的作用,但未必每个测试都想用同样一套测试数据,而且每当有与这种数据准备相冲突的修改(如修改约束)发生时,这种修改仍然避免不了。尤其是在测试重点并不在领域类本身的时候,这种修改更让人难以接受!
以上情况还没有谈到拥有复杂关系的领域类的数据初始化……不说别的,即使没有其他改变,但就数据准备来讲,这个工作就让人烦心。
这些都是build-test-data插件出现的原因,而且就在前不久,它的1.0版发布了。
要是你不熟悉build-test-data,可以简单地把它概括为给所有Grails领域类都增加了一个build()方法。调用该方法会自动构造并保存该领域对象的实例,而且还会遵循所有的领域约束。它还允许你覆盖你想显式设置的值。它让你的测试更清晰,而且更加牢靠,因为你只需要指定跟某个测试方法实际相关的值,而不是一个仅仅满足约束的巨型对象图。
以下代码摘自Ted Naleid的幻灯片,说明了这个插件的基本使用:
如果你对build-test-data插件感兴趣,可以从这个wiki了解详细信息。还有这个优秀的幻灯片可以帮助你快速对它有个了解。
如果你给Grails应用写过单元测试,那么应该会对在测试前初始化领域类数据这一步骤不会感到陌生。刚开始,你可能会觉得,Grails实在是太好了,比起以前直接用Spring+Hibernate时要爽多了,尤其是单元测试,提供了这么多便利的方法和配置,这次一定要好好的坚持写单元测试!慢慢地,新鲜劲过了,剩下的就是对每次重复工作(尤其是领域类的测试数据准备)的厌烦,但是这时还没有到你抓狂的时候,而且冲着测试为你应用提供的安全防线,你还是能够接受。毕竟,日子比起以前来讲要好过多了。后来,由于业务需要,领域类又增加了一个新的约束。当你稍稍改动几行程序写完测试用例之后,信心满满地输入“grails test-app”之后,许多原本没有改动,而且之前通过的测试,此时却都失败了。靠,怎么回事!
这时,你猛然记起,刚才给领域类增加了一个约束,而领域类在保存时是需要满足约束的。前面的测试看来很可能是与测试数据的准备相关了……原因找到了,但失败的测试还得让它们通过,没办法,挽起袖子,花上半个钟头把前面那100来个测试用例中与这个约束所属领域类相关的测试的数据准备部分都看看吧……
或许你会讲,不是还有setup吗,初始化工作就放在那里就行了。没错,这确实可以起到一部分的作用,但未必每个测试都想用同样一套测试数据,而且每当有与这种数据准备相冲突的修改(如修改约束)发生时,这种修改仍然避免不了。尤其是在测试重点并不在领域类本身的时候,这种修改更让人难以接受!
以上情况还没有谈到拥有复杂关系的领域类的数据初始化……不说别的,即使没有其他改变,但就数据准备来讲,这个工作就让人烦心。
这些都是build-test-data插件出现的原因,而且就在前不久,它的1.0版发布了。
要是你不熟悉build-test-data,可以简单地把它概括为给所有Grails领域类都增加了一个build()方法。调用该方法会自动构造并保存该领域对象的实例,而且还会遵循所有的领域约束。它还允许你覆盖你想显式设置的值。它让你的测试更清晰,而且更加牢靠,因为你只需要指定跟某个测试方法实际相关的值,而不是一个仅仅满足约束的巨型对象图。
以下代码摘自Ted Naleid的幻灯片,说明了这个插件的基本使用:
//领域类 class Author { String name static hasMany = [books: Book] } class Book { String title static belongsTo = [author: Author] } //缺省值 def book = Book.build() assertNotNull book.author assertNotNull book.title //显式设置title def book = Book.build(title:"Infinite Jest") //设置author def book = Book.build(author: Author.build(name: "Charlie Stross") )
如果你对build-test-data插件感兴趣,可以从这个wiki了解详细信息。还有这个优秀的幻灯片可以帮助你快速对它有个了解。