Unit Testing: a couple of questions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Emanuele D'Arrigo

    Unit Testing: a couple of questions

    Hi everybody,

    I'm just having a go with Unit Testing for the first time and my
    feeling about it in short is: Neat!

    I'm a bit worried about the time it's taking me to develop the tests
    but after only a day or so I'm already much faster than when I started
    with it and the code is already much improved in terms of robustness.
    A couple of "philosophi cal" questions have emerged in the process.

    1) Granularity
    Given a simple class

    class myClass():
    def __init__(self, data):
    __data = data;

    def getData(self):
    return __data

    def setData(self, data):
    __data = data

    I've been wondering: where do I stop in terms of testing for things
    that could go wrong? In this case for example, it might be reasonable
    to expand the class to make sure it only receives integers and test
    accordingly, i.e.:

    def setData(self, data):
    try:
    data = int(data)
    except ValueError:
    raise ValueError("Arg ument received cannot be converted to
    integer: " + data)

    But would it be reasonable to test also for the assignment operators?
    After all, if, for some strange reason, there isn't enough memory,
    couldn't even __data = data potentially fail?

    2) Testing in isolation
    I'm not entirely clear on this point. I can see how I need to test
    each path of the program flow separately. But should a test -only-
    rely on the object being tested and mock ones in supporting roles?
    I.e. would this be wrong if SupportObject is not a mockup?

    def testObjectToBeT ested _forReallyBadEr ror(self):
    supportObject = SupportObject()
    objectToBeTeste d = ObjectToBeTeste d()
    result = objectToBeTeste d.addSupportObj ect(supportObje ct)
    self.failIf(res ult != kSuccess, "Support Object could not be
    added!")

    I can see how if the SupportObject class had a bug introduced in it,
    this test would fail even though it has nothing to do with the
    ObjectToBeTeste d class. However, creating mock objects can be quite an
    overhead (?). I'm wondering if there is a threshold, even a fuzzy one,
    under which it isn't worth doing and a test like the one above is
    "good enough".

    What do you guys think?

    Manu
  • Antoine De Groote

    #2
    Re: Unit Testing: a couple of questions

    I'm wondering if don't want your class to look something like this:

    class myClass():
    def __init__(self, data):
    self.__data = data

    def getData(self):
    return self.__data

    def setData(self, data):
    self.__data = data

    For the rest I'll let the experts argue, I don't have a lot of
    experience with unit testing either... Shame on me! ;-)

    Regards,
    antoine

    Emanuele D'Arrigo wrote:
    Hi everybody,
    >
    I'm just having a go with Unit Testing for the first time and my
    feeling about it in short is: Neat!
    >
    I'm a bit worried about the time it's taking me to develop the tests
    but after only a day or so I'm already much faster than when I started
    with it and the code is already much improved in terms of robustness.
    A couple of "philosophi cal" questions have emerged in the process.
    >
    1) Granularity
    Given a simple class
    >
    class myClass():
    def __init__(self, data):
    __data = data;
    >
    def getData(self):
    return __data
    >
    def setData(self, data):
    __data = data
    >
    I've been wondering: where do I stop in terms of testing for things
    that could go wrong? In this case for example, it might be reasonable
    to expand the class to make sure it only receives integers and test
    accordingly, i.e.:
    >
    def setData(self, data):
    try:
    data = int(data)
    except ValueError:
    raise ValueError("Arg ument received cannot be converted to
    integer: " + data)
    >
    But would it be reasonable to test also for the assignment operators?
    After all, if, for some strange reason, there isn't enough memory,
    couldn't even __data = data potentially fail?
    >
    2) Testing in isolation
    I'm not entirely clear on this point. I can see how I need to test
    each path of the program flow separately. But should a test -only-
    rely on the object being tested and mock ones in supporting roles?
    I.e. would this be wrong if SupportObject is not a mockup?
    >
    def testObjectToBeT ested _forReallyBadEr ror(self):
    supportObject = SupportObject()
    objectToBeTeste d = ObjectToBeTeste d()
    result = objectToBeTeste d.addSupportObj ect(supportObje ct)
    self.failIf(res ult != kSuccess, "Support Object could not be
    added!")
    >
    I can see how if the SupportObject class had a bug introduced in it,
    this test would fail even though it has nothing to do with the
    ObjectToBeTeste d class. However, creating mock objects can be quite an
    overhead (?). I'm wondering if there is a threshold, even a fuzzy one,
    under which it isn't worth doing and a test like the one above is
    "good enough".
    >
    What do you guys think?
    >
    Manu

    Comment

    • Orestis Markou

      #3
      Re: Unit Testing: a couple of questions

      For the first bit, a colleague has recently asked the philosophical
      question, "How do you test what happens when the power goes down?" :)

      In other words, only test the bits that your code does. If you want to
      provide type checking, then yes, you have to test that.

      It's fair to assume that everything that is *not* your code will work
      as expected. If you do find 3rd-party bugs that affect you, then you
      should write a unit test that exposes that bug. When they fix it, your
      unittest fails, prompting you to remove any workarounds you had.

      On Tue, Oct 28, 2008 at 2:56 PM, Emanuele D'Arrigo <manu3d@gmail.c omwrote:
      Hi everybody,
      >
      I'm just having a go with Unit Testing for the first time and my
      feeling about it in short is: Neat!
      >
      I'm a bit worried about the time it's taking me to develop the tests
      but after only a day or so I'm already much faster than when I started
      with it and the code is already much improved in terms of robustness.
      A couple of "philosophi cal" questions have emerged in the process.
      >
      1) Granularity
      Given a simple class
      >
      class myClass():
      def __init__(self, data):
      __data = data;
      >
      def getData(self):
      return __data
      >
      def setData(self, data):
      __data = data
      >
      I've been wondering: where do I stop in terms of testing for things
      that could go wrong? In this case for example, it might be reasonable
      to expand the class to make sure it only receives integers and test
      accordingly, i.e.:
      >
      def setData(self, data):
      try:
      data = int(data)
      except ValueError:
      raise ValueError("Arg ument received cannot be converted to
      integer: " + data)
      >
      But would it be reasonable to test also for the assignment operators?
      After all, if, for some strange reason, there isn't enough memory,
      couldn't even __data = data potentially fail?
      >
      2) Testing in isolation
      I'm not entirely clear on this point. I can see how I need to test
      each path of the program flow separately. But should a test -only-
      rely on the object being tested and mock ones in supporting roles?
      I.e. would this be wrong if SupportObject is not a mockup?
      >
      def testObjectToBeT ested _forReallyBadEr ror(self):
      supportObject = SupportObject()
      objectToBeTeste d = ObjectToBeTeste d()
      result = objectToBeTeste d.addSupportObj ect(supportObje ct)
      self.failIf(res ult != kSuccess, "Support Object could not be
      added!")
      >
      I can see how if the SupportObject class had a bug introduced in it,
      this test would fail even though it has nothing to do with the
      ObjectToBeTeste d class. However, creating mock objects can be quite an
      overhead (?). I'm wondering if there is a threshold, even a fuzzy one,
      under which it isn't worth doing and a test like the one above is
      "good enough".
      >
      What do you guys think?
      >
      Manu
      --

      >


      --
      orestis@orestis .gr

      Comment

      • Mel

        #4
        Re: Unit Testing: a couple of questions

        Emanuele D'Arrigo wrote:
        I'm a bit worried about the time it's taking me to develop the tests
        but after only a day or so I'm already much faster than when I started
        with it and the code is already much improved in terms of robustness.
        A couple of "philosophi cal" questions have emerged in the process.
        [ ... ]
        But would it be reasonable to test also for the assignment operators?
        After all, if, for some strange reason, there isn't enough memory,
        couldn't even __data = data potentially fail?
        I would say, don't test for anything you can't fix. If you have (what the
        agile-programming people call) a "user story" describing how your program
        will recover from out-of-memory, then test whether that recovery is carried
        out. Otherwise forget it.

        Best think of unit tests as your sub-program spec written in a different
        form: i.e. as executable programs. You don't test for "things that can go
        wrong", you test for behaviour that your program must exhibit.
        >
        2) Testing in isolation
        I'm not entirely clear on this point. I can see how I need to test
        each path of the program flow separately. But should a test -only-
        rely on the object being tested and mock ones in supporting roles?
        I.e. would this be wrong if SupportObject is not a mockup?
        >
        def testObjectToBeT ested _forReallyBadEr ror(self):
        supportObject = SupportObject()
        objectToBeTeste d = ObjectToBeTeste d()
        result = objectToBeTeste d.addSupportObj ect(supportObje ct)
        self.failIf(res ult != kSuccess, "Support Object could not be
        added!")
        >
        I can see how if the SupportObject class had a bug introduced in it,
        this test would fail even though it has nothing to do with the
        ObjectToBeTeste d class. However, creating mock objects can be quite an
        overhead (?). I'm wondering if there is a threshold, even a fuzzy one,
        under which it isn't worth doing and a test like the one above is
        "good enough".
        I have heard people talk, matter-of-factly about support objects that got so
        complicated that they needed unit tests of their own. Of course, anything
        can be done in a ridiculous way, but good comprehensive unit tests give you
        the eternal assurance that your program is behaving properly, through all
        maintenance and modification. That's worth a lot.

        Comment

        • Emanuele D'Arrigo

          #5
          Re: Unit Testing: a couple of questions

          Thank you all for the very instructive replies! Much appreciated!

          By the sound of it I just have to relax a little and acquire a little
          bit more experience on the matter as I go along. =)

          Thank you again!

          Manu

          Comment

          Working...