Unit Tests |
Top Previous Next |
Running from Unit Test
You can run a solution/project as an unit test, if you don't want to use the graphical user interface. Have a look at the examples in
lap -> src -> net.simplace.client -> simulation.lap -> test -> model -> ...
(Right click a test and choose Run As -> JUnitTest to run it).
No chart is displayed, but outputs are normally written to (attention !!! ) lap -> outputs rather than lapclient -> outputs.
Please put your UnitTests for runing simulations in the simplacerun eclipse-project. simplacerun -> src ->net.simplace.runs -> yourname -> ...
General prerequisits
You need
•a properly configured system (see: Install and Setup).
•a solution file
•and eventually a project file, if your simulation should run multiple times
Unit Tests have to be implemented
- For the framework
- For each simulation module (SimComponent)
- For each resource format
Unit tests are designed to run a program and to check whether computed values are equal to expected.
They are used to check
•Whether an implementation of an algorithm does what it is supposed to do.
•Whether changes of existing code does introduce errors.
The check is done via asserts, for example if someone implemented a function mySquare that squares numbers, one could do a test like the following.
@Test
public void TestMySquare()
{
assertEqual(4, mySquare(2));
assertEqual(4, mySquare(-2));
assertEqual(0, mySquare(0));
assertEqual(mySquare(5), mySquare(3) + mySquare(4));
}
If the implementation of mySquare is correct, the test will pass (in Eclipse it shows a green checkmark).
If the test fails (blue cross in Eclipse), then implementation of mySquare is wrong.
Notice: The statement "if the implementation is wrong, then the test fails" is not correct, as the test checks only a very small subset of possible inputs. Same holds for the statement "if the test passes, then the implementation is correct".
Testing simulations
Unit tests are normally suitable to detect technical problems, but seldom suitable to detect scientific problems of your simulation. E.g. you can check whether your input data is read in correctly or whether your simulation produces same LAI values as in previous runs, but you can't check, whether computed LAI values make sense or not.
Technical implementation
In order to check the values of SimVariables during the runs, there is a method assertSimulation that takes as parameter an assertFunction additionally to the solution (and project) name.
@Test
public void testCompareLintulPotentialGrowth() throws Exception
{
String tSolutionFileName = "${_WORKDIR_}/solution/lintul/LintulPotentialGrowthTest.sol.xml";
Consumer<FWSimVarMap> myAsserts = varmap -> {
Double expected = (Double) varmap.getSimVariable("referencedata.yield").getValue();
Double simulated = (Double) varmap.getSimVariable("LintulBiomass.sWSO").getValue();
Assert.assertEquals(expected, simulated, 0.0000001);
};
assertSimulation(tSolutionFileName, myAsserts);
showMessage("finished comparison Test LintulPotentialGrowth");
}
Explanation
1. The Test annotation marks the following method as an unit test, that will be run by the JUnit framework.
2. Start defining the method named testCompareLintulPotentialGrowth, note that the method might throw an exception
3. Define the solution file name
4. Begin of the assert functions. Pay attenttion at the somehow unusual systax (new functional language elements of Java)
5. The actual expected value (taken from the simulation from the resource referencedata) is retrieved from the simulation variables map.
6. The actual simulated value is retrieved from the simulation variables map.
7. The assertEqual function checks if expected is same as simulated, allowing a maximal tolerance of 0.0000001.
8. End of the assert function.
9. Call assertSimulation and pass the solution file name and the assert function (see in depth explanation below).
10. Display a message when finished.
The assertSimulation function runs the simulation day by day. After each step, the assert function myAssert is evaluated. If the assert fails, i.e. the simulated value deviates to much from the expected, then the execution stops with an error and the unit test is marked as failed (by a blue cross in Eclipse).
Non daily tests
What if there is no daily comparison data available? The assert function will be executed nevertheless still daily. One has to take care inside the function to compare only when there is data available.
...
Consumer<FWSimVarMap> myAsserts = varmap -> {
Double expected = (Double) varmap.getSimVariable("referencedata.yield").getValue();
Double simulated = (Double) varmap.getSimVariable("LintulBiomass.sWSO").getValue();
if(expected != null)
Assert.assertEquals(expected, simulated, 0.0000001);
};
...
In the upper function, the assertEquals method is executed only, when reference data is available (i.e. the value is not null).