Sunday, June 28, 2009

Creating Custom Data Generators in Visual Studio 2008

Recently I was working on creating some test data in Visual Studio 2008. I created a Data Generation Plan, and used the Regular Expression Data Generator quite a bit, but found myself wanting more options to create data. VS2008 has that option available: write some custom Data Generators.

I quickly headed down that path, which was pretty straightforward. But when it came time to install my custom data generators into VS2008, I ran into problems. Apparently there are multiple versions of VS2008 out there, some of which expect the DLL and XML files in different places. A question I posted on the MSDN Forums resulted in an answer that proved to be quite helpful.

I was using VS2008 Team Suite, and here's the process I used:

Create a new project
The first step is to create a new VS2008 DLL project. In that project, create your custom data generator, such as this sample custom date generator:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator;

namespace CustomDataGenerators
{
///
/// This class generates random DateTimes in the specified range.
/// User specifies the StartingDays (the number of days to add or subtract to today's
/// date to get the beginning of the range) and the DateRange (number of days past
/// that date in which random DateTimes will be selected).
///
public class DateGenerator : Generator
{
private DateTime _rndDate;
private DateTime _secondDate;
private int _startDays = -30;
private int _dayRange = 60;
private int _daysToSecondDate = 30;
private int _secondDateDayRange = 0;
Random _rnd = null;

private Random RandomObject
{
get
{
if (_rnd == null)
_rnd = new Random(base.Seed);
return _rnd;
}
}

[Input(Name="Starting Days",
Description="Number of days to add (or subtract) from today's date to set the bottom end of the date range",
DefaultValue=-30)]
public int StartingDays
{
set { _startDays = value; }
get { return _startDays; }
}

[Input(Name = "Days in Range",
Description = "Number of days in the date range",
DefaultValue = 60)]
public int DateRange
{
set { _dayRange = value; }
get { return _dayRange; }
}

[Input(Name = "Second Date Days",
Description = "Number of days after the first date for the second date",
DefaultValue = 30)]
public int DaysToSecondDate
{
set { _daysToSecondDate = value; }
get { return _daysToSecondDate; }
}

[Input(Name = "Second Date Random Days",
Description = "Number of days after 'Second Date Days' to create a range in which the Second Date will be randomized. Leave at zero for a set second date.",
DefaultValue = 0)]
public int DayRangeSecondDate
{
set { _secondDateDayRange= value; }
get { return _secondDateDayRange; }
}

[Output(Name="Output", Description="A random date/time string in the specified date range")]
public DateTime Output
{
get { return _rndDate; }
}

[Output(Name="SecondDate", Description="A second date/time string X number of days past the first random output date")]
public DateTime SecondDate
{
get { return _secondDate; }
}

protected override void OnGenerateNextValues()
{
_rndDate = DateTime.Now;
_rndDate = _rndDate.AddDays(_startDays);
int randomHours = RandomObject.Next(0, _dayRange*24);
_rndDate = _rndDate.AddHours(randomHours);
_secondDate = _rndDate.AddDays(_daysToSecondDate);
if (_secondDateDayRange != 0)
{ //randomize the 2nd date
int hrs2 = RandomObject.Next(0, _secondDateDayRange * 24);
_secondDate = _secondDate.AddHours(hrs2);
}
}
}
}
Compile the project to make sure it works.

Write the XML descriptor
Add an XML file to your project, name it DLLNAME.extensions.xml (where DLLNAME is the exact filename of your DLL, without the ".DLL") and structure it as follows:

<extensions assembly="CustomDataGenerators, Version=1.1.0.0, Culture=neutral, PublicKeyToken=95510968c816b5ce" version="1" xmlns="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions Microsoft.VisualStudio.TeamSystem.Data.Extensions.xsd">
<extension type="CustomDataGenerators.DateGenerator" enabled="true">
</extension>

If you create more data generator classes, add a new "" tag for each class.

Copy the DLL and XML file into your VS2008 application directory
Now it's time to copy the DLL and the extensions XML file into the VS2008 application directory so that VS2008 can use them in your data generation plan. In my case, I have CustomDataGenerators.DLL (should be in bin\debug under your project directory) and CustomDataGenerators.Extensions.XML. They go into the following directories (assuming that you installed VS2008 in c:\Program Files):

CustomDataGenerators.Extensions.xml: c:\Program Files\Microsoft Visual Studio 9.0\DBPro
CustomDataGenerators.DLL: c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\Private Assemblies


Restart VS2008 and use your custom data generator
VS2008 needs to be restarted for it to see the custom data generator. If there's a problem with it, you should get an error message. Otherwise, open your data generation plan and you should have your custom data generator(s) available in the drop downs for appropriate fields.

No comments:

Post a Comment