`
love~ruby+rails
  • 浏览: 849183 次
  • 性别: Icon_minigender_1
  • 来自: lanzhou
社区版块
存档分类
最新评论

Test JBoss Rules 5 (or Drools) with TestNG

阅读更多

We have been using our own flavor of Fit for Rules (which is build on top of fit) for about 1 1/2 years now to test our business logic written in JBoss Rules 5. It’s relatively easy to get the Business Analyst on board since he is using his tool (which is Microsoft Excel) to communicate test cases for the rules. So in theory, he writes the tests in Excel, we do the rules coding and voila, all tests turn green.

Reality is, we have to tweak the Excel sheets. We need to put in imports of our fact model, insert facts and create objects within that not so programmer friendly table environment. A couple of days ago we got the request to tweak some rules and we all had to start doing rules again (and we used to use Eclipse for writing rules because that’s the only IDE having a plugin for that).

After half a day of coding Java syntax in Excel sheets we decided that the ramp up time for the not so knowledgeable rules/fit programmers like me is too much. With debugging, copy and paste we spent easily 5-10 times more time on making the tests work than writing the code itself. Test driven design is not really an option here, since you need to know the imports of the rules file to get the sheet even to compile.

So what did we do ? Well why not try to get things working the way we used to do it ? TestNG anyone ?

There are many pros to use unit testing but also some cons. The biggest issue is that we will loose the direct communication to the business analyst. It’s always better if someone else writes the test and I just have to implement the solution. Maybe we can find another solution involving Active Spec or DSL. For now we stick to unit tests and the task the we have to make sure we convert every Excel test case to java code (but hey, that’s what our code reviews are for).

Checkout our current base class for testing our rules:

01.public abstract class AbstractRulesTest {
02.public abstract String[] getRulesFileNames();
03.private final String GET_FINDINGS = "import com.maxheapsize.RulesFinding;" +
04."query \"getAllRulesFindings\"\n" +
05."  finding : FRulesFinding()\n" +
06."end";
07. 
08.private static Logger LOG = Logger.getLogger(AbstractRulesTest.class);
09. 
10.public final List<FRulesFinding> fireRules(Set factsForWorkingMemory) {
11.KnowledgeBase ruleBase = setUpKnowledgeBase();
12.return fireRules(ruleBase, factsForWorkingMemory);
13.}
14. 
15.public KnowledgeBase setUpKnowledgeBase() {
16.KnowledgeBaseConfiguration configuration = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
17.KnowledgeBase ruleBase = KnowledgeBaseFactory.newKnowledgeBase(configuration);
18. 
19.KnowledgeBuilder build = KnowledgeBuilderFactory.newKnowledgeBuilder();
20.build.add(ResourceFactory.newReaderResource(new StringReader(GET_FINDINGS)), ResourceType.DRL);
21.String[] fileNames = getRulesFileNames();
22.for (String fileName : fileNames) {
23.File userDefinedFile = new File(fileName);
24.build.add(ResourceFactory.newFileResource(userDefinedFile), ResourceType.DRL);
25.}
26. 
27.handleBuilderErrors(build);
28. 
29.ruleBase.addKnowledgePackages(build.getKnowledgePackages());
30.return ruleBase;
31.}
32. 
33.private void handleBuilderErrors(KnowledgeBuilder build) {
34.if (build.hasErrors()) {
35.KnowledgeBuilderErrors knowledgeBuilderErrors = build.getErrors();
36.for (KnowledgeBuilderError knowledgeBuilderError : knowledgeBuilderErrors) {
37.int[] ints = knowledgeBuilderError.getErrorLines();
38.LOG.error("Error at : "+ints[0]+" : "+ints[1]);
39.LOG.error(knowledgeBuilderError.getMessage());
40.}
41.}
42.}
43. 
44.private List<FRulesFinding> fireRules(KnowledgeBase ruleBase, Set facts) {
45.List<FRulesFinding> result = new ArrayList<FRulesFinding>();
46.StatefulKnowledgeSession statefulSession = ruleBase.newStatefulKnowledgeSession();
47.for (Object fact : facts) {
48.statefulSession.insert(fact);
49.}
50.statefulSession.fireAllRules();
51. 
52.QueryResults results = statefulSession.getQueryResults("getAllRulesFindings");
53.try {
54.FRulesFinding finding = (FRulesFinding) results.iterator().next().get("finding");
55.result.add(finding);
56.}
57.catch (NoSuchElementException e) {
58.result = new ArrayList<FRulesFinding>();
59.}
60.return result;
61.}
62.}

All my rules insert a RulesFinding (and only one at the moment) into the working memory when triggered. The rest is pretty easy. You subclass it, overwrite getRulesFileNames and call fireRules with a set of objects (your tests) which need be insert into the working memory. To get the finding back you need to execute an already inserted query which needs to have an identifier (line 3, 20, 52, 54). It will contain the result of your rule execution.

Sample code would look like this:

01.public class RulesTest extends AbstractRulesTest {
02. 
03.private Set facts;
04. 
05.@BeforeMethod
06.public void setUp() {
07.facts = new HashSet();
08.}
09. 
10.@Override
11.public String[] getRulesFileNames() {
12.return new String[]{
13."src/main/rules/myrules.drl",
14."src/main/rules/generealRules.drl"
15.};
16.}
17. 
18.@Test
19.public void testDemoRule() {
20. 
21.FMyFact myFact = new FMyFact();
22.myFact.setColor("green");
23.facts.add(myFact); // add all your facts here
24. 
25.List<FRulesFinding> findings = fireRules(facts);
26.Assert.assertTrue(findings.size() == 1);
27.FRulesFinding finding = findings.get(0);
28.Assert.assertTrue(finding.getStatus() == FStatus.OK);
29.}
30.}

Depending on how you cut your rules you can extract the assertion of the status.

Each test case in Excel now takes about 5-10 lines of java code. Considering we are covering each rule with about 5-15 test cases and boundary conditions this amounts to 75-150 lines of test code. I take that any day over programming in Excel.

分享到:
评论

相关推荐

    Drools JBoss Rules 5 Developers Guide

    ### Drools JBoss Rules 5 开发者指南 #### 知识点一:Drools 平台介绍 - **定义与背景**:Drools 是一个开源业务规则管理系统(Business Rule Management System, BRMS),它支持开发人员通过声明式编程来实现...

    jboss rules 用户指南(中文)

    内容摘要:JBoss Rules 的前身是Codehaus的一个开源项目叫Drools。JBoss Rules,成为了JBoss应用服务器的规则引擎。JBoss Rules是一个商业规则引擎,那我们就要先知道到底什么是Rules,即规则。JBoss Rules中,规则...

    Drools JBoss Rules 5.X Developer's Guide

    在描述中提到的“Define and execute your business rules with Drools”表明了本书的核心内容——提供一套详细的教程和指南,教读者如何定义和执行业务规则,以及如何使用Drools JBoss Rules来处理各种业务逻辑。...

    JAVA规则引擎JBOSS RULES(DROOLS 6.5) 动态规则

    JAVA规则引擎JBOSS RULES,也被称为DROOLS,是一种强大的业务规则管理系统,它允许开发者用自然语言来编写业务规则,并在运行时执行这些规则。DROOLS 6.5是该规则引擎的一个版本,提供了许多改进和新特性,以提高...

    JBoss Rules入门资料集锦

    JBoss Rules,现名为Drools,是一款强大的开源业务规则管理系统(BRMS),它允许开发者在应用程序中嵌入复杂的业务规则。本入门资料集锦涵盖了从基础到高级的多个方面,帮助初学者全面理解并掌握如何使用JBoss Rules...

    myeclipse安装drools jboss rules规则引擎

    myeclipse安装drools jboss rules规则引擎

    jboss 规则引擎 drools库 drools-compiler-5.1.1.jar

    jboss 规则引擎 drools库。 api,core,compiler,jsr94 drools-compiler-5.1.1.jar

    Drools JBoss Rules 5.0 Developer's Guide

    ### Drools JBoss Rules 5.0 Developer's Guide #### 概述 《Drools JBoss Rules 5.0 Developer's Guide》是一本专为希望利用Drools平台开发基于规则的业务逻辑的开发者而编写的指南。本书由Michal Bali撰写,于...

    jboss rules 中文用户指南

    jboss rules 中文用户指南,mht文件,共十章。

    JBoss Rules 初学实例

    【JBoss Rules 初学实例】是针对Drools规则引擎的一个入门教程,适用于初次接触该框架的开发者。Drools是一款开源的业务规则管理系统,它允许开发人员以声明式的方式编写业务规则,使得复杂的逻辑处理变得更加简洁...

    jboss rules 中文学习资料.chm

    jboss rules 中文学习资料.chm

    jboss rules 用户指南

    ### jBoss Rules 用户指南知识点详解 #### 一、规则引擎概念及背景 ##### 1.1 什么是规则引擎 规则引擎是一种软件系统,它能够基于一组预定义的规则来处理数据,进而推导出结论或者执行特定的操作。规则引擎的...

    规则引擎drools-jboss rules

    规则引擎 Drools-JBoss Rules 规则引擎是人工智能(Artificial Intelligence)领域中的一种技术,用于实现专家系统,专家系统使用知识表示把知识编码简化成一个可用于推理的知识库。规则引擎是一个基于规则的方法...

    Drools Jboss Rules 5.0 Developer's Guide

    ### Drools JBoss Rules 5.0 Developer's Guide:规则引擎技术详解 #### 一、概述 《Drools JBoss Rules 5.0 Developer's Guide》是一本深入讲解Drools规则引擎技术的书籍。本书由Michal Bali编写,旨在帮助读者...

    jboss drools5.5 规则流完整代码

    **JBoss Drools 5.5 规则流完整代码详解** JBoss Drools 是一个开源的业务规则管理系统(BRMS),它允许开发者通过规则语言(如DRL)来定义和执行业务规则。在5.5版本中,Drools 提供了强大的规则流(Rule Flow)...

Global site tag (gtag.js) - Google Analytics