Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
3d7bd9aa
Commit
3d7bd9aa
authored
Mar 25, 2015
by
Calen Pennington
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make BulkAssertionTest.bulk_assertions work with any assert* method
parent
aeff0880
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
281 additions
and
80 deletions
+281
-80
common/lib/xmodule/xmodule/tests/__init__.py
+151
-40
common/lib/xmodule/xmodule/tests/test_bulk_assertions.py
+130
-40
No files found.
common/lib/xmodule/xmodule/tests/__init__.py
View file @
3d7bd9aa
...
@@ -7,35 +7,35 @@ Run like this:
...
@@ -7,35 +7,35 @@ Run like this:
"""
"""
import
inspect
import
json
import
json
import
os
import
os
import
pprint
import
pprint
import
sys
import
traceback
import
unittest
import
unittest
import
inspect
import
mock
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
,
nested
from
eventtracking
import
tracker
from
eventtracking.django
import
DjangoTracker
from
functools
import
wraps
from
lazy
import
lazy
from
lazy
import
lazy
from
mock
import
Mock
from
mock
import
Mock
,
patch
from
operator
import
attrgetter
from
operator
import
attrgetter
from
path
import
path
from
path
import
path
from
eventtracking
import
tracker
from
eventtracking.django
import
DjangoTracker
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xblock.field_data
import
DictFieldData
from
xblock.field_data
import
DictFieldData
from
xblock.fields
import
ScopeIds
,
Scope
,
Reference
,
ReferenceList
,
ReferenceValueDict
from
xblock.fields
import
ScopeIds
,
Scope
,
Reference
,
ReferenceList
,
ReferenceValueDict
from
xmodule.x_module
import
ModuleSystem
,
XModuleDescriptor
,
XModuleMixin
from
xmodule.modulestore.inheritance
import
InheritanceMixin
,
own_metadata
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.assetstore
import
AssetMetadata
from
xmodule.assetstore
import
AssetMetadata
from
xmodule.error_module
import
ErrorDescriptor
from
xmodule.mako_module
import
MakoDescriptorSystem
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.draft_and_published
import
DIRECT_ONLY_CATEGORIES
,
ModuleStoreDraftAndPublished
from
xmodule.modulestore.inheritance
import
InheritanceMixin
,
own_metadata
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.mongo.draft
import
DraftModuleStore
from
xmodule.modulestore.xml
import
CourseLocationManager
from
xmodule.modulestore.xml
import
CourseLocationManager
from
xmodule.
modulestore.draft_and_published
import
DIRECT_ONLY_CATEGORIES
,
ModuleStoreDraftAndPublished
from
xmodule.
x_module
import
ModuleSystem
,
XModuleDescriptor
,
XModuleMixin
MODULE_DIR
=
path
(
__file__
)
.
dirname
()
MODULE_DIR
=
path
(
__file__
)
.
dirname
()
...
@@ -58,7 +58,7 @@ class TestModuleSystem(ModuleSystem): # pylint: disable=abstract-method
...
@@ -58,7 +58,7 @@ class TestModuleSystem(ModuleSystem): # pylint: disable=abstract-method
"""
"""
ModuleSystem for testing
ModuleSystem for testing
"""
"""
@
mock.
patch
(
'eventtracking.tracker.emit'
)
@patch
(
'eventtracking.tracker.emit'
)
def
__init__
(
self
,
mock_emit
,
**
kwargs
):
# pylint: disable=unused-argument
def
__init__
(
self
,
mock_emit
,
**
kwargs
):
# pylint: disable=unused-argument
id_manager
=
CourseLocationManager
(
kwargs
[
'course_id'
])
id_manager
=
CourseLocationManager
(
kwargs
[
'course_id'
])
kwargs
.
setdefault
(
'id_reader'
,
id_manager
)
kwargs
.
setdefault
(
'id_reader'
,
id_manager
)
...
@@ -224,57 +224,152 @@ def map_references(value, field, actual_course_key):
...
@@ -224,57 +224,152 @@ def map_references(value, field, actual_course_key):
return
value
return
value
class
BulkAssertionManager
(
object
):
class
BulkAssertionError
(
AssertionError
):
"""
An AssertionError that contains many sub-assertions.
"""
def
__init__
(
self
,
assertion_errors
):
self
.
errors
=
assertion_errors
super
(
BulkAssertionError
,
self
)
.
__init__
(
"The following assertions were raised:
\n
{}"
.
format
(
"
\n\n
"
.
join
(
self
.
errors
)
))
class
_BulkAssertionManager
(
object
):
"""
"""
This provides a facility for making a large number of assertions, and seeing all of
This provides a facility for making a large number of assertions, and seeing all of
the failures at once, rather than only seeing single failures.
the failures at once, rather than only seeing single failures.
"""
"""
def
__init__
(
self
,
test_case
):
def
__init__
(
self
,
test_case
):
self
.
_
equal_assertion
s
=
[]
self
.
_
assertion_error
s
=
[]
self
.
_test_case
=
test_case
self
.
_test_case
=
test_case
def
run_assertions
(
self
):
def
log_error
(
self
,
formatted_exc
):
if
len
(
self
.
_equal_assertions
)
>
0
:
"""
raise
AssertionError
(
self
.
_equal_assertions
)
Record ``formatted_exc`` in the set of exceptions captured by this assertion manager.
"""
self
.
_assertion_errors
.
append
(
formatted_exc
)
def
raise_assertion_errors
(
self
):
"""
Raise a BulkAssertionError containing all of the captured AssertionErrors,
if there were any.
"""
if
self
.
_assertion_errors
:
raise
BulkAssertionError
(
self
.
_assertion_errors
)
class
BulkAssertionTest
(
unittest
.
TestCase
):
class
BulkAssertionTest
(
unittest
.
TestCase
):
"""
"""
This context manager provides a BulkAssertionManager to assert with,
This context manager provides a
_
BulkAssertionManager to assert with,
and then calls `r
un_assertion
s` at the end of the block to validate all
and then calls `r
aise_assertion_error
s` at the end of the block to validate all
of the assertions.
of the assertions.
"""
"""
def
setUp
(
self
,
*
args
,
**
kwargs
):
def
setUp
(
self
,
*
args
,
**
kwargs
):
super
(
BulkAssertionTest
,
self
)
.
setUp
(
*
args
,
**
kwargs
)
super
(
BulkAssertionTest
,
self
)
.
setUp
(
*
args
,
**
kwargs
)
self
.
_manager
=
None
# Use __ to not pollute the namespace of subclasses with what could be a fairly generic name.
self
.
__manager
=
None
@contextmanager
@contextmanager
def
bulk_assertions
(
self
):
def
bulk_assertions
(
self
):
if
self
.
_manager
:
"""
A context manager that will capture all assertion failures made by self.assert*
methods within its context, and raise a single combined assertion error at
the end of the context.
"""
if
self
.
__manager
:
yield
yield
else
:
else
:
try
:
try
:
self
.
_
manager
=
BulkAssertionManager
(
self
)
self
.
_
_manager
=
_
BulkAssertionManager
(
self
)
yield
yield
finally
:
except
Exception
:
self
.
_manager
.
run_assertions
()
raise
self
.
_manager
=
None
else
:
manager
=
self
.
__manager
self
.
__manager
=
None
manager
.
raise_assertion_errors
()
def
assertEqual
(
self
,
expected
,
actual
,
message
=
None
):
@contextmanager
if
self
.
_manager
is
not
None
:
def
_capture_assertion_errors
(
self
):
"""
A context manager that captures any AssertionError raised within it,
and, if within a ``bulk_assertions`` context, records the captured
assertion to the bulk assertion manager. If not within a ``bulk_assertions``
context, just raises the original exception.
"""
try
:
try
:
super
(
BulkAssertionTest
,
self
)
.
assertEqual
(
expected
,
actual
,
message
)
# Only wrap the first layer of assert functions by stashing away the manager
except
Exception
as
error
:
# pylint: disable=broad-except
# before executing the assertion.
exc_stack
=
inspect
.
stack
()[
1
]
manager
=
self
.
__manager
if
message
is
not
None
:
self
.
__manager
=
None
msg
=
'{} -> {}:{} -> {}'
.
format
(
message
,
exc_stack
[
1
],
exc_stack
[
2
],
unicode
(
error
))
yield
except
AssertionError
:
# pylint: disable=broad-except
if
manager
is
not
None
:
# Reconstruct the stack in which the error was thrown (so that the traceback)
# isn't cut off at `assertion(*args, **kwargs)`.
exc_type
,
exc_value
,
exc_tb
=
sys
.
exc_info
()
# Count the number of stack frames before you get to a
# unittest context (walking up the stack from here).
relevant_frames
=
0
for
frame_record
in
inspect
.
stack
():
# This is the same criterion used by unittest to decide if a
# stack frame is relevant to exception printing.
frame
=
frame_record
[
0
]
if
'__unittest'
in
frame
.
f_globals
:
break
relevant_frames
+=
1
stack_above
=
traceback
.
extract_stack
()[
-
relevant_frames
:
-
1
]
stack_below
=
traceback
.
extract_tb
(
exc_tb
)
formatted_stack
=
traceback
.
format_list
(
stack_above
+
stack_below
)
formatted_exc
=
traceback
.
format_exception_only
(
exc_type
,
exc_value
)
manager
.
log_error
(
""
.
join
(
formatted_stack
+
formatted_exc
)
)
else
:
else
:
msg
=
'{}:{} -> {}'
.
format
(
exc_stack
[
1
],
exc_stack
[
2
],
unicode
(
error
))
raise
self
.
_manager
.
_equal_assertions
.
append
(
msg
)
# pylint: disable=protected-access
finally
:
self
.
__manager
=
manager
def
_wrap_assertion
(
self
,
assertion
):
"""
Wraps an assert* method to capture an immediate exception,
or to generate a new assertion capturing context (in the case of assertRaises
and assertRaisesRegexp).
"""
@wraps
(
assertion
)
def
assert_
(
*
args
,
**
kwargs
):
"""
Execute a captured assertion, and catch any assertion errors raised.
"""
context
=
None
# Run the assertion, and capture any raised assertionErrors
with
self
.
_capture_assertion_errors
():
context
=
assertion
(
*
args
,
**
kwargs
)
# Handle the assertRaises family of functions by returning
# a context manager that surrounds the assertRaises
# with our assertion capturing context manager.
if
context
is
not
None
:
return
nested
(
self
.
_capture_assertion_errors
(),
context
)
return
assert_
def
__getattribute__
(
self
,
name
):
"""
Wrap all assert* methods of this class using self._wrap_assertion,
to capture all assertion errors in bulk.
"""
base_attr
=
super
(
BulkAssertionTest
,
self
)
.
__getattribute__
(
name
)
if
name
.
startswith
(
'assert'
):
return
self
.
_wrap_assertion
(
base_attr
)
else
:
else
:
super
(
BulkAssertionTest
,
self
)
.
assertEqual
(
expected
,
actual
,
message
)
return
base_attr
assertEquals
=
assertEqual
class
LazyFormat
(
object
):
class
LazyFormat
(
object
):
...
@@ -297,6 +392,12 @@ class LazyFormat(object):
...
@@ -297,6 +392,12 @@ class LazyFormat(object):
def
__repr__
(
self
):
def
__repr__
(
self
):
return
unicode
(
self
)
return
unicode
(
self
)
def
__len__
(
self
):
return
len
(
unicode
(
self
))
def
__getitem__
(
self
,
index
):
return
unicode
(
self
)[
index
]
class
CourseComparisonTest
(
BulkAssertionTest
):
class
CourseComparisonTest
(
BulkAssertionTest
):
"""
"""
...
@@ -432,6 +533,13 @@ class CourseComparisonTest(BulkAssertionTest):
...
@@ -432,6 +533,13 @@ class CourseComparisonTest(BulkAssertionTest):
for
item
in
actual_items
for
item
in
actual_items
}
}
# Split Mongo and Old-Mongo disagree about what the block_id of courses is, so skip those in
# this comparison
self
.
assertItemsEqual
(
[
map_key
(
item
.
location
)
for
item
in
expected_items
if
item
.
scope_ids
.
block_type
!=
'course'
],
[
key
for
key
in
actual_item_map
.
keys
()
if
key
[
0
]
!=
'course'
],
)
for
expected_item
in
expected_items
:
for
expected_item
in
expected_items
:
actual_item_location
=
actual_course_key
.
make_usage_key
(
expected_item
.
category
,
expected_item
.
location
.
block_id
)
actual_item_location
=
actual_course_key
.
make_usage_key
(
expected_item
.
category
,
expected_item
.
location
.
block_id
)
# split and old mongo use different names for the course root but we don't know which
# split and old mongo use different names for the course root but we don't know which
...
@@ -445,7 +553,10 @@ class CourseComparisonTest(BulkAssertionTest):
...
@@ -445,7 +553,10 @@ class CourseComparisonTest(BulkAssertionTest):
actual_item
=
actual_item_map
.
get
(
map_key
(
actual_item_location
))
actual_item
=
actual_item_map
.
get
(
map_key
(
actual_item_location
))
# Formatting the message slows down tests of large courses significantly, so only do it if it would be used
# Formatting the message slows down tests of large courses significantly, so only do it if it would be used
self
.
assertIsNotNone
(
actual_item
,
LazyFormat
(
u'cannot find {} in {}'
,
map_key
(
actual_item_location
),
actual_item_map
))
self
.
assertIn
(
map_key
(
actual_item_location
),
actual_item_map
.
keys
())
if
actual_item
is
None
:
continue
# compare fields
# compare fields
self
.
assertEqual
(
expected_item
.
fields
,
actual_item
.
fields
)
self
.
assertEqual
(
expected_item
.
fields
,
actual_item
.
fields
)
...
...
common/lib/xmodule/xmodule/tests/test_bulk_assertions.py
View file @
3d7bd9aa
import
ddt
import
ddt
from
xmodule.tests
import
BulkAssertionTest
import
itertools
from
xmodule.tests
import
BulkAssertionTest
,
BulkAssertionError
@ddt.ddt
STATIC_PASSING_ASSERTIONS
=
(
class
TestBulkAssertionTestCase
(
BulkAssertionTest
):
@ddt.data
(
(
'assertTrue'
,
True
),
(
'assertTrue'
,
True
),
(
'assertFalse'
,
False
),
(
'assertFalse'
,
False
),
(
'assertIs'
,
1
,
1
),
(
'assertIs'
,
1
,
1
),
(
'assertEqual'
,
1
,
1
),
(
'assertEquals'
,
1
,
1
),
(
'assertIsNot'
,
1
,
2
),
(
'assertIsNot'
,
1
,
2
),
(
'assertIsNone'
,
None
),
(
'assertIsNone'
,
None
),
(
'assertIsNotNone'
,
1
),
(
'assertIsNotNone'
,
1
),
...
@@ -16,16 +16,15 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
...
@@ -16,16 +16,15 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
(
'assertNotIn'
,
5
,
(
1
,
2
,
3
)),
(
'assertNotIn'
,
5
,
(
1
,
2
,
3
)),
(
'assertIsInstance'
,
1
,
int
),
(
'assertIsInstance'
,
1
,
int
),
(
'assertNotIsInstance'
,
'1'
,
int
),
(
'assertNotIsInstance'
,
'1'
,
int
),
(
'assertRaises'
,
KeyError
,
{}
.
__getitem__
,
'1'
),
(
'assertItemsEqual'
,
[
1
,
2
,
3
],
[
3
,
2
,
1
])
)
)
@ddt.unpack
def
test_passing_asserts_passthrough
(
self
,
assertion
,
*
args
):
getattr
(
self
,
assertion
)(
*
args
)
@ddt.data
(
STATIC_FAILING_ASSERTIONS
=
(
(
'assertTrue'
,
False
),
(
'assertTrue'
,
False
),
(
'assertFalse'
,
True
),
(
'assertFalse'
,
True
),
(
'assertIs'
,
1
,
2
),
(
'assertIs'
,
1
,
2
),
(
'assertEqual'
,
1
,
2
),
(
'assertEquals'
,
1
,
2
),
(
'assertIsNot'
,
1
,
1
),
(
'assertIsNot'
,
1
,
1
),
(
'assertIsNone'
,
1
),
(
'assertIsNone'
,
1
),
(
'assertIsNotNone'
,
None
),
(
'assertIsNotNone'
,
None
),
...
@@ -33,45 +32,136 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
...
@@ -33,45 +32,136 @@ class TestBulkAssertionTestCase(BulkAssertionTest):
(
'assertNotIn'
,
1
,
(
1
,
2
,
3
)),
(
'assertNotIn'
,
1
,
(
1
,
2
,
3
)),
(
'assertIsInstance'
,
'1'
,
int
),
(
'assertIsInstance'
,
'1'
,
int
),
(
'assertNotIsInstance'
,
1
,
int
),
(
'assertNotIsInstance'
,
1
,
int
),
(
'assertItemsEqual'
,
[
1
,
1
,
1
],
[
1
,
1
])
)
CONTEXT_PASSING_ASSERTIONS
=
(
(
'assertRaises'
,
KeyError
,
{}
.
__getitem__
,
'1'
),
(
'assertRaisesRegexp'
,
KeyError
,
"1"
,
{}
.
__getitem__
,
'1'
),
)
CONTEXT_FAILING_ASSERTIONS
=
(
(
'assertRaises'
,
ValueError
,
lambda
:
None
),
(
'assertRaises'
,
ValueError
,
lambda
:
None
),
)
(
'assertRaisesRegexp'
,
KeyError
,
"2"
,
{}
.
__getitem__
,
'1'
),
@ddt.unpack
)
def
test_failing_asserts_passthrough
(
self
,
assertion
,
*
args
):
# Use super(BulkAssertionTest) to make sure we get un-adulturated assertions
with
super
(
BulkAssertionTest
,
self
)
.
assertRaises
(
AssertionError
):
@ddt.ddt
class
TestBulkAssertionTestCase
(
BulkAssertionTest
):
# We have to use assertion methods from the base UnitTest class,
# so we make a number of super calls that skip BulkAssertionTest.
# pylint: disable=bad-super-call
def
_run_assertion
(
self
,
assertion_tuple
):
"""
Run the supplied tuple of (assertion, *args) as a method on this class.
"""
assertion
,
args
=
assertion_tuple
[
0
],
assertion_tuple
[
1
:]
getattr
(
self
,
assertion
)(
*
args
)
getattr
(
self
,
assertion
)(
*
args
)
def
test_no_bulk_assert_equals
(
self
):
def
_raw_assert
(
self
,
assertion_name
,
*
args
,
**
kwargs
):
"""
Run an un-modified assertion.
"""
# Use super(BulkAssertionTest) to make sure we get un-adulturated assertions
# Use super(BulkAssertionTest) to make sure we get un-adulturated assertions
with
super
(
BulkAssertionTest
,
self
)
.
assertRaises
(
AssertionError
):
return
getattr
(
super
(
BulkAssertionTest
,
self
),
'assert'
+
assertion_name
)(
*
args
,
**
kwargs
)
self
.
assertEquals
(
1
,
2
)
@ddt.data
(
*
(
STATIC_PASSING_ASSERTIONS
+
CONTEXT_PASSING_ASSERTIONS
))
@ddt.data
(
def
test_passing_asserts_passthrough
(
self
,
assertion_tuple
):
'assertEqual'
,
'assertEquals'
self
.
_run_assertion
(
assertion_tuple
)
)
def
test_bulk_assert_equals
(
self
,
asserterFn
):
@ddt.data
(
*
(
STATIC_FAILING_ASSERTIONS
+
CONTEXT_FAILING_ASSERTIONS
))
asserter
=
getattr
(
self
,
asserterFn
)
def
test_failing_asserts_passthrough
(
self
,
assertion_tuple
):
with
self
.
_raw_assert
(
'Raises'
,
AssertionError
)
as
context
:
self
.
_run_assertion
(
assertion_tuple
)
self
.
_raw_assert
(
'NotIsInstance'
,
context
.
exception
,
BulkAssertionError
)
@ddt.data
(
*
CONTEXT_PASSING_ASSERTIONS
)
@ddt.unpack
def
test_passing_context_assertion_passthrough
(
self
,
assertion
,
*
args
):
assertion_args
=
[]
args
=
list
(
args
)
exception
=
args
.
pop
(
0
)
while
not
callable
(
args
[
0
]):
assertion_args
.
append
(
args
.
pop
(
0
))
function
=
args
.
pop
(
0
)
with
getattr
(
self
,
assertion
)(
exception
,
*
assertion_args
):
function
(
*
args
)
@ddt.data
(
*
CONTEXT_FAILING_ASSERTIONS
)
@ddt.unpack
def
test_failing_context_assertion_passthrough
(
self
,
assertion
,
*
args
):
assertion_args
=
[]
args
=
list
(
args
)
exception
=
args
.
pop
(
0
)
while
not
callable
(
args
[
0
]):
assertion_args
.
append
(
args
.
pop
(
0
))
function
=
args
.
pop
(
0
)
with
self
.
_raw_assert
(
'Raises'
,
AssertionError
)
as
context
:
with
getattr
(
self
,
assertion
)(
exception
,
*
assertion_args
):
function
(
*
args
)
self
.
_raw_assert
(
'NotIsInstance'
,
context
.
exception
,
BulkAssertionError
)
@ddt.data
(
*
list
(
itertools
.
product
(
CONTEXT_PASSING_ASSERTIONS
,
CONTEXT_FAILING_ASSERTIONS
,
CONTEXT_FAILING_ASSERTIONS
)))
@ddt.unpack
def
test_bulk_assert
(
self
,
passing_assertion
,
failing_assertion1
,
failing_assertion2
):
contextmanager
=
self
.
bulk_assertions
()
contextmanager
=
self
.
bulk_assertions
()
contextmanager
.
__enter__
()
contextmanager
.
__enter__
()
s
uper
(
BulkAssertionTest
,
self
)
.
assertIsNotNone
(
self
.
_manager
)
s
elf
.
_run_assertion
(
passing_assertion
)
asserter
(
1
,
2
)
self
.
_run_assertion
(
failing_assertion1
)
asserter
(
3
,
4
)
self
.
_run_assertion
(
failing_assertion2
)
# Use super(BulkAssertionTest) to make sure we get un-adulturated assertions
with
self
.
_raw_assert
(
'Raises'
,
BulkAssertionError
)
as
context
:
with
super
(
BulkAssertionTest
,
self
)
.
assertRaises
(
AssertionError
):
contextmanager
.
__exit__
(
None
,
None
,
None
)
contextmanager
.
__exit__
(
None
,
None
,
None
)
@ddt.data
(
self
.
_raw_assert
(
'Equals'
,
len
(
context
.
exception
.
errors
),
2
)
'assertEqual'
,
'assertEquals'
)
def
test_bulk_assert_closed
(
self
,
asserterFn
):
asserter
=
getattr
(
self
,
asserterFn
)
@ddt.data
(
*
list
(
itertools
.
product
(
CONTEXT_FAILING_ASSERTIONS
)))
@ddt.unpack
def
test_nested_bulk_asserts
(
self
,
failing_assertion
):
with
self
.
_raw_assert
(
'Raises'
,
BulkAssertionError
)
as
context
:
with
self
.
bulk_assertions
():
with
self
.
bulk_assertions
():
asserter
(
1
,
1
)
self
.
_run_assertion
(
failing_assertion
)
asserter
(
2
,
2
)
with
self
.
bulk_assertions
():
self
.
_run_assertion
(
failing_assertion
)
self
.
_run_assertion
(
failing_assertion
)
# Use super(BulkAssertionTest) to make sure we get un-adulturated assertions
self
.
_raw_assert
(
'Equal'
,
len
(
context
.
exception
.
errors
),
3
)
with
super
(
BulkAssertionTest
,
self
)
.
assertRaises
(
AssertionError
):
asserter
(
1
,
2
)
@ddt.data
(
*
list
(
itertools
.
product
(
CONTEXT_PASSING_ASSERTIONS
,
CONTEXT_FAILING_ASSERTIONS
,
CONTEXT_FAILING_ASSERTIONS
)))
@ddt.unpack
def
test_bulk_assert_closed
(
self
,
passing_assertion
,
failing_assertion1
,
failing_assertion2
):
with
self
.
_raw_assert
(
'Raises'
,
BulkAssertionError
)
as
context
:
with
self
.
bulk_assertions
():
self
.
_run_assertion
(
passing_assertion
)
self
.
_run_assertion
(
failing_assertion1
)
self
.
_raw_assert
(
'Equals'
,
len
(
context
.
exception
.
errors
),
1
)
with
self
.
_raw_assert
(
'Raises'
,
AssertionError
)
as
context
:
self
.
_run_assertion
(
failing_assertion2
)
self
.
_raw_assert
(
'NotIsInstance'
,
context
.
exception
,
BulkAssertionError
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment