Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
0f221d09
Commit
0f221d09
authored
Nov 08, 2018
by
Lisa Roach
Committed by
GitHub
Nov 08, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-24412: Adds cleanUps for setUpClass and setUpModule. (GH-9190)
parent
49fa4a9f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
783 additions
and
18 deletions
+783
-18
Doc/library/unittest.rst
Doc/library/unittest.rst
+65
-0
Doc/whatsnew/3.8.rst
Doc/whatsnew/3.8.rst
+9
-0
Lib/unittest/__init__.py
Lib/unittest/__init__.py
+4
-3
Lib/unittest/case.py
Lib/unittest/case.py
+45
-1
Lib/unittest/suite.py
Lib/unittest/suite.py
+50
-10
Lib/unittest/test/test_runner.py
Lib/unittest/test/test_runner.py
+606
-4
Misc/NEWS.d/next/Library/2018-09-11-10-51-16.bpo-24412.i-F_E5.rst
...S.d/next/Library/2018-09-11-10-51-16.bpo-24412.i-F_E5.rst
+4
-0
No files found.
Doc/library/unittest.rst
View file @
0f221d09
...
...
@@ -1448,6 +1448,39 @@ Test cases
.. versionadded:: 3.1
.. classmethod:: addClassCleanup(function, *args, **kwargs)
Add a function to be called after :meth:`tearDownClass` to cleanup
resources used during the test class. Functions will be called in reverse
order to the order they are added (:abbr:`LIFO (last-in, first-out)`).
They are called with any arguments and keyword arguments passed into
:meth:`addClassCleanup` when they are added.
If :meth:`setUpClass` fails, meaning that :meth:`tearDownClass` is not
called, then any cleanup functions added will still be called.
.. versionadded:: 3.8
.. classmethod:: doClassCleanups()
This method is called unconditionally after :meth:`tearDownClass`, or
after :meth:`setUpClass` if :meth:`setUpClass` raises an exception.
It is responsible for calling all the cleanup functions added by
:meth:`addCleanupClass`. If you need cleanup functions to be called
*prior* to :meth:`tearDownClass` then you can call
:meth:`doCleanupsClass` yourself.
:meth:`doCleanupsClass` pops methods off the stack of cleanup
functions one at a time, so it can be called at any time.
.. versionadded:: 3.8
.. class:: FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)
...
...
@@ -2268,6 +2301,38 @@ module will be run and the ``tearDownModule`` will not be run. If the exception
:exc:`SkipTest` exception then the module will be reported as having been skipped
instead of as an error.
To add cleanup code that must be run even in the case of an exception, use
``addModuleCleanup``:
.. function:: addModuleCleanup(function, *args, **kwargs)
Add a function to be called after :func:`tearDownModule` to cleanup
resources used during the test class. Functions will be called in reverse
order to the order they are added (:abbr:`LIFO (last-in, first-out)`).
They are called with any arguments and keyword arguments passed into
:meth:`addModuleCleanup` when they are added.
If :meth:`setUpModule` fails, meaning that :func:`tearDownModule` is not
called, then any cleanup functions added will still be called.
.. versionadded:: 3.8
.. function:: doModuleCleanups()
This function is called unconditionally after :func:`tearDownModule`, or
after :func:`setUpModule` if :func:`setUpModule` raises an exception.
It is responsible for calling all the cleanup functions added by
:func:`addCleanupModule`. If you need cleanup functions to be called
*prior* to :func:`tearDownModule` then you can call
:func:`doModuleCleanups` yourself.
:func:`doModuleCleanups` pops methods off the stack of cleanup
functions one at a time, so it can be called at any time.
.. versionadded:: 3.8
Signal Handling
---------------
...
...
Doc/whatsnew/3.8.rst
View file @
0f221d09
...
...
@@ -233,6 +233,15 @@ unicodedata
is in a specific normal form. (Contributed by Max Belanger and David Euresti in
:issue:`32285`).
unittest
--------
* Added :func:`~unittest.addModuleCleanup()` and
:meth:`~unittest.TestCase.addClassCleanup()` to unittest to support
cleanups for :func:`~unittest.setUpModule()` and
:meth:`~unittest.TestCase.setUpClass()`.
(Contributed by Lisa Roach in :issue:`24412`.)
venv
----
...
...
Lib/unittest/__init__.py
View file @
0f221d09
...
...
@@ -48,7 +48,8 @@ __all__ = ['TestResult', 'TestCase', 'TestSuite',
'TextTestRunner'
,
'TestLoader'
,
'FunctionTestCase'
,
'main'
,
'defaultTestLoader'
,
'SkipTest'
,
'skip'
,
'skipIf'
,
'skipUnless'
,
'expectedFailure'
,
'TextTestResult'
,
'installHandler'
,
'registerResult'
,
'removeResult'
,
'removeHandler'
]
'registerResult'
,
'removeResult'
,
'removeHandler'
,
'addModuleCleanup'
]
# Expose obsolete functions for backwards compatibility
__all__
.
extend
([
'getTestCaseNames'
,
'makeSuite'
,
'findTestCases'
])
...
...
@@ -56,8 +57,8 @@ __all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])
__unittest
=
True
from
.result
import
TestResult
from
.case
import
(
TestCase
,
FunctionTestCase
,
SkipTest
,
skip
,
skipIf
,
skipUnless
,
expectedFailure
)
from
.case
import
(
addModuleCleanup
,
TestCase
,
FunctionTestCase
,
SkipTest
,
skip
,
skip
If
,
skip
Unless
,
expectedFailure
)
from
.suite
import
BaseTestSuite
,
TestSuite
from
.loader
import
(
TestLoader
,
defaultTestLoader
,
makeSuite
,
getTestCaseNames
,
findTestCases
)
...
...
Lib/unittest/case.py
View file @
0f221d09
...
...
@@ -84,6 +84,30 @@ class _Outcome(object):
def
_id
(
obj
):
return
obj
_module_cleanups
=
[]
def
addModuleCleanup
(
function
,
*
args
,
**
kwargs
):
"""Same as addCleanup, except the cleanup items are called even if
setUpModule fails (unlike tearDownModule)."""
_module_cleanups
.
append
((
function
,
args
,
kwargs
))
def
doModuleCleanups
():
"""Execute all module cleanup functions. Normally called for you after
tearDownModule."""
exceptions
=
[]
while
_module_cleanups
:
function
,
args
,
kwargs
=
_module_cleanups
.
pop
()
try
:
function
(
*
args
,
**
kwargs
)
except
Exception
as
exc
:
exceptions
.
append
(
exc
)
if
exceptions
:
# Swallows all but first exception. If a multi-exception handler
# gets written we should use that here instead.
raise
exceptions
[
0
]
def
skip
(
reason
):
"""
Unconditionally skip a test.
...
...
@@ -390,6 +414,8 @@ class TestCase(object):
_classSetupFailed
=
False
_class_cleanups
=
[]
def
__init__
(
self
,
methodName
=
'runTest'
):
"""Create an instance of the class that will use the named test
method when executed. Raises a ValueError if the instance does
...
...
@@ -445,6 +471,12 @@ class TestCase(object):
Cleanup items are called even if setUp fails (unlike tearDown)."""
self
.
_cleanups
.
append
((
function
,
args
,
kwargs
))
@
classmethod
def
addClassCleanup
(
cls
,
function
,
*
args
,
**
kwargs
):
"""Same as addCleanup, except the cleanup items are called even if
setUpClass fails (unlike tearDownClass)."""
cls
.
_class_cleanups
.
append
((
function
,
args
,
kwargs
))
def
setUp
(
self
):
"Hook method for setting up the test fixture before exercising it."
pass
...
...
@@ -651,9 +683,21 @@ class TestCase(object):
function
(
*
args
,
**
kwargs
)
# return this for backwards compatibility
# even though we no longer us it internally
# even though we no longer us
e
it internally
return
outcome
.
success
@
classmethod
def
doClassCleanups
(
cls
):
"""Execute all class cleanup functions. Normally called for you after
tearDownClass."""
cls
.
tearDown_exceptions
=
[]
while
cls
.
_class_cleanups
:
function
,
args
,
kwargs
=
cls
.
_class_cleanups
.
pop
()
try
:
function
(
*
args
,
**
kwargs
)
except
Exception
as
exc
:
cls
.
tearDown_exceptions
.
append
(
sys
.
exc_info
())
def
__call__
(
self
,
*
args
,
**
kwds
):
return
self
.
run
(
*
args
,
**
kwds
)
...
...
Lib/unittest/suite.py
View file @
0f221d09
...
...
@@ -166,10 +166,18 @@ class TestSuite(BaseTestSuite):
raise
currentClass
.
_classSetupFailed
=
True
className
=
util
.
strclass
(
currentClass
)
errorName
=
'setUpClass (%s)'
%
className
self
.
_addClassOrModuleLevelException
(
result
,
e
,
errorName
)
self
.
_createClassOrModuleLevelException
(
result
,
e
,
'setUpClass'
,
className
)
finally
:
_call_if_exists
(
result
,
'_restoreStdout'
)
if
currentClass
.
_classSetupFailed
is
True
:
currentClass
.
doClassCleanups
()
if
len
(
currentClass
.
tearDown_exceptions
)
>
0
:
for
exc
in
currentClass
.
tearDown_exceptions
:
self
.
_createClassOrModuleLevelException
(
result
,
exc
[
1
],
'setUpClass'
,
className
,
info
=
exc
)
def
_get_previous_module
(
self
,
result
):
previousModule
=
None
...
...
@@ -199,21 +207,37 @@ class TestSuite(BaseTestSuite):
try
:
setUpModule
()
except
Exception
as
e
:
try
:
case
.
doModuleCleanups
()
except
Exception
as
exc
:
self
.
_createClassOrModuleLevelException
(
result
,
exc
,
'setUpModule'
,
currentModule
)
if
isinstance
(
result
,
_DebugResult
):
raise
result
.
_moduleSetUpFailed
=
True
errorName
=
'setUpModule (%s)'
%
currentModule
self
.
_addClassOrModuleLevelException
(
result
,
e
,
errorName
)
self
.
_createClassOrModuleLevelException
(
result
,
e
,
'setUpModule'
,
currentModule
)
finally
:
_call_if_exists
(
result
,
'_restoreStdout'
)
def
_addClassOrModuleLevelException
(
self
,
result
,
exception
,
errorName
):
def
_createClassOrModuleLevelException
(
self
,
result
,
exc
,
method_name
,
parent
,
info
=
None
):
errorName
=
f'
{
method_name
}
(
{
parent
}
)'
self
.
_addClassOrModuleLevelException
(
result
,
exc
,
errorName
,
info
)
def
_addClassOrModuleLevelException
(
self
,
result
,
exception
,
errorName
,
info
=
None
):
error
=
_ErrorHolder
(
errorName
)
addSkip
=
getattr
(
result
,
'addSkip'
,
None
)
if
addSkip
is
not
None
and
isinstance
(
exception
,
case
.
SkipTest
):
addSkip
(
error
,
str
(
exception
))
else
:
result
.
addError
(
error
,
sys
.
exc_info
())
if
not
info
:
result
.
addError
(
error
,
sys
.
exc_info
())
else
:
result
.
addError
(
error
,
info
)
def
_handleModuleTearDown
(
self
,
result
):
previousModule
=
self
.
_get_previous_module
(
result
)
...
...
@@ -235,10 +259,17 @@ class TestSuite(BaseTestSuite):
except
Exception
as
e
:
if
isinstance
(
result
,
_DebugResult
):
raise
errorName
=
'tearDownModule (%s)'
%
previousModule
self
.
_addClassOrModuleLevelException
(
result
,
e
,
errorName
)
self
.
_createClassOrModuleLevelException
(
result
,
e
,
'tearDownModule'
,
previousModule
)
finally
:
_call_if_exists
(
result
,
'_restoreStdout'
)
try
:
case
.
doModuleCleanups
()
except
Exception
as
e
:
self
.
_createClassOrModuleLevelException
(
result
,
e
,
'tearDownModule'
,
previousModule
)
def
_tearDownPreviousClass
(
self
,
test
,
result
):
previousClass
=
getattr
(
result
,
'_previousTestClass'
,
None
)
...
...
@@ -261,10 +292,19 @@ class TestSuite(BaseTestSuite):
if
isinstance
(
result
,
_DebugResult
):
raise
className
=
util
.
strclass
(
previousClass
)
errorName
=
'tearDownClass (%s)'
%
className
self
.
_addClassOrModuleLevelException
(
result
,
e
,
errorName
)
self
.
_createClassOrModuleLevelException
(
result
,
e
,
'tearDownClass'
,
className
)
finally
:
_call_if_exists
(
result
,
'_restoreStdout'
)
previousClass
.
doClassCleanups
()
if
len
(
previousClass
.
tearDown_exceptions
)
>
0
:
for
exc
in
previousClass
.
tearDown_exceptions
:
className
=
util
.
strclass
(
previousClass
)
self
.
_createClassOrModuleLevelException
(
result
,
exc
[
1
],
'tearDownClass'
,
className
,
info
=
exc
)
class
_ErrorHolder
(
object
):
...
...
Lib/unittest/test/test_runner.py
View file @
0f221d09
...
...
@@ -11,8 +11,41 @@ from unittest.test.support import (LoggingResult,
ResultWithNoStartTestRunStopTestRun
)
class
TestCleanUp
(
unittest
.
TestCase
):
def
resultFactory
(
*
_
):
return
unittest
.
TestResult
()
def
getRunner
():
return
unittest
.
TextTestRunner
(
resultclass
=
resultFactory
,
stream
=
io
.
StringIO
())
def
runTests
(
*
cases
):
suite
=
unittest
.
TestSuite
()
for
case
in
cases
:
tests
=
unittest
.
defaultTestLoader
.
loadTestsFromTestCase
(
case
)
suite
.
addTests
(
tests
)
runner
=
getRunner
()
# creating a nested suite exposes some potential bugs
realSuite
=
unittest
.
TestSuite
()
realSuite
.
addTest
(
suite
)
# adding empty suites to the end exposes potential bugs
suite
.
addTest
(
unittest
.
TestSuite
())
realSuite
.
addTest
(
unittest
.
TestSuite
())
return
runner
.
run
(
realSuite
)
def
cleanup
(
ordering
,
blowUp
=
False
):
if
not
blowUp
:
ordering
.
append
(
'cleanup_good'
)
else
:
ordering
.
append
(
'cleanup_exc'
)
raise
Exception
(
'CleanUpExc'
)
class
TestCleanUp
(
unittest
.
TestCase
):
def
testCleanUp
(
self
):
class
TestableTest
(
unittest
.
TestCase
):
def
testNothing
(
self
):
...
...
@@ -47,10 +80,10 @@ class TestCleanUp(unittest.TestCase):
test
=
TestableTest
(
'testNothing'
)
outcome
=
test
.
_outcome
=
_Outcome
()
exc1
=
Exception
(
'foo'
)
CleanUpExc
=
Exception
(
'foo'
)
exc2
=
Exception
(
'bar'
)
def
cleanup1
():
raise
exc1
raise
CleanUpExc
def
cleanup2
():
raise
exc2
...
...
@@ -63,7 +96,7 @@ class TestCleanUp(unittest.TestCase):
((
_
,
(
Type1
,
instance1
,
_
)),
(
_
,
(
Type2
,
instance2
,
_
)))
=
reversed
(
outcome
.
errors
)
self
.
assertEqual
((
Type1
,
instance1
),
(
Exception
,
exc1
))
self
.
assertEqual
((
Type1
,
instance1
),
(
Exception
,
CleanUpExc
))
self
.
assertEqual
((
Type2
,
instance2
),
(
Exception
,
exc2
))
def
testCleanupInRun
(
self
):
...
...
@@ -135,6 +168,575 @@ class TestCleanUp(unittest.TestCase):
self
.
assertEqual
(
ordering
,
[
'setUp'
,
'test'
,
'tearDown'
,
'cleanup1'
,
'cleanup2'
])
class
TestClassCleanup
(
unittest
.
TestCase
):
def
test_addClassCleanUp
(
self
):
class
TestableTest
(
unittest
.
TestCase
):
def
testNothing
(
self
):
pass
test
=
TestableTest
(
'testNothing'
)
self
.
assertEqual
(
test
.
_class_cleanups
,
[])
class_cleanups
=
[]
def
class_cleanup1
(
*
args
,
**
kwargs
):
class_cleanups
.
append
((
3
,
args
,
kwargs
))
def
class_cleanup2
(
*
args
,
**
kwargs
):
class_cleanups
.
append
((
4
,
args
,
kwargs
))
TestableTest
.
addClassCleanup
(
class_cleanup1
,
1
,
2
,
3
,
four
=
'hello'
,
five
=
'goodbye'
)
TestableTest
.
addClassCleanup
(
class_cleanup2
)
self
.
assertEqual
(
test
.
_class_cleanups
,
[(
class_cleanup1
,
(
1
,
2
,
3
),
dict
(
four
=
'hello'
,
five
=
'goodbye'
)),
(
class_cleanup2
,
(),
{})])
TestableTest
.
doClassCleanups
()
self
.
assertEqual
(
class_cleanups
,
[(
4
,
(),
{}),
(
3
,
(
1
,
2
,
3
),
dict
(
four
=
'hello'
,
five
=
'goodbye'
))])
def
test_run_class_cleanUp
(
self
):
ordering
=
[]
blowUp
=
True
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
)
if
blowUp
:
raise
Exception
()
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
runTests
(
TestableTest
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'cleanup_good'
])
ordering
=
[]
blowUp
=
False
runTests
(
TestableTest
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'test'
,
'tearDownClass'
,
'cleanup_good'
])
def
test_debug_executes_classCleanUp
(
self
):
ordering
=
[]
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
suite
=
unittest
.
defaultTestLoader
.
loadTestsFromTestCase
(
TestableTest
)
suite
.
debug
()
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'test'
,
'tearDownClass'
,
'cleanup_good'
])
def
test_doClassCleanups_with_errors_addClassCleanUp
(
self
):
class
TestableTest
(
unittest
.
TestCase
):
def
testNothing
(
self
):
pass
def
cleanup1
():
raise
Exception
(
'cleanup1'
)
def
cleanup2
():
raise
Exception
(
'cleanup2'
)
TestableTest
.
addClassCleanup
(
cleanup1
)
TestableTest
.
addClassCleanup
(
cleanup2
)
with
self
.
assertRaises
(
Exception
)
as
e
:
TestableTest
.
doClassCleanups
()
self
.
assertEquals
(
e
,
'cleanup1'
)
def
test_with_errors_addCleanUp
(
self
):
ordering
=
[]
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
)
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
self
.
addCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
def
testNothing
(
self
):
pass
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'setUp'
,
'cleanup_exc'
,
'tearDownClass'
,
'cleanup_good'
])
def
test_run_with_errors_addClassCleanUp
(
self
):
ordering
=
[]
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
self
.
addCleanup
(
cleanup
,
ordering
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'setUp'
,
'test'
,
'cleanup_good'
,
'tearDownClass'
,
'cleanup_exc'
])
def
test_with_errors_in_addClassCleanup_and_setUps
(
self
):
ordering
=
[]
class_blow_up
=
False
method_blow_up
=
False
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
if
class_blow_up
:
raise
Exception
(
'ClassExc'
)
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
if
method_blow_up
:
raise
Exception
(
'MethodExc'
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'setUp'
,
'test'
,
'tearDownClass'
,
'cleanup_exc'
])
ordering
=
[]
class_blow_up
=
True
method_blow_up
=
False
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: ClassExc'
)
self
.
assertEqual
(
result
.
errors
[
1
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'cleanup_exc'
])
ordering
=
[]
class_blow_up
=
False
method_blow_up
=
True
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: MethodExc'
)
self
.
assertEqual
(
result
.
errors
[
1
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpClass'
,
'setUp'
,
'tearDownClass'
,
'cleanup_exc'
])
class
TestModuleCleanUp
(
unittest
.
TestCase
):
def
test_add_and_do_ModuleCleanup
(
self
):
module_cleanups
=
[]
def
module_cleanup1
(
*
args
,
**
kwargs
):
module_cleanups
.
append
((
3
,
args
,
kwargs
))
def
module_cleanup2
(
*
args
,
**
kwargs
):
module_cleanups
.
append
((
4
,
args
,
kwargs
))
class
Module
(
object
):
unittest
.
addModuleCleanup
(
module_cleanup1
,
1
,
2
,
3
,
four
=
'hello'
,
five
=
'goodbye'
)
unittest
.
addModuleCleanup
(
module_cleanup2
)
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[(
module_cleanup1
,
(
1
,
2
,
3
),
dict
(
four
=
'hello'
,
five
=
'goodbye'
)),
(
module_cleanup2
,
(),
{})])
unittest
.
case
.
doModuleCleanups
()
self
.
assertEqual
(
module_cleanups
,
[(
4
,
(),
{}),
(
3
,
(
1
,
2
,
3
),
dict
(
four
=
'hello'
,
five
=
'goodbye'
))])
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[])
def
test_doModuleCleanup_with_errors_in_addModuleCleanup
(
self
):
module_cleanups
=
[]
def
module_cleanup_good
(
*
args
,
**
kwargs
):
module_cleanups
.
append
((
3
,
args
,
kwargs
))
def
module_cleanup_bad
(
*
args
,
**
kwargs
):
raise
Exception
(
'CleanUpExc'
)
class
Module
(
object
):
unittest
.
addModuleCleanup
(
module_cleanup_good
,
1
,
2
,
3
,
four
=
'hello'
,
five
=
'goodbye'
)
unittest
.
addModuleCleanup
(
module_cleanup_bad
)
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[(
module_cleanup_good
,
(
1
,
2
,
3
),
dict
(
four
=
'hello'
,
five
=
'goodbye'
)),
(
module_cleanup_bad
,
(),
{})])
with
self
.
assertRaises
(
Exception
)
as
e
:
unittest
.
case
.
doModuleCleanups
()
self
.
assertEqual
(
str
(
e
.
exception
),
'CleanUpExc'
)
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[])
def
test_run_module_cleanUp
(
self
):
blowUp
=
True
ordering
=
[]
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
if
blowUp
:
raise
Exception
(
'setUpModule Exc'
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
TestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'cleanup_good'
])
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: setUpModule Exc'
)
ordering
=
[]
blowUp
=
False
runTests
(
TestableTest
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'test'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_good'
])
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[])
def
test_run_multiple_module_cleanUp
(
self
):
blowUp
=
True
blowUp2
=
False
ordering
=
[]
class
Module1
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
if
blowUp
:
raise
Exception
()
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
Module2
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule2'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
if
blowUp2
:
raise
Exception
()
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule2'
)
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
class
TestableTest2
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass2'
)
def
testNothing
(
self
):
ordering
.
append
(
'test2'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass2'
)
TestableTest
.
__module__
=
'Module1'
sys
.
modules
[
'Module1'
]
=
Module1
TestableTest2
.
__module__
=
'Module2'
sys
.
modules
[
'Module2'
]
=
Module2
runTests
(
TestableTest
,
TestableTest2
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'cleanup_good'
,
'setUpModule2'
,
'setUpClass2'
,
'test2'
,
'tearDownClass2'
,
'tearDownModule2'
,
'cleanup_good'
])
ordering
=
[]
blowUp
=
False
blowUp2
=
True
runTests
(
TestableTest
,
TestableTest2
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'test'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_good'
,
'setUpModule2'
,
'cleanup_good'
])
ordering
=
[]
blowUp
=
False
blowUp2
=
False
runTests
(
TestableTest
,
TestableTest2
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'test'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_good'
,
'setUpModule2'
,
'setUpClass2'
,
'test2'
,
'tearDownClass2'
,
'tearDownModule2'
,
'cleanup_good'
])
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[])
def
test_debug_module_executes_cleanUp
(
self
):
ordering
=
[]
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
TestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
suite
=
unittest
.
defaultTestLoader
.
loadTestsFromTestCase
(
TestableTest
)
suite
.
debug
()
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'test'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_good'
])
self
.
assertEqual
(
unittest
.
case
.
_module_cleanups
,
[])
def
test_with_errors_in_addClassCleanup
(
self
):
ordering
=
[]
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
cls
.
addClassCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
TestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'test'
,
'tearDownClass'
,
'cleanup_exc'
,
'tearDownModule'
,
'cleanup_good'
])
def
test_with_errors_in_addCleanup
(
self
):
ordering
=
[]
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
self
.
addCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
def
tearDown
(
self
):
ordering
.
append
(
'tearDown'
)
TestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUp'
,
'test'
,
'tearDown'
,
'cleanup_exc'
,
'tearDownModule'
,
'cleanup_good'
])
def
test_with_errors_in_addModuleCleanup_and_setUps
(
self
):
ordering
=
[]
module_blow_up
=
False
class_blow_up
=
False
method_blow_up
=
False
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup
,
ordering
,
blowUp
=
True
)
if
module_blow_up
:
raise
Exception
(
'ModuleExc'
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
@
classmethod
def
setUpClass
(
cls
):
ordering
.
append
(
'setUpClass'
)
if
class_blow_up
:
raise
Exception
(
'ClassExc'
)
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
if
method_blow_up
:
raise
Exception
(
'MethodExc'
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
@
classmethod
def
tearDownClass
(
cls
):
ordering
.
append
(
'tearDownClass'
)
TestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'setUp'
,
'test'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_exc'
])
ordering
=
[]
module_blow_up
=
True
class_blow_up
=
False
method_blow_up
=
False
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
result
.
errors
[
1
][
1
].
splitlines
()[
-
1
],
'Exception: ModuleExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'cleanup_exc'
])
ordering
=
[]
module_blow_up
=
False
class_blow_up
=
True
method_blow_up
=
False
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: ClassExc'
)
self
.
assertEqual
(
result
.
errors
[
1
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'tearDownModule'
,
'cleanup_exc'
])
ordering
=
[]
module_blow_up
=
False
class_blow_up
=
False
method_blow_up
=
True
result
=
runTests
(
TestableTest
)
self
.
assertEqual
(
result
.
errors
[
0
][
1
].
splitlines
()[
-
1
],
'Exception: MethodExc'
)
self
.
assertEqual
(
result
.
errors
[
1
][
1
].
splitlines
()[
-
1
],
'Exception: CleanUpExc'
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUpClass'
,
'setUp'
,
'tearDownClass'
,
'tearDownModule'
,
'cleanup_exc'
])
def
test_module_cleanUp_with_multiple_classes
(
self
):
ordering
=
[]
def
cleanup1
():
ordering
.
append
(
'cleanup1'
)
def
cleanup2
():
ordering
.
append
(
'cleanup2'
)
def
cleanup3
():
ordering
.
append
(
'cleanup3'
)
class
Module
(
object
):
@
staticmethod
def
setUpModule
():
ordering
.
append
(
'setUpModule'
)
unittest
.
addModuleCleanup
(
cleanup1
)
@
staticmethod
def
tearDownModule
():
ordering
.
append
(
'tearDownModule'
)
class
TestableTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
ordering
.
append
(
'setUp'
)
self
.
addCleanup
(
cleanup2
)
def
testNothing
(
self
):
ordering
.
append
(
'test'
)
def
tearDown
(
self
):
ordering
.
append
(
'tearDown'
)
class
OtherTestableTest
(
unittest
.
TestCase
):
def
setUp
(
self
):
ordering
.
append
(
'setUp2'
)
self
.
addCleanup
(
cleanup3
)
def
testNothing
(
self
):
ordering
.
append
(
'test2'
)
def
tearDown
(
self
):
ordering
.
append
(
'tearDown2'
)
TestableTest
.
__module__
=
'Module'
OtherTestableTest
.
__module__
=
'Module'
sys
.
modules
[
'Module'
]
=
Module
runTests
(
TestableTest
,
OtherTestableTest
)
self
.
assertEqual
(
ordering
,
[
'setUpModule'
,
'setUp'
,
'test'
,
'tearDown'
,
'cleanup2'
,
'setUp2'
,
'test2'
,
'tearDown2'
,
'cleanup3'
,
'tearDownModule'
,
'cleanup1'
])
class
Test_TextTestRunner
(
unittest
.
TestCase
):
"""Tests for TextTestRunner."""
...
...
Misc/NEWS.d/next/Library/2018-09-11-10-51-16.bpo-24412.i-F_E5.rst
0 → 100644
View file @
0f221d09
Add :func:`~unittest.addModuleCleanup()` and
:meth:`~unittest.TestCase.addClassCleanup()` to unittest to support
cleanups for :func:`~unittest.setUpModule()` and
:meth:`~unittest.TestCase.setUpClass()`. Patch by Lisa Roach.
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