unittest setup

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • paul kölle

    #1

    unittest setup

    hi all,

    I noticed that setUp() and tearDown() is run before and after *earch*
    test* method in my TestCase subclasses. I'd like to run them *once* for
    each TestCase subclass. How do I do that.

    thanks
    paul

  • Diez B. Roggisch

    #2
    Re: unittest setup

    paul kölle wrote:[color=blue]
    > hi all,
    >
    > I noticed that setUp() and tearDown() is run before and after *earch*
    > test* method in my TestCase subclasses. I'd like to run them *once* for
    > each TestCase subclass. How do I do that.[/color]

    Create a global/test instance flag.

    Diez

    Comment

    • paul kölle

      #3
      Re: unittest setup

      Diez B. Roggisch wrote:[color=blue]
      > paul kölle wrote:
      >[color=green]
      >>hi all,
      >>
      >>I noticed that setUp() and tearDown() is run before and after *earch*
      >>test* method in my TestCase subclasses. I'd like to run them *once* for
      >>each TestCase subclass. How do I do that.[/color]
      >
      >
      > Create a global/test instance flag.[/color]

      I'm not sure if I understood what you mean, I tried:

      setup = 'down'

      class BaseTest(unitte st.TestCase):
      def setUp(self):
      global setup
      if setup == 'up':
      print 'Not running setUp() again...'
      return
      ...
      all setup work goes here.
      ...
      setup = 'up'


      This didn't work, (tried to reset the flag in the last test* method to
      'down', no dice)
      and:

      class BaseTest(unitte st.TestCase):
      def __init__(self, ...):
      unittest.TestCa se.__init__(sel f, ...)
      self.setup = 'down'

      def setUp(self):
      if self.setup == 'up':
      return
      dowork
      self.setup = 'up'

      Failed also, I'm not sure why, __init__ was called way too often and
      self.setup was always reset to 'down'. I finally gave up and created my
      own method which I call in *every* test* method which is ugly, leads to
      longer runtime and code duplication.


      But at least it encouraged me to read the unittest docs more carefully.
      Now I seem to understand that:

      TestSuite.addTe st(TestCaseSubc lass('testSomet hing'))
      TestSuite.addTe st(TestCaseSubc lass('testSomet hingOther'))

      will create two instances of TestCaseSubclas s, so there is no way that
      'testSomethingO ther' will ever see what 'testSomething' might have
      created if all work is done with instance data right? Initially I
      thought it goes like: "run setUp(), run all test* methods, run
      tearDown()" and that is what the unittest docs call a "fixture"

      <cite python 2.3 docs for unittest>
      A test fixture represents the preparation needed to perform one or more
      tests, and any associate cleanup actions.
      </cite>

      but further down:
      <cite python 2.3 docs for unittest>
      Each instance of the TestCase will only be used to run a single test
      method, so a new fixture is created for each test.
      </cite>

      It seems to me my case is not that exotic, I thought it would be quite
      natural to write the boilerplate stuff in setUp() and build on that to
      step through the applications state with test* methods each building on
      top of each other. Is that the wrong approach? Are there other
      frameworks supporting such a style?

      thanks
      Paul

      Comment

      • George Sakkis

        #4
        Re: unittest setup

        "paul kölle" <paul@subsignal .org> wrote:[color=blue]
        >
        > [snipped]
        >
        > It seems to me my case is not that exotic, I thought it would be quite
        > natural to write the boilerplate stuff in setUp() and build on that to
        > step through the applications state with test* methods each building on
        > top of each other. Is that the wrong approach? Are there other
        > frameworks supporting such a style?[/color]

        Yes, py.test: http://codespeak.net/py/current/doc/test.html.

        George


        Comment

        • François Pinard

          #5
          Re: unittest setup

          [George Sakkis]
          [color=blue]
          > Yes, py.test: http://codespeak.net/py/current/doc/test.html.[/color]

          The whole http://codespeak.net site contains many interesting projects,
          which are all worth a good look!

          However, there is a generic ``LICENSE`` file claiming copyrights on all
          files, without explaining what the copyright conditions are. This file
          also delegates copyright issues to individual files, which are usually
          silent on the matter. Could this whole issue be clarified? Or did I
          miss something I should not have?

          --
          François Pinard http://pinard.progiciels-bpi.ca

          Comment

          • Kent Johnson

            #6
            Re: unittest setup

            paul kölle wrote:[color=blue]
            > hi all,
            >
            > I noticed that setUp() and tearDown() is run before and after *earch*
            > test* method in my TestCase subclasses. I'd like to run them *once* for
            > each TestCase subclass. How do I do that.[/color]

            One way to do this is to make a TestSuite subclass that includes your startup and shutdown code.

            For example I have some tests that rely on a webserver being started. I have a TestSuite that starts the server, runs the tests and stops the server. This way the server is only started once per test module. Here is the TestSuite class:

            class CbServerTestSui te(unittest.Tes tSuite):
            ''' A test suite that starts an instance of CbServer for the suite '''
            def __init__(self, testCaseClass):
            unittest.TestSu ite.__init__(se lf)
            self.addTest(un ittest.defaultT estLoader.loadT estsFromTestCas e(testCaseClass ))

            def __call__(self, result):
            CbServer.start( )
            unittest.TestSu ite.__call__(se lf, result)
            CbServer.stop()


            I use it like this:

            class MyTest(unittest .TestCase):
            def testWhatever(se lf):
            pass

            def suite():
            return CbServerTestSui te(MyTest)

            if __name__=='__ma in__':
            unittest.TextTe stRunner().run( suite())


            This runs under Jython (Python 2.1); in more recent Python I think you can override TestSuite.run() instead of __call__().

            Kent

            Comment

            Working...