Reputation: 5236
In unit test I create 3 objects (articles) at the beginning. After test complete I notice that there are 3 images in media_root
folder.
Question: How to delete that images which was created after test finished?
P.S. I tried to use next code but it delete media_root
folder.
def tearDown(self):
rmtree(settings.MEDIA_ROOT, ignore_errors=True)
NOTE: Problems in methods test_article_form_valid
and test_article_crud
.
tests.py:
class ArticleTestCase(TestCase):
def setUp(self):
self.image = open(os.path.join(BASE_DIR, 'static/images/tests/image.jpg'), "r")
def test_article_form_valid(self):
data = {
'head': 'TEXT',
}
files_data = {
'image': SimpleUploadedFile(
name=self.image.name,
content=self.image.read(),
content_type='image/jpeg'
)
}
form = ArticleForm(data=data, files=files_data)
self.assertTrue(form.is_valid()) <-- ERROR
def test_article_crud(self):
response = self.client.get(reverse("article:article_create"))
self.assertEquals(response.status_code, 200)
response = self.client.post(
reverse("article:article_create"),
data={
'head': 'TEST',
'image': self.image
},
follow=True,
format='multipart'
)
self.assertEqual(response.status_code, 200)
self.assertEqual(Article.objects.all().count(), 1) <-- ERROR
def test_article_view(self):
first_article = Article.objects.create(
pk=150,
head='First',
image=SimpleUploadedFile(
name=self.image.name,
content=self.image.read(),
content_type='image/jpeg'
)
)
second_article = Article.objects.create(
pk=160,
head='Second',
image=SimpleUploadedFile(
name=self.image.name,
content=self.image.read(),
content_type='image/jpeg'
)
)
third_article = Article.objects.create(
pk=170,
head='Third',
image=SimpleUploadedFile(
name=self.image.name,
content=self.image.read(),
content_type='image/jpeg'
)
)
[***]
ERROR:
FAIL: test_article_crud (article.tests.ArticleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nurzhan/CA/article/tests.py", line 55, in test_article_crud
self.assertEqual(Article.objects.all().count(), 1)
AssertionError: 0 != 1
======================================================================
FAIL: test_article_form_valid (article.tests.ArticleTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nurzhan/CA/article/tests.py", line 117, in test_article_form_valid
self.assertTrue(form.is_valid())
AssertionError: False is not true
Upvotes: 7
Views: 4493
Reputation: 76
I believe the best solution is to create a directory that will contain a '/media'
folder, this directory can then be deleted in the tearDown function.
Based on this article, I tried the solution and it worked perfectly. You won't even notice the creation and deletion of the test directory and the files created in your tests won't be in your default media location.
from django.test import override_settings
import shutil
TEST_DIR = 'test_data'
class SomeTests(TestCase):
...
# use the `override_settings` decorator on
# those methods where you're uploading images
@override_settings(MEDIA_ROOT=(TEST_DIR + '/media'))
def test_file_upload(self):
...
# your code
...
...
# then create a tearDownModule function
# to remove the `TEST_DIR` folder at the
# end of tests
def tearDownModule():
print "\nDeleting temporary files...\n"
try:
shutil.rmtree(TEST_DIR)
except OSError:
pass
If you want to implement this solution in DRF, your code should look like this:
from django.test import override_settings
import shutil
from rest_framework.test import APITestCase
TEST_DIR = 'test_data'
class SomeTest(APITestCase):
...
# use the `override_settings` decorator on
# those methods where you're uploading images
# do this if any logic exists to create files
# in your setUp
@override_settings(MEDIA_ROOT=(TEST_DIR + '/media'))
def setUp(self):
...
# your code
...
@override_settings(MEDIA_ROOT=(TEST_DIR + '/media'))
def test_file_upload(self):
...
# your code
...
def tearDown(self):
print "\nDeleting temporary files...\n"
try:
shutil.rmtree(TEST_DIR)
except OSError:
pass
Upvotes: 2
Reputation: 461
I found this article and it worked to me
import shutil, tempfile
from django.test import TestCase, override_settings
MEDIA_ROOT = tempfile.mkdtemp()
@override_settings(MEDIA_ROOT=MEDIA_ROOT)
class MeuPetTest(TestCase):
@classmethod
def tearDownClass(cls):
shutil.rmtree(MEDIA_ROOT, ignore_errors=True)
super().tearDownClass()
Upvotes: 10
Reputation: 1
For me best solution was to write a function which delete images and add it into test class tearDown method.
def delete_test_image():
images_path = os.path.join(PROJECT_PATH, 'media/images')
files = [i for i in os.listdir(images_path)
if os.path.isfile(os.path.join(images_path, i))
and i.startswith('test_image_')]
for file in files:
os.remove(os.path.join(images_path, file))
Upvotes: 0
Reputation: 9235
Use tempfile
module in python, use it as settings.MEDIA_ROOT
in the TestCase
setUp()
method,
from django.conf import settings
import tempfile
def setUp(self):
settings.MEDIA_ROOT = tempfile.mkdtemp()
Then, the files created in the test will be automatically removed when the test is finished.
UPDATE:
Then, the files created in the test will not be automatically removed when the test is finished, so do not forget to delete the temporary directory after finishing the test.
Upvotes: 0