Search code examples
python-3.xpython-importpython-unittest

How to suppress ImportWarning in a python unittest script


I am currently running a unittest script which successfully passes the various specified test with a nagging ImportWarning message in the console:

...../lib/python3.6/importlib/_bootstrap.py:219: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
  return f(*args, **kwds)
....
----------------------------------------------------------------------
Ran 7 tests in 1.950s

OK

The script is run with this main function:

if __name__ == '__main__':
    unittest.main()

I have read that warnings can be surpressed when the script is called like this:

python  -W ignore:ImportWarning -m unittest testscript.py

However, is there a way of specifying this ignore warning in the script itself so that I don't have to call -W ignore:ImportWarning every time that the testscript is run?

Thanks in advance.


Solution

  • To programmatically prevent such warnings from showing up, adjust your code so that:

    import warnings
    if __name__ == '__main__':
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', category=ImportWarning)
            unittest.main()
    

    Source: https://stackoverflow.com/a/40994600/328469

    Update:

    @billjoie is certainly correct. If the OP chooses to make answer 52463661 the accepted answer, I am OK with that. I can confirm that the following is effective at suppressing such warning messages at run-time using python versions 2.7.11, 3.4.3, 3.5.4, 3.6.5, and 3.7.1:

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import unittest
    import warnings
    
    
    class TestPandasImport(unittest.TestCase):
        def setUp(self):
            warnings.simplefilter('ignore', category=ImportWarning)
    
        def test_01(self):
            import pandas  # noqa: E402
            self.assertTrue(True)
    
        def test_02(self):
            import pandas  # noqa: E402
            self.assertFalse(False)
    
    
    if __name__ == '__main__':
        unittest.main()
    

    However, I think that the OP should consider doing some deeper investigation into the application code targets of the unit tests, and try to identify the specific package import or operation which is causing the actual warning, and then suppress the warning as closely as possible to the location in code where the violation takes place. This will obviate the suppression of warnings throughout the entirety of one's unit test class, which may be inadvertently obscuring warnings from other parts of the program.

    Outside the unit test, somewhere in the application code:

    with warnings.catch_warnings():
        warnings.simplefilter('ignore', category=ImportWarning)
        # import pandas
        # or_ideally_the_application_code_unit_that_imports_pandas()
    

    It could take a bit of work to isolate the specific spot in the code that is either causing the warning or leveraging third-party software which causes the warning, but the developer will obtain a clearer understanding of the reason for the warning, and this will only improve the overall maintainability of the program.