수색…


테스트 - 완전한 예제

여기서는 새로운 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

왜 그런 일이 일어날까요? 우리는 뷰를 정의하지 않았기 때문에! 그럼 해보 죠. views.py라는 파일을 만들고 다음 코드를 그 안에 넣으십시오.

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 and viola !!

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

OK

장고 모델을 효과적으로 테스트하기

가정 할 때

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):
        ...

몇 점

  • created_properly tests는 django 모델의 상태 속성을 확인하는 데 사용됩니다. 그들은 우리가 기본값, file_upload_paths 등을 변경 한 곳을 잡는 데 도움이됩니다.
  • absolute_url 은 사소한 것 같지만 URL 경로를 변경할 때 버그를 예방할 수 있다는 것을 알았습니다.
  • 나는 모델 내에서 구현 된 모든 메소드에 대한 테스트 케이스를 비슷하게 작성한다 ( mock 객체 등을 사용하여)
  • 공통 BaseModelTestCase 를 정의함으로써 적절한 테스트를 위해 필요한 모델 간의 관계를 설정할 수 있습니다.

마지막으로 의심 스러울 때 테스트를 작성하십시오. 사소한 행동 변화는 세부 사항에주의를 기울임으로써 포착되며 오랫동안 잊혀진 코드 조각은 불필요한 문제를 일으키지 않습니다.

장고보기 액세스 제어 테스트

tl; dr : 두 개의 사용자 객체를 정의하는 기본 클래스를 만듭니다 (예 : useranother_user ). 다른 모델을 작성하고 세 개의 Client 인스턴스를 정의하십시오.

  • self.client : 브라우저에 로그인 한 user self.client .
  • self.another_client : another_user 의 클라이언트를 another_user self.another_client .
  • self.unlogged_client : self.unlogged_client 않은 사람을 self.unlogged_client .

이제이 세 클라이언트 객체의 공개 URL과 비공개 URL에 모두 액세스하여 원하는 응답을 받아들입니다. 아래에서는 private (소수의 권한있는 사용자 소유) 또는 public (모든 사용자에게 public ) 중 하나 일 수있는 Book 개체에 대한 전략을 보여 드렸습니다.

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 메소드에서 생성하십시오. 또한 장고 프로젝트에서 조명기를 정의했다면 다음과 같이 포함시킬 수 있습니다 :

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

기본적으로 django는 각 app의 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 사용하여 첫 번째 실패시 테스트 스위트를 중지 할 수 있습니다. 이 인수를 사용하면 스위트에서 발생할 수있는 잠재적 인 오류를 신속하게 얻을 수 있습니다.

$ 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