Commit a63b9709 authored by Jérome Perrin's avatar Jérome Perrin

runUnitTest: show "default" warnings when running tests

By default, DeprecationWarning and PendingDeprecationWarning, and
ImportWarning are ignored, we want to see those while running tests, so
we reset the warnings module to use "default" behavior for all warnings.

https://docs.python.org/3/library/warnings.html#default-warning-filter
https://docs.python.org/2.7/library/warnings.html#updating-code-for-new-versions-of-python

This also implements the recommendation from
https://docs.python.org/3/library/warnings.html#overriding-the-default-filter

> Developers of test runners for Python code are advised to instead
> ensure that all warnings are displayed by default for the code under
> test, using code like:

    import sys

    if not sys.warnoptions:
        import os, warnings
        warnings.simplefilter("default") # Change the filter in this process
        os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses

This also extend the "Run Live Test" action to allow controlling the
warnings filter, but on python2 this does not work so well, once a
warning was ignored, later switching to "always" or "error" does not
process the warning again ( it might be because of
 https://bugs.python.org/issue4180 )
parent f41b33cd
......@@ -110,6 +110,7 @@
<list>
<string>your_debug</string>
<string>your_verbose</string>
<string>your_warnings</string>
</list>
</value>
</item>
......
......@@ -148,7 +148,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: {\'run_test_url\': here.absolute_url() + \'/runLiveTest\', \'read_test_url\': here.absolute_url() + \'/readTestOutput\', \'test_list\': here.REQUEST.get(\'field_your_test\', \'\'), \'run_only\': here.REQUEST.get(\'field_your_run_only\', \'\'), \'debug\': int(here.REQUEST.get(\'field_your_debug\', \'\') == \'on\'), \'verbose\': int(here.REQUEST.get(\'field_your_verbose\', \'\') == \'on\')}</string> </value>
<value> <string>python: {\'run_test_url\': here.absolute_url() + \'/runLiveTest\', \'read_test_url\': here.absolute_url() + \'/readTestOutput\', \'test_list\': here.REQUEST.get(\'field_your_test\', \'\'), \'run_only\': here.REQUEST.get(\'field_your_run_only\', \'\'), \'debug\': int(here.REQUEST.get(\'field_your_debug\', \'\') == \'on\'), \'verbose\': int(here.REQUEST.get(\'field_your_verbose\', \'\') == \'on\'), \'warnings\': request.get(\'field_your_warnings\')}</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ListField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>your_warnings</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>Input is required but no input given.</string> </value>
</item>
<item>
<key> <string>unknown_selection</string> </key>
<value> <string>You selected an item that was not in the list.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>items</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>autocomplete</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Default warnings action. See python\'s warnings module for details</string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra_item</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>first_item</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>items</string> </key>
<value>
<list>
<tuple>
<string>default</string>
<string>default</string>
</tuple>
<tuple>
<string>error</string>
<string>error</string>
</tuple>
<tuple>
<string>ignore</string>
<string>ignore</string>
</tuple>
<tuple>
<string>always</string>
<string>always</string>
</tuple>
<tuple>
<string>module</string>
<string>module</string>
</tuple>
<tuple>
<string>once</string>
<string>once</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>size</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Warnings</string> </value>
</item>
<item>
<key> <string>unicode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>whitespace_preserve</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -275,7 +275,7 @@ class Test(ERP5TypeTestCase):
security.declareProtected(Permissions.ManagePortal, 'runLiveTest')
def runLiveTest(self, test_list=None, run_only=None, debug=False,
verbose=False):
verbose=False, warnings='default'):
"""
Launch live tests
......@@ -315,7 +315,8 @@ class Test(ERP5TypeTestCase):
debug=debug,
stream=global_stream,
request_server_url=request_server_url,
verbosity=verbosity)
verbosity=verbosity,
warnings=warnings)
except ImportError:
import traceback
traceback.print_exc(file=global_stream)
......
......@@ -31,6 +31,7 @@ import os
import sys
import imp
import re
import warnings
from zope.site.hooks import setSite
from zope.globalrequest import getRequest
......@@ -297,11 +298,14 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
output.write("**Running Live Test:\n")
ZopeTestCase._print = output.write
# Test may login/logout with different users, so ensure that at the end the
# original SecurityManager is restored
from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager
sm = getSecurityManager()
try:
result = TestRunner(stream=output, verbosity=verbosity).run(suite)
finally:
setSecurityManager(sm)
with warnings.catch_warnings():
warnings.simplefilter(kw['warnings'])
# Test may login/logout with different users, so ensure that at the end the
# original SecurityManager is restored
from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager
sm = getSecurityManager()
try:
result = TestRunner(stream=output, verbosity=verbosity).run(suite)
finally:
setSecurityManager(sm)
......@@ -11,6 +11,7 @@ import shutil
import errno
import random
import transaction
import warnings
from glob import glob
......@@ -495,6 +496,13 @@ class DebugTestResult:
_print = sys.stderr.write
def setupWarnings():
if not sys.warnoptions:
warnings.simplefilter("default")
os.environ["PYTHONWARNINGS"] = "default"
def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
if "zeo_client" in os.environ and "zeo_server" in os.environ:
_print("conflicting options: --zeo_client and --zeo_server\n")
......@@ -898,6 +906,8 @@ def main(argument_list=None):
elif opt == "--with_wendelin_core":
os.environ["with_wendelin_core"] = "1"
setupWarnings()
bt5_path_list += filter(None,
os.environ.get("erp5_tests_bt5_path", "").split(','))
valid_path_list = []
......
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