Acceptance Test Library

Acceptance Test Library (ATL) in F&O isn’t a new feature, but many people aren’t aware of it, therefore let me try to raise awareness a bit.

ATL is used in automated tests written by developers and its purpose is to easily create test data and verify results.

Here is an example of such a test:

// Create the data root node
var data = AtlDataRootNode::construct();
// Get a reference to a well-known warehouse 
var warehouse = data.invent().warehouses().default();
// Create a new item with the "default" setup using the item creator class. Adjust the default warehouse before saving the item.
var item = items.defaultBuilder().setDefaultWarehouse(warehouse).create();
// Add on-hand (information about availability of the item in the warehouse) by using the on-hand adjustment command.
// Create a sales order with one line using the sales order entity
var salesOrder = data.sales().salesOrders().createDefault();
var salesLine = salesOrder.addLine().setItem(item).setQuantity(10).save();
// Reserve 3 units of the item using the reserve() command that is exposed directly on the sales line entity
// Verify inventory transactions that are associated with the sales line using the inventoryTransactions query and specifications

These few lines do a lot of things – create an item and ensure that it has quantity on hand, create a sales order, run quantity reservation and so on. At the end, they ensure that the expect set of inventory transactions has been created, and the test with fail if more or less lines are created or they don’t have the expected field values. Writing code for that without ATL would require a lot of work.

AX/F&O has a framework for unit tests (SysTest) and that’s where you’ll use Acceptance Test Library, you’ll just create acceptance tests rather then unit tests. Unit tests should test just a single code unit, be very fast and so on, which isn’t the case with ATL, but ATL has other benefits. It allows you to test complete processes and it may be used for testing of code that wasn’t written with unit testing in mind (which is basically all X++ code…). The disadvantage is slower execution, more things (unrelated to what you’re testing) that can break, more difficult identification of the cause of a test failure, and so on.

If you’ve never seen SysTest framework, a simple test class may look like this:

public class MyTest extends SysTestCase
    public void demo()
        int calculationResult = 1 + 2;
        this.assertEquals(3, calculationResult);

The ATL adds special assertions methods such as assertExpectedLines(), but you can utilize the usual assertions of SysTest framework (such as assertEquals()) as well.

You write code in classes and then execute in Test Explorer, where you can see the result, you can easily navigate to or start debugging a particular test.

You can learn more about ALT in documentation, but let me share my real-world experience and a few tips.

Development time

These tests surely require time to write, especially if you’re new to it. Usually the first test for a given use case takes a lot of time and adding more tests is much easier, because they’re just variations of the same thing.

It’s not just about what the test does, but you also need to set up the system correctly, which typically isn’t trivial.

As any other code, test code too may contain bugs and debugging will take time.

Isolation and performance

A great feature of SysTest is data isolation. When you run a test, a new partition is created and your tests run there, therefore your tests can’t be broken by wrong existing data (including those from previous tests), nor the tests can destroy any data you use for manual testing.

But it means that there is no data at all (unless you give up this isolation) and you must prepare everything inside your test case. Of course, the Acceptance Test Library is there to help you. On the other hand, it’s easy to forget some important setup.

This creation of the partition and setting up test data takes time, therefore running these tests takes a few minutes. It’s a bit annoying when you have a single test, but the more tests you have, the more time you’re saving.

Number sequences

One of thing you typically need to set up are number sequences. Fortunately, there is a surprisingly easy solution: decorate your test case class with SysTestCaseAutomaticNumberSequences attribute and the system will create number sequences as needed.

Code samples

F&O comes with a model called Acceptance Test Library – Sample Tests, where you’ll find a few tests that you can review and execute. To see how complete test cases may look like is very useful for learning.


Documentation exist: Acceptance test library resources.

You don’t need to read the whole thing to use ATL, but it’s very beneficial if you familiarize yourself with things like Navigation concepts.

You’ll need to go a bit deeper if you decide to create ATL classes for you own entities, or those in the standard application that aren’t covered well by Microsoft. For example, I added ATL classes for trade agreements, because we made significant changes to pricing and utilizing ATL was beneficial.

From another point of view, tests also work as a kind of running documentation. Not only that I document my own code by showing others how it’s supposed to be called and what behaviour we expect, but I sometimes look to ATL to see how Microsoft does certain actions that I need in my real code.

Models and pipelines

You can’t put tests into the same module as your normal code. You’ll need reference to ATL modules (Acceptance Test Library Foundation, at least), which aren’t available in Tier 2+ environments, therefore you will have to configure your build pipeline not to add you test module to deployable packages.

Feeling safe

It’s not specific to tests with ATL, but a great thing of automated tests in general is the level of certainty that my recent changes didn’t break anything. Without automated tests, you either have to spend a lot of time with manual testing (and hope that all tests were executed and interpreted correctly), or you just hope for the best…

Leave a Reply

Your email address will not be published. Required fields are marked *