Skip to content

Instantly share code, notes, and snippets.

@andresriancho
Created October 6, 2012 11:47
Show Gist options
  • Save andresriancho/3844715 to your computer and use it in GitHub Desktop.
Save andresriancho/3844715 to your computer and use it in GitHub Desktop.
nosetests plugin to randomize test ordering
"""
This plugin randomizes the order of tests within a unittest.TestCase class
"""
__test__ = False
import logging
import os
from nose.plugins import Plugin
from nose import loader
from inspect import isfunction, ismethod
from nose.case import FunctionTestCase, MethodTestCase
from nose.failure import Failure
from nose.config import Config
from nose.importer import Importer, add_path, remove_path
from nose.selector import defaultSelector, TestAddress
from nose.util import getpackage, isclass, isgenerator, ispackage, \
resolve_name, transplant_func, transplant_class
from nose.suite import ContextSuiteFactory, ContextList, LazySuite
import random
import unittest
log = logging.getLogger(__name__)
class Randomize(Plugin):
"""
Randomize the order of the tests within a unittest.TestCase class
"""
name = 'randomize'
# Generate a seed for deterministic behaviour
# Could use getstate and setstate, but that would involve
# pickling the state and storing it somewhere. too lazy.
seed = random.getrandbits(32)
def options(self, parser, env):
"""Register commandline options.
"""
Plugin.options(self, parser, env)
parser.add_option('--randomize', action='store_true', dest='randomize',
help="Randomize the order of the tests within a unittest.TestCase class")
parser.add_option('--seed', action='store', dest='seed', default=None, type = long,
help="Initialize the seed for deterministic behavior in reproducing failed tests")
def configure(self, options, conf):
"""
Configure plugin.
"""
Plugin.configure(self, options, conf)
if options.randomize:
self.enabled = True
if options.seed is not None:
self.seed = options.seed
random.seed(self.seed)
print("Using %d as seed" % (self.seed,))
def makeTest(self, obj, parent=None):
"""Given a test object and its parent, return a test case
or test suite.
"""
ldr = loader.TestLoader()
if isinstance(obj, unittest.TestCase):
return obj
elif isclass(obj):
if parent and obj.__module__ != parent.__name__:
obj = transplant_class(obj, parent.__name__)
if issubclass(obj, unittest.TestCase):
# Randomize the order of the tests in the TestCase
return self.Randomized_loadTestsFromTestCase(obj)
else:
return ldr.loadTestsFromTestClass(obj)
elif ismethod(obj):
if parent is None:
parent = obj.__class__
if issubclass(parent, unittest.TestCase):
return parent(obj.__name__)
else:
if isgenerator(obj):
return ldr.loadTestsFromGeneratorMethod(obj, parent)
else:
return MethodTestCase(obj)
elif isfunction(obj):
if parent and obj.__module__ != parent.__name__:
obj = transplant_func(obj, parent.__name__)
if isgenerator(obj):
return ldr.loadTestsFromGenerator(obj, parent)
else:
return FunctionTestCase(obj)
else:
return Failure(TypeError,
"Can't make a test from %s" % obj)
def Randomized_loadTestsFromTestCase(self, testCaseClass):
l = loader.TestLoader()
tmp = l.loadTestsFromTestCase(testCaseClass)
randomized_tests = []
for t in tmp._tests:
randomized_tests.append(t)
random.shuffle(randomized_tests)
tmp._tests = (t for t in randomized_tests)
return tmp
"""
Randomize test order plugin
"""
try:
import ez_setup
ez_setup.use_setuptools()
except ImportError:
pass
from setuptools import setup
setup(
name='Randomize test order plugin',
version='0.1',
author='Charles McCreary',
author_email = 'charles.mccreary@tiawichiresearch.com',
description = 'Randomize the order of the tests within a unittest.TestCase class',
license = 'GNU LGPL',
py_modules = ['randomize'],
entry_points = {
'nose.plugins.0.10': [
'randomize = randomize:Randomize'
]
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment