Getting nosy with testing

Nose automatically discovers tests when fed with a package, a module, or a file.

How to do it...

With the following steps, we will explore how nose automatically finds test cases and runs them:

  1. Create a new file called recipe11.py in which to put all our code for this recipe.
  2. Create a class to test. For this recipe, we will use a shopping cart application that lets us load items and then calculate the bill.
    class ShoppingCart(object):
        def __init__(self):
            self.items = []
    
        def add(self, item, price):
            self.items.append(Item(item, price))
            return self
    
        def item(self, index):
            return self.items[index-1].item
    
        def price(self, index):
            return self.items[index-1].price
    
        def total(self, sales_tax):
            sum_price = sum([item.price for item in self.items])
            return sum_price*(1.0 + sales_tax/100.0)
    
        def __len__(self):
            return len(self.items)
    
    class Item(object):
        def __init__(self, item, price):
            self.item = item
            self.price = price
  3. Create a test case that exercises the various parts of the shopping cart application.
    import unittest
    
    class ShoppingCartTest(unittest.TestCase):
        def setUp(self):
            self.cart = ShoppingCart().add("tuna sandwich", 15.00)
    
        def test_length(self):
            self.assertEquals(1, len(self.cart))
    
        def test_item(self):
            self.assertEquals("tuna sandwich", self.cart.item(1))
    
        def test_price(self):
            self.assertEquals(15.00, self.cart.price(1))
    
        def test_total_with_sales_tax(self):
            self.assertAlmostEquals(16.39, 
                                    self.cart.total(9.25), 2)
  4. Use the command-line nosetests tool to run this recipe by filename and also by module.
    How to do it...

How it works...

We started off by creating a simple application that lets us load up a ShoppingCart with Items. This application lets us look up each item and its price. Finally, we can calculate the total billing amount including the sales tax.

Next, we coded some test methods to exercise all these features using unittest.

Finally, we used the command-line nosetests tool that discovers test cases and automatically runs them. This saved us from handcoding any test runner to load test suites.

There's more...

What's so important about not writing the test runner? What do we gain by using nosetests? After all, unittest gives us the ability to embed an auto-discovering test runner like this:

if __name__ == "__main__":
    unittest.main()

Would the same block of code work, if the tests spread across several modules? No, because unittest.main() only looks in the current module. To grow into multiple modules, we need to start loading tests using unittest's loadTestsFromTestCase method or other customized suites. It doesn't matter how we assemble suites. When we are at risk of missing test cases, nosetests conveniently lets us search for all tests, or a subset, as needed.

A common situation on projects is to spread out test cases between lots of modules. Instead of writing one big test case, we typically break things up into smaller test cases based on various setups, scenarios, and other logical groupings. It's a common practice to split up test cases based on which module is being tested. The point is that manually loading all the test cases for a real world test suite can become labor intensive.

Nose is extensible

Auto-discovery of tests isn't the only reason to use nose. Later in this chapter, we will explore how we can write a plugin to customize what it discovers and also the output of a test run.

Nose is embeddable

All the functionality which nose provides can be utilized either by command line, or from inside a Python script. We will also explore this further in this chapter.

See also

Asserting the basics section mentioned in Chapter 1

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.14.132