Django test FileField using test fixtures

前端 未结 5 1316
囚心锁ツ
囚心锁ツ 2020-12-25 11:52

I\'m trying to build tests for some models that have a FileField. The model looks like this:

class SolutionFile(models.Model):
    \'\'\'
    A file from a s         


        
相关标签:
5条回答
  • 2020-12-25 12:23

    Django provides a great way to write tests on FileFields without mucking about in the real filesystem - use a SimpleUploadedFile.

    from django.core.files.uploadedfile import SimpleUploadedFile
    
    my_model.file_field = SimpleUploadedFile('best_file_eva.txt', b'these are the contents of the txt file')
    

    It's one of django's magical features-that-don't-show-up-in-the-docs :). However it is referred to here.

    0 讨论(0)
  • 2020-12-25 12:23

    This is what I did for my test. After uploading the file it should end up in the photo property of my organization model object:

        import tempfile
        filename = tempfile.mkstemp()[1]
        f = open(filename, 'w')
        f.write('These are the file contents')
        f.close()
        f = open(filename, 'r')
        post_data = {'file': f}
        response = self.client.post("/org/%d/photo" % new_org_data["id"], post_data)
        f.close()
        self.assertEqual(response.status_code, 200)
    
        ## Check the file
        ## org is where the file should end up
        org = models.Organization.objects.get(pk=new_org_data["id"])
        self.assertEqual("These are the file contents", org.photo.file.read())
    
        ## Remove the file
        import os
        os.remove(org.photo.path)
    
    0 讨论(0)
  • 2020-12-25 12:26

    You can override the MEDIA_ROOT setting for your tests using the @override_settings() decorator as documented:

    from django.test import override_settings
    
    
    @override_settings(MEDIA_ROOT='/tmp/django_test')
    def test_post_solution_file(self):
      # your code here
    
    0 讨论(0)
  • 2020-12-25 12:28

    with pytest and pytest-django, I use this in conftest.py file:

    import tempfile
    import shutil
    from pytest_django.lazy_django import skip_if_no_django
    from pytest_django.fixtures import SettingsWrapper
    
    
    @pytest.fixture(scope='session')
    #@pytest.yield_fixture()
    def settings():
        """A Django settings object which restores changes after the testrun"""
        skip_if_no_django()
    
        wrapper = SettingsWrapper()
        yield wrapper
        wrapper.finalize()
    
    
    @pytest.fixture(autouse=True, scope='session')
    def media_root(settings):
        tmp_dir = tempfile.mkdtemp()
        settings.MEDIA_ROOT = tmp_dir
        yield settings.MEDIA_ROOT
        shutil.rmtree(tmp_dir)
    
    
    @pytest.fixture(scope='session')
    def django_db_setup(media_root, django_db_setup):
        print('inject_after')
    

    might be helpful:

    1. https://dev.funkwhale.audio/funkwhale/funkwhale/blob/de777764da0c0e9fe66d0bb76317679be964588b/api/tests/conftest.py
    2. https://framagit.org/ideascube/ideascube/blob/master/conftest.py
    3. https://stackoverflow.com/a/56177770/5305401
    0 讨论(0)
  • 2020-12-25 12:39

    I've written unit tests for an entire gallery app before, and what worked well for me was using the python tempfile and shutil modules to create copies of the test files in temporary directories and then delete them all afterwards.

    The following example is not working/complete, but should get you on the right path:

    import os, shutil, tempfile
    
    PATH_TEMP = tempfile.mkdtemp(dir=os.path.join(MY_PATH, 'temp'))
    
    def make_objects():
        filenames = os.listdir(TEST_FILES_DIR)
    
        if not os.access(PATH_TEMP, os.F_OK):
            os.makedirs(PATH_TEMP)
    
        for filename in filenames:
            name, extension = os.path.splitext(filename)
            new = os.path.join(PATH_TEMP, filename)
            shutil.copyfile(os.path.join(TEST_FILES_DIR, filename), new)
    
            #Do something with the files/FileField here
    
    def remove_objects():
        shutil.rmtree(PATH_TEMP)
    

    I run those methods in the setUp() and tearDown() methods of my unit tests and it works great! You've got a clean copy of your files to test your filefield that are reusable and predictable.

    0 讨论(0)
提交回复
热议问题