From d79ed12f0ffab6132b633df0ab4a033f0053f514 Mon Sep 17 00:00:00 2001 From: Gabriel Falcao Date: Mon, 28 Jan 2013 18:51:10 -0500 Subject: [PATCH] supporting pdb out of the box. closes #250 --- lettuce/__init__.py | 9 +++-- lettuce/bin.py | 7 ++++ lettuce/django/management/commands/harvest.py | 6 +++- lettuce/plugins/autopdb.py | 33 +++++++++++++++++++ setup.py | 2 +- 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 lettuce/plugins/autopdb.py diff --git a/lettuce/__init__.py b/lettuce/__init__.py index 2fcf1db97..7dbbcf781 100644 --- a/lettuce/__init__.py +++ b/lettuce/__init__.py @@ -41,7 +41,10 @@ from lettuce.registry import STEP_REGISTRY from lettuce.registry import CALLBACK_REGISTRY from lettuce.exceptions import StepLoadingError -from lettuce.plugins import xunit_output +from lettuce.plugins import ( + xunit_output, + autopdb +) from lettuce import fs from lettuce import exceptions @@ -84,7 +87,7 @@ class Runner(object): """ def __init__(self, base_path, scenarios=None, verbosity=0, random=False, enable_xunit=False, xunit_filename=None, tags=None, - failfast=False): + failfast=False, auto_pdb=False): """ lettuce.Runner will try to find a terrain.py file and import it from within `base_path` """ @@ -101,6 +104,8 @@ def __init__(self, base_path, scenarios=None, verbosity=0, random=False, self.verbosity = verbosity self.scenarios = scenarios and map(int, scenarios.split(",")) or None self.failfast = failfast + if auto_pdb: + autopdb.enable(self) sys.path.remove(base_path) diff --git a/lettuce/bin.py b/lettuce/bin.py index cc4f47d38..f35fb0bb8 100755 --- a/lettuce/bin.py +++ b/lettuce/bin.py @@ -72,6 +72,12 @@ def main(args=sys.argv[1:]): action="store_true", help='Stop running in the first failure') + parser.add_option("--pdb", + dest="auto_pdb", + default=False, + action="store_true", + help='Launches an interactive debugger upon error') + options, args = parser.parse_args(args) if args: base_path = os.path.abspath(args[0]) @@ -93,6 +99,7 @@ def main(args=sys.argv[1:]): enable_xunit=options.enable_xunit, xunit_filename=options.xunit_file, failfast=options.failfast, + auto_pdb=options.auto_pdb, tags=tags, ) diff --git a/lettuce/django/management/commands/harvest.py b/lettuce/django/management/commands/harvest.py index e81349b3a..f4e430ddd 100644 --- a/lettuce/django/management/commands/harvest.py +++ b/lettuce/django/management/commands/harvest.py @@ -76,6 +76,9 @@ class Command(BaseCommand): make_option("--failfast", dest="failfast", default=False, action="store_true", help='Stop running in the first failure'), + + make_option("--pdb", dest="auto_pdb", default=False, + action="store_true", help='Launches an interactive debugger upon error'), ) def stopserver(self, failed=False): @@ -105,6 +108,7 @@ def handle(self, *args, **options): run_server = not options.get('no_server', False) tags = options.get('tags', None) failfast = options.get('failfast', False) + auto_pdb = options.get('auto_pdb', False) server = Server(port=options['port']) @@ -134,7 +138,7 @@ def handle(self, *args, **options): runner = Runner(path, options.get('scenarios'), verbosity, enable_xunit=options.get('enable_xunit'), xunit_filename=options.get('xunit_file'), - tags=tags, failfast=failfast) + tags=tags, failfast=failfast, auto_pdb=auto_pdb) result = runner.run() if app_module is not None: diff --git a/lettuce/plugins/autopdb.py b/lettuce/plugins/autopdb.py new file mode 100644 index 000000000..d37d1cd61 --- /dev/null +++ b/lettuce/plugins/autopdb.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import sys +from lettuce.terrain import after + + +def enable(runner): + @after.each_step + def failfast_or_pdb(step): + has_traceback = step.why + + if not has_traceback: + return + + sys.stdout.write(step.why.traceback + '\n') + + try: + from IPython.core.debugger import Pdb + pdb = Pdb() + except ImportError: + try: + from IPython.Debugger import Pdb + from IPython.Shell import IPShell + IPShell(argv=['']) + pdb = Pdb() + except ImportError: + import pdb + + matched, defined = step.pre_run(False) + if matched: + args = matched.groups() + kwargs = matched.groupdict() + pdb.runcall(defined.function, step, *args, **kwargs) diff --git a/setup.py b/setup.py index 0a12b9e54..9e80b7865 100755 --- a/setup.py +++ b/setup.py @@ -29,7 +29,7 @@ def get_packages(): return packages -required_modules = ['sure', 'fuzzywuzzy'] +required_modules = ['sure', 'fuzzywuzzy', 'ipdb'] if sys.version_info[:2] < (2, 6): required_modules.append('multiprocessing')