Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

py.test fixture from another file

I have the following file I want to test

manage.py

import socket
def __get_pod():
    try:
        pod = socket.gethostname().split("-")[-1].split(".")[0]
    except:
        pod = "Unknown"

    return pod

Here is my test script tests/test_manage.py

import sys
import pytest

sys.path.append('../')

from manage import __get_pod

#
# create a fixture for a softlayer IP stack
@pytest.fixture
def patch_socket(monkeypatch):

    class my_gethostname:
        @classmethod
        def gethostname(cls):
            return 'web01-east.domain.com'

    monkeypatch.setattr(socket, 'socket', my_gethostname)


def test__get_pod_single_dash():
    assert __get_pod() == 'east'

So when I try to test it hosts my laptop hostname when I want it to use the fixture.. is it possible to use a fixture in another file?

$ py.test -v
======================================================================= test session starts ========================================================================
platform darwin -- Python 2.7.8 -- py-1.4.26 -- pytest-2.6.4 -- /usr/local/opt/python/bin/python2.7
collected 1 items

test_manage.py::test__get_pod_single_dash FAILED

============================================================================= FAILURES =============================================================================
____________________________________________________________________ test__get_pod_single_dash _____________________________________________________________________

    def test__get_pod_single_dash():
>       assert __get_pod() == 'east'
E       assert '2' == 'east'
E         - 2
E         + east
like image 914
Mike Avatar asked Jan 11 '15 15:01

Mike


People also ask

Can a pytest fixture use another fixture?

fixtures have explicit names and are activated by declaring their use from test functions, modules, classes or whole projects. fixtures are implemented in a modular manner, as each fixture name triggers a fixture function which can itself use other fixtures.

Can you import pytest fixtures?

Fixtures and their visibility are a bit odd in pytest. They don't require importing, but if you defined them in a test_*. py file, they'll only be available in that file. You can however put them in a (project- or subfolder-wide) conftest.py to use them in multiple files.

Can you have multiple Conftest files?

You can have multiple nested directories/packages containing your tests, and each directory can have its own conftest.py with its own fixtures, adding on to the ones provided by the conftest.py files in parent directories.


1 Answers

The first thing you need to do it modify your test function so that it takes an argument named patch_socket:

def test__get_pod_single_dash(patch_socket):
    assert __get_pod() == 'east'

This means that py.test will call your fixture, and pass the result to your function. The important thing here is that is does get called.

The second thing it that your monkeypatch call will set a variable called socket.socket to my_gethostname, which then does not affect your function. Simplifying the patch_socket to:

import socket

@pytest.fixture
def patch_socket(monkeypatch):
    def gethostname():
        return 'web01-east.domain.com'

    monkeypatch.setattr(socket, 'gethostname', gethostname)

Then allows the test to pass.

like image 104
matsjoyce Avatar answered Oct 03 '22 17:10

matsjoyce