Friday, May 8, 2009

Debugging business logic in AX 2009 SSRS reports


With AX2009 you are now able to do SSRS reports in Visual Studio. The typical process for designing a report consist in creating a query and bind to it, code some business logic (BL) specific to the report and design the visual part.
This post will focus on debugging the report business logic. For more information on designing reports in general, see the msdn documentation
You can have an idea on it from excellent post on Channel 9 here.


Let say you've designed a fancy report in VS and in order to make it do cool stuff, you had to write some pretty complex business logic. Unfortunately, your business logic does not do what you think it should be doing. You know that you've been working too late on too much caffeine, so you suspect that there might be a bug there and you need to do some debugging.

The 'attach-to-the-server-process' approach

One approach to debug your business logic consist of the following steps
· Rebuild the report in VS in debug mode
· Save it back to the AOD
· Redeploy the report
· Set a breakpoint at a strategic location in your business logic code
· Attach to the server process
· Invoke your report
· Hit the breakpoint and start debugging
While being perfectly valid, this approach has a rather long turn-around-time, especially considering the fact that during a debugging session, you will most likely need to ride the modify-code-rebuild-test carrousel several times.
Also you are an agile programmer and you know about the values ofTest Driven Development (TDD), so you are thinking: 'Damn, I wish I had developed this report using the good TDD methods and wrote some unit test for my business logic'. Well, don't despair, Visual Studio (professional edition and above) comes with several cool features that can help you do TDD and debugging on your reports. Let's see how.

Creating unit test for SSRS based reports business logic

Let's assume that you have created your report solution with its related report project
For the sake of simplicity, let's pretend that you have written the following dull BL method

public static DataTable MyMethod() {          DataTable result = new DataTable();          result.Columns.Add("Col1");          result.Columns.Add("Col2");         result.Columns.Add("Col3");          result.Columns.Add("Col4"); 
        return result; }
Now we are going to create a unit test for this method. But before doing so, we need to help Visual Studio a bit to resolve certain assemblies. In the business logic project, go the reference node, select theMicrosoft.Dynamics.Framework.Reports assembly and set the property 'Copy Local' to 'True'.
Then, right-click in the editor and choose 'Create unit test...'. Browse to the folder where the business logic assembly is built (for example <...>\DynamicsReportsLibrary1\DynamicsReportsLibrary1\BusinessLogic\bin\debug\)
and select the DynamicsReportsLibrary1.BusinessLogic.dll assembly. Unfold the tree node and select the method you want to debug as shown below:
You'll notice that Visual Studio will create test project for you if you don't have one. Alternatively, you can create one by right clicking on the solution and choosing 'Add project' and then select the test project template:
Then you can target this project when creating a unit test.
Visual Studio has generated the following unit test method :

Sample code:
[TestMethod()] public void MyMethodTest()
  DataTable expected = null// TODO: Initialize to an appropriate value
DataTable actual;       
actual = Report1.MyMethod();
  Assert.AreEqual(expected, actual);       
  Assert.Inconclusive("Verify the correctness of this test method."); 
In our example, as we use the DataTable type, we'll also need to add references to System.Data and System.xml in order to get your test project to build. Once you've done that, you should be able to build your solution and run the test. You can either do this from the test toolbar:
or from the test view, where you can select each unit test individually.
Now you can start rewriting the auto-generated test and do some real testing. For the sake of simplicity, I'll write a simple test, which checks that the created data table actually has 4 columns.

Sample code:
public void MyMethodTest() 
  DataTable dataTable = Report1.MyMethod();       
  Assert.AreEqual(dataTable.Columns.Count, 4, "The data table must have 4 colums"); 

Running this test provides the following output:

What about Debugging?

That's what we initially wanted to achieve, wasn't it?. Well, that's just a few clicks away. Put a breakpoint at the beginning of your BL method and from the test view window, right-click on the test method and select 'Debug Selection'.
Next thing you know, you are hitting your breakpoint and you can start, debugging your business logic:

Code coverage

As a freebie, you can get Visual Studio to calculate the code coverage for you. Simply edit the test configuration (Tools -> Edit Test Run Configuration -> Local Test Run) to enable the code coverage instrumentation on your BL assembly
Then re-run the test, and click on the 'Show Code Coverage Results'icon in the toolbar of the Test Results window, which will give you the nice view below for free:


The technique described above shows how to debug business logic for SSRS based AX 2009 reports with a quick turn-around time, following the Test Driven Development methodology and providing code coverage measurement on the side. Beware that there might be some scenarios where attaching to the server process is the only way to track a specific bug. Some bugs might only show there ugly faces when the report in running in its deployment context on the server. But if you follow the good principles of TDD and use this local debugging approach, you might not need to go to these extends and you'll likely catch most of the errors at an early stage. Happy debugging :-).

No comments:

Post a Comment

I will appreciate your comments !

Download large bacpac (sandbox database) to DEV environment much faster

As the LCS website gets slower and slower and the database backups get bigger and bigger.  Use AZCopy to download objects out of LCS asset l...