I ran into something interesting today which confused me for a while.
Working on a client site, they have an inheritance stack 4 levels deep for integration tests. Completely unnecessary, but why start singing that song right now… I’ll save it for another series of posts.
Anyhow, I was using the R# test runner and my base class overrides a function which is called by the base, base, base classes TestFixtureSetup method. No classes apart from my base class were attributed with the TestFixture attribute (apparently that’s not necessary anymore; as NUnit will identify tests and do its thing without it now).
My problem was that my TestFixtureSetup overridden method was executing twice, and immediately after the first (successful) run, the base class would be marked as ignored in the test runner. Then the setup would be run again for the test class inheriting from it… Hmmm. Two things:
- If a class is marked as a Test Fixture but contains no tests, R# will run it and then mark it as ignored (it will go yellow)
- Any class that is marked as a TestFixture will be instantiated and any TestFixtureSetup / Setup will be run by NUnit, regardless of whether the class actually contains any tests.
So what was happening is that the base class was being instantiated and it’s setup run, as it was marked as a TestFixture and it was public. Then the child class was being instantiated and because of its polymorphic relationship with the base class, the setup was running again.
Removing the TestFixture attribute from the base class stopped the behavior, as well as making the class abstract.
- Mark all base classes in a test inheritance hierarchy as abstract, so that NUnit doesn’t actually do anything until it finds a real test class in the stack
- Don’t bother marking classes as TestFixtures anymore
- Remember that setups will run from the bottom of the inheritance hierarchy upwards, in order.