Prueba de salidas de línea de tiempo

Un atributo de regla que devuelve una línea de tiempo de valores deben probarse en las pruebas JUnit de forma similar a las pruebas para valores primitivos (no de línea de tiempo).

Para simplificar las pruebas, no necesita probar que timelineoperation acumula correctamente las fechas de cambio (a menos que lo desee). Para que las pruebas sean simples, generalmente puede utilizar líneas de tiempo de entrada que tengan un valor constante para siempre.

Por ejemplo, digamos que tiene un atributo de regla que calcula (en forma de línea de tiempo) el total de una lista de números:

<?xml version="1.0" encoding="UTF-8"?>
<RuleSet name="Example_NumberSumTimeline"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation=
"http://www.curamsoftware.com/CreoleRulesSchema.xsd">

  <Class name="Totalizer">

    <!-- Las líneas de tiempo a sumar -->
    <Attribute name="inputNumberTimelines">
      <type>
        <javaclass name="List">
          <javaclass name="curam.creole.value.Timeline">
            <javaclass name="Number"/>
          </javaclass>
        </javaclass>
      </type>
      <derivation>
        <specified/>
      </derivation>
    </Attribute>

    <!-- El total resultante -->
    <Attribute name="totalTimeline">
      <type>
        <javaclass name="curam.creole.value.Timeline">
          <javaclass name="Number"/>
        </javaclass>
      </type>
      <derivation>
        <timelineoperation>
          <sum>
            <dynamiclist>
              <list>
                <reference attribute="inputNumberTimelines"/>
              </list>
              <listitemexpression>
                <intervalvalue>
                  <current/>
                </intervalvalue>
              </listitemexpression>
            </dynamiclist>

          </sum>
        </timelineoperation>
      </derivation>
    </Attribute>

  </Class>
</RuleSet>

...entonces puede escribir una prueba simple que utilice líneas de tiempo de entrada que tengan un valor constante en todo momento:

package curam.creole.example;

import java.util.Arrays;

import junit.framework.TestCase;
import curam.creole.calculator.CREOLETestHelper;
import curam.creole.execution.session.RecalculationsProhibited;
import curam.creole.execution.session.Session;
import curam.creole.execution.session.Session_Factory;
import
 curam.creole.execution.session.StronglyTypedRuleObjectFactory;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer_Factory;
import curam.creole.storage.inmemory.InMemoryDataStorage;
import curam.creole.value.Timeline;

public class TestForeverValuedTimelines extends TestCase {

  public void testNumberSumTimeline() {

    final Session session =
        Session_Factory.getFactory().newInstance(
            new RecalculationsProhibited(),
            new InMemoryDataStorage(
                new StronglyTypedRuleObjectFactory()));

    final Totalizer totalizer =
        Totalizer_Factory.getFactory().newInstance(session);

    // utilizar valores de entrada que no varían a lo largo del tiempo

    final Timeline<Number> inputTimeline1 =
        new Timeline<Number>(1);
    final Timeline<Number> inputTimeline2 =
        new Timeline<Number>(2);
    final Timeline<Number> inputTimeline3 =
        new Timeline<Number>(3);

    totalizer.inputNumberTimelines().specifyValue(
        Arrays.asList(inputTimeline1, inputTimeline2,
            inputTimeline3));

    // comprobar que la línea de tiempo resultante es siempre 6
    CREOLETestHelper.assertEquals(new Timeline<Number>(6),
        totalizer.totalTimeline().getValue());

  }
}
Consejo: La clase Timeline tiene un constructor preparado para crear una línea de tiempo con un valor constante para siempre.

En algunas situaciones, por ejemplo cuando ha creado su propio algoritmo de desplazamiento de fecha o si realmente necesita probar que las fechas de cambio para las líneas de tiempo de entrada están correctamente reflejadas en las líneas de tiempo resultantes, hay diferentes enfoques que puede adoptar según sus necesidades:

Figura 1. Ejemplo de prueba estricta de una línea de tiempo resultante
package curam.creole.example;

import java.util.Arrays;

import junit.framework.TestCase;
import curam.creole.calculator.CREOLETestHelper;
import curam.creole.execution.session.RecalculationsProhibited;
import curam.creole.execution.session.Session;
import curam.creole.execution.session.Session_Factory;
import
 curam.creole.execution.session.StronglyTypedRuleObjectFactory;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer_Factory;
import curam.creole.storage.inmemory.InMemoryDataStorage;
import curam.creole.value.Interval;
import curam.creole.value.Timeline;
import curam.util.type.Date;

public class TestStrictTimelineChecking extends TestCase {

  public void testNumberSumTimeline() {

    final Session session =
        Session_Factory.getFactory().newInstance(
            new RecalculationsProhibited(),
            new InMemoryDataStorage(
                new StronglyTypedRuleObjectFactory()));

    final Totalizer totalizer =
        Totalizer_Factory.getFactory().newInstance(session);

    // utilizar valores de entrada que varían a lo largo del tiempo

    final Timeline<Number> inputTimeline1 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 1),
          new Interval<Number>(Date.fromISO8601("20010101"), 1.1)
        ));

    final Timeline<Number> inputTimeline2 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 2),
          new Interval<Number>(Date.fromISO8601("20020101"), 2.2)
        ));

    final Timeline<Number> inputTimeline3 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 3),
          new Interval<Number>(Date.fromISO8601("20030101"), 3.3)
         ));

    totalizer.inputNumberTimelines().specifyValue(
        Arrays.asList(inputTimeline1, inputTimeline2,
            inputTimeline3));

    // comprobar estrictamente el valor exacto de la línea de tiempo resultante
    CREOLETestHelper.assertEquals(

    new Timeline<Number>(Arrays.asList(
      new Interval<Number>(null, 6),
      new Interval<Number>(Date.fromISO8601("20010101"), 6.1),
      new Interval<Number>(Date.fromISO8601("20020101"), 6.3),
      new Interval<Number>(Date.fromISO8601("20030101"), 6.6)
    )),

    totalizer.totalTimeline().getValue());

  }
}
Figura 2. Ejemplo de pruebas más flexibles de una línea de tiempo resultante
package curam.creole.example;

import java.util.Arrays;

import junit.framework.TestCase;
import curam.creole.calculator.CREOLETestHelper;
import curam.creole.execution.session.RecalculationsProhibited;
import curam.creole.execution.session.Session;
import curam.creole.execution.session.Session_Factory;
import
 curam.creole.execution.session.StronglyTypedRuleObjectFactory;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer;
import
 curam.creole.ruleclass.Example_NumberSumTimeline.impl.Totalizer_Factory;
import curam.creole.storage.inmemory.InMemoryDataStorage;
import curam.creole.value.Interval;
import curam.creole.value.Timeline;
import curam.util.type.Date;

public class TestLaxTimelineChecking extends TestCase {

  public void testNumberSumTimeline() {

    final Session session =
        Session_Factory.getFactory().newInstance(
            new RecalculationsProhibited(),
            new InMemoryDataStorage(
                new StronglyTypedRuleObjectFactory()));

    final Totalizer totalizer =
        Totalizer_Factory.getFactory().newInstance(session);

    // utilizar valores de entrada que varían a lo largo del tiempo

    final Timeline<Number> inputTimeline1 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 1),
          new Interval<Number>(Date.fromISO8601("20010101"), 1.1)
        ));

    final Timeline<Number> inputTimeline2 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 2),
          new Interval<Number>(Date.fromISO8601("20020101"), 2.2)
        ));

    final Timeline<Number> inputTimeline3 =
        new Timeline<Number>(Arrays.asList(
          new Interval<Number>(null, 3),
          new Interval<Number>(Date.fromISO8601("20030101"), 3.3)
        ));

    totalizer.inputNumberTimelines().specifyValue(
        Arrays.asList(inputTimeline1, inputTimeline2,
          inputTimeline3));

    /*
     * No comprobar estrictamente que la línea de tiempo resultante es exactamente
     * como se esperaba; en lugar de ello comprobar el valor de la línea de tiempo resultante
     * en fechas determinadas.
     *
     * Es posible que la línea de tiempo tenga valores incorrectos en
     * otras fechas, pero según el propósito de la prueba,
     * es aconsejable que cambie la rigurosidad por una mejor legibilidad.
     */

    final Timeline<? extends Number> resultantTimeline =
        totalizer.totalTimeline().getValue();
    CREOLETestHelper.assertEquals(6.1,
        resultantTimeline.valueOn(Date.fromISO8601("20010101")));
    CREOLETestHelper.assertEquals(6.6,
        resultantTimeline.valueOn(Date.fromISO8601("20130101")));
  }
}