Примеры использования Doctests в Django Agile / BDD - PullRequest
6 голосов
/ 15 декабря 2009

Мне интересно узнать, как проводить Doctests и Unit тесты более гибким способом / BDD. Я нашел несколько уроков, которые кажутся разумными, но это всего лишь миниатюры. Что я действительно хотел бы увидеть, так это исходный код некоторых проектов Django, которые были разработаны в стиле BDD.

Что мне неясно, так это как вы обрабатываете объекты запроса и т. Д. У меня есть ситуация, когда я развернул свое приложение, и в процессе работы я получаю совершенно другое поведение, чем при разработке или даже из оболочки Python на рабочем сервере. Я надеюсь, что некоторые Doctests помогут мне диагностировать это, а также откроют дверь для более гибкого процесса написания тестов в первую очередь.

В частности, вот код, который я пытаюсь проверить:

def match_pictures_with_products( queryset, number_of_images = 3):      
    products = []  
    i = 0    
    for product in queryset:  
       if i < ( number_of_images ):  
           image =  product.imagemain_set.all()[:1]  
           product.photo_url = image[0].photo.url  

       products.append(product)  
       i += 1  

    return products  

def index(request):  
    """returns the top 10 most clicked products"""     
    products = Product.objects.all()[:10]  
    products = match_pictures_with_products( products, 10)  .  
    return render_to_response('products/product_list.html', {'products': products}) 

Как мне создать Doctest, который гарантирует, что индекс возвращает 10 объектов?
Запросы Product, похоже, работают нормально из оболочки на рабочем сервере. Фактический сервер не возвращает никаких продуктов вообще.

Ответы [ 4 ]

3 голосов
/ 16 декабря 2009

Я задавал себе тот же вопрос раньше. Я обнаружил, что тесты документов имеют ограниченную полезность для таких вещей, как представления, методы моделей и менеджеры, потому что

  1. Вы должны иметь возможность настроить и удалить набор тестовых данных для фактического использования для тестирования
  2. Представления должны принимать объект запроса. Откуда это происходит?

По этой причине я всегда использовал модульное тестирование Django , которое обрабатывает все это для вас. К сожалению, однако, вы не получаете некоторых преимуществ от doctests, и это делает TDD / BDD труднее сделать. Далее следует чистое предположение о том, как вы могли бы сделать эту работу:

Думаю, вы захотите извлечь документы из соответствующих модулей и функций и выполнить их в рамках модульного тестирования. Это позаботится о настройке / разборке тестовых данных. Если ваши тесты выполнялись из тестового метода чего-то, что является подклассом Django unittest.TestCase, они могли бы использовать эту тестовую БД. Вы также сможете передать объект фиктивного запроса в контекст выполнения doc-теста. Вот фрагмент Django , который предоставляет фиктивный объект запроса и info на нем. Допустим, вы хотели протестировать строки документов из всех представлений приложений. Вы можете сделать что-то подобное в tests.py:

from ??? import RequestFactory
from doctest import testmod, DocTestFailure
from django.test import TestCase

from myapp import views

class MyAppTest(TestCase):

    fixtures = ['test_data.json']

    def test_doctests(self):                
        try:
            testmod(views, extraglobs={
                'REQUEST': RequestFactory()
            }, raise_on_error=True)
        except DocTestFailure, e:
            self.fail(e)

Это должно позволить вам сделать что-то вроде этого:

def index(request):  
    """
    returns the top 10 most clicked products

    >>> response = index(REQUEST)
    >>> [test response content here]

    """     
    products = Product.objects.all()[:10]  
    products = match_pictures_with_products( products, 10)  .  
    return render_to_response('products/product_list.html', {'products': products})

Опять же, это просто не в моей голове, и совсем не проверено, но я думаю, что это единственный способ сделать то, что вы хотите, не помещая все свои тесты представлений в среду модульного тестирования.

1 голос
/ 07 января 2010

Вы можете использовать django testclient и проверить установленные переменные контекста:

>>> response = client.get('/foo/')
>>> response.context['name']
'Arthur'

Вы также можете проверить код ответа, чтобы убедиться, что страница вернулась успешно 200.

1 голос
/ 15 декабря 2009

То, как написано ваше мнение, было бы трудно проверить. Вам нужно будет просмотреть html, чтобы увидеть, присутствует ли нужный вам контент, и тогда вы тестируете больше, чем нужно. Лучше было бы переписать вашу точку зрения, чтобы ее было проще тестировать. Начните с параметризации имени вашего шаблона, чтобы вы могли создать простой тестовый шаблон:

def index(request, template_name='products/product_list.html'):  
    """returns the top 10 most clicked products"""     
    products = Product.objects.all()[:10]  
    products = match_pictures_with_products( products, 10)  .  
    return render_to_response(template_name, {'products': products})

Тогда вы можете написать простой шаблон, который просто подсчитывает количество продуктов:

{{ products.count }} 

И убедитесь, что шаблон возвращает «10».

0 голосов
/ 15 декабря 2009

Пакет zope.testbrowser может быть полезен в ваших документах, так как вы хотите проанализировать обработанный HTML-ответ вашего рабочего сервера.

...