Search code examples
unit-testingjunitsimulationanylogic

How to configure unit testing for AnyLogic agent code?


How do you configure unit testing framework to help develop code that is part of AnyLogic agents?

To have a suitable test driven development rhythm, I need to be able to run all tests in a few seconds. I thought of exporting the project as a standalone application (jar) each time, but that's pretty slow.

I thought of trying to write all the code outside AnyLogic in separate classes, but there are many references to built-in AnyLogic classes, as well as various agents. My code would need to refer to these somehow, and I'm not sure how to do that except by writing the code inside AnyLogic.

I wonder if there's a way of adding the test runner as a dependency, and executing that test runner from within AnyLogic.

Does anyone have a setup that works nicely?


Solution

  • This definitely requires some advanced Java, but testing, especially unit testing is too often neglected in building good robust models. I hope this simple example is enough to get you (and lots of other modellers) going.

    For Junit testing, we make use of two libraries that you can add as a dependency to your model.

    enter image description here

    Now there are two main types of logic that you will want to test in simulation models.

    1. Functions in Java classes
    2. Model execution

    Type 1: Suppose I have this very simple Java class

    public class MyClass {
    
        public MyClass() {
        }
        
        public boolean getResult() {
            return true;
        }
    }
    
    

    And I want to test the function getResult()

    I can simply create a new class and create a function that I annotate with the @Test modifier and then also make use of the assertEquals() method, which is standard in junit testing

    import org.junit.Test;
    import static org.junit.Assert.assertEquals;
        
    public class MyTestClass{
    
        @Test
        public void testMyClassFunction1() {
            boolean result = new MyClass().getResult();
            assertEquals("The value of the test class 1", result, true);
        }
    
    

    Now comes the AnyLogic specific implementation (there are other ways to do this but this is the easiest/most useful, you will see in a minute)

    You need to create a custom experiment

    enter image description here

    Now if you run this from the Run Model button you will get this output

    enter image description here

    SUCCESS
    
    Run: 1
    Failed: 0
    
    
    

    You can obviously update and change the output as to your liking

    Type 2: Suppose we have this very simple model

    enter image description here

    And the function getResult() simply returns an int of 2.

    Now we need to create another custom experiment to run this model

    enter image description here

    And then we can write a test to run this Custom Experiment and check the result

    Simply add the following to your MyTestClass

    @Test
        public void testMyClassFunction2() {
            int result = new SingleRun(null).runExperiment();
            assertEquals("Value of a single run", result, 2);
        }
    
    

    And now if you run the RunAllTests customer experiment it will give you this output

    SUCCESS
    
    Run: 2
    Failed: 0
    
    

    This is just the beginning, you can read up tons on using junit to your advantage