Blog Listem

26 Haziran 2022 Pazar

365 F&O - ATL (Acceptance Test Library) ile test

 

 365 F&O ATL geliştirmelerimizi yüklemeden önce otomatik test edip geliştirmemizin başka bir geliştirmeden etkilenip etkilenmediğini veya başka bir geliştirmenin bizim geliştirmemizi etkileyip etkilemediğini anlamamızı sağlar. Örnek demo dataya ihtiyaç duymaz, kendi kayıtlarını kendi oluşturur. Test tamamlandıktan sonra da SQL server seviyesinde tüm işlemleri geri alır. Böylece kirli data problemi yaşamayız ve tekrar tekrar test edebiliriz.

ATL kütüphanesi içinde extend ederek kullanıma hazır çok fazla sınıf vardır.

Basit bir örnekle başlayalım:

[SysTestCaseAutomaticNumberSequences, SysTestTargetAttribute(tableStr(TmpPurchLine), UtilElementType::Table), SysTestGranularityAttribute(SysTestGranularity::Unit)]
class TmpPurchLineTest extends SysTestCase
{

...

 [SysTestMethod]
    public void validateDLvModeAndDlvTermInitiatedPurchLine()
    {
        const VendDlvModeId DlvModeId = 'Air';
        const VendDlvTermId DlvTermId = 'DAP';

        //Arrange
        PurchLine       purchLine;
        TmpPurchLine    tmpPurchLine;

        tmpPurchLine.DlvMode = DlvModeId;
        TmpPurchLine.DlvTerm = DlvTermId;

        //Act
        purchLine.initFromTmpPurchLine(tmpPurchLine);

        //Assert
        this.assertEquals(PurchLine.DlvMode , DlvModeId);
        this.assertEquals(PurchLine.DlvTerm , DlvTermId);

    }

 

PurchLine fieldlarını TmpPurchLine ile doldurmak için PurchLine.initFromTmpPurchLine methodunu kullandık. Son iki kırmızı satır bunu doğrulamak için.


[SysTestGranularity(SysTestGranularity::Component)]
[SysTestCaseDataDependency('USMF')] //Selects USMF company
[SysTestCaseUseSingleInstance] //run every method in class in a single instance, slower but necessary in some cases, if you don't need, don't use
[SysTestCheckinTest]
public final class PurchPurchaseOrderLineV2EntityTest extends DataEntityTestCase
{

...

    [SysTestMethod]
    public void validateDlvTermAndModeInsertedCorrectyFromEntityToPurchLine()
    {
        // Arrange
        PurchPurchaseOrderLineV2Entity entity;

        ttsbegin;
        AtlEntityPurchaseOrder purchaseOrder = data.purch().purchaseOrders().initDefault()
            .setVendor(data.vend().vendors().default())
            .setInventSiteId(data.invent().sites().default().SiteId)
            .save();

        VendDlvModeId dlvMode = data.sales().modesOfDelivery().findOrCreate('Seafreight').parmModeOfDelivery();
        VendDlvTermId dlvTerm = data.purch().deliveryTerms().findOrCreate('DAP').parmDeliveryTerms();

        ItemId itemId = item.ItemId;
        entity.PurchaseOrderNumber = purchaseOrder.parmPurchId();
        entity.ItemNumber = itemId;
        entity.DlvMode = dlvMode;
        entity.DlvTerm = dlvTerm;
        entity.LineNumber = 1;
        
        // Act
        this.insertEntity(entity);

        // Assert
        purchaseOrder.lines()
           .assertExpected(data.purch().purchaseOrderLines().spec().withDlvMode(DlvMode).withDlvTerm(DlvTerm));
        ttsabort;

Bu örnekte dataya sahip olmak için ATL entity kullandık. ATL spec. ile de datanın beklediğimiz gibi olup olmadığını kontrol ediyoruz. 

Eğer test ettiğimiz field Spec, query veya entity sınıfları içinde yoksa sihirbazla kolayca ekleyebiliriz:


ATL istersek test amaçlı kendi şirketimizi bile oluşturmamıza izin verir (Yavaş çalışan bir yöntem olduğu için mecbur kalmadıkça kullanılması tavsiye edilmez):

private void setupDistributorCompany()

    {

     const LegalEntityDataAreaId distributor = 'MTN';

        SysUnitTestData_IntercompanyPlanning::insertCompany(distributor);

 

        changecompany (distributor)

        {

            warehouseInDistr = invent.warehouses().default();

            suppAsVendorInDistr = vendors.createDefault().addRelationToInterCompanyCustomer(distrAsCustomerInSupp);

            normalCustInDist = data.cust().customers().customer002();

        }

    }

 

 

İstersek form kontrolleri de çalıştırabiliriz:

 

using SalesTableFormAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(SalesTable)];
...
public final class PurchLineDlvTermAndModeTest extends AtlPurchaseTestCase
{

...

            using (SalesTableFormAdaptor salesTableForm = SalesTableFormAdaptor::open(salesTable))
            {
                salesTableForm.SalesOrder().activate();
                salesTableForm.buttonCreateDropShipment().click();
                using (PurchCreateFromSalesOrderFormAdaptor purchCreateFromSalesOrder = PurchCreateFromSalesOrderFormAdaptor::attach())
                {
                    purchCreateFromSalesOrder.Grid().moveFirst();
                    purchCreateFromSalesOrder.ChkIncluded().setValue(true);
                    purchCreateFromSalesOrder.SpecifyVendAccount().setValue(vend.vendors().createDefault().record().AccountNum);
                    purchCreateFromSalesOrder.CommandButtonOK().click();
                }
            } 

Satış siparişi oluşturabiliriz:

AtlEntitySalesOrder salesOrder = data.sales().salesOrders()
                .createDefault()
                .setCustomer(normalCustInDist)
                .setWarehouse(invent.warehouses().warehouse10())
                .save();

Burada spec ile birden fazla field kontrol ediyoruz:

purchaseOrder.lines().withQuantity(OrderedQty1).assertExpected(purchaseOrderLines.spec().withDlvTerm(dlvTerm_DAP));

Birden fazla satır kontrol ediyoruz:

AtlEntitySalesOrder salesOrder = AtlEntitySalesOrder::find(purchaseOrder.parmInterCompanySalesId());
            //Assert
            salesOrder.lines().assertExpectedLines(
                    salesOrderLines.spec()
                    .withQuantity(OrderedQty1)
                    .withModeOfDelivery(dlvMode_Seafreight)
                    .withDeliveryTerms(dlvTerm_FOB),
                    salesOrderLines.spec()
                    .withQuantity(OrderedQty2)
                    .withModeOfDelivery(dlvMode_Air)
                    .withDeliveryTerms(dlvTerm_DA));

InterCompanyTradingValueMap, IntercompanyAgreementActionPolicy, InterCompanyEndpointActionPolicy,  ... sınıflarıyla intercompany kuralları için kurulum bile yapabilirsiniz.


VS içinden test edebilirsiniz (açık sınıflarınız veya proje içindeki sınıflar test ekranına otomatik gelir):

 

 


 

 

AOT içinde bu konuda bol bol örnek dışında Michael Cobbin tarafından yayınlanmış güzel bir video da var.