PyTest Fixtures & Fleshing Out Your Stack Class
By implementing the
push functionality of the
Stack class, you’ll meet PyTest fixtures, which are a great way to provide a fixed baseline upon which tests can reliably and repeatedly executed.
is I could do what I did in
test_constructor(), where I create this stack,
s = Stack(). But maybe I have a whole bunch of tests and I keep repeating the same code over and over and over again where I’m saying
s = Stack().
00:50 Instead, I can do what’s called a fixture, and so let me show you what fixtures are. They’re a little interesting, but very powerful. They’re really used for when you have some code that is repetitive, that you keep typing over and over again.
I’m going to call this function
stack()—lowercase, just like that. And it’s a function, so I’m going to say
def that, and put the parentheses on there, and I’ll say
pass—just for right now. Okay.
Now, above this function, to make this thing into a fixture, you have to decorate this function with
@pytest.fixture, like that. So this turns this from a regular function into what’s called a fixture.
stack has to be the same name as this
stack. And so what happens is if you put this
stack right here as a parameter, what will happen is when the test runs, it’ll actually call
def stack()—it’ll create a
Stack object, it’ll return it, and it’ll inject that
Stack object into this function.
02:43 And so then you don’t have to do it like what we did on line 11—you don’t have to do that. Once again, It’s not really necessary in this type of test, but you could imagine a test where you’re creating an object and it’s massive, and there’s a lot of arguments to it, and you don’t want to keep typing it over and over again, and so that sort of alleviates that problem. Okay.
So, I wrote my test and yeah, it should fail. So let’s go ahead and run this. I’m going to switch back to my terminal, run this code here, and it says
1 failed, 1 passed. The constructor one still passes, so that’s good news for us.
And so what we want to do is we want to create an attribute, or a method, called
.push(). So let’s do that. Okay. So, all I have to do is say
def push(self)—and as you can see right here, based on the signature of this function, it looks like you’re passing in some item. Now, I don’t know the datatype of this item. I’m passing in a
3, but it could be a dog, or a cat, or a Boolean, or a floating point number, or a string—so, the type doesn’t really matter.
So I’m not going to call this
num, because that’s not actually accurate. It is technically accurate in this one circumstance, but we want this
Stack data structure to be generally usable, and so instead of just typing in
num, how about we type in
item, so it’s just a generic item. Okay.
So, even though these people are using a stack and they’re using
.pop()—internally, we’re using a list. But we could be using a binary tree, or a linked list, or any other sort of exotic data structure.
The purpose of this is that they don’t necessarily know or even care what the internal data structure looks like—just as long as it works. Just as long as it has a
.push() and a
.pop(), that’s all that matters to them. Okay.
06:56 And that passes as well. Okay! So this looks pretty good. So far, we have our constructor, we have push functionality, we have this fixture that’s dynamically injecting this object during test time, so that that’s pretty nice. The last thing we need to do, of course, is implement pop functionality.
Become a Member to join the conversation.