I am trying to upgrade from NUnit 2 to NUnit 3.
And I built a Data-Driven-Helper to read test case data from several type of data files.
I found that NUnit 3.2's TestCaseSource that can pass parameters can help improve my Data-Driven-Helper, however, the problem is it keeps tell me
"Message: System.Reflection.TargetParameterCountException: Parameter count mismatch."
Here are test codes:
static public IEnumerable GetCases(string a)
{
yield return new object[] { "1", 1 };
}
[TestCaseSource(typeof(BaseFixtureTest), "GetCases", new object[] {"a"})]
public void someTest(string Path, int deg)
{
//*** some test logic
}
Related
Let's say I have the following test case that has been written using xUnit:
public static IEnumerable<object[]> testValues = new List<object[]>
{
new object[] {new double?[] {0.0}, 0.0, 0.0},
};
[Theory]
[MemberData(nameof(testValues))]
public void Test1(double?[] values, double expectedQ1, double expectedQ3)
{
// Test code
}
How could I express the same unit test in nUnit instead of xUnit?
Note: The main problem here seems to be the use of MemberData, which for so far, I haven't been able to find an nUnit equivalent. What would be the correct way of expressing such unit test cases in nUnit?
Like this:
public static IEnumerable<object[]> testValues = new List<object[]>
{
new object[] {new double?[] {0.0}, 0.0, 0.0},
};
[TestCaseSource(nameof(testValues))]
public void Test1(double?[] values, double expectedQ1, double expectedQ3)
{
// Test code
}
Note that NUnit has TheoryAttribute but you don't want it here. In NUnit, a Theory is a bit more than just a parameterized test. You should read the docs to understand what it is before deciding if you need it. Of course, you should read up on TestCaseSourceAttribute as well. :-)
Other attributes in NUnit that allow data to be specified for a test case include TestCaseAttribute, ValuesAttribute, ValueSourceAttribute, RandomAttribute and RangeAttribute.
I have a test that takes in test data. When using nunit console app to run the test, is there a way I can specify the data to be used?
Eg:
[Test, TestCaseSource(typeof(TestData))]
public void ATest(string param1, int param2)
public class TestData : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new object[] { "blah1 blah1", 1};
yield return new object[] { "blah2 blah2", 2};
}
}
I want to be able to run ATest with test data ["blah2 blah2", 2] only. If I run as follows:
nunit3-console.exe Tests.dll --test=ATest --workers=1 --noresult
it will run twice.
Just run...
nunit3-console.exe Tests.dll --test ATest("blah2 blah2", 2)
or
nunit3-console.exe Tests.dll --where "test~=blah2"
If that string is unique to all your tests.
Note that the first one may require some escaping of the quotes, depending on your operating system.
One way to do this would be through returning a TestCaseData object instead.
Something like this: (untested, so syntax might be a little off!)
[Test, TestCaseSource(typeof(TestData))]
public void ATest(string param1, int param2)
public IEnumerator GetEnumerator()
{
yield return new TestCaseData("blah1 blah1", 1).SetName("FirstTest");
yield return new TestCaseData("blah2 blah2", 2).SetName("SecondTest");
}
To run the first test, you would then use the command line:
nunit3-console.exe Tests.dll --test=YourNameSpace.ATest.FirstTest --workers=1 --noresult
Depending what you're doing, setting the category may be more suitable than the name. The docs page shows what's available: https://github.com/nunit/docs/wiki/TestCaseData
I'm using NUnit 3.0 and TestFixtureSource to run test cases inside a fixture multiple times with different parameters/configurations (I do want to do this at TestFixture level). Simple example:
[TestFixtureSource(typeof (ConfigurationProvider))]
public class Fixture
{
public Fixture(Configuration configuration)
{
_configuration = configuration;
}
private Configuration _configuration;
[Test]
public void Test()
{
//do something with _configuration
Assert.Fail();
}
}
Let's say Test() fails for one of the configurations and succeeds for another. In the run report file and in Visual Studio's Test Explorer the name for both the failed and the succeeded runs will be displayed as just Test(), which doesn't tell me anything about which setup caused issues.
Is there a way to affect the test cases names in this situation (i.e. prefix its name per fixture run/configuration)? As a workaround I'm currently printing to the results output before each test case fires but I would rather avoid doing that.
Since NUnit 3.0 is in beta and this feature is fairly new I wasn't able to find anything in the docs. I found TestCaseData but I don't think it's tailored to be used with fixtures just yet (it's designed for test cases).
I can't find a way to change the testname, but it should not be neccessary, because NUnit3 constructs the testname by including a description of the testfixture.
The example class Fixture from the question can be used unchanged if the Configuration and ConfigurationProvider has an implementation like this:
public class Configuration
{
public string Description { get; }
public Configuration(string description)
{
Description = description;
}
public override string ToString()
{
return Description;
}
}
public class ConfigurationProvider : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new Configuration("Foo");
yield return new Configuration("Bar");
yield return new Configuration("Baz");
}
}
The 'trick' is to make sure the constructor-parameter to the fixture is a string or has a ToString-method that gives a sensible description of the fixture.
If you are using NUnit 3 Test Adapter in Visual Studio, then the testfixtures will be displayed as Fixture(Foo), Fixture(Bar) and Fixture(Baz) so you can easily distinguish between their tests. The xml-output from nunit3-console.exe also uses descriptive names, fx: fullname=MyTests.Fixture(Bar).Test
<test-case id="0-1003" name="Test" fullname="MyTests.Fixture(Bar).Test" methodname="Test" classname="MyTests.Fixture" runstate="Runnable" result="Failed" ... >
<failure>
<message><![CDATA[]]></message>
<stack-trace><![CDATA[at MyTests.Fixture.Test() in ... ]]></stack-trace>
</failure>
...
</test-case>
One way to perform such actions is to have find and replace tokens in source code and dynamically build test libraries before execution using command line msbuild. High level steps are
Define test case names as sometest_TOKEN in source then using command line tools like fnr.exe replce _TOKEN with whatever you like. For example sometest_build2145.
Compile the dll with using msbuild for example msbuild /t:REbuild mytestproj.sln. Thereafter execute all test cases in mytestproj.dll.
i have a ASP.Net project and Nunitasp framework work for unit testing,i have a object in account.aspx.cs file when i tried to test the object(NugetplatformModel) value i get"object reference not set to an instance" error,
my account page code is given below
public partial class Account : System.Web.UI.Page
{
public NugetPlatformModel NugetPlatformModels;
public string result = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!WebSecurity.IsAuthenticated)
{
Response.Redirect("/login", true);
}
else
{
result = "success";
NugetPlatformModels = new NugetPlatformModel();
}
}
my test case code is given below
[Test]
public void AccountPage_ValidCredential_AccessModel()
{
Browser.GetPage(domain + "account");
string ExpectedPage = domain + "account";
logon();
Account acccountPage = new Account();
AssertEquals("success", acccountPage.result);
AssertEquals("should have license",true,acccountPage.NugetPlatformModels.IsHavingLicense);
}
How can I access and test that code behind variables? when start the testing the NUgetplatformmodel has been assigned i have checked it by debugging but after that in nunit gui it displays null reference error, i thought there is a problem in accessing variable in testcase..please help me..
It seems your code is not complete. From what I see here your account needs to run Page_Load in order to fill result and NugetPlatformModels. But I do not see how this method is launched in your test. Is it run from the constructor of Account?
It would be helpfull if you put all the code for Account in your post.
I have a base object, that contains a Version property, marked as ConcurrencyCheck
public class EntityBase : IEntity, IConcurrencyEnabled
{
public int Id { get; set; }
[ConcurrencyCheck]
[Timestamp]
public byte[] Version { get; set; }
}
This works, however, I want to write a test to ensure it doesn't get broken. Unfortunately, I can't seem to figure out how to write a test that doesn't rely on the physical database!
And the relevant test code that works, but uses the database...
protected override void Arrange()
{
const string asUser = "ConcurrencyTest1"; // used to anchor and lookup this test record in the db
Context1 = new MyDbContext();
Context2 = new MyDbContext();
Repository1 = new Repository<FooBar>(Context1);
Repository2 = new Repository<FooBar>(Context2);
UnitOfWork1 = new UnitOfWork(Context1);
UnitOfWork2 = new UnitOfWork(Context2);
Sut = Repository1.Find(x => x.CreatedBy.Equals(asUser)).FirstOrDefault();
if (Sut == null)
{
Sut = new FooBar
{
Name = "Concurrency Test"
};
Repository1.Insert(Sut);
UnitOfWork1.SaveChanges(asUser);
}
ItemId = Sut.Id;
}
protected override void Act()
{
_action = () =>
{
var item1 = Repository1.FindById(ItemId);
var item2 = Repository2.FindById(ItemId);
item1.Name = string.Format("Changed # {0}", DateTime.Now);
UnitOfWork1.SaveChanges("test1");
item2.Name = string.Format("Conflicting Change # {0}", DateTime.Now);
UnitOfWork2.SaveChanges("test2"); //Should throw DbUpdateConcurrencyException
};
}
[TestMethod]
[ExpectedException(typeof(DbUpdateConcurrencyException))]
public void Assert()
{
_action();
}
How can I remove the DB requirement???
I would recommend extracting your MyDbContext into an interface IMyDbContext, and then creating a TestDbContext class that will also implement SaveChanges the way you have it up there, except with returning a random value (like 1) instead of actually saving to the database.
At that point then all you'd need to do is to test that, in fact, all of the entities got their version number upped.
Or you could also do the examples found here or here, as well.
EDIT: I actually just found a direct example with using TimeStamp for concurrency checks on this blog post.
It's my opinion that you should not try to mock this behaviour to enable "pure" unit testing. For two reasons:
it requires quite a lot of code that mocks database behaviour: materializing objects in a way that they have a version value, caching the original objects (to mock a store), modifying the version value when updating, comparing the version values with the original ones, throwing an exception when a version is different, and maybe more. All this code is potentially subject to bugs and, worse, may differ slightly from what happens in reality.
you'll get trapped in circular reasoning: you write code specifically for unit tests and then... you write unit tests to test this code. Green tests say everything is OK, but essential parts of application code are not covered.
This is only one of the many aspects of linq to entities that are hard (impossible) to mock. I am compiling a list of these differences here.