Unit-testing

What is unit-testing?

  • Unit testing is a method by which individual units of source code are tested to determine if they are fit for use.
  • Also a means of automatic code walkthrough.

Why unit-testing?

  • It makes sure that you code is syntactically error-free
  • It helps in resolving complex logical issues.
  • It leads to modular, extensible code that is easy to test, understand, and maintain.
  • If you stack together enough guesses, you may eventually build something that appears to function, but that no human could ever say with certainty ever worked properly.

“With a dynamic language like Python, Perl, or Ruby, it is easy to develop software by simply banging away at the problem, often interactively, until you get what seems to be the correct result and calling it a day.
Unfortunately, this approach, while tempting, often leads to a false sense of accomplishment that is fraught with danger.Much of the danger lies in not designing a solution to be testable, and part lies in not properly controlling the complexity of the software written. If you don’t have tests, you don’t know if your software works!! PERIOD”

Unit tests framework for python – pyunit

  • Pyunit : A unit testing framework for python like JUnit for java
  • unittest supports test automation, sharing of setup and shutdown code for tests, and independence of the tests from the reporting framework. The unittest module provides classes that make it easy to support these qualities for a set of tests.
  • All your pyunit test class should extend the unittest.TestCase :
  • It supports some important concepts like:
    • setup()
    • teardown()
    • setupUpClass()
    • tearDownClass()

setup():

  • This is called immediately before calling the test method.
  • It will be called each time the test_method is called.
  • Exists to make sure that each method has its own environment to work on with and hence the each test_methods can be executed independently.
  • Any exception raised by this method will be considered an error rather than a test failure

teardown():

  • This is called immediately after the test method has been called.
  • It will be called each time the test_method is called.
  • Exists to make sure that after a test method has been executed the environment is destroyed so the next method to be executed can have a clean environment to work on with.
  • Any exception raised by this method will be considered an error rather than a test failure.
  • This method will only be called if the setUp() succeeds, regardless of the outcome of the test method.

setUpClass():

  • This is called before tests in an individual class run.
  • setUpClass is called with the class as the only argument and must be decorated as a classmethod():

    @classmethod

    def setUpClass(cls):

tearDownClass():

  • This is called after tests in an individual class run.
  • setUpClass is called with the class as the only argument and must be decorated as a classmethod():

    @classmethod

    def tearDownClass(cls):

A Simple Illustration

What if the method which I am testing calls other methods inside?

  • Mocking the method is a solution to that.
  • Mocking a method means you are faking the call and returning a desired value for the method being mocked without executing the method.
  • The method to be mocked should exists in real, you can’t mock an imaginary method or class.
  • You can check if the mocked method is actually put into use or not by putting a VerifyAll call. If the mocked method is not being used VerifyAll will let the test to fail.

By mocking am I comprising with the quality?

  • Absolutely not.
  • You mock a method to make sure a piece of source code you are testing is sane. If the piece of code is dependent on some other piece of code you should write different unit tests for checking their sanity.

Advertisements