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 @@ ...@@ -110,6 +110,7 @@
<list> <list>
<string>your_debug</string> <string>your_debug</string>
<string>your_verbose</string> <string>your_verbose</string>
<string>your_warnings</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -148,7 +148,7 @@ ...@@ -148,7 +148,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_text</string> </key> <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> </item>
</dictionary> </dictionary>
</pickle> </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): ...@@ -275,7 +275,7 @@ class Test(ERP5TypeTestCase):
security.declareProtected(Permissions.ManagePortal, 'runLiveTest') security.declareProtected(Permissions.ManagePortal, 'runLiveTest')
def runLiveTest(self, test_list=None, run_only=None, debug=False, def runLiveTest(self, test_list=None, run_only=None, debug=False,
verbose=False): verbose=False, warnings='default'):
""" """
Launch live tests Launch live tests
...@@ -315,7 +315,8 @@ class Test(ERP5TypeTestCase): ...@@ -315,7 +315,8 @@ class Test(ERP5TypeTestCase):
debug=debug, debug=debug,
stream=global_stream, stream=global_stream,
request_server_url=request_server_url, request_server_url=request_server_url,
verbosity=verbosity) verbosity=verbosity,
warnings=warnings)
except ImportError: except ImportError:
import traceback import traceback
traceback.print_exc(file=global_stream) traceback.print_exc(file=global_stream)
......
...@@ -31,6 +31,7 @@ import os ...@@ -31,6 +31,7 @@ import os
import sys import sys
import imp import imp
import re import re
import warnings
from zope.site.hooks import setSite from zope.site.hooks import setSite
from zope.globalrequest import getRequest from zope.globalrequest import getRequest
...@@ -297,6 +298,9 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, ** ...@@ -297,6 +298,9 @@ def runLiveTest(test_list, verbosity=1, stream=None, request_server_url=None, **
output.write("**Running Live Test:\n") output.write("**Running Live Test:\n")
ZopeTestCase._print = output.write ZopeTestCase._print = output.write
with warnings.catch_warnings():
warnings.simplefilter(kw['warnings'])
# Test may login/logout with different users, so ensure that at the end the # Test may login/logout with different users, so ensure that at the end the
# original SecurityManager is restored # original SecurityManager is restored
from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager from AccessControl.SecurityManagement import getSecurityManager, setSecurityManager
......
...@@ -11,6 +11,7 @@ import shutil ...@@ -11,6 +11,7 @@ import shutil
import errno import errno
import random import random
import transaction import transaction
import warnings
from glob import glob from glob import glob
...@@ -495,6 +496,13 @@ class DebugTestResult: ...@@ -495,6 +496,13 @@ class DebugTestResult:
_print = sys.stderr.write _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): def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
if "zeo_client" in os.environ and "zeo_server" in os.environ: if "zeo_client" in os.environ and "zeo_server" in os.environ:
_print("conflicting options: --zeo_client and --zeo_server\n") _print("conflicting options: --zeo_client and --zeo_server\n")
...@@ -898,6 +906,8 @@ def main(argument_list=None): ...@@ -898,6 +906,8 @@ def main(argument_list=None):
elif opt == "--with_wendelin_core": elif opt == "--with_wendelin_core":
os.environ["with_wendelin_core"] = "1" os.environ["with_wendelin_core"] = "1"
setupWarnings()
bt5_path_list += filter(None, bt5_path_list += filter(None,
os.environ.get("erp5_tests_bt5_path", "").split(',')) os.environ.get("erp5_tests_bt5_path", "").split(','))
valid_path_list = [] 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