221: How to get pytest to import your code under test

Brian:

In this episode and the next, I'm gonna talk about imports a bit. In this episode, we're talking about importing our code under test. In the next episode, we're gonna talk about importing the API of a project from within the project. This is partly for testing purposes and partly for example purposes, but we'll get into that in the next episode. In this episode, setting up everything right so that our tests can import our code under test.

Brian:

Now let's get to it. So we've got some code we wanna test and some tests. The tests need to be able to import the code under test or at least the API of the code under test in order to test it. Let's be more specific. Let's say our code under test is either a single Python file or module with functions in it that need testing or a directory full of Python files and modules with a dunder init.py file.

Brian:

This is sometimes called a directory package or just a package, but it's a little confusing because we also have PIP installable packages. That's something else we could be testing. And if we're installing an installable package, I'm gonna assume that it's a package that's local to our machine. It's not something that's up on PyPI. So that's our code we wanna test.

Brian:

It's either a single file mo single file module or a directory package or installable package. Now our test code. Let's assume our test code and our source code are in different directories. So for the sake of, this discussion, we've got a top level project directory, and then we've got a source subdirectory, usually spelled s r c in my case, and a test directory. And what's one of our test files look like?

Brian:

In our test files, it's just gonna be test underscore something dot py, and inside of it, it'll have something like import project or import project name or import project dot module or from project dot module import func name. You get it. Somehow, I've got the thing that I'm testing or the part of the project I'm testing within this file. I've got to import that function or the module or something so that I can access it from the test code. But the test code is in a different directory from the source code.

Brian:

So how does that import work? Well, really, we have to do 1 of 2 things. We either have to take the code under test and install it using pip, or we need to tell pytest where to find the code under test. So, again, our code under test is either a single file or a package, directory package, or an installable package. If it's an installable package, that's the, using PIP to install our code under test.

Brian:

So we just say PIP install dot local dir name, and that will install into our virtual environment. Hopefully, we're using virtual environments. So what are the other cases? The other cases are the tricky part. So if it's a single file module or a directory package or even just a directory of stuff.

Brian:

That's the hard part, and that's probably why you're listening to this episode. However, let's not dismiss the packaging thing right away. Packaging has gotten so much easier in the last few years that even if you don't intend to distribute your project via a package index like PIP or a local repository or your work repository, let's take taking the extra few steps to create an installable package from your directory package might be pretty easy, and it's something you might wanna look into. But that's let's say you didn't. Let's say you just wanna have this directory, and and normally, you're gonna access it.

Brian:

You know how you're accessing it, but the tests don't see it out that way. So we need to we need to tell pytest where to find this code. Luckily, there's a setting specifically for this. It's called Python path, and I'll put a link in the show notes to the documentation around this. And the gist of this is in your settings file, like, say, your Pytest any or your tox any or pyproject.toml, let's say you for the sake of this argument, let's say your Pytest any file.

Brian:

That's gonna be in your top level directory. So your top project directory, the one at the same level as your source and your tests. In that file, you're gonna have a line that says Python path equal SRC or source or source slash subder or however I get to my code relative to that top level. That's the setting that you wanna put in Python path. And that's really all we have to do to tell pytest where to find that import and make that import work.

Brian:

What's cool about this is even when we're testing not from if you test from that directory, if you're in pytest from the top level, pytest will look in the test directory. Actually, look in all directories to find all the tests. At your top level, you it'll find the test, and it'll find the code under test because of our Python path setting. Even if we're if we've CDed into, or changed directories into one of the subdirectory of the test directory, like, maybe even, like, several layers deep, Pytest will still find that Pytest any file. It'll find that Python path setting and set that relative to that top level thing, and it'll still find the source code.

Brian:

So that's really all you need to do to get your test code to find your source code. Another thing you can do with the Python path setting is you can set up a path to your helper functions. So let's say your tests have some some help utility help test helper functions that you've defined. You could stick those in, say, tests slash helper or really lib or really anything and reference that from your Python path setting, and that can, now you can use test helper functions. So what are we gonna talk about in the next episode?

Brian:

In the next episode, we're going to look at specifically different parts of your project and how to import those different parts of your project into other parts of your project. Specifically, I'm gonna address a question where I have taken a a possibly nonstandard way for some of my for the command line interface to access the API for a project.

Creators and Guests

Brian Okken
Host
Brian Okken
Software Engineer, also on Python Bytes and Python People podcasts
221: How to get pytest to import your code under test
Broadcast by