Hi Charlie,
[...]
> Yes... with the addition that the constructor is actually guaranteed _not_ to
> run once per test! NUnit historically chose the pattern of use where
> one instance of the fixture is used for all tests.
Okay, so the constructor currently has the same semantics as a
TestFixtureSetUp method?
[...]
>> - You can't use simple field initializer expressions.
>
> Except as below...
>
>> - You can't make fields readonly to express that tests are not
>> supposed to change the values of those fields.
>
> Actually, there's no harm in using simple readonly fields initialized in the
> constructor. I do that all the time. You want to avoid readonly instances
> (e.g. collections) where a test could change the contents.
You're right of course. I've made avoiding field initializers a
general rule for my own tests, as it's simply more robust and avoids
mistakes, but it's of course possible to make a case-by-case decision.
>> Is this something that may be changed for NUnit 3.0 (or maybe even before)?
>
> Maybe for 3.0. Such a major change would justify calling the release (at least)
> 2.7, and we don't plan for it. BTW, I say "major" with respect to the
> implications
> for users, not because it's a lot of work. Actually, it should be easy.
Yep, I thought so. One thing to consider would be a replacement for
TestFixtureSetUp and TestFixtureTearDown - now often used as a
performance improvement for lengthy initialization code. Maybe static
TestFixtureSetUp and TestFixtureTearDown methods could be the way to
go then.
> One possibility for NUnit 3.0 is to allow either model - single instance or one
> per test - with one of them selected as the default. What do folks think of
> this idea?
I think the main reason why one would choose the "classic model"
(assuming the two models are equivalent in functionality) is backwards
compatibility. There are two compatibility concerns:
- tests that have TestFixtureSetUp and TestFixtureTearDown instance
methods, as those wouldn't (couldn't) work as expected any more, and
- existing tests that rely on the guarantee that a test fixture is
constructed only once, using the fixture's ctor as a replacement for
TestFixtureSetUp (and IDisposable for TestFixtureTearDown).
Yes, for such tests (of which we ourselves have quite many), a
compatibility mode would be required, I think.
>> If so, I'd suggest also allowing to use IDisposable instead of or in
>> addition to TearDown methods, as the Dispose method is the "natural"
>> way of disposing the members initialized from within the constructor.
>
> IDisposable is already supported. If you implement it on your fixture class, it
> will be called right after TestFixtureTearDown.
Great, I didn't know that. If the ctor behaves like TestFixtureSetUp,
it's logical to have IDisposable behave like TestFixtureTearDown.
In the new model, those semantics would be changed to SetUp and
TearDown semantics.
Fabian