Utilizing your .NET Project's Automated Acceptance Tests on Crystal Reports - Part 1
Published: 19 May 2008
In this first part of the series, Eric shows how to use automated acceptance testing against Crystal Reports using the object model. After providing the requirements, he examines how to utilize automated acceptance tests with reports along with sample code to validate the report. He concludes the article by providing a structure of the report settings.
by Eric Landes
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 25522/ 71


As agile development methods become more accepted in the development world, I have wondered the best way to incorporate agile methods on the reporting side of projects.  Face it, reporting is often the forgotten step-child of most projects. 

Agile has many practices, including Stories, Planning Poker, daily standups, team rooms, continuous integration and more. How and can we incorporate reports in these practices? 

Some of these questions have easy answers. For instance, we can turn a request for a report into a story. And most teams worth their salt can score those stories in their Planning Poker sessions.  We can discuss the reports in our daily standups, and ask for help on these reports in our team rooms.

The practice that is vital to most of the projects I have worked on is Automated Customer Acceptance tests. Automated Customer Acceptance Tests constitute our customer requirements document. The customers create or are highly engaged in creating these tests. They also get to see the tests turn green or red when the backend code is executed against the tests. If the tests are not green, the customers and developers know something is wrong. Combine this with live demos every week of the software using these methods, and the customers develop faith and trust in the development process.

These acceptance tests represent executable requirements. Executable requirements make for a highly maintainable software project. Your continuous integration constantly runs all of your automated tests when team members check in source and this verifies that the new changes have not broken the software. In this series of articles, we will investigate how to include your automated acceptance tests against Crystal Reports.

System Requirements

·         Crystal Reports.NET

·         Fitnesse

·         Visual Studio 2008

Utilizing Automated Acceptance Tests with Reports

Now that we have established the purpose of these articles, let us discuss the theory behind Automated tests, and specifically what this article expects of these tests. Then we will look at how we create our Automated Acceptance testing. These theories are attributed to many folks, but Robert Martin, is the specific inspiration for me. Ron Jeffries has also had an impact.

We assume that you have your customer's co locate with the team when writing these tests for each story. These tests are not the only testing used for acceptance of the software, but they provide a reliable method for defining customer specifications that can be executed against your code. We should also release software into the wild, allowing the customers to run the latest version of the software. The customer runs that software after you complete the latest iteration.  Do not expect to discard manual testing if you are new to this concept. But having these tests should make your manual testing less painful.

This article uses the fitnesse testing framework to create our tests. We use fitnesse to allow business customers to define their requirements in an Excel like manner. 

Fitnesse is a front end to the Fit testing framework.  Based on the idea that many acceptance tests can be defined in an Excel style format, Fitnesse allows end users to quickly write up tests.  Once those tests are created, developers can quickly hook up their business objects to these tests, and run the tests. Running Fitnesse tests give the standard green red results.

So as an example, you might define your business logic to calculate taxes. To write the test, a grid is created that gives the cost of the product, the location sales tax, and the expected result.  It might look something like this:













In the table, the user defines what values go into cost, the value in tax, and then the total they expect from this. The developer then needs to hook their business logic up to place the value of cost, into their object cost, and the tax percentage into their objects tax. Finally, the developer runs the business logic to calculate the Total, and check if it equals the expected total entered in the test.

Writing our first test to validate the Report

The first story we write defines this report.

Any user of the system can run a report to view the changeset history of any project. This report is grouped by Visual Studio project and shows the files changed and dates.

In our current iteration, the customer selects this story, so they now need to define a test. We did not want them to select the story, but we are agile, and we have agreed that the customers select the priority of the stories. Since our rule also insists on an executeable test for each story, our customer must create a fitnesse test for this report. 

Our customer begins defining this story in a table to conform to the fitnesse format. The first test confirms the existence of fields. The next article in this series will show how to test against values in the report. 

The customer decides that in their test they want the following fields: changeset, project name, and the override comments fields. It is a bit cheeky of them, but it is their story and their requirements. So the customers create a table similar to what is above, except they need to have a true or false returned saying the field is there or it is not.  So for their first test, they come up with this:

Fields In Report



Field name

data type















This simple table tests for the existence or non-existence of fields on a report. The customer does not know how we hook this into the actual code and quite honestly you may not know how to hook this into actual code. That last part is a bit tongue in cheek, but keep in mind that this article is not a primer for fitnesse. To learn fitnesse fixtures, etc., go to the fitnesse web site, there are good tutorials there. This article does go over some of the fixtures, but we expect familiarity with the fitnesse software, or at least a willingness to become familiar with it.

The first column and row in this table defines our fitnesse method name, FieldsInReport. Since our fitnesse test code uses a columnfixture, the next row defines each column name (fieldname, datatype, and ok()).  The third row shows that the customer expects the field name Changeset to be on the report, and the data type is Text. That test should return a true is what the ok() field means. The next row is similar, and expects the report to have a field named ProjectName that is Text data type. The last row tests for a false outcome by looking for a field that they do not want on the report. Let us look at the code needed to run this report.

Fitnesse Code

Below is a snapshot of the fitnesse code used to validate your report.

Listing 1

public class fieldsinreport: ColumnFixture
  public string fieldname;
  public string datatype;
  public Boolean ok()
    CrystalReport1 report = new CrystalReport1();
    foreach (CrystalDecisions.CrystalReports.Engine.ReportObject currentObject
      in report.ReportDefinition.ReportObjects)
      if (currentObject.Name == fieldname)
        return true;
    return false;

The code in listing 1 assumes that you have a report called CrystalReport1 in an assembly somewhere. In our solution we have placed the report in the namespace Eric.Landes.Sample.AutomateCRTest.TestingCR. 

Notice that our fixture simply runs tests. The fixture is a wrapper that runs basic functions needed to determine if your code can pass the tests. For our report, iterate through the objects in CrystalReport1 to determine if the current objects fieldname equals the fieldname in the report.  Let us look at the actual report to see what that means for the Crystal Reporting side of things.

Report Settings

Our Crystal report is set up in a grouping format, with the ChangeSet field in the detail section of the report. See Figure 1 for an example of how that looks.

Figure 1

This report also has the Project name in the grouping header section. The comments are in the details section. Because our first test simply tests the naming of the report objects, this first report test is simple. We will go over testing for the type and then value in the next part of this series.

I will be honest; this is not a pretty report. I can say that because it is mine! The point is, our fitness code should work on any report, fancy or not. The intention of this article is to get you started understanding the ability you have to run executable requirements against your Crystal Reports.


That concludes the first part of our series on using Automated Acceptance Tests on Crystal Reports. We have gone over why Automated Acceptance tests are critical to our project (they are the customers' executable requirements). That critical fact, and just the coolness factor of executing requirements, makes this a must have for all elements of our projects, including Crystal Reports.

In our next part of the series, we take you into testing for actual values and data types. Until then, Happy Coding!

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 

Community Advice: ASP | SQL | XML | Regular Expressions | Windows

©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-04-16 10:49:44 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search