nunit-core team mailing list archive
-
nunit-core team
-
Mailing list archive
-
Message #00176
[Bug 462896] Re: Please support abstract base types
It's such a nice writeup that I feel bad marking it "invalid." :-)
Nevertheless, NUnit does support what you are asking for, provided you
leave the TestFixtureAttribute off the abstract base class.
When you put the attribute on that class you are *insisting* that NUnit
instantiate it, which it cannot do. So, the pattern is to leave the
attribute off any base class you don't want separately instantiated as a
test and put it only on those leaf classes that are intended to run as
tests.
Any tests are inherited. A setup or teardown is inherited as well. In
2.4 you can only put the teardown in the base OR the derived class. In
2.5 you can put it in both of them. For more discussion, please come to
the nunit-discuss list.
** Changed in: nunit-3.0
Status: New => Invalid
--
Please support abstract base types
https://bugs.launchpad.net/bugs/462896
You received this bug notification because you are a member of NUnit
Core Developers, which is the registrant for NUnit Framework.
Status in NUnit Test Framework: Invalid
Bug description:
Ran across this interesting presentation:
http://www.infoq.com/presentations/integration-tests-scam
It suggested having "Contract" and "Collaboration" tests. "Contract" tests are tests that validate an interface implementation, thus enforcing (and checking) all "assumptions" that mock objects may make use of.
For example, a Collaboration test may make the assumption that for an ICollection<T> implementation, if you call ICollection<T>.Add() then ICollection<T>.Count will be incremented.
The Contract test would thus create an ICollection<T> implementation and actually assert that if you call ICollection<T>.Add(T) then ICollection<T>.Count will be incremented.
Of course, the "obvious" way to do this would be to use abstract classes for the tests themselves:
[TestFixture]
public abstract class CollectionContract {
protected abstract ICollection<T> CreateCollection();
[Test]
public void DoesAddIncrementCount()
{
var list = CreateCollection<int>();
var c = list.Count;
list.Add(1);
Assert.AreEqual(c+1, list.Count);
}
}
Of course, an abstract type isn't very useful, so for EACH implementation we'd provide an additional test fixture:
[TestFixture]
public class ListCollectionContract : CollectionContract {
protected override ICollection<T> CreateCollection<T>()
{
return new List<T>();
}
}
All well and good...except it doesn't work (in NUnit 2.4.8; haven't tested other versions).
The intention here is that the CollectionContract tests will be skipped (abstract type can't be instantiated), BUT that ALL of the CollectionContract tests will be executed AS PART OF ListCollectionContract (and ALL other CollectionContract subclasses).
This allows us to trivially test new interface implementations (in the above case, write one new class + one new method to get all ICollection<T> tests contained within CollectionContract).
The only alternative (that I can currently think of) is for ListCollectionContract to duplicate all of the test declarations within CollectionContract, and delegating them to an internal instance. This makes test maintenance annoying (and less flexible than what it could be).
References