在 Drools 单元测试中在哪里创建知识库?

Where to create KnowledgeBase in a Drools unit test?

简介

我希望在 JUnit 中编写单元测试来检查各个流口水规则。单元测试应该写起来简单并且快速到 运行。如果单元测试很慢,那么开发人员将避免 运行ning 它们并且构建将变得非常慢。考虑到这一点,我正在尝试找出编写这些单元测试的最佳(执行速度最快且最容易编写)方法。

第一次尝试

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

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

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

备选

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

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

总结

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

这是一个非常好的体验合集。让我贡献一些想法。

如果你有一个场景,其中大量规则对于测试结果是必不可少的,因为规则相互竞争,你应该创建包含所有规则的 KieBase 并将其序列化一次。对于单个测试,要么为每个测试从中派生一个会话,插入事实并触发所有规则,要么预先派生会话,然后 运行 测试,清除会话(!),插入事实并触发所有规则。

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

规则设计也需要考虑。不应在 DRL 中不择手段地实现过多的迭代算法;使用 DRL 函数或某些(静态)Java 方法可能要好得多。像这样的测试要容易得多。

此外,遵循既定的规则设计模式也很有帮助。 Google "Design Patterns in Production Systems".