以敏捷/ BDD方式在Django中使用Doctests的示例

Bry*_*ock 6 python django agile doctest

我有兴趣学习如何以更敏捷/ BDD的方式进行Doctests和Unit测试.我发现了一些看似合理的教程,但它们只是缩略图.我真正希望看到的是一些开发了BDD风格的Django项目的源代码.

我不清楚的事情是你如何处理请求对象等我有一种情况,我已经部署了我的应用程序,我在生产中得到了完全不同的行为,我在开发中甚至从生产中的Python shell服务器.我希望一些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}) 
Run Code Online (Sandbox Code Playgroud)

如何创建一个Doctest来确保索引返回10个对象?
产品查询似乎可以从生产服务器上的shell中正常工作.实际的服务器根本没有返回任何产品.

maz*_*ife 3

我以前也问过自己同样的问题。我发现文档测试对于视图、模型方法和管理器等内容的实用性有限,因为

  1. 您需要能够设置和拆卸测试数据集以实际用于测试
  2. 视图需要接受请求对象。在文档测试中,它来自哪里?

出于这个原因,我一直使用 Django单元测试框架来为您处理所有这些事情。但不幸的是,您无法获得文档测试的一些好处,并且这使得 TDD/BDD 更难实现。接下来的内容纯粹是关于如何实现这项工作的猜测:

我认为您希望从各自的模块和函数中获取文档测试,并在单元测试框架中执行它们。这将负责测试数据的设置/拆卸。如果您的文档测试是从 Django 的 unittest.TestCase 子类的测试方法中执行的,那么它们就能够使用该测试数据库。您还可以将模拟请求对象传递到文档测试的执行上下文中。下面是一个Django 代码片段,它提供了一个模拟请求对象及其信息。假设您想要测试所有应用程序视图中的文档字符串。你可以在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)
Run Code Online (Sandbox Code Playgroud)

应该允许你做这样的事情:

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})
Run Code Online (Sandbox Code Playgroud)

再说一次,这只是我的想法,根本没有经过测试,但我认为这是您不需要将所有视图测试都放在单元测试框架中就可以实现您想要的效果的唯一方法。