microsoft / testfx

MSTest framework and adapter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Get test file location and test line number with MSTest.Sdk/3.x.x programmatically

MarcZw opened this issue · comments

Question

Is there a way to get both the test file location and test line number programmatically?

Problem

As I am not sure this is a bug or intended behavior, I chose to make an issue in the other category.
Currently I am working on implementing the MSTest runner in Stryker.NET and for internal workings Stryker needs to know the test file location (CodeFilePath) and the line number of the TestNode.

When querying the TestNode for this information, it only returns null.
The other properties contained in the PropertyBag that could be used for this (VSTestProperty TestCase.CodeFilePath and VSTestProperty TestCase.LineNumber) are also not provided and are respectively null and -1.

See the code below for the current way of calling the runner.

Testapplication

var builder = await TestApplication.CreateBuilderAsync([]);
builder.AddMSTest(() => [assembly]);
builder.TestHost.AddDataConsumer((_) => new DiscoveryConsumer());
var app = await builder.BuildAsync();
await app.RunAsync();

DataConsumer

internal class DiscoveryConsumer : IDataConsumer {
  
  public Type[] DataTypesConsumed => [typeof(TestNodeUpdateMessage)];
  
  ...

  public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationToken cancellationToken)
  {
      var update = value as TestNodeUpdateMessage;

      var state = update!.TestNode.Properties.Single<TestNodeStateProperty>();

      if(state is InProgressTestNodeStateProperty)
      {
          return Task.CompletedTask;
      }
      
      // Location is always null!
      var location = update.TestNode.Properties.SingleOrDefault<TestFileLocationProperty>();

      ...

      return Task.CompletedTask;
   }
} 

This depends on RunConfiguration.CollectSourceInformation, which we set to false by default. Collecting source info from PDBs has a quite big overhead.

You can re-enable it by in runsettings.

    public static class Program
    {
        public static async Task Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var builder = await TestApplication.CreateBuilderAsync(args);
            builder.AddMSTest(() => [assembly]);
            builder.TestHost.AddDataConsumer((_) => new DiscoveryConsumer());
            var app = await builder.BuildAsync();
            await app.RunAsync();
        }
    }

launchSettings.json

{
  "profiles": {
    "TestProject99": {
      "commandName": "Project",
      "commandLineArgs": "--settings C:\\Users\\jajares\\source\\repos\\TestProject99\\TestProject99\\settings.runsettings"
    }
  }
}

settings.runsettings:

<RunSettings>
        <RunConfiguration>
            <CollectSourceInformation>True</CollectSourceInformation>
</RunConfiguration>
</RunSettings>

Seems to work, thank you so much!