Getting started with pytest Transcripts
Chapter: pytest Fixtures
Lecture: Specifying fixture scope
0:00 With our fixture in place, taking a look at this and in the setup interference happening. And this for our little cards application,
0:10 the uh the setup of a temporary direct creating a new temporary directory and initializing the cards database. This database is pretty lightweight.
0:19 So this probably isn't going to take a lot of time. But there are other types of databases where this initialization could take quite a long time
0:27 And right now when we're running even just two tests, eventually I can see us using running a lot of tests,
0:36 but we're setting up and tearing down the entire database twice and it might not be
0:42 necessary. So this is where we can utilize test scope or fixture scope. So I'm gonna take a grab all of this code and stick it in a new
0:53 file called mod scope. So this is the same. So let's just make sure that pytests. mod scope.py, Cool. Still works.
1:05 Obviously we haven't changed anything but I'm going to do one change. So we've got we're using using cards dB here and here.
1:15 And this is just giving us an empty database. Right coming in. Empty empty database,
1:25 checking the count to zero and here we are taking an empty database, adding one item so that we can have one item awesome.
1:32 But why not just use the same database? Why do we have to tear it down between? So let's change the scope.
1:40 So in within this fixture decorator we can specify a scope I'd like to specify here module and we just give it a name so it can be the most common
1:52 ones by default, it's a function scope, which means that like we've seen before, it runs runs around each test function.
2:00 And if we do module, it should just run once per module. And this this whole this test file is a module. The other scopes available our class.
2:10 So for test class, you can run it for each test class or you can do package for each directory or session.
2:19 So once, once for the entire test run with multiple directories. But right now we'll use module and that's it.
2:26 That's just the one change. Let's see what that does. So making sure that both tests still pass.
2:32 They do, but let's do set up show and see what happens then. So now we've got a little m and it says it's running cards DB once and
2:45 then it's running the two tests and then it runs the tear down for for here So that's pretty awesome. This is just initializing the doing the set up
2:57 and tear down once for the entire module. And if so that again, if this takes a long time this this setup,
3:05 then we're saving this time when we're running a whole bunch of tests. Now we have a subtle bug here and it's just a bug in the test ordering
3:16 and I want to demonstrate with the module scope, fixtures or higher level fixtures. Sometimes this can happen. So we've got in our module scope.
3:28 our database is just getting created and torn down once for all the tests and it
3:33 happens to be that we're testing empty first and then we're testing one item but the
3:39 database is still sticking around after between tests so I want to demonstrate why this is
3:46 a problem. So grab all of this code and I'm gonna stick it in the fail file. And the the only change I'm gonna do is I'm gonna
3:59 take the empty and put it after. So now I'm gonna test, we're gonna run a pytest runs tests in order, let's go ahead and tighten this up.
4:11 Uh pytest tests them in order that they appear in the file by default. There's ways to change that but so it'll just one item and then it'll leave the
4:21 date. This one item is probably going to stay in the database and then when we check for an empty one it is not gonna be empty.
4:29 Let's see if that have failed as I expected to. So the mod scope fail. Yes, as expected, the second test,
4:42 first test passed the second test failed because the count was one so we've got some
4:49 corruption in the state of the system between between tests now some people might say,
4:55 well that's that's why you should just totally always only use function scope but I think there's a way around it so we gonna look at couple of fixes.