Nose automatically discovers tests when fed with a package, a module, or a file.
With the following steps, we will explore how nose automatically finds test cases and runs them:
recipe11.py
in which to put all our code for this recipe.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
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)
nosetests
tool to run this recipe by filename and also by module.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.
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.
Asserting the basics section mentioned in Chapter 1
3.145.14.132