locked
When a unit test times-out, does the "Finally" get invoked? (VS2010) RRS feed

  • Question

  • I have a unit test that inserts data into SQL (ie, doesn't use a mocked data store).

    After the test completes, it must delete the inserted data. So I put the delete logic in the Finally clause.

    But it appears that if the test times-out, the Finally clause isn't invoked.

    I suppose I could move the delete logic to the method decorated with [TestCleanup], but that could get messy, since there are multiple tests in one .cs file, and not all of them need to do the same "deletes".

    DadCat

     

     

     

    Friday, December 30, 2011 3:47 PM

All replies

  • More testing reveals that...

    Moving the delete logic to the method decorated with [TestCleanup] works when a timeout occurs when the unit test is run in VS debug mode (CTRL R, T). The database rows get deleted as expected.

    But the method decorated with [TestCleanup] apparently isn't invoked when a timeout occurs when the same unit test is run using the Test List Editor. The database rows are still there. 

    What's going on?  Should a timeout bypass both the Finally clause and the [TestCleanup] method when the test is being run by from the Test List Editor?

    If so, how am I going to cleanup the database after a timeout?

    BTW: using a mocked database isn't a solution... I have other tests that do that, but the test-in-question is an "integration" test that must exercise the "real" data access tier and real database.

    Thanks,

    DadCat

     

     

    Friday, December 30, 2011 4:26 PM
  • Hi DadCat,

    Glad to see you again.

    Based on my understanding, you mean that if the unit tests don’t have the Timeout issue, the unit test can insert the data into SQL with the “Finally clause”. If it has this issue, the “Finally clause” isn't invoked. If I have misunderstood anything, make free feel to let us know.

    I might not have the correct detailed answer you need, but I might lead you into the right direction to solve your problem.

    1.       If it has the “Timeout” issue, we can resolve it, I mean that the unit test doesn’t have the “Timeout” issue, it will run normally.

    2.       If the Timeout generated before the unit test started, so the data wasn’t inserted into the SQL, so we don’t need to delete the inserted data. If the Timeout generated after the data was insert into the SQL. We need to delete the inserted data. So the root reason, we need to check that when the Timeout generates. I think it is not very easy, so I think the step1 is a good way.

    In addition, the [TestCleanup ()] method is executed after all unit tests run. As you said, if not all of them need to do the same "deletes", I think the [TestCleanup ()] method is not so available.

    Have a nice day,


    Jack Zhai [MSFT]
    MSDN Community Support | Feedback to us



    Tuesday, January 3, 2012 6:22 AM
  • Jack,

    I don't understand your reply. I'm not sure you understood the problem, so I've attached my unit test code below...

    First: the issue is NOT with the timeout itself. The timeout is probably caused by an environmental problem that I can resolve locally. The problem I need help with is that the unit test doesn't get "control" after a timeout occurs.

    In testing the example code below, I have found that...

    1) The "finally" clause is not invoked with a timeout occrus, regardless of how the unit test is executed

    2) The TestCleanup method is invoked if the unit test is executed in VS debug (CTRL R,T) but the TestCleanup method is not invoked when the unit test is launched from the Test List editor or is launched from a build. 

    Thanks,

    DadCat

    ----------------------------------------------------------------------------------------------------------------------------------------------

         [TestClass]
         public class MyTests
         {
            bool deleteRows = false;   // if true, cleanup must delete added rows
               
            [TestMethod, Timeout(3600000)] 
            public void MyTest()
            {
                try
                {
                    deleteRows = true;
                    perform operation which inserts rows into a "real" (not mocked) database and times-out
                }
                finally
                {
                   if (deleteRows)
                   {
                       perform the cleanup operation
                   }
                }
            }
           
          [TestCleanup]
          public void TestCleanup()
          {
              if (deleteRows)
              {
                 perform the cleanup operation
               }
            }
        }

    Tuesday, January 3, 2012 4:19 PM
  • Hi DadCat,

    Glad to receive your reply.

    The problem I need help with is that the unit test doesn't get "control" after a timeout occurs.

    Sorry for my misunderstanding about this issue.

    I have involved someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Sincerely,


    Jack Zhai [MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, January 4, 2012 2:32 AM
  • I mean that the finally clause and the TestCleanup method do not get invoked, as I described:

    1) The "finally" clause is not invoked with a timeout occurs, regardless of how the unit test is executed

    2) The TestCleanup method is invoked if the unit test is executed in VS debug (CTRL R,T) but the TestCleanup method is not invoked when the unit test is launched from the Test List editor or is launched from a build.

    DadCat

    Wednesday, January 4, 2012 2:44 PM
  • Hi DadCat,

    Just to confirm, have you installed VS2010 SP1 and KB2580221?

    Thanks!

     


    Sophia Lu [MSFT]
    Wednesday, February 1, 2012 10:35 AM