Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get PyTest fixtures to autocomplete in PyCharm (type hinting)

Tags:

pytest

I had a bear of a time figuring this out, and it was really bugging me, so I thought I'd post this here in case anyone hit the same problem...

(and the answer is so dang simple it hurts :-)

The Problem

The core of the issue is that sometimes, not always, when dealing with fixtures in PyTest that return objects, when you use those fixtures in a test in PyCharm, you don't get autocomplete hints. If you have objects with large numbers of methods you want to reference while writing a test, this can add a lot of overhead and inconvenience to the test writing process.

Here's a simple example to illustrate the issue:

Let's say I've got a class "event_manager" that lives in:

location.game.events

Let's further say that in my conftest.py file (PyTest standard thing for the unfamiliar), I've got a fixture that returns an instance of that class:

from location.game.events import event_manager

...

@pytest.fixture(scope="module")
def event_mgr():
    """Creates a new instance of event generate for use in tests"""
    return event_manager()

I've had issues sometimes, (but not always - I can't quite figure out why) with classes like this where autocomplete will not work properly in the test code where I use the fixture, e.g.

def test_tc10657(self, evt_mgr):
    """Generates a Regmod and expects filemod to be searchable on server"""
    evt_mgr.(This does not offer autocomplete hints when you type ".")

So the answer is actually quite simple, once you review type hinting in PyCharm: http://www.jetbrains.com/help/pycharm/2016.1/type-hinting-in-pycharm.html

Here's how to fix the above test code so that autocomplete works properly:

from location.game.events import event_manager 

...

def test_tc10657(self, evt_mgr: event_manager):
    """Generates a Regmod and expects filemod to be searchable on server"""
    evt_mgr.(This DOES offer hints when you type "." Yay!)

Notice how I explicitly type the fixture as an input parameter of type event_manager.

like image 950
schmitty Avatar asked Oct 07 '16 01:10

schmitty


1 Answers

Also if you add a docstring to a function and specify the type of the the parameters, you will get the code completion for those parameters.

For example using pytest and Selenium:

# The remote webdriver seems to be the base class for the other webdrivers
from selenium.webdriver.remote.webdriver import WebDriver

def test_url(url, browser_driver):
    """
    This method is used to see if IBM is in the URL title
    :param  WebDriver browser_driver: The browser's driver
    :param str url: the URL to test
    """
    browser_driver.get(url)
    assert "IBM" in browser_driver.title

Here's my conftest.py file as well

import pytest
from selenium import webdriver

# Method to handle the command line arguments for pytest
def pytest_addoption(parser):
    parser.addoption("--driver", action="store", default="chrome", help="Type in browser type")
    parser.addoption("--url", action="store", default='https://www.ibm.com', help="url")


@pytest.fixture(scope='module', autouse=True)
def browser_driver(request):
    browser = request.config.getoption("--driver").lower()
    # yield the driver to the specified browser
    if browser == "chrome":
        driver = webdriver.Chrome(executable_path='/path/to/chromedriver')
    else:
        raise Exception("No driver for browser " + browser)
    yield driver
    driver.quit()


@pytest.fixture(scope="module")
def url(request):
    return request.config.getoption("--url")

Tested using Python 2.7 and PyCharm 2017.1. The docstring format is reStructuredText and the "Analyze Python code in docstrings" checkbox is checked in settings.

like image 159
ChristianOB Avatar answered Jan 18 '23 14:01

ChristianOB