简介
我希望在 JUnit 中编写单元测试来检查各个流口水规则。单元测试应该编写简单且运行快速。如果单元测试很慢,那么开发人员将避免运行它们,并且构建将变得非常慢。考虑到这一点,我试图找出编写这些单元测试的最佳(执行最快且最容易编写)方法。
第一次尝试
我尝试的第一个选项是将KnowledgeBase
创建为静态类属性并在一个.drl 文件上进行初始化。然后,每个测试都会在 @Before
方法中创建一个新 session 。这是基于 Drools JBoss 规则开发人员指南中的代码示例。
I've seen a second option通过创建一些注释来抽象初始化代码来整理这个问题,但它基本上是相同的方法。
我注意到对一个 .drl 文件的基本单元测试需要几秒钟才能运行。对于一个单元测试来说这还不错,但是一旦扩大规模,我就会发现这是一个问题。我做了一些阅读,发现 KnowledgeBase
的创建成本很高,而 session 则很便宜。这就是为什么这些示例将 KnowledgeBase
设为静态,因此仅创建一次,但是,对于多个单元测试类,它可能会创建多次。
替代方案
我尝试的替代方案是创建一个单例KnowledgeBase
来加载所有.drl 文件。这将为测试套件全局完成一次,然后自动连接到每个测试类中。我使用了 spring @Configuration
类,并将 KnowledgeBase
定义为 @Bean
。我现在发现 KnowledgeBase
需要 2 秒(但只运行一次), session 创建大约需要 0.2 秒,而测试本身根本不需要时间。
似乎 spring 方法可以更好地扩展,但我不确定测试单个规则但使用在所有文件上初始化的 KnowledgeBase
是否会遇到其他问题?我正在使用 AgendaFilter
来定位我想要测试的特定规则。另外,我在网上搜索了很多,但没有发现其他人这样做。
摘要
编写这些测试的最具可扩展性的方法是什么?谢谢
最佳答案
这是一个非常好的体验集合。让我贡献一些想法。
如果您的场景需要大量规则来测试结果,因为规则相互竞争,那么您应该创建包含所有规则的 KieBase 并将其序列化一次。对于单个测试,可以为每个测试从中派生一个 session ,插入事实并触发所有规则,或者预先派生 session ,然后运行测试,清除 session (!),插入事实并触发所有规则。
对于测试单个规则或一小组(<10)规则,为每组测试从头开始编译 DRL 可能是可以忍受的,特别是当您采用通过清除工作内存来重用 session (!)的策略时各个测试之间。
规则设计还应该考虑一些。在DRL中不应该千方百计地实现过多的迭代算法;使用 DRL 函数或某些(静态)Java 方法可能要优越得多。而且诸如此类的测试要容易得多。
此外,遵循既定的规则设计模式也有很大帮助。 Google“生产系统中的设计模式”。
关于junit - 在 Drools 单元测试中在哪里创建知识库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47454641/