I have a c# unit test project (.NET 4.8).
My unit test are using a .testsetting file that I want to remove.
In my unit test I use TestContext too:
private TestContext testContextInstance;
public TestContext TestContext
{
get { return testContextInstance; }
set { testContextInstance = value; }
}
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
LoadSettings(testContext.DeploymentDirectory);
}
First I removed the .testsettings file, then I modified the unit test removing the TestContext:
[ClassInitialize]
public static void MyClassInitialize()
{
LoadSettings(Directory.GetCurrentDirectory());
}
My problem is when I run the unit test I got this error:
MyClassInitialize has wrong signature. The method must be static,
public, does not return a value and should take a single parameter of
type TestContext.
Looking at this issue, I changed the version of "Microsoft.VisualStudio.QualityTools.UnittestFramework" from 10.0.0.0 to 10.1.0.0 with no success.
Before run the tests I unchecked the .testsettings from "Test" menu and then I deleted it.
Currently use Visual Studio 2019 version 16.3.2.
I still got the same error. Do I need to reference another dll or another version? Do I need to install something?
UPDATE:
Here how I added the reference:
Here the row added by Visual Studio in the .csproj file:
Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework,Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL"
And It is how look the reference properties in Visual Studio:
I still got the error, but the strange thing is If I restart Visual Studio in the reference property I continue to see the old version (10.0.0.0)!!!
I tried also with Visual Studio 2017 version 15.9.16. Same result!
As the error message says, a method decorated with the ClassInitializeAttribute must take a TestContext parameter.
You can just ignore it if you don't ever indend to use a .testsettings file, but you cannot remove the parameter.
Related
I have two projects in Visual Studio, the core project which is a Windows Service Executable, and the Unit Test Project.
The core project has two original files broken out like this
File1.cs:
using static Proj.ConfigHelper;
namespace Proj
{
class MyClass
{
(lots of code)
}
}
File2.cs looks something like this.
namespace Proj
{
static class ConfigHelper
{
public static NameValueCollection AppSettings { get { return ConfigurationManager.AppSettings; } }
public static NameValueCollection CustomSection { get { return ConfigurationManager.GetSection("CustomSection") as NameValueCollection; } }
}
}
Both of those classes are internal and made visible to the unit test project via InternalsVisibleToAttribute.
Inside of the UnitTest project which is a discrete project within the same solution (and so it has its own app.config), calling ConfigHelper.AppSettings results in a 0-item collection, and calling ConfigHelper.CustomSection results in null. If I attempt to unit test a method within File1.cs that depends on those settings, they run as default values as if they were not configured at all. I don't quite understand why this is happening. Can anyone help me understand what I did wrong? It seems as though the ConfigHelper is not loading the App.Config for its own project.
The app.config for the Windows Service Project is set to "always copy" and the app.config for the unit test project is set to "never copy"
The test will use its own config so you need to mirror it. There are work runarounds: Can a unit test project load the target application's app.config file?
I have some test like this:
[Test, Combinatorial]
public void SomeTest(
[Values(false, true)] bool flag,
[Values(2, 5)] int someValue))
{
var entity = new SomeClass();
entity.Flag = flag;
entity.SomeValue = someValue;
var context = entity.GetContext();
Assert.AreEqual(context.SomeValue, entity.SomeValue);
}
When I try to run test, it throws TargetParameterCountException. StackTrace:
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
at NUnit.Core.TestMethod.RunTestMethod(TestResult testResult)
at NUnit.Core.TestMethod.RunTestCase(TestResult testResult)
What is wrong? I use Nunit 3.4.1and VS 2012.
Simple tests work well.
Your code is fine and runs fine for me using the NUnit 3 Visual Studio Adapter. Based on the callstack, you are trying to run the code in an older NUnit 2 based adapter. It is either an older version of Resharper or an old version of the NUnit Visual Studio Extension from before it was updated to not run NUnit 3 tests.
Install the NUnit 3 Visual Studio adapter and give that a try. If you are using Resharper, you need to pay for an update.
Also, pro-tip, you don't need to include the values in the attribute for bool or enums, all values will be automatically injected. You also don't need the Test attribute.
Here is my simplified version of your example,
[Combinatorial]
public void SomeTest([Values] bool flag, [Values(2, 5)] int someValue)
{
TestContext.WriteLine($"{flag} - ${someValue}");
}
And the results in the Visual Studio Adapter,
I want to add a custom test reporter to NUnit. I already did it with NUnit2, but I now need to use NUnit3.
To implement the reporter, I need to get various events from the framework, like start, end and failure of tests.
In NUnit2 I used NUnitHook to register my EventListener and it worked pretty good.
In NUnit3 I need to use the extension point mechanism, but when I add the extension point to the project, VisualStudio (2012 ultimate) immediately fails to discover the NUnit tests.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
If I remove the ITestEventListener implementation declaration from the class, it rediscovers the tests perfectly.
[TypeExtensionPoint(Description = "Test Reporter Extension")]
public class MyTestEventListener //: ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
Am I doing something wrong? is there a better way to achieve it?
You don't say where you are putting this code, but I am suspecting it's in your test assembly. If so, that's not where it belongs. NUnit engine extensions get installed into the NUnit engine, so they need to be in a separate assembly. Once you have a separate assembly, you need to tell the engine where it is. Currently, you do this by creating a file of type .addins in the same directory as the engine. (You could modify the existing file, but that introduces maintenance problems in the future)
A future release will have an easier way to install addins, but they will continue to be entirely separate from your tests.
A further problem is that you are using TypeExtensionPointAttribute. I didn't notice this originally in your code and it's probably the biggest error so I'm adding this info now.
An "ExtensionPoint" is the thing you are extending. NUnit defines ExtensionPoints, while you create Extenisons to extend them. TypeExtensionPointAttribute is used inside NUnit to define extension points. It's not used by you. You use the ExtensionAttribute to define your extension.
Your extension should be defined something like this:
[Extension(Description = "Test Reporter Extension", EngineVersion="3.4")]
public class MyTestEventListener : ITestEventListener
{
public void OnTestEvent(string report)
{
Console.WriteLine(report);
}
}
You don't say what version of NUnit you are running. Test Listeners are only supported beginning with version 3.4. The EngineVersion property above is purely documentary at this point, because 3.4 is also the first version to recognize it.
There is a new writeup in the NUnit docs that may be helpful: https://github.com/nunit/docs/wiki/Writing-Engine-Extensions
I have the following code:
[TestFixture]
public class LexicalTests
{
[Test]
public void LexicalTest1()
{
TestContext.CurrentContext.TestDirectory;
}
}
CurrentContext throws an exception while attempting to get TestDirectory or WorkingDirectory property.
How can I solve this problem?
P.S.: On my home PC tests work perfectly (without strange exceptions).
It seems that some applications that offer the functionality to run NUnit unit tests have a problem with the TestContext class.
The test in class below should pass:
using NUnit.Framework;
namespace UnitTests
{
[TestFixture]
public class UnitTests
{
[Test]
public void CurrentContextTest()
{
Assert.IsNotNull(TestContext.CurrentContext);
Assert.IsNotNull(TestContext.CurrentContext.TestDirectory);
Assert.IsNotNull(TestContext.CurrentContext.WorkDirectory);
}
}
}
If the test doesn't pass then, as Dmitry wrote in his comment above, change the NUnit version in the ReSharper menu. From within Visual Studio, go to ReSharper -> Options -> Tools -> NUnit. Click the Specified NUnit installation radio button and ensure that a folder with nunit.core.dll, nunit.core.interfaces.dll and nunit.util.dll is specified. An error will be displayed if the listed files cannot be found.
Once the NUnit version has been changed, re-run the test and it should pass.
I am using nunit 2.5.9.10348 and trying to extract the current test name in the TearDown event so I can assign a screengrab filename the test name however it is always null (see the attached image). The private _context variable does have the TestName however this is no use to me!
Has anyone had success using this new TestContext functionality (from 2.5.7).
From your screenshot I see that _context has keys "TestName" and "Properties". But TestAdapter looks for keys "Test.Name" for Name and "Test.Properties" for Properties. So, there is something wrong with TestContext initialization (I think wrong data was put to Remoting.Messaging.CallContext).
After a little investigation (see comments):
NUnit tests should run by NUnit testig environment for Context to be available.
I had the same issue. It occurred when in a TearDown method I executed method, which actually was to make the teardown
[TearDown]
public void CleanUp()
{
TestContext.CurrentContext.Test.FullName; //!=null
someClassInstance.DoTearDown();
}
class SomeClass
{
public void DoTearDown()
{
TestContext.CurrentContext.Test.FullName; //==null
}
}
I have no idea why, but it seemed so. Is it your case?
UPDATE: Now I looked at the screenshot, so it's not your case :)
Same issue with R# test runner. Just downloaded NUnit sources and added a workaround in TestAdapter to make it work with r#
public string Name
{
get
{
return (_context["Test.Name"] ?? _context["TestName"]) as string;
}
}