Commit 8627b981 by David Miller

Add a -r --random option.

When passing -r or --random to the lettuce executable, we run both
features, and scenarios within features in a pseudo-random order.

This is helpful to detect issues that may arise from tests that
cause significant side-effects, the detection of locks etc
parent be50d4c0
......@@ -23,6 +23,7 @@ import sys
import traceback
from imp import reload
from datetime import datetime
import random
from lettuce.core import Feature, TotalResult
......@@ -76,7 +77,7 @@ class Runner(object):
Takes a base path as parameter (string), so that it can look for
features and step definitions on there.
"""
def __init__(self, base_path, scenarios=None, verbosity=0,
def __init__(self, base_path, scenarios=None, verbosity=0, random=False,
enable_xunit=False, xunit_filename=None, tags=None):
""" lettuce.Runner will try to find a terrain.py file and
import it from within `base_path`
......@@ -107,6 +108,8 @@ class Runner(object):
else:
from lettuce.plugins import colored_shell_output as output
self.random = random
if enable_xunit:
xunit_output.enable(filename=xunit_filename)
......@@ -132,6 +135,8 @@ class Runner(object):
features_files = [self.single_feature]
else:
features_files = self.loader.find_feature_files()
if self.random:
random.shuffle(features_files)
if not features_files:
self.output.print_no_features_found(self.loader.base_dir)
......@@ -142,7 +147,7 @@ class Runner(object):
for filename in features_files:
feature = Feature.from_file(filename)
results.append(
feature.run(self.scenarios, tags=self.tags))
feature.run(self.scenarios, tags=self.tags, random=self.random))
except exceptions.LettuceSyntaxError, e:
sys.stderr.write(e.msg)
......
......@@ -47,6 +47,12 @@ def main(args=sys.argv[1:]):
'(prefixing tags with "-" will exclude them and '
'prefixing with "~" will match approximate words)')
parser.add_option("-r", "--random",
dest="random",
action="store_true",
default=False,
help="Run scenarios in a more random order to avoid interference")
parser.add_option("--with-xunit",
dest="enable_xunit",
action="store_true",
......@@ -73,6 +79,7 @@ def main(args=sys.argv[1:]):
base_path,
scenarios=options.scenarios,
verbosity=options.verbosity,
random=options.random,
enable_xunit=options.enable_xunit,
xunit_filename=options.xunit_file,
tags=options.tags,
......
......@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import random as rand
import re
import codecs
from fuzzywuzzy import fuzz
......@@ -983,10 +984,13 @@ class Feature(object):
return scenarios, description
def run(self, scenarios=None, ignore_case=True, tags=None):
def run(self, scenarios=None, ignore_case=True, tags=None, random=False):
call_hook('before_each', 'feature', self)
scenarios_ran = []
if random:
rand.shuffle(self.scenarios)
if isinstance(scenarios, (tuple, list)):
if all(map(lambda x: isinstance(x, int), scenarios)):
scenarios_to_run = scenarios
......
......@@ -15,8 +15,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import random
import lettuce
from mock import Mock
from mock import Mock, patch
from StringIO import StringIO
from os.path import dirname, join, abspath
from nose.tools import assert_equals, with_setup, assert_raises
......@@ -1096,3 +1097,12 @@ def test_run_only_fast_tests():
"1 scenario (1 passed)\n"
"2 steps (2 passed)\n"
)
def test_run_random():
"Randomise the feature order"
filename = tag_feature_name('timebound')
runner = Runner('some_basepath', random=True)
assert_equals(True, runner.random)
with patch.object(random, 'shuffle') as pshuffle:
runner.run()
pshuffle.assert_called_once_with([])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment