Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing MEDIA_ROOT before each Django Test

I want to my Django tests to create and modify media files. So, much like Django tests do with databases, I want to set up an empty MEDIA_ROOT folder before each test is run.

I figured I'll create a temporary folder and point MEDIA_ROOT to it. However, I can't figure out where to put the code that does this. In this example, a special Runner is created. The runner sets up the media root and tears it down.

Unfortunately, setup_test_environment is called once before the first test function is run, and not every time a test is run.

I tried creating a FileSystemTestCase class that sets up the file system in its setUp function, and have all my test cases derive from it. While this works, it requires every person who writes a testcase to remember to call my setUp method, as it's not called automatically.

Usually I wouldn't bother with this, but the cost of forgetting to call the parent setUp method can be very high - if someone forgets the call and the tests are accidentally run on a live system, bad things will happen.

EDIT: The temporary solution I've found was to implement both my own runner and a base TestCase. Both set up a temporary MEDIA_ROOT, so if someone forgets to call my setUp method, the test will run in the temporary folder of the previous test, or the one set up by the runner. This can cause tests to fail, but will not ruin live data.

I'm hoping for a more elegant solution.

like image 906
zmbq Avatar asked Nov 01 '22 05:11

zmbq


1 Answers

It seems to me that you're trying to address two separate issues:

  1. Allow tests to run independently (with regard to MEDIA_ROOT) when testers do the right thing (i.e. inherit from your test class and call your setUp()).
  2. Keep testers from messing up real data when they accidentally do the wrong thing.

Given that, I think a two-pronged approach makes sense. Your setUp() solves problem 1. Setting up MEDIA_ROOT in the test runner, though, hides the fact that your testers have done the wrong thing. Instead I would just focus on protecting the data: for example, you could set MEDIA_ROOT to None. That would shield the real data in MEDIA_ROOT; make it more likely that the tester will see an error if they don't use your setUp(); and reduce code duplication.

A more robust approach would be to write your own test runner that does the setup before each test (modeled after the way Django handles the database), but that may be overkill for your needs.

like image 200
Kevin Christopher Henry Avatar answered Nov 15 '22 04:11

Kevin Christopher Henry