pythonpytest

How to set dynamic default parameters for py.test?


I have a framework which working under py.test. py.test can generate beauty reports with params --html and --junitxml. But clients that using my framework not always type this params to command line where they using py.test. I want make py.test to generate reports always when the py.test used with my framework. And i want to put this reports with log folder. So i need to generate path for report in runtime. Can i do this by fixtures? Or maybe by the plugin API?


Solution

  • Note

    The part of my answer with the custom plugin is way too overengineered; it is already sufficient to just reassign the xmlpath option as in this answer. Use that instead. The XML plugin reconfiguration is only needed if you want to make deeper changes in XML report assembly, which isn’t the case here.

    Original answer

    First of all, if you want to implicitly add the command line args to pytest, you can use the pytest.ini placed in the tests root dir with the addopts config value:

    [pytest]
    addopts=--verbose --junit-xml=/tmp/myreport.xml  # etc
    

    Of course, if you want to dynamically calculate the directory to store the reports, then you can't put it in the config and will need to extend pytest. The best spot would be the pytest_configure hook. Example:

    # conftest.py
    import tempfile
    import pytest
    from _pytest.junitxml import LogXML
    
    
    @pytest.hookimpl(tryfirst=True)
    def pytest_configure(config):
        if config.option.xmlpath:  # was passed via config or command line
            return  # let pytest handle it
        if not hasattr(config, 'slaveinput'):
            with tempfile.NamedTemporaryFile(suffix='.xml') as tmpfile:
                xmlpath = tmpfile.name
                config._xml = LogXML(xmlpath, config.option.junitprefix, config.getini('junit_suite_name'))
                config.pluginmanager.register(config._xml)
    

    If you remove the first if block, then pytest will completely ignore --junit-xml arg passed via command line or in addopts value in config.

    Example run:

    $ pytest
    =================================== test session starts ====================================
    platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0
    rootdir: /Users/hoefling/projects/private/stackoverflow/so-48320357, inifile:
    plugins: forked-0.2, asyncio-0.8.0, xdist-1.22.0, mock-1.6.3, hypothesis-3.44.4
    collected 1 item
    
    test_spam.py .                                                                        [100%]
    
    --- generated xml file: /var/folders/_y/2qk6029j4c7bwv0ddk3p96r00000gn/T/tmp1tleknm3.xml ---
    ================================ 1 passed in 0.01 seconds ==================================
    

    The xml report is now put in a tempfile.