public void Load(string settingsXml) { if (string.IsNullOrEmpty(settingsXml)) { settingsXml = "<RunSettings />"; } // Visual Studio already gives a good error message if the .runsettings // file is poorly formed, so we don't need to do anything more. var doc = new XmlDocument(); doc.LoadXml(settingsXml); var nunitNode = doc.SelectSingleNode("RunSettings/NUnit"); Verbosity = GetInnerTextAsInt(nunitNode, nameof(Verbosity), 0); _logger.Verbosity = Verbosity; var runConfiguration = doc.SelectSingleNode("RunSettings/RunConfiguration"); MaxCpuCount = GetInnerTextAsInt(runConfiguration, nameof(MaxCpuCount), -1); ResultsDirectory = GetInnerTextWithLog(runConfiguration, nameof(ResultsDirectory)); TargetPlatform = GetInnerTextWithLog(runConfiguration, nameof(TargetPlatform)); TargetFrameworkVersion = GetInnerTextWithLog(runConfiguration, nameof(TargetFrameworkVersion)); TestAdapterPaths = GetInnerTextWithLog(runConfiguration, nameof(TestAdapterPaths)); CollectSourceInformation = GetInnerTextAsBool(runConfiguration, nameof(CollectSourceInformation), true); DisableAppDomain = GetInnerTextAsBool(runConfiguration, nameof(DisableAppDomain), false); DisableParallelization = GetInnerTextAsBool(runConfiguration, nameof(DisableParallelization), false); DesignMode = GetInnerTextAsBool(runConfiguration, nameof(DesignMode), false); CollectDataForEachTestSeparately = GetInnerTextAsBool(runConfiguration, nameof(CollectDataForEachTestSeparately), false); TestProperties = new Dictionary <string, string>(); UpdateTestProperties(); // NUnit settings InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning", "Info", "Verbose", "Debug"); WorkDirectory = GetInnerTextWithLog(nunitNode, nameof(WorkDirectory)); Where = GetInnerTextWithLog(nunitNode, nameof(Where)); DefaultTimeout = GetInnerTextAsInt(nunitNode, nameof(DefaultTimeout), 0); NumberOfTestWorkers = GetInnerTextAsInt(nunitNode, nameof(NumberOfTestWorkers), -1); ShadowCopyFiles = GetInnerTextAsBool(nunitNode, nameof(ShadowCopyFiles), false); UseVsKeepEngineRunning = GetInnerTextAsBool(nunitNode, nameof(UseVsKeepEngineRunning), false); BasePath = GetInnerTextWithLog(nunitNode, nameof(BasePath)); PrivateBinPath = GetInnerTextWithLog(nunitNode, nameof(PrivateBinPath)); TestOutputXml = GetInnerTextWithLog(nunitNode, nameof(TestOutputXml)); RandomSeed = GetInnerTextAsNullableInt(nunitNode, nameof(RandomSeed)); RandomSeedSpecified = RandomSeed.HasValue; if (!RandomSeedSpecified) { RandomSeed = new Random().Next(); } DefaultTestNamePattern = GetInnerTextWithLog(nunitNode, nameof(DefaultTestNamePattern)); ShowInternalProperties = GetInnerTextAsBool(nunitNode, nameof(ShowInternalProperties), false); UseParentFQNForParametrizedTests = GetInnerTextAsBool(nunitNode, nameof(UseParentFQNForParametrizedTests), false); UseNUnitIdforTestCaseId = GetInnerTextAsBool(nunitNode, nameof(UseNUnitIdforTestCaseId), false); ConsoleOut = GetInnerTextAsInt(nunitNode, nameof(ConsoleOut), 1); // 0 no output to console, 1 : output to console StopOnError = GetInnerTextAsBool(nunitNode, nameof(StopOnError), false); // Adapter Diagnostics DumpXmlTestDiscovery = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestDiscovery), false); DumpXmlTestResults = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestResults), false); FreakMode = GetInnerTextAsBool(nunitNode, nameof(FreakMode), false); // End Diagnostics // Adapter Display Options MapDisplayName(GetInnerText(nunitNode, nameof(DisplayName), Verbosity > 0)); FullnameSeparator = GetInnerText(nunitNode, nameof(FullnameSeparator), Verbosity > 0)?[0] ?? ':'; // EndDisplay PreFilter = GetInnerTextAsBool(nunitNode, nameof(PreFilter), false); MapTestCategory(GetInnerText(nunitNode, nameof(VsTestCategoryType), Verbosity > 0)); MapWarningTo = MapWarningOutcome(GetInnerText(nunitNode, nameof(MapWarningTo), Verbosity > 0)); UseTestNameInConsoleOutput = GetInnerTextAsBool(nunitNode, nameof(UseTestNameInConsoleOutput), false); var inProcDataCollectorNode = doc.SelectSingleNode("RunSettings/InProcDataCollectionRunSettings/InProcDataCollectors"); InProcDataCollectorsAvailable = inProcDataCollectorNode != null && inProcDataCollectorNode.SelectNodes("InProcDataCollector")?.Count > 0; // Older versions of VS do not pass the CollectDataForEachTestSeparately configuration together with the LiveUnitTesting collector. // However, the adapter is expected to run in CollectDataForEachTestSeparately mode. // As a result for backwards compatibility reasons enable CollectDataForEachTestSeparately mode whenever LiveUnitTesting collector is being used. var hasLiveUnitTestingDataCollector = inProcDataCollectorNode?.SelectSingleNode( "InProcDataCollector[@uri='InProcDataCollector://Microsoft/LiveUnitTesting/1.0']") != null; // TestPlatform can opt-in to run tests one at a time so that the InProcDataCollectors can collect the data for each one of them separately. // In that case, we need to ensure that tests do not run in parallel and the test started/test ended events are sent synchronously. if (CollectDataForEachTestSeparately || hasLiveUnitTestingDataCollector) { NumberOfTestWorkers = 0; SynchronousEvents = true; if (Verbosity >= 4) { if (!InProcDataCollectorsAvailable) { _logger.Info( "CollectDataForEachTestSeparately is set, which is used to make InProcDataCollectors collect data for each test separately. No InProcDataCollectors can be found, thus the tests will run slower unnecessarily."); } } } // If DisableAppDomain settings is passed from the testplatform, set the DomainUsage to None. if (DisableAppDomain) { DomainUsage = "None"; } // Update NumberOfTestWorkers based on the DisableParallelization and NumberOfTestWorkers from runsettings. UpdateNumberOfTestWorkers(); string ValidatedPath(string path, string purpose) { try { if (string.IsNullOrEmpty(WorkDirectory)) { return(Path.GetFullPath(path)); } if (Path.IsPathRooted(path)) { return(Path.GetFullPath(path)); } return(Path.GetFullPath(Path.Combine(WorkDirectory, path))); } catch (Exception) { _logger.Error($" Invalid path for {purpose}: {path}"); throw; } } void UpdateTestProperties() { foreach (XmlNode node in doc.SelectNodes("RunSettings/TestRunParameters/Parameter")) { var key = node.GetAttribute("name"); var value = node.GetAttribute("value"); if (key != null && value != null) { TestProperties.Add(key, value); } } } }
public void Load(string settingsXml) { if (string.IsNullOrEmpty(settingsXml)) { settingsXml = "<RunSettings />"; } // Visual Studio already gives a good error message if the .runsettings // file is poorly formed, so we don't need to do anything more. var doc = new XmlDocument(); doc.LoadXml(settingsXml); var nunitNode = doc.SelectSingleNode("RunSettings/NUnit"); Verbosity = GetInnerTextAsInt(nunitNode, nameof(Verbosity), 0); _logger.Verbosity = Verbosity; var runConfiguration = doc.SelectSingleNode("RunSettings/RunConfiguration"); MaxCpuCount = GetInnerTextAsInt(runConfiguration, nameof(MaxCpuCount), -1); ResultsDirectory = GetInnerTextWithLog(runConfiguration, nameof(ResultsDirectory)); TargetPlatform = GetInnerTextWithLog(runConfiguration, nameof(TargetPlatform)); TargetFrameworkVersion = GetInnerTextWithLog(runConfiguration, nameof(TargetFrameworkVersion)); TestAdapterPaths = GetInnerTextWithLog(runConfiguration, nameof(TestAdapterPaths)); CollectSourceInformation = GetInnerTextAsBool(runConfiguration, nameof(CollectSourceInformation), true); DisableAppDomain = GetInnerTextAsBool(runConfiguration, nameof(DisableAppDomain), false); DisableParallelization = GetInnerTextAsBool(runConfiguration, nameof(DisableParallelization), false); DesignMode = GetInnerTextAsBool(runConfiguration, nameof(DesignMode), false); CollectDataForEachTestSeparately = GetInnerTextAsBool(runConfiguration, nameof(CollectDataForEachTestSeparately), false); TestProperties = new Dictionary <string, string>(); foreach (XmlNode node in doc.SelectNodes("RunSettings/TestRunParameters/Parameter")) { var key = node.GetAttribute("name"); var value = node.GetAttribute("value"); if (key != null && value != null) { TestProperties.Add(key, value); } } // NUnit settings InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning", "Info", "Verbose", "Debug"); WorkDirectory = GetInnerTextWithLog(nunitNode, nameof(WorkDirectory)); DefaultTimeout = GetInnerTextAsInt(nunitNode, nameof(DefaultTimeout), 0); NumberOfTestWorkers = GetInnerTextAsInt(nunitNode, nameof(NumberOfTestWorkers), -1); ShadowCopyFiles = GetInnerTextAsBool(nunitNode, nameof(ShadowCopyFiles), false); UseVsKeepEngineRunning = GetInnerTextAsBool(nunitNode, nameof(UseVsKeepEngineRunning), false); BasePath = GetInnerTextWithLog(nunitNode, nameof(BasePath)); PrivateBinPath = GetInnerTextWithLog(nunitNode, nameof(PrivateBinPath)); var testOutput = GetInnerTextWithLog(nunitNode, nameof(TestOutputXml)); if (!string.IsNullOrEmpty(testOutput)) { TestOutputXml = ValidatedPath(testOutput, nameof(TestOutputXml)); } RandomSeed = GetInnerTextAsNullableInt(nunitNode, nameof(RandomSeed)); RandomSeedSpecified = RandomSeed.HasValue; if (!RandomSeedSpecified) { RandomSeed = new Random().Next(); } DefaultTestNamePattern = GetInnerTextWithLog(nunitNode, nameof(DefaultTestNamePattern)); DumpXmlTestDiscovery = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestDiscovery), false); DumpXmlTestResults = GetInnerTextAsBool(nunitNode, nameof(DumpXmlTestResults), false); var vsTestCategoryType = GetInnerText(nunitNode, nameof(VsTestCategoryType), Verbosity > 0); if (vsTestCategoryType != null) { switch (vsTestCategoryType.ToLower()) { case "nunit": VsTestCategoryType = VsTestCategoryType.NUnit; break; case "mstest": VsTestCategoryType = VsTestCategoryType.MsTest; break; default: _logger.Warning( $"Invalid value ({vsTestCategoryType}) for VsTestCategoryType, should be either NUnit or MsTest"); break; } } #if SUPPORT_REGISTRY_SETTINGS // Legacy (CTP) registry settings override defaults var registry = RegistryCurrentUser.OpenRegistryCurrentUser(@"Software\nunit.org\VSAdapter"); if (registry.Exist("ShadowCopy") && (registry.Read <int>("ShadowCopy") == 1)) { ShadowCopyFiles = true; } if (registry.Exist("Verbosity")) { Verbosity = registry.Read <int>("Verbosity"); } if (registry.Exist("UseVsKeepEngineRunning") && (registry.Read <int>("UseVsKeepEngineRunning") == 1) UseVsKeepEngineRunning = true; #endif #if DEBUG && VERBOSE // Force Verbosity to 1 under Debug Verbosity = 1; #endif var inProcDataCollectorNode = doc.SelectSingleNode("RunSettings/InProcDataCollectionRunSettings/InProcDataCollectors"); InProcDataCollectorsAvailable = inProcDataCollectorNode != null && inProcDataCollectorNode.SelectNodes("InProcDataCollector").Count > 0; // Older versions of VS do not pass the CollectDataForEachTestSeparately configuration together with the LiveUnitTesting collector. // However, the adapter is expected to run in CollectDataForEachTestSeparately mode. // As a result for backwards compatibility reasons enable CollectDataForEachTestSeparately mode whenever LiveUnitTesting collector is being used. var hasLiveUnitTestingDataCollector = inProcDataCollectorNode?.SelectSingleNode( "InProcDataCollector[@uri='InProcDataCollector://Microsoft/LiveUnitTesting/1.0']") != null; // TestPlatform can opt-in to run tests one at a time so that the InProcDataCollectors can collect the data for each one of them separately. // In that case, we need to ensure that tests do not run in parallel and the test started/test ended events are sent synchronously. if (CollectDataForEachTestSeparately || hasLiveUnitTestingDataCollector) { NumberOfTestWorkers = 0; SynchronousEvents = true; if (Verbosity >= 4) { if (!InProcDataCollectorsAvailable) { _logger.Info( "CollectDataForEachTestSeparately is set, which is used to make InProcDataCollectors collect data for each test separately. No InProcDataCollectors can be found, thus the tests will run slower unnecessarily."); } } } // If DisableAppDomain settings is passed from the testplatform, set the DomainUsage to None. if (DisableAppDomain) { DomainUsage = "None"; } // Update NumberOfTestWorkers based on the DisableParallelization and NumberOfTestWorkers from runsettings. UpdateNumberOfTestWorkers(); string ValidatedPath(string path, string purpose) { try { if (string.IsNullOrEmpty(WorkDirectory)) { return(Path.GetFullPath(path)); } if (Path.IsPathRooted(path)) { return(Path.GetFullPath(path)); } return(Path.GetFullPath(Path.Combine(WorkDirectory, path))); } catch (Exception) { _logger.Error($" Invalid path for {purpose}: {path}"); throw; } } }
// The Adapter is constructed using the default constructor. // We don't have any info to initialize it until one of the // ITestDiscovery or ITestExecutor methods is called. The // each Discover or Execute method must call this method. protected void Initialize(IDiscoveryContext context, IMessageLogger messageLogger) { TestEngine = new TestEngineClass(); TestLog = new TestLogger(messageLogger, Settings.Verbosity); try { Settings.Load(context); } catch (Exception e) { TestLog.Error("Error initializing RunSettings. Default settings will be used"); TestLog.Error(e.ToString()); } }