Re: Tearing down when SetUp fails?
Hans Christian Falkenberg <[email protected]> Fri, 12 Sep 2008 23:15:13 +0200 (CEST)
| Newsgroups | gmane.comp.windows.dotnet.nunit.devel |
|---|---|
| Message-ID | <[email protected]> |
Ah, I thought I had read somewhere that , 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=/