summaryrefslogtreecommitdiff
path: root/python/helpers/pycharm/lettuce_runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/helpers/pycharm/lettuce_runner.py')
-rw-r--r--python/helpers/pycharm/lettuce_runner.py132
1 files changed, 132 insertions, 0 deletions
diff --git a/python/helpers/pycharm/lettuce_runner.py b/python/helpers/pycharm/lettuce_runner.py
new file mode 100644
index 000000000000..6aaa566df719
--- /dev/null
+++ b/python/helpers/pycharm/lettuce_runner.py
@@ -0,0 +1,132 @@
+# coding=utf-8
+"""
+BDD lettuce framework runner
+"""
+__author__ = 'Ilya.Kazakevich'
+import os
+from lettuce.exceptions import ReasonToFail
+import time
+import sys
+import tcmessages
+import lettuce
+from lettuce import core
+
+
+# Error message about unsupported outlines
+_NO_OUTLINE_ERROR = "Outline scenarios are not supported due to https://github.com/gabrielfalcao/lettuce/issues/451"
+
+
+class LettuceRunner(object):
+ """
+ TODO: Runs lettuce
+ """
+
+ def __init__(self, base_dir):
+ """
+ :param base_dir base directory to run tests in
+ :type base_dir: str
+
+ """
+ self.base_dir = base_dir
+ self.runner = lettuce.Runner(base_dir)
+ self.messages = tcmessages.TeamcityServiceMessages()
+ self.test_start_time = None
+
+ def report_tests(self):
+ """
+ :returns : number of tests
+ :rtype : int
+ """
+ result = 0
+ for feature_file in self.runner.loader.find_feature_files():
+ feature = core.Feature.from_file(feature_file)
+ for scenario in feature.scenarios:
+ assert isinstance(scenario, core.Scenario), scenario
+ if not scenario.outlines:
+ result += len(scenario.steps)
+ self.messages.testCount(result)
+
+ def report_scenario_started(self, scenario):
+ """
+ Reports scenario launched
+ :type scenario core.Scenario
+ :param scenario: scenario
+ """
+ if scenario.outlines:
+ self.messages.testIgnored(scenario.name,
+ _NO_OUTLINE_ERROR)
+ scenario.steps = [] # Clear to prevent running. TODO: Fix when this issue fixed
+ scenario.background = None # TODO: undocumented
+ return
+ self.report_suite(True, scenario.name, scenario.described_at)
+
+ def report_suite(self, is_start, name, described_at):
+ """
+ Reports some suite (scenario, feature, background etc) is started or stopped
+ :param is_start: started or not
+ :param name: suite name
+ :param described_at: where it is described (file, line)
+ :return:
+ """
+ if is_start:
+ self.messages.testSuiteStarted(name, self._gen_location(described_at))
+ else:
+ self.messages.testSuiteFinished(name)
+
+ def report_step(self, is_start, step):
+ """
+ Reports step start / stop
+ :param is_start: true if step started
+ :type step core.Step
+ :param step: step
+ """
+ test_name = step.sentence
+ if is_start:
+ self.test_start_time = time.time()
+ self.messages.testStarted(test_name, self._gen_location(step.described_at))
+ elif step.passed:
+ duration = 0
+ if self.test_start_time:
+ duration = long(time.time() - self.test_start_time)
+ self.messages.testFinished(test_name, duration=duration)
+ self.test_start_time = None
+ elif step.failed:
+ reason = step.why
+ assert isinstance(reason, ReasonToFail), reason
+ self.messages.testFailed(test_name, message=reason.exception, details=reason.traceback)
+
+ def _gen_location(self, description):
+ """
+ :param description: "described_at" (file, line)
+ :return: location in format file:line by "described_at"
+ """
+ return "file:///{}/{}:{}".format(self.base_dir, description.file, description.line)
+
+ def run(self):
+ """
+ Launches runner
+ """
+ self.report_tests()
+ self.messages.testMatrixEntered()
+
+ lettuce.before.each_feature(lambda f: self.report_suite(True, f.name, f.described_at))
+ lettuce.after.each_feature(lambda f: self.report_suite(False, f.name, f.described_at))
+
+ lettuce.before.each_scenario(lambda s: self.report_scenario_started(s))
+ lettuce.after.each_scenario(lambda s: self.report_suite(False, s.name, s.described_at))
+
+ lettuce.before.each_background(
+ lambda b, *args: self.report_suite(True, "Scenario background", b.feature.described_at))
+ lettuce.after.each_background(
+ lambda b, *args: self.report_suite(False, "Scenario background", b.feature.described_at))
+
+ lettuce.before.each_step(lambda s: self.report_step(True, s))
+ lettuce.after.each_step(lambda s: self.report_step(False, s))
+
+ self.runner.run()
+
+
+if __name__ == "__main__":
+ path = sys.argv[1] if len(sys.argv) > 1 else "."
+ assert os.path.exists(path), "{} does not exist".format(path)
+ LettuceRunner(path).run() \ No newline at end of file