2

I would like to pass parameter values from test cases which are present in Team Foundation Server. I do the automation with the help of Microsoft Test Manager.

Below is example test method created using Unit Test Project.

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]

        public void TestMethod1(int a, int b, int expectedResult)
        {

            var sut = new Class1();

            var result = sut.Add(a,b);

            Assert.AreEqual(expectedResult, result);

        }
    }
}

Now when I try to build this, I get the below error:

UTA007: Method TestMethod1 defined in class UnitTestProject1.UnitTest1 does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, does not return a value and should not take any parameter. for example: public void Test.Class1.Test(). Additionally, return-type must be Task if you are running async unit tests. Example: public async Task Test.Class1.Test2().

How to achieve parameter passing in this scenario?

meshsf
  • 163
  • 2
  • 14
  • 1
    Possible duplicate of [How to run a test method with multiple parameters in MSTest?](http://stackoverflow.com/questions/9021881/how-to-run-a-test-method-with-multiple-parameters-in-mstest) – ivayle Mar 01 '17 at 06:42
  • I would suggest you use `TestContext` instead? https://blogs.msdn.microsoft.com/vstsqualitytools/2006/01/09/using-testcontext-in-unit-tests/ – zaitsman Mar 01 '17 at 09:55

2 Answers2

3

To read parameter values from a TestCase in TFS, you could use Data-Driven unit testing:

public TestContext TestContext { get; set; }
public DataRow DataRow { get; set; }

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://serverName:8080/tfs/MyCollection;teamProjectName", "541", DataAccessMethod.Sequential)]

[TestMethod]
public void TestMethod()
{
            string parameter1 = TestContext.DataRow[0].ToString(); // read parameter by column index
            string parameter2 = TestContext.DataRow[1].ToString(); 

            var sut = new Class1();

            var result = sut.Add(a, b);

            Assert.AreEqual(parameter1, result);
}

Note: 541 is the TestCase id.

Tingting0929
  • 4,142
  • 1
  • 14
  • 14
  • I have setup my TFS online. So is this path correct? [DataSource("Microsoft.VisualStudio.TestTools.DataSource.TestCase", "http://abc.visualstudio.com/MyFirstProject;unittestproject", "15", DataAccessMethod.Sequential)] I tried this but getting error - The unit test adapter failed to connect to the data source or to read the data. – meshsf Mar 02 '17 at 13:13
  • I myself found the answer. This works fine .[DataSource("Microsoft.VisualStudio.TestTools.DataSource.Tes‌​tCase", "https://abc.visualstudio.com;MyFirstProject, "15", DataAccessMethod.Sequential)] – meshsf Mar 06 '17 at 08:57
  • How to pass XML file (which will have test data) as test parameter for each test case in TFS?Something like this [DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "https://abc.visualstudio.com;MyFirstProject", "TestData.xml", DataAccessMethod.Sequential)] is this possible? – meshsf Mar 15 '17 at 04:51
  • Sorry, I didn't understand your requirement. Could you please post a new question and give your request a detail description. – Tingting0929 Mar 15 '17 at 09:40
  • Sure. I will do and update here once post it. So that you can have a look. Thanks. – meshsf Mar 15 '17 at 11:11
  • I have posted new question here http://stackoverflow.com/questions/42827835/how-to-read-xml-attachment-from-tfs-test-case-to-test-method. – meshsf Mar 16 '17 at 07:33
0

I know that question is quite old, but recently I had to migrate a couple of tests to the newer library versions and I have found out that Microsoft.VisualStudio.TestTools.DataSource.TestCase doesn't work in MSTestV2 , apart from that TestContext doesn't have DataRow anymore in .net core. So here is an approach that will work for newer versions of MSTest and dotnet.

Couple of things need to be done:

  • Instead of DataSource attribute will use new ITestDataSource interface and we'll implement it as data source attribute for team foundation server. This interface will inject parameters from TDS workitem to the test itself.

  • We'll use TeamFoundationServerClient for interaction with TFS

ITestDataSource implementation, it actually queries TFS before test execution and passes parameters from TFS work item to the test as arguments (checkout GetData method):

public class TfsDataSourceAttribute : System.Attribute, ITestDataSource
{
    private readonly int _workItemId;

    public TfsDataSourceAttribute(int workItemId)
    {
        _workItemId = workItemId;
    }

    public IEnumerable<object[]> GetData(MethodInfo methodInfo)
    {
        using (var connection = new VssConnection(new Uri("http://team:8080/tfs/MyCompany-Collection"), new VssCredentials()))
        {
            using (var client = connection.GetClient<WorkItemTrackingHttpClient>())
            {
                WorkItem workItem = null;
                try
                {
                    var task = client.GetWorkItemAsync(_projectName, _workItemId);
                    task.Wait(); // force exception to bubble up here
                    workItem = task.Result;
                }
                catch (AggregateException ex)
                {
                    // rethrow exception so it will have normal display
                    // in test exploere
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                }

                // this filed in a test case in TFS has all the params
                var dataSource = workItem.Fields["Microsoft.VSTS.TCM.LocalDataSource"];

                // parse this xml and prepare data for test
                var tables = XElement
                    .Parse(dataSource.ToString())
                    .Descendants()
                    .Where(xe => xe.Name.ToString().StartsWith("Table"));

                foreach (var table in tables)
                {
                    // return array with only one dictionary
                    // that will be injected into test decorated with this attribute
                    yield return new object[] { table
                        .Descendants()
                        .ToDictionary(xe => xe.Name.ToString(), xe => xe.Value) };
                }
            }
        }
    }

    // Gets the display name corresponding to test data row for displaying in test manager
    public string GetDisplayName(MethodInfo methodInfo, object[] data)
    {
      if (data != null)
      {
          var testParams = (Dictionary<string, string>)data[0];
          return $"{methodInfo.Name} workitem: '{_workItemId}' - ({string.Join(" ", testParams)})";
      }
      return null;
    }
}

Example usage of the attribute with a test:

    [TestMethod]
    [TfsDataSource(242141223)]
    public void MyTest(Dictionary<string, string> testParams)
    {
        // testParams has all parameters extracted by TfsDataSource from test item in TFS
    }
Monsieur Merso
  • 1,459
  • 1
  • 15
  • 18