Unit Testing X++ code in Visual Studio (AX 2012) [EN]

I’m pretty sure everybody who has tried will agree with me that the Unit Testing framework included in the AX 2012 development environment (aka MorphX) has some limitations. Sometimes such limits become so impacting that makes the framework almost useless when the code you need to test starts growing (let’s discuss design problems in a separate post :)).

But I’m not going to talk here about limitations, but about what we actually can do, and one of such things is to use X++ proxy classes to write our unit tests in Visual Studio, and use the native testing framework included here with all its possibilities. Let’s see how it works with an easy example.

I wrote this simple X++ class in order to have something to test:

/// <summary>
/// Dummy fluid class for testing purposes
/// </summary>
class DEVDummyTestCalcClass
{
    real value;
}
public void new(real _value)
{
    value = _value;
}
public real Value()
{
    return value;
}
public DEVDummyTestCalcClass Add(real _value)
{
    return new DEVDummyTestCalcClass(value + _value);
}
public DEVDummyTestCalcClass Substract(real _value)
{
    return new DEVDummyTestCalcClass(value - _value);
}
public DEVDummyTestCalcClass Multiply(real _value)
{
    return new DEVDummyTestCalcClass(value * _value);
}
public DEVDummyTestCalcClass Divide(real _value)
{
    return new DEVDummyTestCalcClass(value / _value);
}

First of all, go to the Visual Studio 2010 instance we all have in our AX 2012 development environments and create a new Test Project. (I’ve chosen C# but it should work in Visual Basic if that’s your preferred choice):

AX 2012 X++ Unit Test

Add this new project to AOT. By doing so, Visual Studio will add the Interop assembly to the project, allowing us to run our X++ code from this CIL project, automatically creating all needed proxy classes:

AX 2012 X++ Unit Test

Show the Application Explorer panel so we can see AOT objects from the Visual Studio editor:

AX 2012 X++ Unit Test

Choose the class (or classes) you want to test and add them to the project. This will automatically create all required proxy classes:

AX 2012 X++ Unit Test

Now remove the TestMethod1 method in the default class or create your own test classes at your convenience. For instance, for testing the X++ simple class shown above, we can write some test methods like these ones:

[TestMethod]
public void TestConstruct()
{
    using (Session axSession = new Session())
    {
        axSession.Logon(null, null, null, null);

        Assert.AreEqual(0, new DEVDummyTestCalcClass(0).Value());
        Assert.AreEqual(-1, new DEVDummyTestCalcClass(-1).Value());
    }
}

[TestMethod]
public void TestSum()
{
    using (Session axSession = new Session())
    {
        axSession.Logon(null, null, null, null);

        Assert.AreEqual(10, new DEVDummyTestCalcClass(0).Add(10).Value());
        Assert.AreEqual(10, new DEVDummyTestCalcClass(0).Add(5).Add(5).Value());
    }
}

[TestMethod]
public void TestDivide()
{
    using (Session axSession = new Session())
    {
        axSession.Logon(null, null, null, null);

        Assert.AreEqual(10, new DEVDummyTestCalcClass(20).Divide(2).Value());
    }
}

[TestMethod]
[ExpectedException(typeof(Microsoft.Dynamics.AX.ManagedInterop.NumericException))]
public void TestDivideByZeroException()
{
    using (Session axSession = new Session())
    {
        axSession.Logon(null, null, null, null);

        new DEVDummyTestCalcClass(100).Divide(0).Value(); // Exception
    }
}

Finally, we can run our test cases as a regular Visual Studio test project, to be sure our X++ class works as expected:

00500-ax2012-xpp-unittests

How cool is that? Isn’t it easy?

If this is an interesting topic I’ll publish more about it, including more complicated and close-to-real scenarios. In the meantime, please feel free to comment or get in touch via twitter! 🙂