Friday, October 26, 2012

VS 2010 – Generating a TRX file for a list of Tests


I came across a situation where I needed to generate a TRX file dynamically for a set of tests. This TRX would then to be used to rerun the set of tests.

To create a utility for this, I needed 3 pre-requisites:

·         List of test names

·         A TRX file template with one test

·         VSMDI file which has the test case details

The TRX template looks like this:

<?xml version="1.0" encoding="UTF-8"?>

<TestRun id="75ef9a27-b8ce-4c81-a2bb-fb3e26088e32" name="xxx" runUser="xxx" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">

          <TestSettings name="Local" id="3402c4f6-3b10-4472-9f2c-14a883c33075">

                   <Description>These are default test settings for a local test run.</Description>

                   <Deployment enabled="false" runDeploymentRoot="anujc_ANUJDEV1 2012-10-09 17_43_06">

                   </Deployment>

                   <Execution hostProcessPlatform="MSIL">

                             <TestTypeSpecific>

                                      <UnitTestRunConfig testTypeId="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b">

                                                <AssemblyResolution applicationBaseDirectory="xxx ">

                                                          <TestDirectory useLoadContext="true" />

                                                          <RuntimeResolution>

                                                                   <Directory path=" xxx " includeSubDirectories="true" />

                                                          </RuntimeResolution>

                                                </AssemblyResolution>

                                      </UnitTestRunConfig>

                             </TestTypeSpecific>

                             <AgentRule name="LocalMachineDefaultRole">

                             </AgentRule>

                   </Execution>

          </TestSettings>

          <Times creation="2012-10-09T17:43:06.8818053-07:00" queuing="2012-10-09T17:43:08.3979569-07:00" start="2012-10-09T17:43:08.5789750-07:00" finish="2012-10-09T18:01:43.5194579-07:00" />

          <ResultSummary outcome="Failed">

                   <Counters total="1" executed="1" passed="0" error="0" failed="0" timeout="0" aborted="0" inconclusive="0" passedButRunAborted="0" notRunnable="0" notExecuted="0" disconnected="0" warning="0" completed="1" inProgress="0" pending="0" />

          </ResultSummary>

          <TestDefinitions>

                   <UnitTest name="DefaultTestName" storage=" xxx">

                             <Description>DefaultDescription</Description>

                             <Execution id="e58026f9-1eb9-4f96-8fc9-e672dce1e6c7" />

                             <Properties>

                                      <Property>

                                                <Key>JobID</Key>

                                                <Value>133069</Value>

                                      </Property>

                             </Properties>

                             <TestMethod codeBase=" xxx" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className=" xxx, Federation4.5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" name="DefaultTestName" />

                   </UnitTest>

          </TestDefinitions>

          <TestLists>

                   <TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />

          </TestLists>

          <TestEntries>

                   <TestEntry testId="5099c33a-7e6b-4dff-8872-c0b6f614bbed" executionId="e58026f9-1eb9-4f96-8fc9-e672dce1e6c7" testListId="19431567-8539-422a-85d7-44ee4e166bda" />

          </TestEntries>

          <Results>

                   <UnitTestResult executionId="e58026f9-1eb9-4f96-8fc9-e672dce1e6c7" testId="5099c33a-7e6b-4dff-8872-c0b6f614bbed" testName="DefaultTestName" computerName=" xxx" duration="00:00:15.4887422" startTime="2012-10-09T17:43:08.7109882-07:00" endTime="2012-10-09T17:43:25.0076177-07:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Completed" testListId="19431567-8539-422a-85d7-44ee4e166bda" relativeResultsDirectory="e58026f9-1eb9-4f96-8fc9-e672dce1e6c7">

                             <Output>

                                      <StdOut>Fake Log</StdOut>

                             </Output>

                   </UnitTestResult>

          </Results>

</TestRun>

Now I created one method which reads the test properties from the VSMDI

static string GetTestcaseIdFromVsmdi(string testcase)

        {

            XmlDocument doc = new XmlDocument();

            doc.Load(oldVsmdi);

            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());

            namespaceManager.AddNamespace("ns", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010");

 

            XmlNode testLink = doc.SelectSingleNode("//ns:TestLink[@name='" + testcase + "']", namespaceManager);

            return testLink.Attributes["id"].Value;

        }

The below method creates a TRX for the list of test names

static void CreateNewTrx(List<string> selectedTests)

        {

            XmlDocument doc = new XmlDocument();

            doc.Load(oldTrx);

            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());

            namespaceManager.AddNamespace("ns", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010");

 

            XmlNode unitTest = doc.SelectSingleNode("//ns:UnitTest", namespaceManager);

            XmlNode testEntry = doc.SelectSingleNode("//ns:TestEntry", namespaceManager);

            XmlNode unitTestResult = doc.SelectSingleNode("//ns:UnitTestResult", namespaceManager);

 

            XmlNode counters = doc.SelectSingleNode("//ns:ResultSummary/ns:Counters", namespaceManager);

            counters.Attributes["total"].Value = selectedTests.Count.ToString();

            counters.Attributes["executed"].Value = selectedTests.Count.ToString();

            counters.Attributes["completed"].Value = selectedTests.Count.ToString();

 

            foreach (string selectedTest in selectedTests)

            {

                string testId = GetTestcaseIdFromVsmdi(selectedTest);

                string executionId = Guid.NewGuid().ToString();

                if (doc.SelectSingleNode("//ns:UnitTest[@name='DefaultTestName']", namespaceManager) != null)

                {

                    unitTest.Attributes["name"].Value = selectedTest;

                    unitTest.Attributes["id"].Value = testId;

                    unitTest.SelectSingleNode("ns:Execution", namespaceManager).Attributes["id"].Value = executionId;

                    unitTest.SelectSingleNode("ns:TestMethod", namespaceManager).Attributes["name"].Value = selectedTest;

                    testEntry.Attributes["testId"].Value = testId;

                    testEntry.Attributes["executionId"].Value = executionId;

                    unitTestResult.Attributes["executionId"].Value = executionId;

                    unitTestResult.Attributes["testName"].Value = selectedTest;

                    unitTestResult.Attributes["testId"].Value = testId;

                }

                else

                {

                    XmlNode newUnitTest = unitTest.Clone();

                    newUnitTest.Attributes["name"].Value = selectedTest;

                    newUnitTest.Attributes["id"].Value = testId;

                    newUnitTest.SelectSingleNode("ns:Execution", namespaceManager).Attributes["id"].Value = executionId;

                    newUnitTest.SelectSingleNode("ns:TestMethod", namespaceManager).Attributes["name"].Value = selectedTest;

                    unitTest.ParentNode.AppendChild(newUnitTest);

 

                    XmlNode newtestEntry = testEntry.Clone();

                    newtestEntry.Attributes["testId"].Value = testId;

                    newtestEntry.Attributes["executionId"].Value = executionId;

                    testEntry.ParentNode.AppendChild(newtestEntry);

 

                    XmlNode newUnitTestResult = unitTestResult.Clone();

                    newUnitTestResult.Attributes["executionId"].Value = executionId;

                    newUnitTestResult.Attributes["testName"].Value = selectedTest;

                    newUnitTestResult.Attributes["testId"].Value = testId;

                    unitTestResult.ParentNode.AppendChild(newUnitTestResult);

                }

            }

 

            doc.Save(newTrx);

        }

Now you are ready to run the tests from the TRX.

The only thing to note is that while running the tests from the Test Results window, don’t check any test. Just click Run and Enjoy!

 

No comments:

Post a Comment