Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 1 | # coding=utf-8 |
| 2 | """ |
| 3 | BDD lettuce framework runner |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 4 | TODO: Support other params (like tags) as well. |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 5 | Supports only 2 params now: folder to search "features" for or file and "-s scenario_index" |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 6 | """ |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 7 | import argparse |
| 8 | import os |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 9 | import _bdd_utils |
| 10 | |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 11 | __author__ = 'Ilya.Kazakevich' |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 12 | from lettuce.exceptions import ReasonToFail |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 13 | import lettuce |
| 14 | from lettuce import core |
| 15 | |
| 16 | |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 17 | class _LettuceRunner(_bdd_utils.BddRunner): |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 18 | """ |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 19 | Lettuce runner (BddRunner for lettuce) |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 20 | """ |
| 21 | |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 22 | def __init__(self, base_dir, what_to_run, scenarios): |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 23 | """ |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 24 | |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 25 | :param scenarios scenario numbers to run |
| 26 | :type scenarios list |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 27 | :param base_dir base directory to run tests in |
| 28 | :type base_dir: str |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 29 | :param what_to_run folder or file to run |
| 30 | :type what_to_run str |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 31 | |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 32 | """ |
| 33 | super(_LettuceRunner, self).__init__(base_dir) |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 34 | self.__runner = lettuce.Runner(what_to_run, ",".join(scenarios)) |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 35 | |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 36 | def _get_features_to_run(self): |
| 37 | super(_LettuceRunner, self)._get_features_to_run() |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 38 | features = [] |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 39 | if self.__runner.single_feature: # We need to run one and only one feature |
| 40 | features = [core.Feature.from_file(self.__runner.single_feature)] |
| 41 | else: |
| 42 | # Find all features in dir |
| 43 | for feature_file in self.__runner.loader.find_feature_files(): |
| 44 | feature = core.Feature.from_file(feature_file) |
| 45 | assert isinstance(feature, core.Feature), feature |
| 46 | # TODO: cut out due to https://github.com/gabrielfalcao/lettuce/issues/451 Fix when this issue fixed |
| 47 | feature.scenarios = filter(lambda s: not s.outlines, feature.scenarios) |
| 48 | if feature.scenarios: |
| 49 | features.append(feature) |
| 50 | |
| 51 | # Choose only selected scenarios |
| 52 | if self.__runner.scenarios: |
| 53 | for feature in features: |
| 54 | filtered_feature_scenarios = [] |
| 55 | for index in [i - 1 for i in self.__runner.scenarios]: # decrease index by 1 |
| 56 | if index < len(feature.scenarios): |
| 57 | filtered_feature_scenarios.append(feature.scenarios[index]) |
| 58 | feature.scenarios = filtered_feature_scenarios |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 59 | return features |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 60 | |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 61 | def _run_tests(self): |
| 62 | super(_LettuceRunner, self)._run_tests() |
| 63 | self.__install_hooks() |
| 64 | self.__runner.run() |
| 65 | |
| 66 | def __step(self, is_started, step): |
| 67 | """ |
| 68 | Reports step start / stop |
| 69 | :type step core.Step |
| 70 | :param step: step |
| 71 | """ |
| 72 | test_name = step.sentence |
| 73 | if is_started: |
| 74 | self._test_started(test_name, step.described_at) |
| 75 | elif step.passed: |
| 76 | self._test_passed(test_name) |
| 77 | elif step.failed: |
| 78 | reason = step.why |
| 79 | assert isinstance(reason, ReasonToFail), reason |
| 80 | self._test_failed(test_name, message=reason.exception, details=reason.traceback) |
| 81 | elif step.has_definition: |
| 82 | self._test_skipped(test_name, "In lettuce, we do know the reason", step.described_at) |
| 83 | else: |
| 84 | self._test_undefined(test_name, step.described_at) |
| 85 | |
| 86 | def __install_hooks(self): |
| 87 | """ |
| 88 | Installs required hooks |
| 89 | """ |
| 90 | |
| 91 | # Install hooks |
| 92 | lettuce.before.each_feature( |
| 93 | lambda f: self._feature_or_scenario(True, f.name, f.described_at)) |
| 94 | lettuce.after.each_feature( |
| 95 | lambda f: self._feature_or_scenario(False, f.name, f.described_at)) |
| 96 | |
| 97 | lettuce.before.each_scenario( |
| 98 | lambda s: self.__scenario(True, s)) |
| 99 | lettuce.after.each_scenario( |
| 100 | lambda s: self.__scenario(False, s)) |
| 101 | |
| 102 | lettuce.before.each_background( |
| 103 | lambda b, *args: self._background(True, b.feature.described_at)) |
| 104 | lettuce.after.each_background( |
| 105 | lambda b, *args: self._background(False, b.feature.described_at)) |
| 106 | |
| 107 | lettuce.before.each_step(lambda s: self.__step(True, s)) |
| 108 | lettuce.after.each_step(lambda s: self.__step(False, s)) |
| 109 | |
| 110 | def __scenario(self, is_started, scenario): |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 111 | """ |
| 112 | Reports scenario launched |
| 113 | :type scenario core.Scenario |
| 114 | :param scenario: scenario |
| 115 | """ |
| 116 | if scenario.outlines: |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 117 | scenario.steps = [] # Clear to prevent running. TODO: Fix when this issue fixed |
| 118 | scenario.background = None # TODO: undocumented |
| 119 | return |
Tor Norbye | 02cf98d6 | 2014-08-19 12:53:10 -0700 | [diff] [blame] | 120 | self._feature_or_scenario(is_started, scenario.name, scenario.described_at) |
Tor Norbye | 2e5965e | 2014-07-25 12:24:15 -0700 | [diff] [blame] | 121 | |
| 122 | |
| 123 | if __name__ == "__main__": |
Tor Norbye | e782c57 | 2014-09-18 11:43:07 -0700 | [diff] [blame^] | 124 | (base_dir, scenarios, what_to_run) = _bdd_utils.get_what_to_run_by_env(os.environ) |
| 125 | if len(what_to_run) > 1: |
| 126 | raise Exception("Lettuce can't run more than one file now") |
| 127 | _bdd_utils.fix_win_drive(what_to_run[0]) |
| 128 | _LettuceRunner(base_dir, what_to_run[0], scenarios).run() |