Re: Tearing down when SetUp fails?
"Charlie Poole" <[email protected]> Wed, 17 Sep 2008 14:29:15 -0700
| Newsgroups | gmane.comp.windows.dotnet.nunit.devel |
|---|---|
| Message-ID | <007901c9190c$70e186a0$6402a8c0@ferrari> |
Hi Kelly, > Ok Charlie, I totally understand the SetUp TearDown thing in > the inheritance model. That makes sense, because it's just > like constructors and destructors (at least in C++, let's not > get into the weird end of life of C# objects) and the order > they are executed makes sense because of that prior > experience. I think I've done this myself, in fact. It was useful. I undersand what you mean. And it's a fairly natural way to think as well - which is why folks asked for it. > That being said, if you have two SetUps in the same class, I > would assume they are all executed prior to calling each > test. But how do you know which one is executed first? Or > must the order of execution not matter to be safe? My answer is that it must not matter. This will, of course, need to be documented. Charlie > -Kelly > > On Tue, Sep 16, 2008 at 9:46 PM, Charlie Poole > <[email protected]> wrote: > > Hi Guys, > > > > This isn't planned - it's implemented. :-) > > > > The motivation for multiple setups is to allow use of inheritance, > > with base class setups called before derived class and teardowns > > called in the reverse order. [Note I'm using lower case to > mean "all > > kinds of setup.] > > > > Having multiple setups in the same class - not just in the > base is a > > fallout of the implementation. In other words, the simplest > thing to > > do was to just let it happen - it would take more code ot > detect and > > prevent it. We can do that, but I always like to have a > reason before > > doing extra work. :-)h > > > > It's possible that figuring out how to handle failures may > serve as > > the reason for that work, but I don't see it yet. > > > > If we change to always running teardown if setup was run, > then there > > is no problem. NUnit would just treat multiple setups at the same > > level as if it were one big setup. It's only if we have to > > discriminate among them that it gets hard. In that case, > I'd write the > > code to prevent it, but otherwise, I'd just let it happen. > > > > Charlie > >> -----Original Message----- > >> From: [email protected] > >> [mailto:[email protected]] On > Behalf Of > >> Olof Bjarnason > >> Sent: Tuesday, September 16, 2008 12:45 PM > >> To: [email protected] > >> Subject: Re: [nunit-developer] Tearing down when SetUp fails? > >> > >> Start simple, extent if needed ... > >> > >> So one Setup, one TearDown is my vote > >> > >> 2008/9/15 Kelly Anderson <[email protected]>: > >> > Multiple Setups seems like a bad idea to me. If you need > multiple > >> > setups, why not have multiple TestFixture classes? > >> > > >> > What order would they run in? How do you associate a > >> particular SetUp > >> > with a particular TearDown... this sounds like opening > up a can of > >> > worms with no real payback. > >> > > >> > Is this really being considered seriously? > >> > > >> > -Kelly > >> > > >> > On Fri, Sep 12, 2008 at 3:22 PM, Hans Christian Falkenberg > >> > <[email protected]> wrote: > >> >> (Let me just try again with batteries in the crazy keyboard) > >> >> > >> >> Ah, I thought I had some place about support for > multiple [SetUp], > >> >> but I couldn't remember if it was decided for or against, > >> so I read > >> >> the 2.5 docs (which understandably aren't up to date > yet then) and > >> >> concluded that there would only be a single [SetUp]. > >> >> > >> >> With multiple ones, the conclusion is a given, I think. > >> >> Consider this: > >> >> > >> >> [SetUp] public void SetUp1() { > >> >> Acquire1(); > >> >> } > >> >> [SetUp] public void SetUp2() { > >> >> Acquire2(); > >> >> } > >> >> > >> >> [TearDown] public void TearDown1() { > >> >> Release1(); > >> >> } > >> >> > >> >> [TearDown] public void TearDown2() { > >> >> Release2(); > >> >> } > >> >> > >> >> Now, if SetUp1 succeeds and SetUp2 throws - what are > you gonna do? > >> >> Annotate which [TearDown] belongs to which [SetUp]? > >> >> That's the sure road to overhead, strange constraints and > >> confusion. > >> >> > >> >> To me it looks like the only intuitive and easily > understandable > >> >> approach is: > >> >> 1. If any [SetUp] method throws, no further [SetUp] > methods will be > >> >> called. > >> >> 2. All [TearDown] methods will *always* be called. > >> >> (Just check for null values, people) 3. Correspondingly > >> >> [TestFixture*], obviously > >> >> > >> >> But feel free to correct me with coming up with something > >> simpler :) > >> >> > >> >> + Hans Christian > >> >> > >> >> > >> >> On Fri, 12 Sep 2008, Charlie Poole wrote: > >> >> > >> >>> OK, I re-read your first mail and I now see you did make a > >> >>> distinction betweeen running resharper and nunit-console. > >> >>> > >> >>> I want to do some research before I get back to you on > >> the "how it > >> >>> should be" part. I have a vague sense that we may have > >> changed the > >> >>> behavior from what the docs say as the result of a user > >> request and > >> >>> if so I'd like to get the reasons for that request into the > >> >>> discussion. > >> >>> > >> >>> One part I can explain: in the 2.4 docs I meant the > phrase "any > >> >>> setup method" to mean "either SetUp or TestFixtureSetUp." > >> >>> It's still not working as described, but I should have > spelled it > >> >>> out for clarity. > >> >>> > >> >>> In 2.5, there can be multiple SetUp methods, and the > >> logic of which > >> >>> TearDowns should and should not be run still has to be > >> determined. > >> >>> Since there is not likely to be another 2.4 release, it's > >> 2.5 that > >> >>> is the key to this discussion. > >> >>> > >> >>> Charlie > >> >>> > >> >>> Charlie > >> >>> > >> >>>> -----Original Message----- > >> >>>> From: Hans Christian Falkenberg [mailto:[email protected]] > >> >>>> Sent: Friday, September 12, 2008 1:12 PM > >> >>>> To: Charlie Poole > >> >>>> Cc: [email protected] > >> >>>> Subject: RE: [nunit-developer] Tearing down when SetUp fails? > >> >>>> > >> >>>> Err, well sorry about the name of the test - I > >> originally used it > >> >>>> to submit a bug report to ReSharper because I saw different > >> >>>> behavior wrt. whether the [TearDown] method was invoked > >> when I used > >> >>>> 1) nunit-console.exe (see my exact command in orig mail) and > >> >>>> 2) Right click -> Run Unit Tests (with ReSharper in VS) > >> >>>> > >> >>>> So the answer is most likely that I used both :) > >> >>>> > >> >>>> After submitting that bug report I noticed that even > >> NUnit does it > >> >>>> different between [TearDown] and > [TestFixtureTearDown] so I read > >> >>>> the documentation and then I wrote this mail. > >> >>>> > >> >>>> + Hans Christian > >> >>>> > >> >>>> PS! I also told the ReSharper guys (who replied just an > >> hour after > >> >>>> my bug report that they would look on the issue) that I > >> started a > >> >>>> discussion on what the behavior should be in NUnit. > >> >>>> > >> >>>> On Fri, 12 Sep 2008, Charlie Poole wrote: > >> >>>> > >> >>>>> Hi Hans Christian, > >> >>>>> > >> >>>>> We should discuss this behavior and try to get it right > >> >>>> (whatever we > >> >>>>> decide that is) for 2.5. > >> >>>>> > >> >>>>> But before we get into it, because of the name of your > >> test, I'm > >> >>>>> wondering if you actually ran under NUnit. > >> >>>>> When you run under resharper, no matter what version of > >> the NUnit > >> >>>>> framework your test references, you get the semantics that > >> >>>> resharper > >> >>>>> defines. That's because this particular behavior is not > >> >>>> implemented in > >> >>>>> nunit.framework, but in nunit.core, which is not > used in this > >> >>>>> situation. > >> >>>>> > >> >>>>> I'll run my own tests as well, but I thought I should ask. > >> >>>>> > >> >>>>> > >> >>>>> Charlie. > >> >>>>> > >> >>>>>> -----Original Message----- > >> >>>>>> From: [email protected] > >> >>>>>> [mailto:[email protected]] > >> On Behalf > >> >>>>>> Of Hans Christian Falkenberg > >> >>>>>> Sent: Friday, September 12, 2008 5:33 AM > >> >>>>>> To: [email protected] > >> >>>>>> Subject: [nunit-developer] Tearing down when SetUp fails? > >> >>>>>> > >> >>>>>> Hi, > >> >>>>>> > >> >>>>>> I was about to post a bug about this - but then I read the > >> >>>>>> documentation and realized this might be something up for > >> >>>>>> discussion. Please let me know if it's there's a previous > >> >>>>>> conclusion on this and I'll just submit the bug report... > >> >>>>>> > >> >>>>>> Issues: > >> >>>>>> 1. TearDown behavior is inconsistent between > >> >>>>>> [TearDown] and [TestFixtureTearDown] 2. The > documentation > >> >>>>>> specifies that it should > >> >>>>>> do the Wrong Thing (imho) :p > >> >>>>>> > >> >>>>>> What I think should happen: > >> >>>>>> If there is an exception in any [SetUp] method, still run > >> >>>>>> all [TearDown] methods. > >> >>>>>> If there is an exception in any > [TestFixtureSetUp] method, > >> >>>>>> still run all [TestFixtureTearDown] methods. > >> >>>>>> (I realize only one of each method is allowed, but the doc > >> >>>> says "any") > >> >>>>>> > >> >>>>>> What the documentation says (in both 2.4.8 and 2.5 alpha 3): > >> >>>>>> So long as any SetUp method runs without error, the > >> TearDown > >> >>>>>> method is > >> >>>>>> guaranteed to run. It will not run if a SetUp > >> method fails or > >> >>>>>> throws an > >> >>>>>> exception. > >> >>>>>> and > >> >>>>>> So long as any TestFixtureSetUp method runs without > >> error, the > >> >>>>>> TestFixtureTearDown method is guaranteed to run. It > >> will not > >> >>>>>> run if a > >> >>>>>> TestFixtureSetUp method fails or throws an exception. > >> >>>>>> > >> >>>>>> What actually happens (in both 2.4.8 and 2.5 alpha 3): > >> >>>>>> Running attached code: > >> >>>>>> c:\>"c:\Program Files\NUnit 2.4.8\bin\nunit-console.exe" > >> >>>>>> /nologo bin\Debug\Dummy.dll > >> >>>>>> Fixture Setting up > >> >>>>>> .Setting up > >> >>>>>> Tearing down > >> >>>>>> FFixture Tearing down > >> >>>>>> > >> >>>>>> Tests run: 1, Failures: 1, Not run: 0, Time: > 0.030 seconds > >> >>>>>> Uncommenting FixtureSetUp exception: > >> >>>>>> c:\>"c:\Program Files\NUnit 2.4.8\bin\nunit-console.exe" > >> >>>>>> /nologo bin\Debug\Dummy.dll > >> >>>>>> Fixture Setting up > >> >>>>>> .F > >> >>>>>> Tests run: 1, Failures: 1, Not run: 0, Time: > 0.028 seconds > >> >>>>>> > >> >>>>>> > >> >>>>>> So [TearDown] doesn't behave as specified when a > >> [SetUp] method > >> >>>>>> throws an exception, that's a bug report, right? > >> >>>>>> > >> >>>>>> Except I think it *should* behave that way, so I > was going to > >> >>>>>> submit a bug report on [TestFixtureTearDown] :) > >> >>>>>> > >> >>>>>> Here's my reasoning: > >> >>>>>> Say you are acquiring two resources in the SetUp method: > >> >>>>>> [SetUp] public void SetUp() { > >> >>>>>> r1 = Resources.Acquire1(); > >> >>>>>> r2 = Resources.Acquire2(); > >> >>>>>> } > >> >>>>>> > >> >>>>>> And of course the must be released: > >> >>>>>> [TearDown] public void TearDown() { > >> >>>>>> Resources.Release(r1); > >> >>>>>> r1 = null; > >> >>>>>> Resources.Release(r2); > >> >>>>>> r2 = null; > >> >>>>>> } > >> >>>>>> > >> >>>>>> Now, since Resource.Release will just return if its > >> argument is > >> >>>>>> null and never throws, everything is fine. Except if the > >> >>>>>> documentation is to believed: If an exception can > occur while > >> >>>>>> acquiring r2 (and it can), we'll have to write this: > >> >>>>>> > >> >>>>>> [SetUp] public void SetUp() { > >> >>>>>> r1 = Resources.Acquire1(); > >> >>>>>> try { > >> >>>>>> r2 = Resources.Acquire2(); > >> >>>>>> } catch { > >> >>>>>> Resources.Release(r1); > >> >>>>>> throw; > >> >>>>>> } > >> >>>>>> } > >> >>>>>> > >> >>>>>> Which I think is bad, but I guess not *that* bad... > until you > >> >>>>>> have 4-5 resources. Then there's suddenly a crazy amount of > >> >>>>>> TearDown code duplication in SetUp. So here is how I > >> decided to > >> >>>>>> work around this problem: > >> >>>>>> > >> >>>>>> [SetUp] public void SetUp() { > >> >>>>>> setUpCalled = true; > >> >>>>>> r1 = Resources.Acquire1(); > >> >>>>>> r2 = Resources.Acquire2(); > >> >>>>>> } > >> >>>>>> > >> >>>>>> [TearDown] public void TearDown() { > >> >>>>>> if (!setUpCalled) return; > >> >>>>>> setUpCalled = false; > >> >>>>>> Resources.Release(r1); > >> >>>>>> r1 = null; > >> >>>>>> Resources.Release(r2); > >> >>>>>> r2 = null; > >> >>>>>> } > >> >>>>>> > >> >>>>>> Not the worst of solution's, but now I'm basically > >> doing NUnit's > >> >>>>>> work myself. And when the methods in TearDown *can* throw > >> >>>>>> Exceptions they will now be reported as if they > were thrown in > >> >>>>>> SetUp, which is just to ask for someone being > confused later. > >> >>>>>> But at least the code will release resources > properly in both > >> >>>>>> NUnit 2.4.8 (and 2.5 alpha 3), ReSharper 4.1.933.3 > >> (which behaves > >> >>>>>> like the NUnit doc says it should) and future NUnit > versions > >> >>>>>> which might adhere to the documentation. > >> >>>>>> > >> >>>>>> So... could we instead please change the NUnit > >> behavior so that > >> >>>>>> other people don't have to write workarounds like this? > >> >>>>>> > >> >>>>>> I know junit doesn't run TearDown (or didn't when I > >> last used it > >> >>>>>> a year back) when SetUp throws, but junit didn't > report test > >> >>>>>> exceptions when TearDown throwed either, so not much > >> cause to let > >> >>>>>> them set the standard here... > >> >>>>>> > >> >>>>>> A better argument against might be that people didn't > >> write code > >> >>>>>> to check for null in their [TearDown] and > >> [TestFixtureTearDown] > >> >>>>>> methods. But then their [TearDown] methods are already > >> failing, > >> >>>>>> and they'll just have to fix their > >> [TestFixtureTearDown] methods > >> >>>>>> when upgrading to 2.5, > >> >>>> won't they? > >> >>>>>> > >> >>>>>> + Hans Christian > >> >>>>>> > >> >>>>>> > >> >>>>>> > >> >>>>>> PS: If you are wondering wth. I'm thinking wrt. > acquiring 4-5 > >> >>>>>> resources before a unit tests... Well, the > resources are files > >> >>>>>> (with Acquire==Create and Release==Delete) and it > >> would hardly be > >> >>>>>> proper to use mocked files for unit testing when > >> testing writing > >> >>>>>> to the OS - that would kind of void the entire testing. > >> >>>>>> > >> >>>>>> PPS: Why should a unit test need files? Well - it does. > >> >>>>>> > >> >>>>> > >> >>>>> > >> >>>>> > >> >>>> > >> >>> > >> >>> > >> >>> > >> >> > >> >> > >> > --------------------------------------------------------------------- > >> >> ---- This SF.Net email is sponsored by the Moblin Your Move > >> >> Developer's challenge Build the coolest Linux based > >> applications with > >> >> Moblin SDK & win great prizes Grand prize is a trip for > two to an > >> >> Open Source event anywhere in the world > >> >> http://moblin-contest.org/redirect.php?banner_id=100&url=/ > >> >> _______________________________________________ > >> >> nunit-developer mailing list > >> >> [email protected] > >> >> https://lists.sourceforge.net/lists/listinfo/nunit-developer > >> >> > >> > > >> > > >> > --------------------------------------------------------------------- > >> - > >> > --- This SF.Net email is sponsored by the Moblin Your Move > >> Developer's > >> > challenge Build the coolest Linux based applications with > >> Moblin SDK & > >> > win great prizes Grand prize is a trip for two to an Open > >> Source event > >> > anywhere in the world > >> > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > >> > _______________________________________________ > >> > nunit-developer mailing list > >> > [email protected] > >> > https://lists.sourceforge.net/lists/listinfo/nunit-developer > >> > > >> > >> -------------------------------------------------------------- > >> ----------- > >> This SF.Net email is sponsored by the Moblin Your Move Developer's > >> challenge Build the coolest Linux based applications with > Moblin SDK > >> & win great prizes Grand prize is a trip for two to an Open Source > >> event anywhere in the world > >> http://moblin-contest.org/redirect.php?banner_id=100&url=/ > >> _______________________________________________ > >> nunit-developer mailing list > >> [email protected] > >> https://lists.sourceforge.net/lists/listinfo/nunit-developer > >> > > > > > > > > > ---------------------------------------------------------------------- > > --- This SF.Net email is sponsored by the Moblin Your Move > Developer's > > challenge Build the coolest Linux based applications with > Moblin SDK & > > win great prizes Grand prize is a trip for two to an Open > Source event > > anywhere in the world > > http://moblin-contest.org/redirect.php?banner_id=100&url=/ > > _______________________________________________ > > nunit-developer mailing list > > [email protected] > > https://lists.sourceforge.net/lists/listinfo/nunit-developer > > > > -------------------------------------------------------------- > ----------- > This SF.Net email is sponsored by the Moblin Your Move > Developer's challenge Build the coolest Linux based > applications with Moblin SDK & win great prizes Grand prize > is a trip for two to an Open Source event anywhere in the > world http://moblin-contest.org/redirect.php?banner_id=100&url=/ > _______________________________________________ > nunit-developer mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/nunit-developer > ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/