VSMDI...Shmee-SMDI
In our day-to-day development efforts we often find ourselves confronted with an issue screaming to be dealt with by excessive force. Anyone who has spent any time with Microsoft's VSMDI file can empathize. If you have more than one developer on the project, you are guaranteed to run into the dreaded "multiple VSMDI file" issue. It often happens with only one developer, for that matter.
From an application developers perspective, this isn't much of a problem to have to deal with in many circumstances. From an automations perspective, however, it can quickly become a nightmare. In automations, we need to be able to predict the environment we're executing in, or at least be able to establish a certain state that we can rely on. The VSMDI file allows neither of those solutions to work. So what are we to do about it?
Ignore the VSMDI file.
Say what?
You heard me. Ignore the VSMDI file. You don't need it. The only thing you need is the assembly that contains the unit test(s) you are interested in. You're probably thinking "so you expect me to maintain a list of every unit test assembly in the project? Are you out of your mind?" No, and Yes, respectively, but the latter is neither here nor there.
All you need to know is the topmost parent directory of your application (the root of all directories that could possibly contain a unit test directory...without going too far up the directory hierarchy. It does no good to go beyond the scope of your application, so why bother?) Once you have that directory, a simple recursive search will do all you need it to do.
The following C# function will recursively search and find any assemblies that match the search criteria that you specify. In the case of my organization, any assembly that contains unit tests actually contains "UnitTest" or "UnitTests" in the file name, so that makes my search much easier. I also exclude any "obj" directories, or any directories that happen to be named for the service account that runs our automation (any directory with the name of the service account was most likely generated by previous test runs, and will contain assemblies you don't want to re-run). [Sorry about the spacing...still trying to figure out how to best post formatted code on LiveJournal.]
private void LocateAndExecuteUnitTests(string RootDirectory)
{
String[] FileSystemEntries;
FileSystemEntries = Directory.GetFileSystemEntries(RootDirec
foreach (string Entry in FileSystemEntries)
{
if (Directory.Exists(Entry))
{
// Directory found. Need to recurse (if not the \obj directory).
if ( (!(Entry.Contains(Path.DirectorySeparato
{
LocateAndExecuteUnitTests(Entry);
}
}
else
{
// Restrict execution to only those assemblies that contain "UnitTests" or "UnitTest" in the file name.
if ( (Entry.ToUpper().Contains(".UNITTEST.DLL"
{
ExecuteAssemblyWithMSTest(Entry);
}
}
}
}
Once I've located a valid assembly file, I pass it to ExecuteAssemblyWithMSTest like this:
private void ExecuteAssemblyWithMSTest(string PathToAssembly)
{
StringBuilder sb = new StringBuilder(string.Empty);
sb.Append(" /testcontainer:" + PathToAssembly);
sb.Append(" /publish:" + StringConstants.TFS_SERVER_NAME);
sb.Append(" /publishbuild:" + LatestNamedCIBuild);
sb.Append(" /flavor:" + "\"" + StringConstants.OA_BUILD_FLAVOR_CI + "\"");
sb.Append(" /platform:" + "\"" + StringConstants.OA_BUILD_PLATFORM_CI + "\"");
sb.Append(" /teamproject:" + "\"" + StringConstants.TFS_CI_TEAM_PROJECT + "\"");
try
{
Process proc = new Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.WorkingDirectory = StringConstants.OA_PATH_ROOT_DIRECTORY;
proc.StartInfo.FileName = StringConstants.MSTEST_PROCESS_NAME;
proc.StartInfo.Arguments = sb.ToString();
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
}
catch (Exception ex)
{
logger.LogException(ex, true);
throw ex;
}
}
The above function builds a process object and then executes that process. MSTest is invoked (via the process object), and ultimately publishes the test results back to our TFS server.
Voila! No more VSMDI files!




