I have implemented an application in C# (net 7.0) which loads and executes unit tests programmatically using NUnit(3.13.3) and NUnit.Engine (3.16.3). Tests are also implemented in C# net 7.0.
My problem is that the tests are not being executed independent from my application. This means:
- If the application and the tests have common dependencies, the tests are being executed with the dependencies of the application and not with their own. And this is a problem, if for example the versions differ.
- Another problem comes if the application tries to reload the tests. The tests dll is reload but not its dependencies (independently of having them in common with the application).
I know the nunit-console runs tests in a separate process, and this will solve my problem, but I do not know how can I achieve this programmatically. The runner returned by the engine (ITestRunner runner = TestEngineActivator.CreateInstance().GetRunner(_testPackage);) always runs the tests in the same process as my application, not matter which settings my TestPackage have.
My question is, how do I get a runner which runs the tests in an extra process? Which settings do I need for the TestPackage? Do I have to install dome extra NuGets?
As I said, I implemented my application using net 7.0 and I have installed the two NuGets NUnit 3.13.3 and NUnit.Engine 3.16.3.
I get the ITestEngine in this way:
public TestModel() {
_engine = TestEngineActivator.CreateInstance();
_settingsService = new SettingsService(true);
_settingsService.LoadSettings();
_engine.InternalTraceLevel = InternalTraceLevel.Off;
}
Then I load the tests:
public async Task<XmlNode?> LoadTestsAsync(string dllTestFile) {
LoadedTestFile = dllTestFile;
_testPackage = new TestPackage(LoadedTestFile);
_runner = _engine.GetRunner(_testPackage);
var nodes = await Task.Run(() => _runner.Explore(TestFilter.Empty));
XmlWriter writer = XmlWriter.Create("tests.xml", new XmlWriterSettings() { Indent = true});
nodes.WriteContentTo(writer);
writer.Flush();
writer.Dispose();
return nodes;
}
Run the tests:
public void Run(TestNode testNode) {
var filterService = _engine?.Services.GetService<ITestFilterService>();
var builder = filterService?.GetTestFilterBuilder();
CheckVirtualAndAddChildren(builder, testNode);
_runner?.RunAsync(_events, builder?.GetFilter());
}
And reload the tests:
public async Task<XmlNode?> ReloadAsync() {
try {
_runner?.Unload();
} catch (NUnitEngineUnloadException) {}
_runner?.Dispose();
_runner = _engine.GetRunner(_testPackage);
var nodes = await Task.Run(() => _runner?.Explore(TestFilter.Empty));
XmlWriter writer = XmlWriter.Create("tests.xml", new XmlWriterSettings() { Indent = true});
nodes?.WriteContentTo(writer);
writer.Flush();
writer.Dispose();
return nodes;
}
I also let write the xml return by ITestRunner.Explore(TestFilter)
<?xml version="1.0" encoding="utf-8"?>
<test-suite type="Assembly" id="0-1007" name="NUnitTests.dll" fullname="H:/MyApplication/sample/NUnitDemo/NUnitTests/bin/Debug/net7.0/NUnitTests.dll" runstate="Runnable" testcasecount="4">
<environment framework-version="3.13.3.0" clr-version="7.0.5" os-version="Microsoft Windows 10.0.19045" platform="Win32NT" cwd="H:\MyApplication\MyApplication\bin\Debug\net7.0" machine-name="XXXX" user="myself" user-domain="XXXX" culture="de-DE" uiculture="de-DE" os-architecture="x64" />
<settings>
<setting name="NumberOfTestWorkers" value="16" />
</settings>
<properties>
<property name="_PID" value="29016" />
<property name="_APPDOMAIN" value="MyApplication" />
</properties>
<test-suite type="TestSuite" id="0-1008" name="NUnitTests" fullname="NUnitTests" runstate="Runnable" testcasecount="4">
<test-suite type="TestFixture" id="0-1000" name="DemoTests" fullname="NUnitTests.DemoTests" classname="NUnitTests.DemoTests" runstate="Runnable" testcasecount="4">
<test-suite type="ParameterizedMethod" id="0-1006" name="BaseDependency" fullname="NUnitTests.DemoTests.BaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" testcasecount="2">
<test-case id="0-1004" name="BaseDependency(Cycle #1)" fullname="NUnitTests.DemoTests.BaseDependency(Cycle #1)" methodname="BaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" seed="1298419094" />
<test-case id="0-1005" name="BaseDependency(Cycle #2)" fullname="NUnitTests.DemoTests.BaseDependency(Cycle #2)" methodname="BaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" seed="2074295330" />
</test-suite>
<test-suite type="ParameterizedMethod" id="0-1003" name="NoBaseDependency" fullname="NUnitTests.DemoTests.NoBaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" testcasecount="2">
<test-case id="0-1001" name="NoBaseDependency(Cycle #1)" fullname="NUnitTests.DemoTests.NoBaseDependency(Cycle #1)" methodname="NoBaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" seed="1168845109" />
<test-case id="0-1002" name="NoBaseDependency(Cycle #2)" fullname="NUnitTests.DemoTests.NoBaseDependency(Cycle #2)" methodname="NoBaseDependency" classname="NUnitTests.DemoTests" runstate="Runnable" seed="64791598" />
</test-suite>
</test-suite>
</test-suite>
</test-suite>