How to get coverage data from a django app when running in gunicorn

前端 未结 1 814
没有蜡笔的小新
没有蜡笔的小新 2020-12-09 04:51

How do I get code coverage out of a Django project\'s view code (and code called by view code)?

coverage gunicorn does not show any lines

相关标签:
1条回答
  • 2020-12-09 05:24

    coverage gunicorn <params> does not work, because gunicorn creates worker processes, and the coverage module can't work across forks (basically, creation of new processes). You can use the coverage API, though, for example in the python module that contains your WSGI application:

    # wsgi_with_coverage.py
    import atexit
    import sys
    import coverage
    cov = coverage.coverage()
    cov.start()
    
    from wsgi import application  # adjust to python module containing your wsgi application
    
    
    def save_coverage():
        print >> sys.stderr, "saving coverage"
        cov.stop()
        cov.save()
    
    atexit.register(save_coverage)
    

    Then run gunicorn -w 1 wsgi_with_coverage:application <other params>.

    The problem is, the atexit functions are not called if you kill the gunicorn process, for example via CTRL+C. But they are called on SIGHUP, so if you do kill -HUP $(cat <gunicorn_pidfile_here>), the coverage data should be saved (by default to ".coverage" in the current directory).

    A possible caveat is that this won't work with more than one gunicorn worker, because they would all overwrite the ".coverage" file. If you absolutely need more than one worker, you could write to ".coverage-%d" % os.getpid() (set the file name via the data_file parameter to the coverage constructor) and use the combine() method to merge the individual measurements.

    This should work on other WSGI servers, too, depending on whether they allow their worker processes to clean up via the atexit method.

    0 讨论(0)
提交回复
热议问题