pythonunit-testingtestingmockingpython-import

How to test or mock "if __name__ == '__main__'" contents


Say I have a module with the following:

def main():
    pass

if __name__ == "__main__":
    main()

I want to write a unit test for the bottom half (I'd like to achieve 100% coverage). I discovered the runpy builtin module that performs the import/__name__-setting mechanism, but I can't figure out how to mock or otherwise check that the main() function is called.

This is what I've tried so far:

import runpy
import mock

@mock.patch('foobar.main')
def test_main(self, main):
    runpy.run_module('foobar', run_name='__main__')
    main.assert_called_once_with()

Solution

  • I will choose another alternative which is to exclude the if __name__ == '__main__' from the coverage report , of course you can do that only if you already have a test case for your main() function in your tests.

    As for why I choose to exclude rather than writing a new test case for the whole script is because if as I stated you already have a test case for your main() function the fact that you add an other test case for the script (just for having a 100 % coverage) will be just a duplicated one.

    For how to exclude the if __name__ == '__main__' you can write a coverage configuration file and add in the section report:

    [report]
    
    exclude_lines =
        if __name__ == .__main__.:
    

    More info about the coverage configuration file can be found here.

    Hope this can help.