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
}