00:15 There are situations where you might want to have some data that you use over and over. You could of course write the same data into each test function, but that’d be repetitive and error prone.
The standard library’s
unittest way of doing things would be to use a
.setUp() function. pytest uses fixtures instead. You declare a fixture using a decorated function then pass that fixture function into your test function as an argument.
Let’s go see an example. To contrast, I’m starting with an example without a fixture. Consider testing the standard library functions for
max(). In both cases, I want to pass in a list of numbers, but of course the result is going to be different.
01:33 This example, of course, is a little contrived, but if you’ve got a lot of data that needs to be reused, this can be a handy feature. Honestly, I both like and dislike this feature of pytest. Fixtures are a great idea and can help you reduce the chance of making a mistake, but the use of named arguments magically mapping to a fixture somewhere else feels less than Pythonic. The names of arguments to functions shouldn’t be reliant on a declaration somewhere else.
02:01 It can get even worse, as there are ways of putting your fixtures in a different file for organization purposes, which means you have to go hunting for those magic words. But like it or not, this is how the pytest folks have decided to do it.
Out of the box, pytest comes with some fixtures you can use. This is actually where it gets kind of crazy. As a fixture is just an object returned by a function, It can be way more than “data.” First example of that: the
02:33 It’s a generic object that provides a place you can put some state that gets passed between all the tests that use the same fixture. For the most part, tests are meant to be independent of each other, but once in a while you need this. Don’t overuse it, though.
If you’re not careful, the order of your test execution might become important, and it shouldn’t be. The
capsys fixture indicates that
STDOUT (standard out) and
STDERR (standard error) will be captured for you, and you can get at their contents through the fixture. That could be useful if your code does things like print. The next two do the same thing, but two different ways.
tempdir creates a temporary directory for you, unique to each test function and gives you an
os.path object to access it. This is helpful if you need to generate an output file as part of your test and then have it get cleaned up afterwards.
tmp_path is the same thing, but uses the more recent
pathlib library instead of
03:57 You can put all your fixtures in here so that they can be reused across different test files. One common use for this is writing monkey patches. Monkey patches are dynamic code over-writing existing code.
You may want
datetime.now() to return a known value for your tests. Otherwise it can make testing difficult. Hey hey, we’re the Monkees. Wow, that’s going to be like one person who’s old enough to get that reference.
Remember a monkey patch is just a fixture, so it’s declared the same way as other fixtures using a decorator. Adding the
autouse=True argument to the decorator gets this fixture used everywhere, not just in those test functions that explicitly use it as an argument.
There are two key parts to this. The first is at the bottom, on line 12: using the
monkeypatch argument to do the actual patching. In this case, I’ve patched the
You could use the same argument list as the function you’re replacing—in this case, the
requests.get() method—but if you’re not interested in those arguments, like in this case,
**kwargs allows anything to be passed in, and then in this case, just ignore them. The body of the patch on line 10 raises an exception saying you’re not supposed to use this function.
A more realistic case would be to mock out some data to use instead. And that’s pretty much it. Because this is
autouse=True and declared in
conftest.py, you don’t have to do anything else for this to impact all your tests in the same directory or subdirectory. pytest takes care of it all for you and with less code than your average mock that does the same thing.
06:45 This could be a good place to start if you’re trying to change the mark for certain tests so they’re no longer in your smoke test or to figure out how to speed up some of those laggards. All right, that’s fixtures, monkey patches, and a very dated musical reference.
Become a Member to join the conversation.