Skip to content

Commit

Permalink
Merge pull request #36 from redixin/fix_mock_testr
Browse files Browse the repository at this point in the history
Fix different test names with different runs
  • Loading branch information
txels committed Nov 18, 2015
2 parents 2aba978 + e081f9c commit 9fcc499
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 54 deletions.
64 changes: 20 additions & 44 deletions ddt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import json
import os
import re
import sys
from functools import wraps

__version__ = '1.0.0'
Expand All @@ -23,6 +22,20 @@
UNPACK_ATTR = '%unpack' # remember that we have to unpack values


try:
trivial_types = (type(None), bool, int, float, basestring)
except NameError:
trivial_types = (type(None), bool, int, float, str)


def is_trivial(value):
if isinstance(value, trivial_types):
return True
elif isinstance(value, (list, tuple)):
return all(map(is_trivial, value))
return False


def unpack(func):
"""
Method decorator to add unpack feature.
Expand Down Expand Up @@ -70,14 +83,6 @@ def wrapper(func):
return wrapper


def is_hash_randomized():
return (((sys.hexversion >= 0x02070300 and
sys.hexversion < 0x03000000) or
(sys.hexversion >= 0x03020300)) and
sys.flags.hash_randomization and
'PYTHONHASHSEED' not in os.environ)


def mk_test_name(name, value, index=0):
"""
Generate a new name for a test case.
Expand All @@ -86,47 +91,18 @@ def mk_test_name(name, value, index=0):
string representation of the value, and convert the result into a valid
python identifier by replacing extraneous characters with ``_``.
If hash randomization is enabled (a feature available since 2.7.3/3.2.3
and enabled by default since 3.3) and a "non-trivial" value is passed
this will omit the name argument by default. Set `PYTHONHASHSEED`
to a fixed value before running tests in these cases to get the
names back consistently or use the `__name__` attribute on data values.
We avoid doing str(value) if dealing with non-trivial values.
The problem is possible different names with different runs, e.g.
different order of dictionary keys (see PYTHONHASHSEED) or dealing
with mock objects.
Trivial scalar values are passed as is.
A "trivial" value is a plain scalar, or a tuple or list consisting
only of trivial values.
"""

# We avoid doing str(value) if all of the following hold:
#
# * Python version is 2.7.3 or newer (for 2 series) or 3.2.3 or
# newer (for 3 series). Also sys.flags.hash_randomization didn't
# exist before these.
# * sys.flags.hash_randomization is set to True
# * PYTHONHASHSEED is **not** defined in the environment
# * Given `value` argument is not a trivial scalar (None, str,
# int, float).
#
# Trivial scalar values are passed as is in all cases.

trivial_types = (type(None), bool, str, int, float)
try:
trivial_types += (unicode,)
except NameError:
pass

def is_trivial(value):
if isinstance(value, trivial_types):
return True

if isinstance(value, (list, tuple)):
return all(map(is_trivial, value))

return False

if is_hash_randomized() and not is_trivial(value):
if not is_trivial(value):
return "{0}_{1}".format(name, index + 1)

try:
value = str(value)
except UnicodeEncodeError:
Expand Down
27 changes: 17 additions & 10 deletions test/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import six

from ddt import ddt, data, file_data, is_hash_randomized
from ddt import ddt, data, file_data
from nose.tools import assert_equal, assert_is_not_none, assert_raises


Expand Down Expand Up @@ -226,11 +226,7 @@ def test_hello(self, val):

assert_is_not_none(getattr(Mytest, 'test_hello_1_ascii'))
assert_is_not_none(getattr(Mytest, 'test_hello_2_non_ascii__u2603'))
if is_hash_randomized():
assert_is_not_none(getattr(Mytest, 'test_hello_3'))
else:
assert_is_not_none(getattr(Mytest,
'test_hello_3__u__u2603____data__'))
assert_is_not_none(getattr(Mytest, 'test_hello_3'))

elif six.PY3:

Expand All @@ -242,10 +238,21 @@ def test_hello(self, val):

assert_is_not_none(getattr(Mytest, 'test_hello_1_ascii'))
assert_is_not_none(getattr(Mytest, 'test_hello_2_non_ascii__'))
if is_hash_randomized():
assert_is_not_none(getattr(Mytest, 'test_hello_3'))
else:
assert_is_not_none(getattr(Mytest, 'test_hello_3________data__'))
assert_is_not_none(getattr(Mytest, 'test_hello_3'))


def test_ddt_data_object():
"""
Test not using value if non-trivial arguments
"""

@ddt
class Mytest(object):
@data(object)
def test_object(self, val):
pass

assert_is_not_none(getattr(Mytest, 'test_object_1_object'))


def test_feed_data_with_invalid_identifier():
Expand Down

0 comments on commit 9fcc499

Please sign in to comment.