I've found a number of question regarding renaming tests in NUnit, but none that mention how to do so while using TestFixtureSource.
I am using the [TestFixtureSource] attribute to configure parameterized tests, like this:
[TestFixtureSource(nameof(GetTestParams))]
public class MyTestClass
{
private Mock<IMyDependency> _mockDependency;
private TestData _data;
private MyClass _objectUnderTest;
public MyTestClass(TestData data)
{
_data = data;
}
public static IEnumerable<TestData> GetTestParams()
{
yield return new TestData(1, 2, 3);
yield return new TestData(4, 5, 9);
yield return new TestData(7, 8, 15);
}
[SetUp]
public void SetUp()
{
_mockDependency = new Mock<IMyDependency>();
_mockDependency.Setup(d => d.GetNum()).Returns(_data.A);
_objectUnderTest = new MyClass(_mockDependency.Object);
}
[Test]
public void RunTest()
{
var result = _objectUnderTest.doSomething(_data.B);
Assert.That(result, Is.EqualTo(_data.C));
}
}
public class TestData
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public TestData(int a, int b, int c)
{
A = a;
B = b;
C = c;
}
}
public class MyClass
{
private readonly IMyDependency _dependency;
public MyClass(IMyDependency dependency)
{
_dependency = dependency;
}
public int doSomething(int b)
{
return _dependency.GetNum() + b;
}
}
public interface IMyDependency
{
int GetNum();
}
My issue is that all test cases appear to have the same name in the results. They are all simply called "RunTest", which makes it difficult to determine which tests are failing other than simply counting the number of the test and then counting my yield returns to find the correct one.
I would love to be able to set the test name programmatically using an additional property in the TestData class. I attempted to do this using TestContext.CurrentContext.Test.Name = _data.Name, but it turns out this property is readonly so I can't set it.
Is there a way to rename my tests programmatically while using TestFixtureSource?
You need to consider the sequence of execution...
Your TestFixtureSource runs to define what fixture instances will be created.
If you have any TestCaseSources, that code is run to define what tests will be added to the fixture.
*** At this point, the structure of your tests (namespaces, fixtures, test cases) is completely defined and can't be changed. Any overridden test names are already in place.
At this point, the tests start to run. In the console runner, it happens immediately. In a GUI or under VS it happens when the user clicks run. In the second case, it may happen multiple times.
Any OneTimeSetup runs
For each test in the fixture
Setup Runs
The test itself runs (provided Setup didn't throw)
Teardown Runs
Any OneTimeTeardown runs
Key thing here is the break between loading (aka creating or discovering) the tests and running them. Nothing can happen in steps 4 - 6 to change what was done in steps 1 and 2.
Regarding changing the name... It's a constraint within NUnit that users may only change the name of test cases. The part that comes before the test name ... including the displayed name of the fixture ... is invariable because NUnit relies on it. Changing that would give us a different framework, or at least a version of NUnit with breaking changes.
If I understand correctly, you currently have something like this:
but you would prefer something like this:
This is achievable by overriding the ToString() method of the class whose type is the test fixture's parameter - TestData in your code. For example:
public class TestData
{
<...>
public override string ToString() => $"A: {A}, B: {B}, C: {C}";
}
Doing this (with NUnit 3.8 installed) produces the sample output above.
(Caveat: Charlie led the NUnit team for about 13 years and says this can't be done, so even if I've understood the question correctly it's possible that this technique is inadvisable; use at your own risk! But I hope it helps.)
Edit: Please see comments below, especially Charlie's note that this approach should only be taken with test classes, not production classes.
Related
In Nunit I try to test a method. I prepared the same input as in production code, but still method which do my work doesn't call properly. Tried to mock it, with no effect at this moment.
I was told that moq is the answer and it won't be easy, but send me a "Similar" question from this forum. below is try of all that I could. all found in that topic was implemented, but service is still not called properly. Checked if in normal case it would work (program.cs) and there function is called, and works as it should.
public class Helper
{
public string a;
public string b;
public Helper(string aa, string bb)
{
a = aa;
b = bb; //here is some transformation, but I checked it, and it's working properly
}
}
public class Service
{
public static string NotWorkingFunction(Helper o)
{
InternallService w = ThatPrivateFunctionWorks(o);
return ThatPrivateFunctionDont(w);
}
private InternallService ThatPrivateFunctionWorks(Helper o)
{
return DLL_external.SomeInternalService(o); //call was ok in both program, and in NUnit
}
ThatPrivateFunctionDont(InternallService w)
{
return DLL_external.CallingServiceFarAwayFromDLL(w); //this one works if is in part of program, but does not from NUnit. checks if have permission from Windows Credentials, then do a work. Error here from NUnit is that he cannot even call this function!
}
}
public class InternallService
{
public string smth;
public InternallService(Helper o)
{
smth = o.a;
}
}
public class DLL_external
{
public InternallService SomeInternalService(Helper o)
{
InternallService p = new InternallService(o);
return p; //prepare service for function. does not need to connect. output also is checked n another way, and is ok.
}
public InternallService CallingServiceFarAwayFromDLL(InternallService o)
{
return o; //here it connects to the service (don't know how, which protocol etc. works if run under program.cs)
}
}
in Nunit
public class Test
{
[Test]
public void Tester()
{
Mock<Helper> MockedObject = new Mock<Helper>("a", "B"); //Mocking an object
Mock<Service> MockedService = new Mock<Service>(MockBehavior.Strict);
var Helper = new Helper("a", "B");
Service.NotWorkingFunction(MockedObject.Object); //still does not work properly. cannot call service inside the function (But very similar thing Can, but in Program.cs)
MockedService.Object.NotWorkingFunction(MockedObject.Object);//service does not call
MockedService.Setup(p => p.NotWorkingFunction(MockedObject.Object)); //found at Stack overflow, but still function is not called
//of course all uncompiling things are commented in mine code
}
}
Expected to work. but still don't know how call it to test from NUnit. Maybe I am wrong with tool, which I use.
The idea of unit testing is that you test individual units of code rather than the whole system. Integration testing is where you test the whole system. You should test each public interface of each class individually. If that class has dependencies that you want to exclude from the test, you can create mocks of those dependencies: these are fake objects that are called instead of calling your actual code.
For example, to test the function that you say is not working you write a test that calls that function, not a test that goes through the rest of the code to hopefully call that function. You need to set up the data the function being tested needs, either directly or with mock objects. So tests for Dll_External might start like this:
[TestFixture]
public class Dll_External_Tests
{
[Test]
public void ShouldReturnAnInternalServiceFromCallingServiceFarAwayFromDLL()
{
// setup
Helper helper = new Helper("a", "B");
InternallService internalService = new InternallService(helper);
DLL_external dLL_external = new DLL_external();
// act
var result = dLL_external.CallingServiceFarAwayFromDLL(internalService);
// assert
Assert.IsNotNull(result);
Assert.IsTrue(result is InternallService);
// add more assertions for what you expect the result to be
}
}
You will see this test does not use Service at all - it is only testing DLL_External and only creates the objects it needs to be able to do that.
Incidentally, the code you have shown won't compile: you need an object to call a method on. You can only call static methods directly on the class like ClassName.StaticMethod(). Also, it can be a bit confusing if your objects have the same name as the class, convention is that class names start with a capital letter and instances (objects) start with a lower case letter.
I have a class which contains an internal helper such as following code:
[assembly: InternalsVisibleTo("Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
namespace NS.B
{
public class A {
internal readonly B _bHealper;
public int GetBag(string s1, string s2){
return _bHelper.GetBag(s1, s2);
}
}
}
[assembly: InternalsVisibleTo("Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
namespace NS.B
{
internal class B
{
public int GetBag(string str1, string str2){
/// do some work
return result;
}
}
}
then I try to mock my helper inside A class and test A class GetBag function by this code:
[Fact]
public void checkBaggageRule()
{
var repo = Substitute.For<A>();
repo._bHelper.GetBag(Arg.Any<string>(), Arg.Any<string>()).Returns(30);
var result = repo.GetBag("oo", "L");
Assert.True(result != null);
Assert.True(result == 30);
}
but I am getting this exception while I debug my test:
NSubstitute.Exceptions.UnexpectedArgumentMatcherException : Argument
matchers (Arg.Is, Arg.Any) should only be used in place of member
arguments. Do not use in a Returns() statement or anywhere else
outside of a member call.
how can I mock this internal member and pass my test?
There's not quite enough code in the sample to tell for sure, but I'm not sure that the internal keyword is causing the problem here. If you make them all public instead do you get the same error?
There are a few other possible issues that could be causing problems for you here.
First, try installing the NSubstitute.Analyzers package, which will detect issues like trying to substitute for non-virtual members.
Next, the sample code does not show how A._bHelper gets initialised. Let's update it to use constructor injection, and we'll substitute for the dependency rather than the entire class under test (as pointed out by #Nkosi in the comments).
public class A
{
public A(MssqlEntityHelper helper) { _bHelper = helper; }
internal readonly MssqlEntityHelper _bHelper;
public int GetBag(string s1, string s2) {
return _bHelper.GetBag(s1, s2);
}
}
// Tests:
[Fact]
public void SampleTest() {
var repo = new NS.B.A(Substitute.For<NS.B.MssqlEntityHelper>());
repo._bHelper.GetBag(Arg.Any<string>(), Arg.Any<string>()).Returns(30);
var result = repo.GetBag("oo", "L");
Assert.True(result == 30);
}
As the NSubstitute.Analyzers package will point out, MssqlEntityHelper.GetBag() will need to be made virtual in order for NSubstitute to work with it:
public class MssqlEntityHelper {
public virtual int GetBag(string str1, string str2) { ... }
}
Those changes will get a passing test based on the sample code provided. The exact exception you are seeing may be as a result this test or problems in other tests, perhaps attempting to substitute for non-virtual members in earlier tests. Installing the NSubstitute.Analyzers package will hopefully help you find these cases. If this still doesn't resolve the problem there are a few other debugging steps we can try (running the test in isolation, running a single fixture, looking at test logs to see test execution order and seeing if preceding tests are causing problems that bleed into this test, etc.).
So in my test suite, I have an abstract base class that my integration tests inherit from. Each derivation of this base class has their own set of tests. The assertions that the child classes make are run through protected methods on the base class. During those assertions, the base class logs which values in a dictionary have been tested. After the child classes have run all their tests, I want the base class to run a test that verifies all the correct things were tested.
A few disclaimers:
Yes, I know this is an ordered test, and that those are frowned
upon. However, this is something I want to do anyway.
I know this is a test that tests my test suite, in a sense. While this is
often frowned upon, I find it useful. If you want your tests to
genuinely be your documentation, it is good to have some rudimentary
tests that verify some basic things about your documentation - that
it's complete, for example. (In most projects, this would probably
be overkill and not worth it. In this particular project, however,
it is both a personal project and an experiment in working with 100%
code coverage.)
For now, I have marked the summary test with both [Test] and [TestFixtureTearDown], which does make the test run at the end. However, it also means that when the test fails, the test suite gets angry because a tear down failed. What I want in an ideal world is something like [RunLast]. Any ideas on how one might be able to accomplish this?
Example of the code currently:
[TestFixture]
public abstract class AttributesTests : IntegrationTests
{
[Inject]
public IAttributesMapper AttributesMapper { get; set; }
protected abstract String tableName { get; }
private Dictionary<String, IEnumerable<String>> table;
private List<String> testedNames;
[TestFixtureSetUp]
public void FixtureSetup()
{
testedNames = new List<String>();
}
[SetUp]
public void Setup()
{
table = AttributesMapper.Map(tableName);
}
[Test, TestFixtureTearDown]
public void AllNamesTested()
{
var missingNames = table.Keys.Except(testedNames);
Assert.That(missingNames, Is.Empty, tableName);
}
[Test, TestFixtureTearDown]
public void NoNamesTestedNultipleTimes()
{
var duplicateNames = testedNames.Where(n => testedNames.Count(cn => cn == n) > 1).Distinct();
Assert.That(duplicateNames, Is.Empty, tableName);
}
protected void AssertAttributes(String name, IEnumerable<String> attributes)
{
testedNames.Add(name);
Assert.That(table.Keys, Contains.Item(name), tableName);
foreach (var attribute in attributes)
{
Assert.That(table[name], Contains.Item(attribute));
var actualAttributeCount = table[name].Count(a => a == attribute);
var expectedAttributeCount = attributes.Count(a => a == attribute);
Assert.That(actualAttributeCount, Is.EqualTo(expectedAttributeCount));
}
var extraAttributes = table[name].Except(attributes);
Assert.That(extraAttributes, Is.Empty);
}
}
This works for me:
namespace ZZZ
public class ZZZZZ {
[Test]
public void ZZZZLastTest() {
// Whatever . . .
}
}
There is no explicit [LastTest]-like attribute that I am aware off but I believe you can go with [Suite] instead.
I know this JUnit approach to suites will execute your test classes in lineair order as they are defined (although there is no guarantee to the order in which your tests inside one class are executed).
#RunWith(Suite.class)
#SuiteClasses({ CalculatorTestAdd.class, CalculatorTestSubtract.class })
public class AllTests {
}
Here CalculatorTestSubtract will be executed last. Keeping this in mind, I would say that you should create a suite which has your summary test at the end.
Looking at NUnit documentation, I see that something should be equally possible:
namespace NUnit.Tests
{
using System;
using NUnit.Framework;
private class AllTests
{
[Suite]
public static IEnumerable Suite
{
get
{
ArrayList suite = new ArrayList();
suite.Add(new OneTestCase());
suite.Add(new AssemblyTests());
suite.Add(new NoNamespaceTestFixture());
return suite;
}
}
}
}
You'll have to do some tests to see if they get executed linearly because an ArrayList is not guaranteed to be sorted.
Is it possible to skip all tests from a specific class like in NUnit
[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
No - there is no such facility at present, and the last time it was requested it was considered too low value to add,
One quick way of achieving the effect in xUnit is to comment out the public - private classes are not reflected over (obviously it won't appear on the skip list that way though).
UPDATE: Another way is to put a TraitAttribute on the class and then (assuming you're using the xunit.console runner) filter it out by running with /-trait traitName. (e.g. you can achieve ExplicitAttribute, some aspects of the BDD frameworky technique of Pending tests and similar semantics that way - of course the big problem is they don't show up in any reports when using any of these filtering techniques)
UPDATE 2: You can do
const string skip = "Class X disabled";
[Fact(Skip=skip)]
void Test() {}
Then you can change to to const string skip = null to undo the skip. The (dis)advantage of this is that the test is still shown as a Skipped test in the test list, generally with a reason included in the test run report (vs making it private which makes it likely to be forgotten)
Here is my hack to avoid error xUnit1000: Test classes must be public (checked on single Fact, I think Theories can be hacked this way, too).
// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!
// Uncomment to disable tests
internal class FactSwitch : Attribute { }
public class MyTests
{
[FactSwitch]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
(3 years later)
While searching for the same solution I found there are better ways to do the same.
Let's rewrite the example above in a way Ruben Bartelink suggested (continuation of his idea).
public class MyTests
{
//const string SkipOrNot = null; // Run all tests
const string SkipOrNot = "reason"; // Skip all tests
[Fact(Skip = SkipOrNot)]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
Nathan Cooper suggested a good improvement for my idea:
public class MyTests
{
// Uncomment to disable tests
//private class FactAttribute : Attribute { }
[Fact]
public void MyTest1()
{
"it".ShouldBe("it");
}
}
So I like both ideas from Ruben and Nathan. There is a subtle difference between using Skip="something" (Ruben) and not using Skip at all. Using "Skip" will put all your tests in a "Skipped tests" warning zone, while "FactAttribute : Attribute" will hide them.
I've found yet another way of temporary disabling entire class without compiler warning.
Disabled:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}
to enable move the /* one line up (i.e. using alt+up):
/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}
Note that using full namespace path for SupressMessage does not mess up with your usings.
You need to set the your class access level as as internal and surpress message as #Miq did:
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
You can create LocalOnlyFactAttribute
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => base.Skip = value; }
}
As far as I know, the simplest way to dynamically skip a whole xUnit test class at runtime is to use the TestFrameworkAttribute at the assembly level, to point to a class that implements the ITestFramework interface (or inherits from XunitTestFramework, which is simpler) and which overrides the CreateDiscoverer() method to return another class, that implements the ITestFrameworkDiscoverer interface (or inherits from XunitTestFrameworkDiscoverer, which is simpler), where you can finally override the IsValidTestClass() method, to decide whether a class should be skipped or not.
Here is some sample code:
[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]
namespace MyNamespace.Xunit
{
public class MyTestFramework : XunitTestFramework
{
public MyTestFramework(IMessageSink messageSink)
: base(messageSink)
{
}
protected override ITestFrameworkDiscoverer CreateDiscoverer(
IAssemblyInfo assemblyInfo)
=> new MyTestFrameworkDiscoverer(
assemblyInfo,
SourceInformationProvider,
DiagnosticMessageSink);
}
public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
{
public MyTestFrameworkDiscoverer(
IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IMessageSink diagnosticMessageSink,
IXunitTestCollectionFactory collectionFactory = null)
: base(
assemblyInfo,
sourceProvider,
diagnosticMessageSink,
collectionFactory)
{
}
protected override bool IsValidTestClass(ITypeInfo type)
=> base.IsValidTestClass(type) &&
FilterType(type);
protected virtual bool FilterType(ITypeInfo type)
{
// Insert your custom filter conditions here.
return true;
}
}
}
Tested with xUnit 2.4.1.
We are using it in Pomelo.EntityFrameworkCore.MySql (see AssemblyInfo.cs and MySqlXunitTestFrameworkDiscoverer.cs) (a bit more complex than the sample code here).
You could achieve this through a custom ITestClassCommand.
See http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html
Here's another hack that requires minimal changes to code
using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
Any compatible attribute can be used for the replacement.
If you also use the InlineDataAttribute then you'll need to define a replacement as I don't think there's an existing compatible attribute.
using InlineDataAttribute = DummyDataAttribute;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
public DummyDataAttribute(params object[] data)
{
}
}
Adding a reason almost after one year after the initial question. I have a set of tests which are calling real server apis, and I would like to run then on demand. With nUnit, it has Ignore attribute : with that set, test runner will skip those tests, but I can still manually run it.
xUnit has no such feature. The nearest one is setting such a class level attribute, and comment it out when I want to run it.
Consider creating LocalOnlyFactAttribute, which can be reused across multiple test files.
public class LocalOnlyFactAttribute : FactAttribute
{
//uncomment to run on local
//const string skip = null;
//keep this to avoid slow running tests on other env
const string skip = "Disabled slow running tests.";
public override string Skip { get => skip; set => this.Skip = value; }
}
I want that my unit tests to cover my POCO's.
How should I test them?
What If I add a new property? How to make my test fail?
Testing the properties and methods I know, but the problem is, how to make sure my tests fail is anything is added to my poco's.
Testing is about verifying whether what is written is able to do what it should do, nothing more, nothing less. So if you write some code, you do that for a reason. Your tests should reflect that the code indeed matches the reason you wrote the code for. That's it, there's nothing else. I.o.w.: if you write a bunch of classes, you should test whether the behavior you've written indeed is correct compared to what the behavior should do.
From the reading of your question, you either misunderstand what a POCO is, or you misunderstand unit testing.
A POCO is just an old fashioned object. It has state and behavior. You unit test the state by putting (setting) values in to the properties, and asserting that the value is what you expected. You unit test behavior by asserting expectations against methods.
Here would be an oversimplified example of a POCO and its tests. Notice that there's more test code than implementation code. When unit testing is done right (TDD), this is the case.
public class Person
{
private Name name = Name.Empty;
private Address address = Address.Empty;
private bool canMove;
public Name Name
{
set { name = value; }
get { return name; }
}
public Address Address
{
private set { address = value; }
get { return address; }
}
public bool CanMove
{
set { canMove = value; }
get { return value; }
}
public bool MoveToNewAddress(Address newAddress)
{
if (!CanMove) return false;
address = newAddress;
return true;
}
}
[TestFixture]
public class PersonTests
{
private Person toTest;
private readonly static Name NAME = new Name { First = "Charlie", Last = "Brown" };
private readonly static Address ADDRESS =
new Address {
Line1 = "1600 Pennsylvania Ave NW",
City = "Washington",
State = "DC",
ZipCode = "20500" };
[SetUp]
public void SetUp()
{
toTest = new Person;
}
[Test]
public void NameDefaultsToEmpty()
{
Assert.AreEqual(Name.Empty, toTest.Name);
}
[Test]
public void CanMoveDefaultsToTrue()
{
Assert.AreEqual(true, toTest.CanMove);
}
[Test]
public void AddressDefaultsToEmpty()
{
Assert.AreEqual(Address.Empty, toTest.Address);
}
[Test]
public void NameIsSet()
{
toTest.Name = NAME;
Assert.AreEqual(NAME, toTest.Name);
}
[Test]
public void CanMoveIsSet()
{
toTest.CanMove = false;
Assert.AreEqual(false, toTest.CanMove);
}
[Test]
public void AddressIsChanged()
{
Assert.IsTrue(toTest.MoveToNewAddress(ADDRESS));
Assert.AreEqual(ADDRESS, toTest.Address);
}
[Test]
public void AddressIsNotChanged()
{
toTest.CanMove = false;
Assert.IsFalse(toTest.MoveToNewAddress(ADDRESS));
Assert.AreNotEqual(ADDRESS, toTest.Address);
}
}
In order to make the test fail first, stub the methods or properties, but do not implement any behavior. Run the tests, watch them fail, then add in behavior one line at a time until it passes. Once it passes, stop. Do not write any more code unless you write more tests (unless you're refactoring, in which case you do not add behavior).
I believe that you shouldn't test
the framework along with your own code
for example if you have a auto
generated property like this:
public string Name
{get;set;}
it's not necessary to have a test
method to see if it's working fine.
You should not test the inner state of you class instead you should test its behavior.
Sometimes (some may say always) it's better to write the test before writing the code.This way you have to understand what you want do to instead of understanding how to do it.(This approach is called test driven development)
Here's the TDD cycle:
Write the test and get a red signal
Write the code and get a green signal
Refactor the code and you should get
a green signal
If you want to add a new feature to the class, write a test that fails because the feature has not been implemented, then implement the feature and see the test pass.
Or...
Run code-coverage metrics as part of the build. They will indicate if code gas been added without being covered by the tests.
Or...
Run mutation tests as part of the build. They will indicate if any tests that cover the code are just running through it and not actually testing anything.
Or all of the above.
Perhaps by POCOs you meant DTOs, in which case the answer would be:
No you should not test your DTOs -- rather, test the services that work with them.