In this chapter, we have developed several tactics to write and exercise BDD tests. This should help us in developing new projects. An invaluable tool for any project is having a top-level script used to manage things like packaging, bundling, and testing.
This recipe shows how to create a command-line project script that will run all the tests we created in this chapter using the various runners.
With the following steps, we will create a project-level script that will run all the test recipes from this chapter.
recipe34.py
.getopt
library for parsing command-line arguments.import getopt import logging import nose import os import os.path import re import sys import lettuce import doctest from glob import glob def usage(): print print "Usage: python recipe34.py [command]" print print " --help" print " --test" print " --package" print " --publish" print " --register" print try: optlist, args = getopt.getopt(sys.argv[1:], "h", ["help", "test", "package", "publish", "register"]) except getopt.GetoptError: # print help information and exit: print "Invalid command found in %s" % sys.argv usage() sys.exit(2)
BddPrinter
.def test_with_bdd(): from recipe26_plugin import BddPrinter suite = ["recipe26", "recipe30", "recipe31"] print("Running suite %s" % suite) args = [""] args.extend(suite) args.extend(["--with-bdd"]) nose.run(argv=args, plugins=[BddPrinter()])
def test_plain_old_doctest(): for extension in ["doctest", "txt"]: for doc in glob("recipe27*.%s" % extension): print("Testing %s" % doc) doctest.testfile(doc)
doctest
runner.def test_customized_doctests(): from recipe28 import BddDocTestRunner old_doctest_runner = doctest.DocTestRunner doctest.DocTestRunner = BddDocTestRunner for recipe in ["recipe28", "recipe29"]: for file in glob("%s*.doctest" % recipe): given = file[len("%s_" % recipe):] given = given[:-len(".doctest")] given = " ".join(given.split("_")) print("===================================") print("%s: Given a %s..." % (recipe, given)) print( "===================================") doctest.testfile(file) print doctest.DocTestRunner = old_doctest_runner
lettuce
tests.def test_lettuce_scenarios(): print("Running suite recipe32") lettuce.Runner(os.path.abspath("recipe32"), verbosity=3).run() print print("Running suite recipe33") lettuce.Runner(os.path.abspath("recipe33"), verbosity=3).run() print
def test(): test_with_bdd() test_plain_old_doctest() test_customized_doctests() test_lettuce_scenarios()
def package(): print "This is where we can plug in code to run " + "setup.py to generate a bundle." def publish(): print "This is where we can plug in code to upload " + "our tarball to S3 or some other download site." def register(): print "setup.py has a built in function to " + "'register' a release to PyPI. It's " + "convenient to put a hook in here." # os.system("%s setup.py register" % sys.executable)
if len(optlist) == 0: usage() sys.exit(1) # Check for help requests, which cause all other # options to be ignored. for option in optlist: if option[0] in ("--help", "-h"): usage() sys.exit(1) # Parse the arguments, in order for option in optlist: if option[0] in ("--test"): test() if option[0] in ("--package"): package() if option[0] in ("--publish"): publish() if option[0] in ("--register"): register()
–test
.(ptc)gturnquist-mbp:04 gturnquist$ python recipe34.py --test
Running suite ['recipe26', 'recipe30', 'recipe31']
...
Scenario: Cart getting loaded with different items # recipe33/recipe33.feature:22
Given an empty cart # recipe33/steps.py:6
When I add a carton of milk # recipe33/steps.py:50
And I add a frozen pizza # recipe33/steps.py:54
Then the first item is a carton of milk # recipe33/steps.py:34
And the second item is a frozen pizza # recipe33/steps.py:58
And the first price is 2.50 # recipe32/steps.py:69
And the second price is 3.00 # recipe33/steps.py:66
And the total cost with no taxes is 5.50 # recipe33/steps.py:70
And the total cost with 10% taxes is 6.05 # recipe33/steps.py:74
1 feature (1 passed)
3 scenarios (3 passed)
21 steps (21 passed)
–package –publish –register
.For more details about how and why to use getopt
, reasons to write a project-level script, and why we are using getopt
instead of optparse
, see the Writing a project-level script that lets you run different test suites section from Chapter 2.
3.128.198.59