diff --git a/Documentation/Troubleshooting.md b/Documentation/Troubleshooting.md
index f9e66b032..3d8d00d09 100644
--- a/Documentation/Troubleshooting.md
+++ b/Documentation/Troubleshooting.md
@@ -244,4 +244,9 @@ You can live attach and debug collectors with `COVERLET_DATACOLLECTOR_OUTOFPROC_
set COVERLET_DATACOLLECTOR_OUTOFPROC_DEBUG=1
set COVERLET_DATACOLLECTOR_INPROC_DEBUG=1
```
-You will be asked to attach a debugger through UI popup.
+You will be asked to attach a debugger through UI popup.
+To enable exceptions log for in-process data collectors
+```
+ set COVERLET_DATACOLLECTOR_INPROC_EXCEPTIONLOG_ENABLED=1
+```
+
diff --git a/Documentation/VSTestIntegration.md b/Documentation/VSTestIntegration.md
index 47fa12f0d..5471a00db 100644
--- a/Documentation/VSTestIntegration.md
+++ b/Documentation/VSTestIntegration.md
@@ -1,6 +1,14 @@
# Coverlet integration with VSTest (a.k.a. Visual Studio Test Platform)
-**At the moment collectors integration supports only .NET Core applications and not .NET Framework ones.**
+**Supported runtime versions:**
+Before version `3.0.0`
+- .NET Core >= 2.0
+- .NET Framework not fully supported(only out of process collector, could suffer of [known issue](https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/KnownIssues.md#1-vstest-stops-process-execution-earlydotnet-test))
+
+Since version `3.0.0`
+- .NET Core >= 2.0
+- .NET Framework >= 4.6.1
+
As explained in quick start section to use collectors you need to run *SDK v2.2.401* or newer and your project file must reference `coverlet.collector.dll` and a minimum version of `Microsoft.NET.Test.Sdk`.
A sample project file looks like:
diff --git a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
index a3b1b1124..31509474a 100644
--- a/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
+++ b/src/coverlet.collector/DataCollection/CoverletSettingsParser.cs
@@ -237,7 +237,7 @@ private string[] ParseDoesNotReturnAttributes(XmlElement configurationElement)
/// An array of the values in the element
private string[] SplitElement(XmlElement element)
{
- return element?.InnerText?.Split(',', StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray();
+ return element?.InnerText?.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(value => !string.IsNullOrWhiteSpace(value)).Select(value => value.Trim()).ToArray();
}
}
}
diff --git a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs
index 8c4dd05ef..5539d6b04 100644
--- a/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs
+++ b/src/coverlet.collector/InProcDataCollection/CoverletInProcDataCollector.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Reflection;
+using System.Text;
using coverlet.collector.Resources;
using Coverlet.Collector.Utilities;
@@ -14,6 +15,7 @@ namespace Coverlet.Collector.DataCollection
public class CoverletInProcDataCollector : InProcDataCollection
{
private TestPlatformEqtTrace _eqtTrace;
+ private bool _enableExceptionLog = false;
private void AttachDebugger()
{
@@ -24,10 +26,18 @@ private void AttachDebugger()
}
}
- public void Initialize(IDataCollectionSink dataCollectionSink)
+ private void EnableExceptionLog()
{
+ if (int.TryParse(Environment.GetEnvironmentVariable("COVERLET_DATACOLLECTOR_INPROC_EXCEPTIONLOG_ENABLED"), out int result) && result == 1)
+ {
+ _enableExceptionLog = true;
+ }
+ }
+ public void Initialize(IDataCollectionSink dataCollectionSink)
+ {
AttachDebugger();
+ EnableExceptionLog();
_eqtTrace = new TestPlatformEqtTrace();
_eqtTrace.Verbose("Initialize CoverletInProcDataCollector");
@@ -61,9 +71,12 @@ public void TestSessionEnd(TestSessionEndArgs testSessionEndArgs)
}
catch (Exception ex)
{
- _eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
- string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName);
- throw new CoverletDataCollectorException(errorMessage, ex);
+ if (_enableExceptionLog)
+ {
+ _eqtTrace.Error("{0}: Failed to unload module with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
+ string errorMessage = string.Format(Resources.FailedToUnloadModule, CoverletConstants.InProcDataCollectorName);
+ throw new CoverletDataCollectorException(errorMessage, ex);
+ }
}
}
}
@@ -89,7 +102,25 @@ private Type GetInstrumentationClass(Assembly assembly)
}
catch (Exception ex)
{
- _eqtTrace.Warning("{0}: Failed to get Instrumentation class with error: {1}", CoverletConstants.InProcDataCollectorName, ex);
+ if (_enableExceptionLog)
+ {
+ StringBuilder exceptionString = new StringBuilder();
+ exceptionString.AppendFormat("{0}: Failed to get Instrumentation class for assembly '{1}' with error: {2}",
+ CoverletConstants.InProcDataCollectorName, assembly, ex);
+ exceptionString.AppendLine();
+
+ if (ex is ReflectionTypeLoadException rtle)
+ {
+ exceptionString.AppendLine("ReflectionTypeLoadException list:");
+ foreach (Exception loaderEx in rtle.LoaderExceptions)
+ {
+ exceptionString.AppendLine(loaderEx.ToString());
+ }
+ }
+
+ _eqtTrace.Warning(exceptionString.ToString());
+ }
+
return null;
}
}
diff --git a/src/coverlet.collector/coverlet.collector.csproj b/src/coverlet.collector/coverlet.collector.csproj
index d6a7695a8..ba206705c 100644
--- a/src/coverlet.collector/coverlet.collector.csproj
+++ b/src/coverlet.collector/coverlet.collector.csproj
@@ -1,6 +1,6 @@
- netcoreapp2.0
+ netstandard2.0
coverlet.collector
true
true