Pergunta

Qual é a melhor prática para testar as regras de babás com o JUNIT?

Até agora, usamos o Junit com o DBunit para testar as regras. Tivemos dados de amostra que foram colocados no HSQLDB. Tivemos alguns pacotes de regras e, no final do projeto, é muito difícil fazer uma boa entrada de teste para testar certas regras e não demitir outras.

Portanto, a questão exata é: como posso limitar os testes no JUNIT a uma ou mais certas regras para testes?

Foi útil?

Solução

Pessoalmente, uso testes de unidade para testar regras isoladas. Eu não acho que há algo muito errado com isso, desde que você não caia em uma falsa sensação de segurança de que sua base de conhecimento está funcionando porque as regras isoladas estão funcionando. Testar toda a base de conhecimento é mais importante.

Você pode escrever os testes de isolamento com Agendafilter e apatelassess

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.

Fonte de código: http://blog.athico.com/2007/07/my-rules-dont-work-as-expected-what-can.html

Outras dicas

Criei biblioteca simples que ajuda a escrever testes de unidade para babados. Um dos recursos é exatamente o que você precisa: declarar arquivos DRL específicos que você deseja usar para o seu teste de unidade:

@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());
    }
}

Para mais detalhes, dê uma olhada na postagem do blog: http://maciejwalkowiak.pl/blog/2013/11/24/jboss-drools-unit-testing-with-junit-drools/

Não tente limitar a execução da regra a uma única regra para um teste. Ao contrário das classes OO, as regras únicas não são independentes de outras regras; portanto, não faz sentido testar uma regra isolada da mesma maneira que você testaria uma única classe usando um teste de unidade. Em outras palavras, para testar uma única regra, teste que ela tem o efeito certo em combinação com as outras regras.

Em vez disso, execute testes com uma pequena quantidade de dados sobre todas as suas regras, ou seja, com um número mínimo de fatos na sessão de regra e teste os resultados e talvez que uma regra específica tenha sido disparada. O resultado não é realmente muito diferente do que você tem em mente, porque um conjunto mínimo de dados de teste pode ativar apenas uma ou duas regras.

Quanto aos dados da amostra, prefiro usar dados estáticos e definir dados mínimos de teste para cada teste. Existem várias maneiras de fazer isso, mas criar programaticamente objetos de fatos em Java pode ser bom o suficiente.

Um teste de unidade com DBunit realmente não funciona. Um teste de integração com o dbunit faz. Eis o porquê: - Um teste de unidade deve ser rápido. - Uma restauração de banco de dados DBunit é lenta. Leva 30 segundos facilmente. -Um aplicativo do mundo real possui muitas colunas não nulas. Portanto, os dados, isolados para um único recurso, ainda usam facilmente metade das tabelas do banco de dados. - Um teste de unidade deve ser isolado. -Restaurar o banco de dados do DBunit para cada teste para mantê-los isolados tem desvantagens: --- Execução de todos os testes leva horas (especialmente à medida que o aplicativo cresce), então ninguém os executa, então eles se quebram constantemente, para que sejam desativados, portanto, lá Não há teste, então seu aplicativo está cheio de bugs. --- Criando metade de um banco de dados para cada teste de unidade é muito trabalho de criação, muito trabalho de manutenção, pode se tornar facilmente inválido (com relação à validação quais esquemas de banco de dados não suportam, consulte o Hibernate Validator) e, na Usualmente, faz um mal trabalho de representar a realidade.

Em vez disso, escreva testes de integração com dbunit: - Um dbunit, o mesmo para todos os testes. Carregue -o apenas uma vez (mesmo se você executar 500 testes). - Enrole cada teste em uma transação e reversão do banco de dados após cada teste. A maioria dos métodos usa a propagação necessária de qualquer maneira. Defina apenas o TestData Dirty (para redefini -lo no próximo teste, se houver um próximo teste) somente quando a propagação for exigida_new. - Preencha esse banco de dados com casos de canto. Não adicione casos mais comuns do que o estritamente necessário para testar suas regras de negócios; portanto, apenas 2 casos comuns (para poder testar "um a muitos"). - Escreva testes à prova de futuro:- Não teste o número de regras ativadas ou o número de fatos inseridos. - Em vez disso, teste se um certo fato inserido está presente no resultado. Filtre o resultado em uma determinada propriedade definida como x (diferente do valor comum dessa propriedade) e teste o número de fatos inseridos com essa propriedade definida como x.

Por que não escolher a mesma abordagem que temos para o código Java com testes de unidade e integração? O teste de unidade trata de fazer parte mínima de código e testar todas as especificações possíveis de definição de usos. Com os testes de integração, seu objetivo não é todas possíveis USECASES, mas a integração de várias unidades que trabalham juntas. Faça o mesmo com as regras. Segregar regras por significado e propósito dos negócios. A 'unidade mais simples no teste' pode ser arquivada com solteiro ou Alta coensiva Conjunto de regras e o que é necessário para funcionar (se houver), como arquivo de definição DSL comum e tabela de decisão. Para o teste de integração, você pode fazer subconjunto significativo ou todas as regras do sistema.

Com essa abordagem, você terá muitos testes de unidade isolados que não serão impactados e não precisarão de suporte quando adicionar novas regras, porque você terá um conjunto isolado de regras de negócios com subconjunto de dados de entrada para testar os respectivos cenários de negócios. E você terá poucos testes de integração com quantidade limitada de dados de entrada comuns para reproduzir e testar 'cenários comuns'. A adição de novas regras ao teste de integração exigirá para atualizar a saída do teste e refletirá como as novas regras afetarão o fluxo de dados comuns.

Considerar Regra de teste de Junit Isso oferece possibilidade de carregar recursos de maneira declarativa e afirmar regras realmente desencadeadas. Ele preservará as falhas de afirmação interna e relatará quaisquer regras que desencadearão incompatibilidade que o sugere sobre o que deu errado rapidamente. O registro lança luz sobre as relações de causa-efeito entre os eventos. Funciona com SpringRunner.class Para testes de integração da primavera.

Exemplo:

@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());
    }
}

Ver regras.drl
Mais: https://github.com/droolsaSsert/DroolsaSsert

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top