224 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
	
# -*- coding: utf8 -*-
 | 
						|
from __future__ import unicode_literals
 | 
						|
 | 
						|
import sys
 | 
						|
 | 
						|
import pytest
 | 
						|
 | 
						|
 | 
						|
WARNINGS_SUMMARY_HEADER = 'warnings summary'
 | 
						|
 | 
						|
 | 
						|
@pytest.fixture
 | 
						|
def pyfile_with_warnings(testdir, request):
 | 
						|
    """
 | 
						|
    Create a test file which calls a function in a module which generates warnings.
 | 
						|
    """
 | 
						|
    testdir.syspathinsert()
 | 
						|
    test_name = request.function.__name__
 | 
						|
    module_name = test_name.lstrip('test_') + '_module'
 | 
						|
    testdir.makepyfile(**{
 | 
						|
        module_name: '''
 | 
						|
            import warnings
 | 
						|
            def foo():
 | 
						|
                warnings.warn(UserWarning("user warning"))
 | 
						|
                warnings.warn(RuntimeWarning("runtime warning"))
 | 
						|
                return 1
 | 
						|
        ''',
 | 
						|
        test_name: '''
 | 
						|
            import {module_name}
 | 
						|
            def test_func():
 | 
						|
                assert {module_name}.foo() == 1
 | 
						|
        '''.format(module_name=module_name)
 | 
						|
    })
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.filterwarnings('always')
 | 
						|
def test_normal_flow(testdir, pyfile_with_warnings):
 | 
						|
    """
 | 
						|
    Check that the warnings section is displayed, containing test node ids followed by
 | 
						|
    all warnings generated by that test node.
 | 
						|
    """
 | 
						|
    result = testdir.runpytest()
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '*== %s ==*' % WARNINGS_SUMMARY_HEADER,
 | 
						|
 | 
						|
        '*test_normal_flow.py::test_func',
 | 
						|
 | 
						|
        '*normal_flow_module.py:3: UserWarning: user warning',
 | 
						|
        '*  warnings.warn(UserWarning("user warning"))',
 | 
						|
 | 
						|
        '*normal_flow_module.py:4: RuntimeWarning: runtime warning',
 | 
						|
        '*  warnings.warn(RuntimeWarning("runtime warning"))',
 | 
						|
        '* 1 passed, 2 warnings*',
 | 
						|
    ])
 | 
						|
    assert result.stdout.str().count('test_normal_flow.py::test_func') == 1
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.filterwarnings('always')
 | 
						|
def test_setup_teardown_warnings(testdir, pyfile_with_warnings):
 | 
						|
    testdir.makepyfile('''
 | 
						|
        import warnings
 | 
						|
        import pytest
 | 
						|
 | 
						|
        @pytest.fixture
 | 
						|
        def fix():
 | 
						|
            warnings.warn(UserWarning("warning during setup"))
 | 
						|
            yield
 | 
						|
            warnings.warn(UserWarning("warning during teardown"))
 | 
						|
 | 
						|
        def test_func(fix):
 | 
						|
            pass
 | 
						|
    ''')
 | 
						|
    result = testdir.runpytest()
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '*== %s ==*' % WARNINGS_SUMMARY_HEADER,
 | 
						|
 | 
						|
        '*test_setup_teardown_warnings.py:6: UserWarning: warning during setup',
 | 
						|
        '*warnings.warn(UserWarning("warning during setup"))',
 | 
						|
 | 
						|
        '*test_setup_teardown_warnings.py:8: UserWarning: warning during teardown',
 | 
						|
        '*warnings.warn(UserWarning("warning during teardown"))',
 | 
						|
        '* 1 passed, 2 warnings*',
 | 
						|
    ])
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize('method', ['cmdline', 'ini'])
 | 
						|
def test_as_errors(testdir, pyfile_with_warnings, method):
 | 
						|
    args = ('-W', 'error') if method == 'cmdline' else ()
 | 
						|
    if method == 'ini':
 | 
						|
        testdir.makeini('''
 | 
						|
            [pytest]
 | 
						|
            filterwarnings= error
 | 
						|
            ''')
 | 
						|
    result = testdir.runpytest(*args)
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        'E       UserWarning: user warning',
 | 
						|
        'as_errors_module.py:3: UserWarning',
 | 
						|
        '* 1 failed in *',
 | 
						|
    ])
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize('method', ['cmdline', 'ini'])
 | 
						|
def test_ignore(testdir, pyfile_with_warnings, method):
 | 
						|
    args = ('-W', 'ignore') if method == 'cmdline' else ()
 | 
						|
    if method == 'ini':
 | 
						|
        testdir.makeini('''
 | 
						|
        [pytest]
 | 
						|
        filterwarnings= ignore
 | 
						|
        ''')
 | 
						|
 | 
						|
    result = testdir.runpytest(*args)
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '* 1 passed in *',
 | 
						|
    ])
 | 
						|
    assert WARNINGS_SUMMARY_HEADER not in result.stdout.str()
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.skipif(sys.version_info < (3, 0),
 | 
						|
                    reason='warnings message is unicode is ok in python3')
 | 
						|
@pytest.mark.filterwarnings('always')
 | 
						|
def test_unicode(testdir, pyfile_with_warnings):
 | 
						|
    testdir.makepyfile('''
 | 
						|
        # -*- coding: utf8 -*-
 | 
						|
        import warnings
 | 
						|
        import pytest
 | 
						|
 | 
						|
 | 
						|
        @pytest.fixture
 | 
						|
        def fix():
 | 
						|
            warnings.warn(u"测试")
 | 
						|
            yield
 | 
						|
 | 
						|
        def test_func(fix):
 | 
						|
            pass
 | 
						|
    ''')
 | 
						|
    result = testdir.runpytest()
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '*== %s ==*' % WARNINGS_SUMMARY_HEADER,
 | 
						|
        '*test_unicode.py:8: UserWarning: \u6d4b\u8bd5*',
 | 
						|
        '* 1 passed, 1 warnings*',
 | 
						|
    ])
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.skipif(sys.version_info >= (3, 0),
 | 
						|
                    reason='warnings message is broken as it is not str instance')
 | 
						|
def test_py2_unicode(testdir, pyfile_with_warnings):
 | 
						|
    testdir.makepyfile('''
 | 
						|
        # -*- coding: utf8 -*-
 | 
						|
        import warnings
 | 
						|
        import pytest
 | 
						|
 | 
						|
 | 
						|
        @pytest.fixture
 | 
						|
        def fix():
 | 
						|
            warnings.warn(u"测试")
 | 
						|
            yield
 | 
						|
 | 
						|
        @pytest.mark.filterwarnings('always')
 | 
						|
        def test_func(fix):
 | 
						|
            pass
 | 
						|
    ''')
 | 
						|
    result = testdir.runpytest()
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '*== %s ==*' % WARNINGS_SUMMARY_HEADER,
 | 
						|
 | 
						|
        '*test_py2_unicode.py:8: UserWarning: \u6d4b\u8bd5',
 | 
						|
        '*warnings.warn(u"\u6d4b\u8bd5")',
 | 
						|
        '*warnings.py:*: UnicodeWarning: Warning is using unicode non*',
 | 
						|
        '* 1 passed, 2 warnings*',
 | 
						|
    ])
 | 
						|
 | 
						|
 | 
						|
def test_works_with_filterwarnings(testdir):
 | 
						|
    """Ensure our warnings capture does not mess with pre-installed filters (#2430)."""
 | 
						|
    testdir.makepyfile('''
 | 
						|
        import warnings
 | 
						|
 | 
						|
        class MyWarning(Warning):
 | 
						|
            pass
 | 
						|
 | 
						|
        warnings.filterwarnings("error", category=MyWarning)
 | 
						|
 | 
						|
        class TestWarnings(object):
 | 
						|
            def test_my_warning(self):
 | 
						|
                try:
 | 
						|
                    warnings.warn(MyWarning("warn!"))
 | 
						|
                    assert False
 | 
						|
                except MyWarning:
 | 
						|
                    assert True
 | 
						|
    ''')
 | 
						|
    result = testdir.runpytest()
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        '*== 1 passed in *',
 | 
						|
    ])
 | 
						|
 | 
						|
 | 
						|
@pytest.mark.parametrize('default_config', ['ini', 'cmdline'])
 | 
						|
def test_filterwarnings_mark(testdir, default_config):
 | 
						|
    """
 | 
						|
    Test ``filterwarnings`` mark works and takes precedence over command line and ini options.
 | 
						|
    """
 | 
						|
    if default_config == 'ini':
 | 
						|
        testdir.makeini("""
 | 
						|
            [pytest]
 | 
						|
            filterwarnings = always
 | 
						|
        """)
 | 
						|
    testdir.makepyfile("""
 | 
						|
        import warnings
 | 
						|
        import pytest
 | 
						|
 | 
						|
        @pytest.mark.filterwarnings('ignore::RuntimeWarning')
 | 
						|
        def test_ignore_runtime_warning():
 | 
						|
            warnings.warn(RuntimeWarning())
 | 
						|
 | 
						|
        @pytest.mark.filterwarnings('error')
 | 
						|
        def test_warning_error():
 | 
						|
            warnings.warn(RuntimeWarning())
 | 
						|
 | 
						|
        def test_show_warning():
 | 
						|
            warnings.warn(RuntimeWarning())
 | 
						|
    """)
 | 
						|
    result = testdir.runpytest('-W always' if default_config == 'cmdline' else '')
 | 
						|
    result.stdout.fnmatch_lines(['*= 1 failed, 2 passed, 1 warnings in *'])
 |