在Drools单元测试中创建KnowledgeBase的位置?

时间:2017-11-23 11:39:04

标签: junit drools

我正在寻找在JUnit中编写单元测试来检查单个drools规则。单元测试应该易于编写和快速运行。如果单元测试很慢,那么开发人员将避免运行它们,并且构建将变得过慢。考虑到这一点,我试图找出编写这些单元测试的最佳(最快执行和最容易编写)方法。

首次尝试

我尝试的第一个选项是创建KnowledgeBase作为静态类属性并在一个.drl文件上初始化。然后,每个测试都在@Before方法中创建一个新会话。这是基于Drools JBoss规则开发人员指南中的代码示例。

I've seen a second option通过创建一些注释来抽象初始化代码来整理这一点,但它基本上是相同的方法。

我注意到在一个.drl文件上进行这个基本单元测试需要几秒钟才能运行。对于一个单元测试来说这不是太糟糕,但是一旦它扩大了,我就会发现这是一个问题。我做了一些阅读,发现KnowledgeBase创建起来很昂贵,而会话很便宜。这就是为什么示例将KnowledgeBase设置为静态,因此它只创建一次,但是,对于多个单元测试类,它可能会多次创建。

替代

我尝试的替代方法是创建一个将加载所有.drl文件的单例KnowledgeBase。这将在测试套件中全局完成一次,然后自动连接到每个测试类中。我使用了一个spring @Configuration类,并将KnowledgeBase定义为@Bean。我现在发现KnowledgeBase需要2秒钟(但只运行一次),会话创建大约需要0.2秒,测试本身也没有时间。

似乎spring方法可能会更好地扩展,但我不确定在测试单个规则时是否会遇到其他问题,但是在所有文件上使用KnowledgeBase进行初始化?我正在使用AgendaFilter来定位我想要测试的特定规则。此外,我在网上搜索了很多,并没有发现任何其他人这样做。

摘要

编写这些测试的最具扩展性的方法是什么?感谢

1 个答案:

答案 0 :(得分:1)

这是一个非常好的经验集合。让我提出一些想法。

如果您有一个场景,其中大量规则对于测试结果至关重要,因为规则相互竞争,您应该创建包含all的KieBase并将其序列化一次。对于单个测试,要么为每个测试派生一个会话,插入事实并触发所有规则,要么预先派生会话,运行测试,清除会话(!),插入事实并触发所有规则。 / p>

为了测试单个规则或一小组(< 10)规则,可以容忍从头开始为每组测试编译DRL,尤其是当您采用策略通过清除工作重用会话(!)时各个测试之间的记忆。

还应该考虑规则设计。不应该通过钩子或骗子在DRL中实现过多的迭代算法;使用DRL函数或某些(静态)Java方法可能会更胜一筹。这样的测试要容易得多。

此外,遵循既定的规则设计模式有很大帮助。谷歌“生产系统中的设计模式”。