Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Preparing With Fixtures

00:00 In the previous lesson, I showed you how to prevent premature baldness with subtests. In this lesson, I’ll show you how to do additional prep steps before your tests get run.

00:10 When dealing with more complicated tests, you might have some objects you want to reuse. For example, you might create a list that gets used in each of your methods.

00:19 And instead of creating it at the top of each test method, you could create it once. There are special methods in the TestCase class for helping with this. Code that helps prepare a test class for execution is known as a fixture.

00:33 Note that this term gets used very loosely, and in some contexts, people will use the word fixture to mean the data associated with a class. It’s the same idea, though, because you’re prepping the test with the data ahead of time.

00:46 The TestCase class has four methods of controlling data in your tests. The setUp() method gets called before each test method is invoked. The setUpClass() method is a class method that gets called when the class is instantiated.

01:00 The tearDown() method gets called after each test method completes, while the tearDownClass() method gets called when the test class is done.

01:09 The class methods tend to get used when you’re interacting with a resource, like a database, and need a single connection. tearDownClass() could be used, for example, to clean that up.

01:19 Whereas the setUp() and tearDown() methods tend to be used to create instance data to be used within a test method. Now to some code so you can see the difference. Once more, I’m using a standalone test file to demonstrate the concepts.

01:34 In the real world, there would be external code associated with this. As I mentioned, setUpClass() is a class method. It gets invoked when the test case gets built.

01:43 Inside of this one, I’m printing a message and setting up some common data. This is kind of cheating. In the real world, you’d likely only use this if you were connecting to a database or maybe the network.

01:55 Lists typically get put in the regular setUp() method instead. The important part is the print() method so that you can see when it gets invoked.

02:03 This is the corresponding tearDownClass() method. It’s also a class method, and this time I’ve only bothered with the print. The setUp() method gets called before each test.

02:15 Inside here, I’m printing out the contents of the common_data list that got created in setUpClass(), and then showing whether or not specific_data exists yet. It won’t, because I don’t create it until the line after.

02:28 This may seem weird, but there’s a method behind my madness. You see, Python actually creates a new instance object before calling each test method. This sounds like overkill, but it ensures that the state of your system is consistent no matter what order your tests execute in.

02:46 This also allows more complex systems to run tests in parallel. Because of this, the second test to run is really the first method call on a new instance, so specific_data won’t exist on that object until it gets created inside of this setUp() call.

03:03 This is the corresponding tearDown(). Again, I’m just printing that it happened. You may recall that I’ve said you can have non-test methods in your class.

03:12 The setUp() and tearDown() methods aren’t run as tests because their names don’t begin with test, and you can take advantage of this yourself and create utility methods as well.

03:22 Here, I’ve created my own assertion method that asserts True, just to show that it can be an assert, and then prints some info out. Although this is a dummy example, I do write my own assertion methods all the time. If I have very complex data structures that I have to run multiple assertions on, I typically create my own assertion method that does all of it. And again, since this is all Python, you can even create your own extension of the TestCase with utility methods which you can inherit from instead.

03:50 In fact, if you use frameworks like Django or test tools like Selenium, they do exactly that, giving you custom TestCase classes with their own methods that help when you test with those tools.

04:02 Down here at the bottom, I have three tests. Each calls my assertAndDisplay() method, passing in a string. This isn’t particularly real world, but when I run the test, you’ll see the interleave of the print statements from assertAndDisplay() along with those from the setUp() and tearDown() calls.

04:20 Back to my terminal to run the test.

04:27 Remember, the output from the test framework and my own print statements get interleaved, so this gets a little messy. The first message is the print from our setUpClass(). Note, it only got called once, even though three tests were run.

04:42 This is the setUp() invoked before the first test. It shows the values of common_data created in setUpClass(), as well as the result of the hasattr() call, showing that specific_data hasn’t been created yet.

04:56 This is the print statement within assertAndDisplay() from the first test. It prints the string I gave it, 1, common_data, and, of course, the specific_data list created in setUp(). This is the tearDown() message from the first test. Now, on to the second test.

05:16 This is the setUp() call for it. Note that hasattr() on specific_data is showing False, because this is a new object instance, and so this is the first time setUp() has been called on this instance, even though this is the second test run.

05:30 This little dot is the intermix of the output from the testing framework with my print statements. The dot is the indicator that the first test passed. Note that it comes after the first test’s tearDown() method.

05:43 This is all three steps in the second test, the setUp(), the test itself, calling assertAndDisplay(), and then the tearDown().

05:51 Then, the dot, and the results from the third test. Finally, the dot from the third test, and the print() call in tearDownClass().

06:01 I can count on one hand the number of times I’ve used all of these features together. I definitely use setUp() frequently to prepare common data, especially when testing in Django.

06:10 I often need a dummy user account that has to be logged in if the tests require a user in that state. Sometimes I’ll use setUpClass() on occasion with resource management, and the corresponding tearDownClass() to close the resource cleanly, but this isn’t very common.

06:28 The last lesson is next. In it, I’ll summarize the course and point you at some places where you can learn more about writing automated tests.

Become a Member to join the conversation.