7
votes

Comment utiliser élégamment (patch) un paramètre Django FileSystSorage dans vos tests d'unité?

Je suis confronté au problème suivant. J'ai un modèle qui ressemble un peu à ce que ceci: xxx

essentiel dans cet exemple est l'argument stockage = au Filefield constructeur. Il est rempli d'une valeur de Params.py . Il y a le code suivant: xxx

pour une utilisation de la production, cela fonctionne bien. Mais dans mes tests unitaires, les téléchargements que je fais sont maintenant écrits sur / VAR / DATA , qui contient des données de production. J'ai essayé d'échanger le package_store dans packages / tests.py comme ceci xxx

mais le vrai problème est que avant le fichier de test est chargé, les packages et ses modèles ont déjà été chargés, et par conséquent, le paramètre package_storage a été résolu avant i 'M capable de le changer dans le code de configuration du test.

existe un moyen élégant de remplacer ce paramètre spécifique dans un contexte de test?


2 commentaires

Pour compléter: j'ai essayé une évaluation paresseuse sur l'emplacement et le stockage arguments , mais cela n'a pas aidé: FileSystSorage évalue immédiatement tout paresseux Emplacement = Argument en appelant .StartSwith () On IT et Filefield évalue immédiatement tout Stockage = En appelant .get_valid_name () dessus.


Qu'est-ce que paquet_storage ?


7 Réponses :


5
votes

Si vous exécutez le test via Django, cela devrait fonctionner xxx

bien sûr après;) xxx


2 commentaires

Bien que je pense que le test de la valeur argv est assez moche, il s'agit d'au moins une solution qui ne nécessite pas la discipline de mémoriser le fichier de paramètres alternatifs.


@Flimm je voulais dire par défaut_file_storage



10
votes

Je ne sais pas si cela compte aussi élégant, mais vous pouvez utiliser un fichier de paramètres différent pour tester ...

quelque chose comme: xxx

puis exécutez votre Testez à l'aide des paramètres de test, Python Manage.py Test --Settings = Test_Settings .


5 commentaires

Vous vous moquez de vous @meshantz!? Ceci est aussi élégant que possible. Pas le seul moyen, mais defo le plus élégant.


@kron merci. Je crains juste que l'utilisation de différents fichiers de paramètres puissent entraîner des abus et des effets secondaires malheureux à tester. Si vous ne faites pas attention à ce que vous mettez dans les dérogations.


Je ne savais pas à propos de --Settings Param pour le test Django, THC :)


J'aime le plus celui-ci. Cependant, cela nécessite toujours la discipline de toujours ajouter le - Paramètres = Test_Settings argument. Si vous oubliez de l'ajouter, les données de production peuvent facilement être essuyées ou modifiées.


et @vincent, j'ai toujours trois fichiers de paramètres, production.py , paramètres.py et test.py . paramètres.py contient les paramètres de développement, et si exécuté par défaut, spécifie les paramètres de la base de données n'existant pas dans l'environnement de production, ce qui entraîne l'échec de l'échec du test immédiatement, ce qui vous oblige à utiliser - Paramètres en production pour toute commande que vous exécutez. Faites prêter attention avec les stockages de test - Django créera toujours une base de données Test _ pour ne pas échanger avec les données de production dans la base de données, mais cela ne peut pas vous enregistrer de données modifiées physiquement dans vos stockages accidentellement.



3
votes

remplacer la mise en œuvre de stockage sous-jacente pour des instances de Filefield sur votre modèle de manière dynamique: xxx


0 commentaires

3
votes

Je viens de résoudre ceci en ajoutant à mon coureur de test personnalisé. Pour voir comment ajouter un coureur de test personnalisé, voir Définition d'un test de test dans la documentation de Django. Mon code ressemble à ceci:

import shutil
import tempfile
from django.test.simple import DjangoTestSuiteRunner
from django.conf import settings

class CustomTestRunner(DjangoTestSuiteRunner):

    def setup_test_environment(self, **kwargs):
        super(CustomTestRunner, self).setup_test_environment(**kwargs)
        self.backup = {}
        self.backup['DEFAULT_FILE_STORAGE'] = settings.DEFAULT_FILE_STORAGE
        settings.DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
        self.backup['MEDIA_ROOT'] = settings.MEDIA_ROOT
        self.temp_media_root = tempfile.mkdtemp(prefix="myapp-tests")
        settings.MEDIA_ROOT = self.temp_media_root

    def teardown_test_environment(self, **kwargs):
        super(CustomTestRunner, self).teardown_test_environment(**kwargs)
        for name, value in self.backup.iteritems():
            setattr(settings, name, value)

    def run_tests(self, test_labels, **kwargs):
        try:
            test_results = super(CustomTestRunner, self).run_tests(test_labels, **kwargs)
        finally:
            shutil.rmtree(self.temp_media_root, ignore_errors=True)


0 commentaires

0
votes

réponse tardive mais cela m'a pris beaucoup de temps pour trouver cette belle petite bibliothèque;

https://pypi.org/project/djangoverride-storage/


0 commentaires

0
votes

Pour prod que nous utilisons un S3 et Boto3, mais pour des tests d'unités, il suffit d'utiliser super lib DJ- Inmemorystorage qui charte simplement le fichier à la mémoire. Donc, je viens de remplacer le stockage de fichier par défaut dans mes paramètres de test: xxx pré>

puis dans le test: p>

record.receipt_file = SimpleUploadedFile('receipt.txt', b'')


0 commentaires

1
votes

Si vous utilisez Pytest-django et que vous souhaitez conserver un seul fichier de configuration Django, vous pouvez créer un conftest.py et avoir ce paramètre remplacé pour chaque test exécuté ( source ) xxx

Vous pouvez également modifier votre application avant que Django stings utilise Pytest-django . Voir ici .


0 commentaires