Best practices for the Acceptance test library

Use var and declare variables inline

  • Use the var keyword (type inference).
  • Declare variables inline instead of in a separate statement.

Do this

var item = items.default(); 
var salesOrder = data.sales().salesOrders().createDefault();
var salesLine = salesOrder.addLine().setItem(item).setInventDims([warehouse]).setQuantity(10).save();

Don't do this

InventTable item; 
AtlEntitySalesOrder salesOrder;
AtlEntitySaleOrderLine salesLine;
…
item = items.default(); 
salesOrder = data.sales().salesOrders().createDefault();
salesLine = salesOrder.addLine().setItem(item).setInventDims([warehouse]).setQuantity(10).save();

Justification

The advantages of using var are that you write less code, you don't have to remember exact type names, and the test logic isn't cluttered with unimportant information. Overall, the test code easier to read.

In the previous example, it doesn't matter whether item is of the ItemId, InventlTable, or AtlEntityInventItem type. The important detail is that you're creating a sales line that has a well-known default item. The exact types of the salesOrder and salesLine variables aren't important. The contracts of these types are clear from the naming and usage.

Considerations

  • Don't use type inference if you want compilation to fail if the return type of a method changes.
  • Don't use type inference if you can't invent meaningful variable or method names.

Use entities instead of IDs as method parameters

Well-known data methods, creator methods, and init methods usually return records or entities instead of IDs. We recommend that you use records or entities as method parameters.

Do this

var salesLine = salesOrder.addLine().setItem(item).save();

Don't do this

var salesLine = salesOrder.addLine().setItemId(item.ItemId).save();

Justification

The code is easier to read, because it isn't cluttered with unimportant technicalities.

Considerations

If you know only the ID, use the method that takes the ID as an argument.

Use navigation node shortcuts

When you automate a new domain area, introduce a base class that holds shortcuts to the most frequently used navigation objects in that area.

For example, for the warehouse management area, there is a base class that is named AtlWHSTestCase. It contains shortcuts to data.whs(), data.invent(), data.invent().items(), data.invent().units(), and other navigation objects. The shortcuts simplify your test code.

class AtlWHSTestCase extends SysTestCase
{
    AtlDataRootNote          data;
    AtlDataInvent            invent;
    AtlDataInventOnHand      onHand;
    AtlDataProductItems      items;
    AtlDataWHS               whs;

    protected void initDataSetupReferences()
    {
        data = new AtlDataRootNode();
        invent = data.invent();
        onHand = data.invent().onHand();
        items = data.invent().items();
        whs = data.whs();

It also makes sense to introduce shortcuts that are shared among many test methods in the same class.

Do this

class WHSMinMaxReplenishmentScenarioTest extends AtlWHSTestCase
…
    var item = items.default(); 
    var warehouse = invent.warehouses().default(); 

Don't do this

class WHSMinMaxReplenishmentScenarioTest extends SysTestCase
…
    var item = data.invent().items().default(); 
    var warehouse = data.invent().warehouses().default(); 

Considerations

You don't have to create a shortcut for every navigation node that you need. However, consider creating them for the navigation nodes that are frequently used.