Testing ASTRA Programs
The astra-unittest library lets you write unit tests for ASTRA agents in ASTRA. A test is an agent program that inherits the behaviour you want to test, and each test is a goal that the test agent tries to achieve: if the goal succeeds the test passes, and if it fails the test fails.
Setting up a project
Add the astra-unittest library to your project’s pom.xml:
<dependencies>
<dependency>
<groupId>com.astralanguage</groupId>
<artifactId>astra-unittest</artifactId>
<version>2.6.1</version>
<scope>test</scope>
</dependency>
</dependencies>
If your project uses astra-base as its parent (as projects created from the archetype do), nothing else is needed: the parent already configures Maven to compile tests and run them. Test agents are compiled into target/test-classes, so they are not included in your project’s jar.
Test agents go in the src/test/astra folder, next to your normal code in src/main/astra:
|-- src
| |-- main
| | |-- astra
| | |-- calc
| | |-- Calculator.astra
| |-- test
| |-- astra
| |-- tests
| |-- CalculatorTests.astra
|-- pom.xml
Put both your agents and your tests in packages (here calc and tests). A test agent in a package cannot inherit from an agent in the default package, because of the way ASTRA programs are compiled to Java.
Writing a test
Suppose we want to test this agent:
package calc;
agent Calculator {
types calc {
formula total(int);
}
initial total(0);
plan +!add(int X) : total(int T) {
-total(T);
+total(T + X);
}
plan +!square(int X, int R) {
R = X * X;
}
}
A test agent extends astra.unit.ASTRAUnitTest as well as the agent that it tests. ASTRAUnitTest provides a module called UT with the assertions described below.
package tests;
import astra.unit.*;
agent CalculatorTests extends ASTRAUnitTest, calc.Calculator {
plan +!test_square(TestSuite suite) {
!square(4, int R);
UT.assertEquals(suite, 16, R);
}
plan +!test_add(TestSuite suite) : total(int T) {
!add(5);
query(total(int N));
UT.assertEquals(suite, T + 5, N);
}
}
The rules for writing tests are:
Each test is a plan for a goal whose name starts with
test_and which takes a single parameter, theTestSuitethat is running the test. The suite is passed to every assertion.A test passes if its goal succeeds, and fails if its goal fails. Assertions fail when the condition they check is false, which makes the test goal fail. Anything else that fails, such as a
query(...)or a sub-goal, also fails the test.Tests are run one after another, in alphabetical order of their goals, by a single test agent. Beliefs that one test changes are still there for the next one, so do not rely on the order, or reset what you need in each test.
Optional
+!setup(TestSuite suite)and+!teardown(TestSuite suite)plans run once, before the first test and after the last test of the test agent.
Assertions
The UT module provides the following actions. Each takes the TestSuite as its first argument.
Action |
Checks that… |
|---|---|
|
two |
|
a |
|
as above, with a message to report if it is false |
|
the named agent currently holds the belief (a |
|
(always passes) records that the test succeeded |
|
(always fails) records that the test failed |
Two further actions help when testing agents that react to their beliefs:
Action |
Effect |
|---|---|
|
adds the belief to the named agent |
|
removes the belief from the named agent |
Testing multi-agent behaviour
A test can create other agents with the System module, interact with them, and remove them when it has finished. For example, this test (from the astra-protocols library, see Prewritten Protocols) checks that a request made with the FIPA Request protocol succeeds:
import astra.unit.*;
agent FIPARequestTests extends astra.unit.ASTRAUnitTest, astra.protocol.FipaRequest {
plan +!test_request(TestSuite suite) {
system.createAgent("opp", "HelloResponder");
!request_action("opp", hello());
system.terminateAgent("opp");
UT.success(suite);
}
}
Running the tests
Run the tests with:
mvn test
Maven compiles your agents and your test agents, then runs every agent that extends ASTRAUnitTest. When all the tests have run, the test runner prints a summary:
TEST RESULTS:
====================================================
[PASSED] tests.CalculatorTests.test_add (steps: 1) -> 5 == 5
[PASSED] tests.CalculatorTests.test_square (steps: 5) -> 16 == 16
====================================================
results: passed 2 of 2 tests
For a failed test, the message after -> is the reason that the test goal failed, such as the assertion that did not hold.
If any test fails, the build fails with the message There are ASTRA test failures., in the same way as for failing JUnit tests. The usual Maven options are supported:
Option |
Effect |
|---|---|
|
compiles the test agents but does not run them |
|
neither compiles nor runs the test agents |
|
runs the tests and reports failures, but does not fail the build |
A test agent that has no applicable plan for one of its test goals reports that test as failed, with the message No applicable plan for test goal.