All:

A rather long-winded answer to a simple question.

As one who has used JUnit to test rules in a production environment:
Yes, you can write JUnit classes for testing purposes to test the rules.
However, as the number of rules and the number of variable increase the
number of test cases rise dramatically.  Geometrically to be more
specific.  Or is that exponentially?  Either way, it's a TON of test
cases.

On a previous project, the person running the project (who had never
used either JUnit or a rulebase) decided that we would write a test case
under JUnit for these BUT that we would use the 80/20 rule; meaning that
we would only need to write 20% of the possible test cases and that
would cover 80% of the possibilities.  That left 80% of the rules
untested.  Disgraceful.

Now, think about that.  Let's say that we have a financial application,
or an underwriting application.  That means that, even if the hypothesis
is correct, that we're not going to examine 80% of the rules that
represent 20% of the possible failures.  On a large application with
lots of users, it wouldn't take much time at all for someone to figure a
way to get through that kind of reasoning and either get a really cheap
loan or obtain some really cheap insurance.  Or, just as bad, drive away
customers by pricing a loan too high or rejecting insurance on a
perfectly good candidate.

The main problem in verification today is not testing all of the
possible combinations, but trying to discover the missing rules.  XCON
(10,000+ rules) was considered 95% accurate (G&R 1998) but that was in a
domain that was 100% known.  The problem was purported to be missing
rules in most cases.  Verification is difficult even when you have 100%
testing of the known rules.

Though most of those in the testing world will use the infamous 80/20
rule for testing programs, it doesn't work in the real world.  Back when
we did not have sufficient computer power, there might have been an
argument for not testing 100% because of time or money.  Not today.
Many recent authors have acknowledged this problem and, even though some
still maintain that 100% testing as part of the verification process  is
impossible, others have seen the need for 100% testing of the rules that
are available. 

Here are a few examples on which I have worked the past few years:  One
was a validation problem consisting of only 200+ rules.  We developed
15,000+ test cases for that one.  Another was a pricing problem of only
600+ rules.  We developed 45,000+ test cases for that one.  One
underwriting problem that had only seven very complex rules took 5,120
test cases.  Properly done, it only takes a few days (OK, maybe a couple
of weeks) to write the code for the test cases to cover all of the
possibilities.  But, to bullet proof a financial system it's well worth
the time to do this.  

SDG
jco
 
James C. Owen
Knowledgebased Systems Corporation
Senior Consultant
6314 Kelly Circle
Garland, TX   75044
972.530.2895 
214.684.5272 (cell)
 

-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On Behalf Of Brad Cox, Ph.D.
Sent: Friday, July 25, 2003 9:01 AM
To: [EMAIL PROTECTED]
Subject: Re: JESS: Newbie needs help

On Fri, 2003-07-25 at 08:13, [EMAIL PROTECTED] wrote:

> Now, I'm not really sure where JUnit fits in.

You're absolutely right. Java/Jess conditionals should suffice.

Thanks for the boost! Hope you don't mind some follow-on questions. 

The main one being, I don't understand why the deftemplate rule is
needed. I know that's Jess's way of defining a jess object with a slot
(instance var) for the object under test. Is that "just the way it has
to be in Jess" or is there a deeper reason? In any event, I'd never have
guessed this on my own, so thanks!

Style question: I got the JessInsideJava style from the examples
but understand many permutations are possible. Would you recommend this
style for this application, i.e. where the defrule section will grow
interminably?

Finally, it compiled, ran, but the "subject passes" rule didn't fire.
Any advice on debugging tips would be great. Feel free to blow me off on
this one; I'm sure I saw it in the dox somewhere.

Here's what I made of what you sent

package edu.virtc.gauges;
public class Helmet implements MilitaryEquipment
{
        public Helmet()
        {
                super();
        }
        public double getWeight()
        {
                return 5.0;
        }
}
=========
package edu.virtc.gauges;
public interface MilitaryEquipment
{
        double getWeight();
}
==========
package edu.virtc.gauges;

import jess.JessException;
import jess.Rete;

public class Rules
{
        public static void main(String[] argv)
        {
                try
                        {
                                Rete rete = new Rete();

                                rete.executeCommand(
                                        "(deftemplate test-subject (slot
object))"
                                );
                                rete.executeCommand(
                                        "(assert (test-subject (object
(new edu.virtc.gauges.Helmet))))"
                                );
                                rete.executeCommand(
                                        "(deffunction compareWeights
(?n1 ?n2)\n"+
                                        "       (return (< (call Math
abs (- ?n1 ?n2)) 0.000001)))\n"
                                );
                                rete.executeCommand(
                                        "(deffunction computeWeight
(?o)\n"+
                                        "       (return 5.00))\n"
                                );
                                rete.executeCommand(
                                        "(defrule test-get-weight\n"+
                                        "
(test-subject (object ?o))\n"+
                                        "                       (test
(instanceof ?o edu.virtc.gauges.MilitaryEquipment))\n"+
                                        "                       (test
(compareWeights (?o getWeight) (computeWeight ?o)))\n"+
                                        "                       =>\n"+
                                        "
(printout \"Subject passes getWeight test\" crlf))\n"
                                        );
                                rete.reset();
                                rete.run();

                                // System.out.println("The answer is
NOT: " + rete.fetch("RESULT"));
                        }
                catch (JessException re)
                        {
                                re.printStackTrace();
                        }
        }
}

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify
[EMAIL PROTECTED]
--------------------------------------------------------------------

--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------

Reply via email to