জঙ্গোতে কীভাবে পরীক্ষার ফাইল আপলোড করতে হয়


102

আমার জাঙ্গো অ্যাপে আমার একটি ভিউ রয়েছে যা ফাইল আপলোড সম্পন্ন করে core মূল স্নিপেটটি এরকম

...
if  (request.method == 'POST'):
    if request.FILES.has_key('file'):
        file = request.FILES['file']
        with open(settings.destfolder+'/%s' % file.name, 'wb+') as dest:
            for chunk in file.chunks():
                dest.write(chunk)

আমি ইউনিট পরীক্ষা লুকাচ্ছে view.I টা পরিকল্পনা পছন্দ পাশাপাশি খুশি পথ পরীক্ষা করার জন্য যেমন path..ie, কেস যেখানে ব্যর্থ হবে request.FILESকোন কী 'ফাইল' আছে, যদি যেখানে request.FILES['file']রয়েছে None..

আমি কীভাবে সুখী পথের জন্য পোস্ট ডেটা সেট আপ করব? কেউ আমাকে বলতে পারেন?


যেমন আপনি ক্লায়েন্ট ক্লাসটি সঠিক হিসাবে উত্তরটি চিহ্নিত করেছেন, আপনি সম্ভবত কোনও ইউনিট পরীক্ষা খুঁজছেন না, তবে একটি কার্যকরী পরীক্ষা ...
হেনিং

উত্তর:


113

জাজানো ডক্স থেকে এখানে Client.post:

ফাইল জমা দেওয়া একটি বিশেষ ক্ষেত্রে। কোনও ফাইল পোস্ট করার জন্য আপনার কেবলমাত্র ফাইলের ক্ষেত্রের নাম কী হিসাবে এবং সেই মান হিসাবে আপলোড করতে চান এমন ফাইলের একটি ফাইল হ্যান্ডেল সরবরাহ করতে হবে। উদাহরণ স্বরূপ:

c = Client()
with open('wishlist.doc') as fp:
  c.post('/customers/wishes/', {'name': 'fred', 'attachment': fp})

12
সম্পর্কিত জ্যাঙ্গো ডকের
জেন

5
মৃত লিঙ্ক দেখুন docs.djangoproject.com/en/1.7/topics/testing/tools/...
Jocelyn delalande

4
হেনিং প্রযুক্তিগতভাবে সঠিক - এটি আরও বেশি কিছু হবে integration test- যতক্ষণ না আপনি আরও জটিল কোড বেসগুলিতে প্রবেশ না করেন যতক্ষণ না কোনও আসল পরীক্ষার দলও হতে পারে
অ্যালভিন

ওয়েব ফ্রেমওয়ার্কে, আপনি যদি দেখছেন যাচাই করা হয় তবে এটি অনেক কম পার্থক্য করে। ফাংশন থেকে সরাসরি ক্লায়েন্টের মাধ্যমে প্রতিক্রিয়া পাওয়া বেশিরভাগ পরীক্ষার বৈধ হওয়ার পক্ষে যথেষ্ট is প্লাস ক্লায়েন্ট আপনাকে আরও নমনীয়তা দেয়। আমি ব্যক্তিগতভাবে এটি ব্যবহার করি।
trpt4him

4
প্রাসঙ্গিক জ্যাঙ্গো ডক লিঙ্ক আপডেট: docs.djangoproject.com/en/dev/topics/testing/tools/...
ফ্রিজ হইয়া গেল

118

আমি একই কাজ with open('some_file.txt') as fp:করতাম তবে তারপরে আমার রেপোতে চিত্র, ভিডিও এবং অন্যান্য আসল ফাইলগুলির প্রয়োজন ছিল এবং আমি জ্যাঙ্গো কোর উপাদানটির একটি অংশও যাচাই করেছিলাম যা ভালভাবে পরীক্ষা করা হয়েছিল, সুতরাং বর্তমানে আমি যা করছি তা হচ্ছে:

from django.core.files.uploadedfile import SimpleUploadedFile

def test_upload_video(self):
    video = SimpleUploadedFile("file.mp4", "file_content", content_type="video/mp4")
    self.client.post(reverse('app:some_view'), {'video': video})
    # some important assertions ...

ইন পাইথন 3.5+ আপনি ব্যবহার করতে হবে bytesপরিবর্তে বস্তুর str। পরিবর্তন "file_content"করুনb"file_content"

এটি দুর্দান্ত কাজ করছে, SimpleUploadedFileএমন একটি তৈরি করে InMemoryFileযা নিয়মিত আপলোডের মতো আচরণ করে এবং আপনি নাম, সামগ্রী এবং বিষয়বস্তুর ধরণ বেছে নিতে পারেন।


4
আপনার উদাহরণ ব্যবহার করে, ফর্ম বৈধতা আমাকে দেয়: "একটি বৈধ চিত্র আপলোড করুন you আপনি যে ফাইলটি আপলোড করেছেন তা হয় চিত্র বা দূষিত চিত্র নয়" "
অ্যান্টোনেস্টাম

@antonagestam আপনি কি সঠিক সামগ্রীর ধরণটি পার করছেন? আপনার ফর্মটি ফাইলের বিষয়বস্তু যাচাই করছে? যদি "file_content"এটির জন্য একটি বৈধ চিত্রের শিরোনাম হওয়া দরকার তাই আপনার কোড মনে করে এটি একটি বৈধ চিত্র।
ড্যানিলো ক্যাবেলো

জেপিইজি এবং পিএনজি-র জন্য উপযুক্ত শিরোনাম কী কী?
অ্যান্টোনেস্টাম

4
এটি এই সমস্যার সঠিক উত্তর হিসাবে বিবেচনা করা উচিত। ধন্যবাদ @ ড্যানিলোকাবেলো
mannysz

4
আপনি বেস 64.b64decode ("iVBORw0KGgoAAAAUUSAUAGAAAAUA" + "এএএএফসিএএএএএনসিবিবিএএএএএএলএইকিএইচকিউআইআইপিএআইপি / 8 / w38GIAXDIBKE0DHxgljNBAAO" + এজেজি 2 ইজ এজিজেইএইচ 4 এজিজেইএইচ 4 এজিজেইএইচএইচজিএইচআইজিএইচ 4 এজিজেইএইচএইচজিএইচআইজিএইচ 4 এজিজেইএইচএজিএইচএইচএইচজিএইউ 4 এজেজিএইচএক্সইউ 4
হাওডেডো

6

আমি আপনাকে জাজানো রিকোয়েস্টফ্যাক্টরিতে একবার দেখার পরামর্শ দিই । অনুরোধে সরবরাহ করা ডেটা উপহাস করার সর্বোত্তম উপায়।

বলেছিল যে, আমি আপনার কোডে বেশ কয়েকটি ত্রুটি পেয়েছি।

  • "ইউনিট" পরীক্ষার অর্থ কার্যকারিতার মাত্র একটি "ইউনিট" পরীক্ষা করা । সুতরাং, আপনি যদি সেই ভিউটি পরীক্ষা করতে চান তবে আপনি ভিউটি পরীক্ষা করছেন এবং ফাইল সিস্টেমটি, বাস্তবে ইউনিট পরীক্ষা নয় not এই বিষয়টিকে আরও স্পষ্ট করার জন্য। যদি আপনি এই পরীক্ষাটি চালান, এবং দৃশ্যটি ভাল কাজ করে তবে আপনার কাছে সেই ফাইলটি সংরক্ষণের অনুমতি নেই, সেই কারণে আপনার পরীক্ষাটি ব্যর্থ হবে।
  • অন্যান্য গুরুত্বপূর্ণ বিষয় হল পরীক্ষার গতি । আপনি যদি টিডিডির মতো কিছু করে থাকেন তবে আপনার পরীক্ষাগুলি কার্যকর করার গতিটি সত্যই গুরুত্বপূর্ণ। যে কোনও আই / ও অ্যাক্সেস করা ভাল ধারণা নয়

সুতরাং, আমি আপনাকে এইরকম কোনও ফাংশন ব্যবহার করতে আপনার দৃষ্টিভঙ্গিটি রিফ্যাক্ট করার পরামর্শ দিচ্ছি :

def upload_file_to_location(request, location=None): # Can use the default configured

এবং এটি নিয়ে কিছু উপহাস করুন। আপনি পাইথন মোক ব্যবহার করতে পারেন ।

পিএস: আপনি জ্যাঙ্গো টেস্ট ক্লায়েন্টটিও ব্যবহার করতে পারেন তবে এর অর্থ হ'ল আপনি পরীক্ষা করার জন্য আরও একটি জিনিস যুক্ত করছেন, কারণ সেই ক্লায়েন্টটি সেশনস, মিডলওয়্যারগুলি ইত্যাদি ব্যবহার করে ইউনিট পরীক্ষার মতো কিছুই নয় othing


4
আমি ভুল হতে পারি, তবে মনে হচ্ছে তিনি ইন্টিগ্রেশন টেস্ট বোঝাতে চেয়েছিলেন এবং 'ইউনিট টেস্ট' শব্দটি ভুলভাবে ব্যবহার করেছেন।
জুক করুন

4
@ সানটিয়াগোবাসুল্টো আমি টিডিডিতে একজন নবাগত এবং আমি আমার ইউনিট পরীক্ষার গতি বাড়িয়ে দিতে চাই। তবে ইউনিট পরীক্ষার সময়ও ফাইল আপলোডগুলির সাথে আমার বিভিন্ন মতামত রয়েছে যা দূরবর্তী স্টোরেজ (অ্যামাজন এস 3) এ ফাইল আপলোড করে। একটি যে সময় লাগে। আপনি দয়া করে পরীক্ষার সময় I / O অ্যাক্সেস এড়ানো কীভাবে বিশদটি দেখানোর জন্য আপনার উত্তরটি প্রসারিত করতে পারেন?
দিমিত্রি ওয়াজিয়াচোভস্কি

6
আরে @ দিমিত্রি মোক সেখানে যাওয়ার উপায়। যখনই আপনাকে কোনও বাহ্যিক সংস্থান অ্যাক্সেস করতে হবে আপনার এটিকে উপহাস করা উচিত। মনে করুন আপনার কাছে এমন একটি মতামত আছে profile_pictureযা অভ্যন্তরীণভাবে কোনও upload_profile_pictureফাংশন ব্যবহার করে। আপনি যদি এই দর্শনটি পরীক্ষা করতে চান তবে কেবল অভ্যন্তরীণ ফাংশনটিকে উপহাস করুন এবং এটি নিশ্চিত করুন যে এটি আপনার পরীক্ষায় ডেকে আনা হয়েছে। এই সহজ উদাহরণ রয়েছে: gist.github.com/santiagobasulto/6437356
santiagobasulto

4

আমি আমার নিজের ইভেন্ট সম্পর্কিত অ্যাপ্লিকেশনের জন্য এরকম কিছু করি তবে আপনার নিজের ব্যবহারের ক্ষেত্রে যথেষ্ট কোডের চেয়ে বেশি হওয়া উচিত

import tempfile, csv, os

class UploadPaperTest(TestCase):

    def generate_file(self):
        try:
            myfile = open('test.csv', 'wb')
            wr = csv.writer(myfile)
            wr.writerow(('Paper ID','Paper Title', 'Authors'))
            wr.writerow(('1','Title1', 'Author1'))
            wr.writerow(('2','Title2', 'Author2'))
            wr.writerow(('3','Title3', 'Author3'))
        finally:
            myfile.close()

        return myfile

    def setUp(self):
        self.user = create_fuser()
        self.profile = ProfileFactory(user=self.user)
        self.event = EventFactory()
        self.client = Client()
        self.module = ModuleFactory()
        self.event_module = EventModule.objects.get_or_create(event=self.event,
                module=self.module)[0]
        add_to_admin(self.event, self.user)

    def test_paper_upload(self):
        response = self.client.login(username=self.user.email, password='foz')
        self.assertTrue(response)

        myfile = self.generate_file()
        file_path = myfile.name
        f = open(file_path, "r")

        url = reverse('registration_upload_papers', args=[self.event.slug])

        # post wrong data type
        post_data = {'uploaded_file': i}
        response = self.client.post(url, post_data)
        self.assertContains(response, 'File type is not supported.')

        post_data['uploaded_file'] = f
        response = self.client.post(url, post_data)

        import_file = SubmissionImportFile.objects.all()[0]
        self.assertEqual(SubmissionImportFile.objects.all().count(), 1)
        #self.assertEqual(import_file.uploaded_file.name, 'files/registration/{0}'.format(file_path))

        os.remove(myfile.name)
        file_path = import_file.uploaded_file.path
        os.remove(file_path)

4

আমি এরকম কিছু করেছি:

from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.core.files import File
from django.utils.six import BytesIO

from .forms import UploadImageForm

from PIL import Image
from io import StringIO


def create_image(storage, filename, size=(100, 100), image_mode='RGB', image_format='PNG'):
   """
   Generate a test image, returning the filename that it was saved as.

   If ``storage`` is ``None``, the BytesIO containing the image data
   will be passed instead.
   """
   data = BytesIO()
   Image.new(image_mode, size).save(data, image_format)
   data.seek(0)
   if not storage:
       return data
   image_file = ContentFile(data.read())
   return storage.save(filename, image_file)


class UploadImageTests(TestCase):
   def setUp(self):
       super(UploadImageTests, self).setUp()


   def test_valid_form(self):
       '''
       valid post data should redirect
       The expected behavior is to show the image
       '''
       url = reverse('image')
       avatar = create_image(None, 'avatar.png')
       avatar_file = SimpleUploadedFile('front.png', avatar.getvalue())
       data = {'image': avatar_file}
       response = self.client.post(url, data, follow=True)
       image_src = response.context.get('image_src')

       self.assertEquals(response.status_code, 200)
       self.assertTrue(image_src)
       self.assertTemplateUsed('content_upload/result_image.html')

create_image ফাংশনটি চিত্র তৈরি করবে যাতে আপনাকে চিত্রের স্থির পথ দেওয়ার প্রয়োজন হয় না।

দ্রষ্টব্য: আপনি কোড অনুসারে কোড আপডেট করতে পারেন। পাইথন 3.6 এর জন্য এই কোড।


1

জাজানো ১.7-তে টেস্টকেস উইচ নিয়ে একটি সমস্যা ওপেন (ফাইলপথ, 'আরবি') ব্যবহার করে সমাধান করা যেতে পারে তবে পরীক্ষার ক্লায়েন্ট ব্যবহার করার সময় আমাদের এর উপর কোনও নিয়ন্ত্রণ নেই। আমি মনে করি ফাইল.রেড () সর্বদা বাইট রিটার্ন নিশ্চিত করা সবচেয়ে ভাল।

উত্স: https://code.djangoproject.com/ticket/23912 , কেভিন এটিয়েন দ্বারা

আরবি বিকল্প ব্যতীত, একটি টাইপআরার উত্থাপিত হয়:

TypeError: sequence item 4: expected bytes, bytearray, or an object with the buffer interface, str found

1
from rest_framework.test import force_authenticate
from rest_framework.test import APIRequestFactory

factory = APIRequestFactory()
user = User.objects.get(username='#####')
view = <your_view_name>.as_view()
with open('<file_name>.pdf', 'rb') as fp:
    request=factory.post('<url_path>',{'file_name':fp})
force_authenticate(request, user)
response = view(request)

APIRequestFactory ব্যবহার করে একমাত্র উত্তর
majkelx

1

জ্যাঙ্গোর অফিসিয়াল ডকুমেন্টেশনে যেমন উল্লেখ করা হয়েছে :

ফাইল জমা দেওয়া একটি বিশেষ ক্ষেত্রে। কোনও ফাইল পোস্ট করার জন্য আপনার কেবলমাত্র ফাইলের ক্ষেত্রের নাম কী হিসাবে এবং সেই মান হিসাবে আপলোড করতে চান এমন ফাইলের একটি ফাইল হ্যান্ডেল সরবরাহ করতে হবে। উদাহরণ স্বরূপ:

c = Client()
with open('wishlist.doc') as fp:
    c.post('/customers/wishes/', {'name': 'fred', 'attachment': fp})

আরও তথ্য: ফাইলটি কোনও ফাংশনের আর্গুমেন্ট হিসাবে পাস করা হয়েছে কিনা তা কীভাবে পরীক্ষা করবেন?

পরীক্ষার সময়, কখনও কখনও আমরা নিশ্চিত করতে চাই যে কোনও ফাংশনের আর্গুমেন্ট হিসাবে ফাইলটি পাস হয়েছে।

যেমন

...
class AnyView(CreateView):
    ...
    def post(self, request, *args, **kwargs):
        attachment = request.FILES['attachment']
        # pass the file as an argument
        my_function(attachment)
        ...

পরীক্ষাগুলিতে পাইথনের মক এরকম কিছু ব্যবহার করুন :

# Mock 'my_function' and then check the following:

response = do_a_post_request()

self.assertEqual(mock_my_function.call_count, 1)
self.assertEqual(
    mock_my_function.call_args,
    call(response.wsgi_request.FILES['attachment']),
)

0
from django.test import Client
from requests import Response

client = Client()
with open(template_path, 'rb') as f:
    file = SimpleUploadedFile('Name of the django file', f.read())
    response: Response = client.post(url, format='multipart', data={'file': file})

আশাকরি এটা সাহায্য করবে.


0

আমি পাইথন == 3.8.2, জ্যাঙ্গো == 3.0.4, জ্যাঙ্গোরস্ট্রেফ্রেমওয়ার্ক == 3.11.0 ব্যবহার করছি

আমি চেষ্টা করেছি self.client.postকিন্তু পেয়েছিResolver404 ব্যতিক্রম ।

নিম্নলিখিত আমার জন্য কাজ করেছে:

import requests
upload_url='www.some.com/oaisjdoasjd' # your url to upload
with open('/home/xyz/video1.webm', 'rb') as video_file:
    # if it was a text file we would perhaps do
    # file = video_file.read()
    response_upload = requests.put(
        upload_url,
        data=video_file,
        headers={'content-type': 'video/webm'}
    )
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.