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