Back to Blog

Microsoft Dynamics 365 for Finance and Operations type provider tests – Part 2: Writing a test

Post by |

This is the second in a series of posts about creating and using type provider tests within Microsoft Dynamics 365 for Finance and Operations (D365FO), which is the underlying technology of LexisOne. They provide an improved method of building tests that simulate the behaviour of a user in the system. They allow developers to write tests that can access form controls using the IntelliSense features in Visual Studio, without the need for additional generate and compile time. Making the tests easier and quicker to write and maintain compared to the form adaptor tests that they are replacing.

In the first blog post we talked through the steps to set up a model and project required to create a type provider test. This post will explain how to write a type provider test using this setup. In this example you are going to test the creation of a project and you will start by opening the Visual Studio project you created previously.

The steps we will follow are:

  • Navigate to the All projects page
  • Click the +New button

New Project

  • Enter the following details in the New project form
    • NameTP Coded Project
    • Project GroupTM_WIP
    • Project Contract - 00000002
  • Click the Create project button

Create Project

  • Test has completed successfully

Let’s switch now to your test project in Visual Studio, and create a new class in the project called CreateProjectTPTests. This class should extend SysTestCase as it will run as part of the D365FO unit test framework. The class will contain your type provider test code.

If you want the test class to run in a specific company, you need to add an additional attribute to the class called SysTestCaseDataDependencyAttribute and specify the company within which the test should run: the code below specifies the company GBSI.

[SysTestCaseDataDependencyAttribute("GBSI"), SysCodeGenAttribute()]
class CreateProjectTPTest extends SysTestCase
{
}

The first step of the test is to open the ProjProjectsListPage form. This is the form name of the All projects form. To find the form name of the page you would like to test, you can right click the form in the browser and the Form information menu will be displayed. If you hover the mouse over the Form information caption, the current form name will be displayed.

First Step

To access the controls on the ProjProjectsListPage form in your test, you need to declare a type provider for the form as a using statement at the top of our test class. The syntax for this is:

using FormNameAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(FormName)];

In this example the using statement for the ProjProjectsListPage would be added as below:

using ProjectListFormAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjProjectsListPage)];

[SysTestCaseDataDependencyAttribute("GBSI"), SysCodeGenAttribute()]
class CreateProjectTPTest extends SysTestCase
{
}

TIP: It’s a good idea to build your project regularly to make sure everything is working as you progress through the process. Build your project to make sure everything compiles , and verify that your setup is correct at an early stage. If the project builds successfully, you can now add a unit test method to contain your test code.

This is achieved by adding a method which has the SysTestMethodAttribute. You should also give the test a descriptive name, as this name will be displayed in the test explorer when you start to run your tests.

TIP: If you adopt a consistent naming convention for the tests it is much easier to locate them in the test explorer. For this type provider test, we recommend using the naming convention:

FormName_Action_Outcome

So in this case it will be:

ProjProjectsListPage_CreateProject_Success

Let's looks at how that looks in the test explorer...

Form Name

using ProjectListFormAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjProjectsListPage)];

[SysTestCaseDataDependencyAttribute("GBSI"), SysCodeGenAttribute()]
class CreateProjectTPTest extends SysTestCase
{
[SysTestMethodAttribute]
public void ProjProjectsListPage_CreateProject_Success()
{
}
}

Now you have created your test class and test method, you can now write the test code. The ProjectListFormAdaptor variable can be used to access the controls of the ProjProjectListPage. First the test needs to open the ProjProjectListPage: to do this you can call the Open method on the type provider in a using statement.

using ProjectListFormAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjProjectsListPage)];

[SysTestCaseDataDependencyAttribute("GBSI"), SysCodeGenAttribute()]
class CreateProjectTPTest extends SysTestCase
{
[SysTestMethodAttribute]
public void ProjProjectsListPage_CreateProject_Success()
{
using (ProjectListFormAdaptor projectListPage = ProjectListFormAdaptor::open())
{
}
}
}

When you run the test the form will be opened, then you will click the new project button to open the create project form. To do this, you will need to switch to the form in the browser to find the new project control name. Right click the +New project button and hover over the Form information option. Below the form name will be the button’s name: the screenshot below shows it is ProjectNewButton.

Project Button

You can use this information and the projectListPage variable’s IntelliSense to find the ProjectNewButton. Add the code below within the using statement of your test code: the parentheses show that the button is being retrieved as an accessor from the form variable.

projectListPage.ProjectNewButton()

Having retrieved the button, you can then bring up the IntelliSense to find the click method to trigger the event as shown in the full line of code below.

projectListPage.ProjectNewButton().click();

When the test runs, the Create project form will now be opened. In the test code, you need to attach to the form that is opened. First, you have to declare a new type provider using statement at the top of the class for the Create project form. This form is called ProjTableCreate. Again, you could find the name of the form by right clicking on the form in the browser and viewing the form information.

using ProjTableCreateAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjTableCreate)];

Once you have added the using statement for the ProjTableCreate, the ProjTableCreateAdaptor variable will provide you with access to the attach method, which again you call in a using statement.

using (ProjTableCreateAdaptor projTableCreate = ProjTableCreateAdaptor::attach()){}

Within this using statement, you can now use the projTableCreate variable to access the controls on the ProjTableCreate form. Again, to find the control name you can right click the field in the browser and get the form information. This time, instead of click, you use the method setValue() to set the field content. Below are the fields you need to set:

//Set the Project name
projTableCreate.Name().setValue("TP Coded Project");
//Set the Project group
projTableCreate.ProjTable_ProjGroupId().setValue("TM_WIP");
//Set the Project contract ID
projTableCreate.ProjInvoiceId().setValue("00000002");

Now you have set the fields, you need to click the Create project button. Again, you can find the button name by right clicking and selecting Form information in the browser. The button is called OKCommandButton, so you can call the click method on this.

projTableCreate.OKCommandButton().click();

Once you have clicked this button, the create project form is closed and you are taken to the project you have just created. So to end the test you should close the project form to return to the All projects page.

Again, you need to declare the Project form as a type provider using statement as you have done with the other forms. We can find the Project form name by right clicking and viewing the form information in the browser. The form is called ProjTable, so the type provider using statement required is:

using ProjTableAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjTable)];

Adding this using statement then gives you access to the controls on the form. Like the ProjTableCreate though, you first have to attach to the opened project form. Then you are able to call the close method on the form.

using(ProjTableAdaptor projTable = ProjTableAdaptor::attach())
{
projTable.close();
}

Now you have created your test, you can build and run the test from the unit test explorer in Visual Studio.

This example hopefully illustrates how quick and easy it is to start building type provider tests in D365FO. These tests provide a layer on top of the unit tested code to ensure they integrate and function correctly when called from forms.

To wrap up what you have done, review the full code for the test.

using ProjectListFormAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjProjectsListPage)];

using ProjTableCreateAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjTableCreate)];

using ProjTableAdaptor = Microsoft.Dynamics.AX.TypeProviders.FormAdaptors.FormAdaptorTypeProvider@[formStr(ProjTable)];

[SysTestCaseDataDependencyAttribute("GBSI"), SysCodeGenAttribute()]
class CreateProjectTPTest extends SysTestCase
{
[SysTestMethodAttribute]
public void ProjProjectsListPage_CreateProject_Success()
{
using (ProjectListFormAdaptor projectListPage = ProjectListFormAdaptor::open())
{
projectListPage.ProjectNewButton().click();
using (ProjTableCreateAdaptor projTableCreate = ProjTableCreateAdaptor::attach())
{
//Set the Project name
projTableCreate.Name().setValue("TP Coded Project");
//Set the Project group
projTableCreate.ProjTable_ProjGroupId().setValue("TM_WIP");
//Set the Project contract ID
projTableCreate.ProjInvoiceId().setValue("00000002");
projTableCreate.OKCommandButton().click();
using(ProjTableAdaptor projTable = ProjTableAdaptor::attach())
{
projTable.close();
}
}
}
}
}

In the next blog, we will look at how you can create type provider tests that can be run using different security role contexts.

About the Author:


Chris Lowe is a Technical Architect for LexisNexis working on the Dynamics 365 for Finance and Operations version of the LexisOne ERP solution. He is based at the LexisNexis office in Leeds, UK, where he has been working on Dynamics 365 for Finance and Operations for approximately the last 2 years. Prior to this he was working on the Dynamics AX 2012 version of LexisOne. Before his move to Dynamics AX related technologies he worked on .Net browser based applications in both the legal and banking industries. He has 20 years’ experience working in IT software development.

| See all our contributors
Back to Blog