Domanda

Qual è la pratica migliore per testare le regole delle sbavature con Junit?

Fino ad ora abbiamo utilizzato junit con dbunit per testare le regole.Avevamo dati di esempio inseriti in hsqldb.Avevamo un paio di pacchetti di regole e alla fine del progetto è molto difficile fornire un buon input di prova per testare determinate regole e non attivarne altre.

Quindi la domanda esatta è: come posso limitare i test in junit a una o più determinate regole per i test?

È stato utile?

Soluzione

Personalmente io uso unit test per testare le regole isolate. Io non credo che ci sia qualcosa di troppo sbagliato con esso, fino a quando non cadere in un falso senso di sicurezza che la vostra base di conoscenze sta lavorando perché le regole isolate stanno lavorando. Testare l'intera base di conoscenza è più importante.

È possibile scrivere i test di isolamento con AgendaFilter e StatelessSession

StatelessSession session = ruleBase.newStatelessSesssion();

session.setAgendaFilter( new RuleNameMatches("<regexp to your rule name here>") );

List data = new ArrayList();
... // create your test data here (probably built from some external file)

StatelessSessionResult result == session.executeWithResults( data );

// check your results here.

Il codice sorgente: http : //blog.athico.com/2007/07/my-rules-dont-work-as-expected-what-can.html

Altri suggerimenti

Ho creato semplice libreria che aiuta a scrivere unit test per Drools. Una delle caratteristiche è esattamente quello che vi serve: dichiara particolari file DRL che si desidera utilizzare per il test di unità:

@RunWith(DroolsJUnitRunner.class)
@DroolsFiles(value = "helloworld.drl", location = "/drl/")
public class AppTest {

    @DroolsSession
    StatefulSession session;

    @Test
    public void should_set_discount() {
        Purchase purchase = new Purchase(new Customer(17));

        session.insert(purchase);
        session.fireAllRules();

        assertTrue(purchase.getTicket().hasDiscount());
    }
}

Per maggiori dettagli hanno uno sguardo sul post del blog: http://maciejwalkowiak.pl/blog/2013/11/24/jboss-drools-unit-testing-with-junit-drools/

Non tentare di esecuzione della regola limite a una singola regola per un test. A differenza di classi OO, regole singoli non sono indipendenti di altre norme, in modo che non ha senso per testare una regola in isolamento nello stesso modo in cui si prova una singola classe con una prova di unità. In altre parole, per testare una singola regola, test che ha il giusto effetto in combinazione con le altre norme.

Al contrario, i test vengono eseguiti con una piccola quantità di dati su tutte le regole, cioè con un numero minimo di fatti nella sessione regola e verificare i risultati e, forse, che una particolare regola è stato licenziato. Il risultato non è in realtà molto diverso da quello che hai in mente, perché un set minimo di dati di test potrebbe attivare solo una o due regole.

Per quanto riguarda i dati di esempio, io preferisco usare i dati statici e definire i dati di prova minimi per ogni test. Ci sono vari modi per farlo, ma a livello di codice la creazione di oggetti fatto in Java potrebbe essere abbastanza buono.

Un test unitario con DBUnit non funziona davvero.Un test di integrazione con DBUnit lo fa.Ecco perché:- Un test unitario dovrebbe essere veloce.-- Il ripristino del database DBUnit è lento.Richiede facilmente 30 secondi.-- Un'applicazione reale ha molte colonne non nulle.Pertanto i dati, isolati per una singola funzionalità, utilizzano ancora facilmente la metà delle tabelle del database.- Un test unitario dovrebbe essere isolato.-- Il ripristino del database dbunit per ogni test per mantenerli isolati presenta degli inconvenienti:--- L'esecuzione di tutti i test richiede ore (soprattutto man mano che l'applicazione cresce), quindi nessuno li esegue, quindi si interrompono costantemente, quindi sono disabilitati, quindi non ci sono test, quindi l'applicazione è piena di bug.--- Creare mezzo database per ogni test unitario richiede molto lavoro di creazione, molto lavoro di manutenzione, può facilmente diventare non valido (per quanto riguarda la convalida che gli schemi del database non supportano, vedere Hibernate Validator) e di solito fa male compito di rappresentare la realtà.

Scrivi invece test di integrazione con DBunit:- Una DBunit, la stessa per tutti i test.Caricalo solo una volta (anche se esegui 500 test).-- Racchiudi ogni test in una transazione ed esegui il rollback del database dopo ogni test.La maggior parte dei metodi utilizza comunque la propagazione richiesta.Imposta testdata dirty only (per reimpostarlo nel test successivo se c'è un test successivo) solo quando la propagazione è require_new.- Riempi il database con casi angolari.Non aggiungere più casi comuni di quelli strettamente necessari per testare le regole aziendali, quindi di solito solo 2 casi comuni (per poter testare "uno a molti").- Scrivere test a prova di futuro:-- Non testare il numero di regole attivate o il numero di fatti inseriti.-- Invece, verifica se un certo fatto inserito è presente nel risultato.Filtra il risultato su una determinata proprietà impostata su X (diversa dal valore comune di quella proprietà) e verifica il numero di fatti inseriti con quella proprietà impostata su X.

Perché non scegliere stesso approccio che abbiamo per il codice Java con test di unità e di integrazione? Unità di prova è di prendere piece minima di codice e testare tutti i possibili casi d'uso che definiscono specifica. Con l'integrazione mette alla prova il vostro obiettivo è non tutti i possibili casi d'uso, ma l'integrazione di diverse unità che lavorano insieme. Fate lo stesso con le regole. regole segregano per senso di business e lo scopo. Più semplice 'unità sotto il test' potrebbe essere file con singolo o alta cohension insieme di regole e di ciò che è necessario per farlo funzionare (se presente), come file di definizione comune DSL e tabella di decisione. Per il test di integrazione si potrebbe prendere sottoinsieme significativo o tutte le regole del sistema.

Con questo approccio avrai molti test di unità isolate che non sarà influenzati e non richiederanno il supporto quando si aggiungono le nuove regole, perché avrete set isolato di regole di business con sottoinsieme di dati di input per testare rispettivi scenari di business. E avrete alcune prove di integrazione con quantità limitata di dati di input comune a riprodurre e 'scenari comuni' di test. L'aggiunta di nuove regole per test di integrazione richiederà di uscita di test di aggiornamento e rifletterà come le nuove regole di flusso di dati di impatto comuni.

JUnit regola di prova che ti dà la possibilità di risorse di carico in dichiarativa strada e le regole assert effettivamente attivato. Si manterrà errori di asserzione interni e segnalare eventuali regole scatenanti disadattamento che voi suggerimenti su cosa è andato storto a colpo d'occhio. capannoni Registrazione luce sulle relazioni di causa-effetto tra gli eventi. Funziona con SpringRunner.class per i test di integrazione primavera.

Esempio:

@DroolsSession(resources = {
        "classpath*:/org/droolsassert/rules.drl",
        "classpath*:/com/company/project/*/{regex:.*.(drl|dsl|xlsx|gdst)}",
        "classpath*:/com/company/project/*/ruleUnderTest.rdslr" },
        ignoreRules = { "before", "after" })
public class DroolsAssertTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    @AssertRules("atomic int rule")
    public void testInt() {
        drools.insertAndFire(new AtomicInteger());
        assertEquals(1, drools.getObject(AtomicInteger.class).get());
    }
}

rules.drl
Più: https://github.com/droolsassert/droolsassert

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top