खोज…


परीक्षण - एक पूर्ण उदाहरण

यह मानता है कि आपने एक नई Django परियोजना शुरू करने के बारे में प्रलेखन पढ़ा है। आइए हम मान लें कि आपकी परियोजना में मुख्य ऐप का नाम td है (परीक्षण संचालित के लिए छोटा)। अपना पहला परीक्षण बनाने के लिए, test_view.py नाम की एक फ़ाइल बनाएँ और उसमें निम्न सामग्री पेस्ट करें।

from django.test import Client, TestCase

class ViewTest(TestCase):

    def test_hello(self):
        c = Client()
        resp = c.get('/hello/')
        self.assertEqual(resp.status_code, 200)

आप इस परीक्षण को चला सकते हैं

 ./manage.py test

और यह सबसे स्वाभाविक रूप से विफल हो जाएगा! आपको निम्न के समान त्रुटि दिखाई देगी।

Traceback (most recent call last):
  File "/home/me/workspace/td/tests_view.py", line 9, in test_hello
    self.assertEqual(resp.status_code, 200)
AssertionError: 200 != 404

ऐसा क्यों होता है? क्योंकि हमने उसके लिए कोई दृष्टिकोण निर्धारित नहीं किया है! तो ये करते है। व्यू कोड नामक एक फाइल बनाएं और उसमें निम्न कोड रखें

from django.http import HttpResponse
def hello(request):
    return HttpResponse('hello')

अगला नक्शा इसे / hello / urls py को निम्नानुसार संपादित करके:

from td import views

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^hello/', views.hello),
    ....
]

अब दोबारा ./manage.py test फिर से ./manage.py test करें और वायोला !!

Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.004s

OK

Django मॉडल का प्रभावी ढंग से परीक्षण

एक वर्ग मान लिया

from django.db import models

class Author(models.Model):
   name = models.CharField(max_length=50)
   
    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('view_author', args=[str(self.id)])


class Book(models.Model):
    author = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
    private = models.BooleanField(default=false)
    publish_date = models.DateField()

    def get_absolute_url(self):
        return reverse('view_book', args=[str(self.id)])
    
    def __str__(self):
        return self.name

परीक्षण उदाहरण

from django.test import TestCase
from .models import Book, Author

class BaseModelTestCase(TestCase):

    @classmethod
    def setUpClass(cls):
        super(BaseModelTestCase, cls).setUpClass()
        cls.author = Author(name='hawking')
        cls.author.save()
        cls.first_book = Book(author=cls.author, name="short_history_of_time")
        cls.first_book.save()
        cls.second_book = Book(author=cls.author, name="long_history_of_time")
        cls.second_book.save()


class AuthorModelTestCase(BaseModelTestCase):
    def test_created_properly(self):
         self.assertEqual(self.author.name, 'hawking')
         self.assertEqual(True, self.first_book in self.author.book_set.all())
    
    def test_absolute_url(self):
        self.assertEqual(self.author.get_absolute_url(), reverse('view_author', args=[str(self.author.id)]))

class BookModelTestCase(BaseModelTestCase):
    
    def test_created_properly(self:
        ...
        self.assertEqual(1, len(Book.objects.filter(name__startswith='long'))
    
    def test_absolute_url(self):
        ...

कुछ बिंदु

  • django मॉडल के राज्य गुणों को सत्यापित करने के लिए created_properly परीक्षण का उपयोग किया जाता है। वे उन स्थितियों को पकड़ने में सहायता करते हैं जहां हमने डिफ़ॉल्ट मान, file_upload_paths आदि बदले हैं।
  • absolute_url तुच्छ लग सकता है, लेकिन मैंने पाया है कि यह मुझे यूआरएल पथ बदलते समय कुछ कीड़े को रोकने में मदद मिली है
  • मैं इसी तरह एक मॉडल के अंदर लागू सभी तरीकों के लिए परीक्षण मामलों को लिखता हूं ( mock वस्तुओं आदि का उपयोग करके)
  • एक सामान्य BaseModelTestCase को परिभाषित करके हम उचित परीक्षण सुनिश्चित करने के लिए मॉडल के बीच आवश्यक संबंधों को सेट कर सकते हैं।

अंत में, जब संदेह हो, तो एक परीक्षण लिखें। तुच्छ व्यवहार परिवर्तनों को विस्तार से ध्यान देकर पकड़ा जाता है और कोड के लंबे समय तक भूल गए टुकड़े अनावश्यक परेशानी का कारण नहीं बनते हैं।

Django दृश्य में परीक्षण अभिगम नियंत्रण

tl; dr : एक आधार वर्ग बनाएं जो दो उपयोगकर्ता वस्तुओं ( user और another_user ) को परिभाषित करता है। अपने अन्य मॉडल बनाएं और तीन Client इंस्टेंस को परिभाषित करें।

  • self.client : ब्राउज़र में लॉग इन user प्रतिनिधित्व करता है
  • self.another_client : प्रतिनिधित्व another_user के ग्राहक
  • self.unlogged_client : असूचीबद्ध व्यक्ति का प्रतिनिधित्व करना

अब इन तीन ग्राहक वस्तुओं से अपने सभी सार्वजनिक और निजी यूआरएल तक पहुँचें और उस प्रतिक्रिया को निर्धारित करें जो आप अपेक्षा करते हैं। नीचे मैंने एक Book ऑब्जेक्ट के लिए रणनीति दिखाई है जो या तो private हो private (कुछ विशेषाधिकार प्राप्त उपयोगकर्ताओं के स्वामित्व में) या public (सभी के लिए दृश्यमान)।

from django.test import TestCase, RequestFactory, Client
from django.core.urlresolvers import reverse

class BaseViewTestCase(TestCase):

    @classmethod
    def setUpClass(cls):
        super(BaseViewTestCase, cls).setUpClass()
        cls.client = Client()
        cls.another_client = Client()
        cls.unlogged_client = Client()
        cls.user = User.objects.create_user(
                'dummy',password='dummy'
                )
        cls.user.save()
        cls.another_user = User.objects.create_user(
                'dummy2', password='dummy2'
                )
        cls.another_user.save()
        cls.first_book = Book.objects.create(
                name='first',
                private = true
        )
        cls.first_book.readers.add(cls.user)
        cls.first_book.save()
        cls.public_book = Template.objects.create(
                name='public',
                private=False
        )
        cls.public_book.save()


    def setUp(self):
        self.client.login(username=self.user.username, password=self.user.username)
        self.another_client.login(username=self.another_user.username, password=self.another_user.username)


"""
   Only cls.user owns the first_book and thus only he should be able to see it.
   Others get 403(Forbidden) error
"""
class PrivateBookAccessTestCase(BaseViewTestCase):
    
    def setUp(self):
        super(PrivateBookAccessTestCase, self).setUp()
        self.url = reverse('view_book',kwargs={'book_id':str(self.first_book.id)})

    def test_user_sees_own_book(self):
        response = self.client.get(self.url)
        self.assertEqual(200, response.status_code)
        self.assertEqual(self.first_book.name,response.context['book'].name)
        self.assertTemplateUsed('myapp/book/view_template.html')

    def test_user_cant_see_others_books(self):
        response = self.another_client.get(self.url)
        self.assertEqual(403, response.status_code)
        
    def test_unlogged_user_cant_see_private_books(self):
        response = self.unlogged_client.get(self.url)
        self.assertEqual(403, response.status_code)

"""
    Since book is public all three clients should be able to see the book
"""
 class PublicBookAccessTestCase(BaseViewTestCase):
    
    def setUp(self):
        super(PublicBookAccessTestCase, self).setUp()
        self.url = reverse('view_book',kwargs={'book_id':str(self.public_book.id)})

    def test_user_sees_book(self):
        response = self.client.get(self.url)
        self.assertEqual(200, response.status_code)
        self.assertEqual(self.public_book.name,response.context['book'].name)
        self.assertTemplateUsed('myapp/book/view_template.html')

    def test_another_user_sees_public_books(self):
        response = self.another_client.get(self.url)
        self.assertEqual(200, response.status_code)
        
    def test_unlogged_user_sees_public_books(self):
        response = self.unlogged_client.get(self.url)
        self.assertEqual(200, response.status_code)

डेटाबेस और परीक्षण

परीक्षण करते समय Django विशेष डेटाबेस सेटिंग्स का उपयोग करता है ताकि परीक्षण डेटाबेस का सामान्य रूप से उपयोग कर सकें लेकिन खाली डेटाबेस पर डिफ़ॉल्ट रूप से चलाएं। एक परीक्षण में डेटाबेस परिवर्तन दूसरे द्वारा नहीं देखा जाएगा। उदाहरण के लिए, निम्नलिखित दोनों परीक्षण पास होंगे:

from django.test import TestCase
from myapp.models import Thing

class MyTest(TestCase):

    def test_1(self):
        self.assertEqual(Thing.objects.count(), 0)
        Thing.objects.create()
        self.assertEqual(Thing.objects.count(), 1)

    def test_2(self):
        self.assertEqual(Thing.objects.count(), 0)
        Thing.objects.create(attr1="value")
        self.assertEqual(Thing.objects.count(), 1)

फिक्स्चर

यदि आप कई परीक्षण द्वारा डेटाबेस ऑब्जेक्ट का उपयोग करना चाहते हैं, तो या तो उन्हें टेस्ट केस के setUp विधि में बनाएं। इसके अतिरिक्त, यदि आपने अपने django प्रोजेक्ट में फिक्स्चर को परिभाषित किया है, तो उन्हें इस तरह शामिल किया जा सकता है:

class MyTest(TestCase):
    fixtures = ["fixture1.json", "fixture2.json"]

डिफ़ॉल्ट रूप से, django प्रत्येक ऐप में fixtures निर्देशिका में fixtures तलाश कर रहा है। आगे निर्देशिका FIXTURE_DIRS सेटिंग का उपयोग करके सेट की जा सकती है:

# myapp/settings.py
FIXTURE_DIRS = [
    os.path.join(BASE_DIR, 'path', 'to', 'directory'),
]

चलिए मान लेते हैं कि आपने एक मॉडल बनाया है:

# models.py
from django.db import models


class Person(models.Model):
    """A person defined by his/her first- and lastname."""
    firstname = models.CharField(max_length=255)
    lastname = models.CharField(max_length=255)

तब आपकी .json जुड़नार की तरह लग सकता है:

# fixture1.json
[
    { "model": "myapp.person",
        "pk": 1,
        "fields": {
            "firstname": "Peter",
            "lastname": "Griffin"
        }
    },
    { "model": "myapp.person",
        "pk": 2,
        "fields": {
            "firstname": "Louis",
            "lastname": "Griffin"
        }
    },
]

परीक्षण-डेटाबेस का पुन: उपयोग करें

अपने परीक्षण-रनों को गति देने के लिए आप परीक्षण-डेटाबेस का पुन: उपयोग करने के लिए प्रबंधन-कमांड को बता सकते हैं (और इसे हर टेस्ट-रन से पहले हटाने और हटाने से रोकने के लिए)। यह keepdb (या आशुलिपि उपयोग किया जा सकता -k तो) की तरह झंडा:

# Reuse the test-database (since django version 1.8)
$ python manage.py test --keepdb

निष्पादित परीक्षणों की संख्या को सीमित करें

यह परीक्षण द्वारा निष्पादित सीमित करना संभव है manage.py test को निर्दिष्ट जो मॉड्यूल परीक्षण धावक द्वारा की खोज की जानी चाहिए द्वारा:

# Run only tests for the app names "app1"
$ python manage.py test app1

# If you split the tests file into a module with several tests files for an app
$ python manage.py test app1.tests.test_models

# it's possible to dig down to individual test methods.
$ python manage.py test app1.tests.test_models.MyTestCase.test_something

यदि आप परीक्षणों का एक गुच्छा चलाना चाहते हैं, तो आप फ़ाइलनाम का एक पैटर्न पास कर सकते हैं। उदाहरण के लिए, आप केवल उन्हीं परीक्षणों को चलाना चाह सकते हैं जिनमें आपके मॉडल शामिल हैं:

$ python manage.py test -p test_models*
Creating test database for alias 'default'...
.................................................
----------------------------------------------------------------------
Ran 115 tests in 3.869s

OK

अंत में, पहली असफलता पर परीक्षण सूट को रोकना संभव है, - --failfast का उपयोग --failfast । यह तर्क सुइट में आई संभावित त्रुटि को शीघ्रता से प्राप्त करने की अनुमति देता है:

$ python manage.py test app1
...F..
----------------------------------------------------------------------
Ran 6 tests in 0.977s

FAILED (failures=1)


$ python manage.py test app1 --failfast
...F
======================================================================
[Traceback of the failing test]
----------------------------------------------------------------------
Ran 4 tests in 0.372s

FAILED (failures=1)


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow