nunit-core team mailing list archive
-
nunit-core team
-
Mailing list archive
-
Message #01025
Re: [Bug 633884] Re: TestCaseSource does not use Arguments, Categories etc as described in documentation for 2.5.7
Hi Hamish,
I think I'll start again. :-)
Let's say I have a test that I want to run multiple times with
differing arguments. I decide
to use TestCaseSourceAttribute to specify them. The source may be a
field, a method
or a property and should provide an IEnumerable of some type. There
are three choices
with regard to that type:
1. It may be an object array that gives the arguments needed by the
test method, e.g.:
object[] TestArguments = new object[] {
new object[] { 5, "five" },
new object[] { 42, "answer" }
};
In this case the outer object[] is providing the IEnumerable and each
inner object[]
represents a test case. The method signature would have to be M(int, string);
This approach does not allow you to do things like ignoring an
individual case.
2. It may be the exact type required by the method, but only when the method
takes just one argument, e.g.:
int[] TestArguments = new int[] { 5, 42 };
The method signature for this case would be M(int);
This approach does not allow ignoring a test case, etc.
As a special case of this approach, you could pass in a custom struct
or class, e.g.:
object[] TestArguments = new object[] {
new MyStruct( 5, "five"),
new MyStruct( 42, "answer")
};
This last is what you have done and it does not allow ignoring tests
or any of the
other special things suggested in the docs.
3. You may use TestCaseData or any type of your own which has some of the
same properties which are supported by TestCaseData. One of those properties
is Arguments and the items provided there must match the method parameters.
So, for example...
TestCaseData[] TestArguments = new TestCaseData[] {
new TestCaseData(5, "five").Ignore("Still under development),
new TestCaseData(42, "answer")
};
This is the only approach that allows use of Ignore, SetCategory, etc.
So...
The obvious question is "If I define a custom struct or class, how does
NUnit decide whether I'm using approach #2 or #3?"
I had to look at the code to figure it out. It checks for the presence of the
interface NUnit.Framework.ITestCaseData. Note that the interface is not
actually used by NUnit. In order to support multiple framework versions,
reflection is used. But the interface helps identify the class and helps
you to make sure you are implementing the correct properties.
In fact, the entire approach of defining your own replacement for TestCaseData
is probably not worth supporting any longer. The only reason I can see for
defining your own replacement is if you want to use a different fluent syntax
from that supported by TestCaseData.
However, so long as you use the ITestCaseData interface, your code will be
pretty compatible with version 3.0 - the interface could change, but
will likely
only add new properties.
I hope this clears things up. The entire area is a bit too complex for my taste,
so the basic docs will probably just say to use TestCaseData in the future,
and the stuff about implementing your own class will only be discussed
under the heading of extending NUnit.
Charlie
> Thanks. I'm afraid I don't understand your recommendation.
>
> This is the first bit I don't follow:
> "If you want your test to process the contents of your own struct or class, then use it as an argument and return that type."
>
> Do you mean
> [TestCaseSource(typeof(SimTestDataGenerator), "TestArguments")]
> public void IndividualTestCasesShouldBeGenerated(Type simTestDescriptorClass) ?
>
> What do I return "that type" from?
>
> Sorry but I'm feeling pretty foolish here. Can you give me an example?
>
> I don't follow this either:
> "If you want NUnit to perform processing described, then the actual arguments should be stored in an Arguments member."
> A member of which class?
>
> You also say
> "In fact, in that case, you may as well use TestCaseData, which contains all the functionality you are looking for and will also continue to work under NUnit 3.0, where we no longer use reflection in this way."
>
> I don't want to write code that will be deprecated in the next version
> of NUnit so does that mean TestCaseData will be the only way forward?
>
> I don't think I'm stupid but I'm coming at this for the first time and I
> suspect the gulf between your familiarity and mine is the problem.
>
> Thanks for your time.
>
> --
> TestCaseSource does not use Arguments, Categories etc as described in documentation for 2.5.7
> https://bugs.launchpad.net/bugs/633884
> You received this bug notification because you are a member of NUnit
> Developers, which is subscribed to NUnit V2.
>
--
TestCaseSource does not use Arguments, Categories etc as described in documentation for 2.5.7
https://bugs.launchpad.net/bugs/633884
You received this bug notification because you are a member of NUnit
Developers, which is subscribed to NUnit V2.
Status in NUnit V2 Test Framework: Triaged
Bug description:
What happens:
Created a class X that is returned as an IEnumerable<X> in method M of class Z.
This is used in [TestCaseSource(typeof(Z), "M"]
Class X has been given
public string TestName { get; private set; }
public IList<string> Categories { get; private set; }
public bool Ignored;
In the constructor for X, these have been initialised
this.Categories = new List<string> { "foo" };
this.TestName = note;
this.Ignored = true;
The test is executed(contrary to Ignored==true).
There are no categories in the NUinit GUI.
The test is not renamed.
What I expect:
The test is flagged as ignore.
There is a category "foo".
The test is named after the string value in TestName.
NUnit 2.5.7.
Nunit.exe (GUI)
References