Examples of using Doctests in Django in Agile / BDD mode

I am interested to know how to conduct Doctres and Unit tests in a more flexible / BDD way. I found several tutorials that seem reasonable, but they are just thumbnails. I would really like to see the source code of some of the Django projects that were developed in the style of BDD.

What I don't understand is how you handle request objects, etc. I have a situation where I deployed my application and I get completely different production behavior that I did in development or even from the Python shell on the production server. I hope some Doctests help me diagnose this and open the door well for a more flexible test writing process in the first place.

In particular, here is the code I'm trying to verify:

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}) 

How to create a Doctest that ensures that the index returns 10 objects?
Product requests seem to work fine with the shell on the production server. The actual server does not return any products.

+6
python django doctest agile
source share
4 answers

I asked myself the same question before. I believe that doctrines have limited usefulness for things like representations, model methods, and managers, because

  • You need to be able to customize and delete the test data set that is actually used for testing.
  • Views must have a request object. In the doctrine, where does this come from?

For this reason, I have always used the Django unit testing unit , which handles all this for you. Unfortunately, you do not get some of the benefits of doctrines, and this makes TDD / BDD more difficult. The following is pure speculation on how you can do this:

I think you want to capture doctrines from your respective modules and functions and execute them as part of unit testing. This will take care of setting up / deleting test data. If your doctrines were executed from a test method for subclassing Django unittest.TestCase, they will be able to use this test database. You can also pass the mock request object to the doc test execution context. Here's a Django snippet that provides a mock request object and info on it. Let's say you wanted to test docstrings from all kinds of applications. You can do something like this in 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) 

This should allow you to do something like this:

 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}) 

Again, this is not at all in my head, but not tested at all, but this is the only way that, as I think, you could wish for simply not putting all your tests for viewing in a unit testing system.

+3
source share

As your opinion is written, it would be difficult to verify. You will need to clear the html to see if the content you want is present and then you test more than you need. It would be better to rewrite your opinion to make it easier to test. Start by parameterizing the template name to create a simple test template:

 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}) 

Then you can write a simple template that simply counts the number of products:

 {{ products.count }} 

And make sure the pattern returns "10".

+1
source share

You can use django testclient and check the context variables that are set:

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

You can also check the response code to make sure the page returned a success of 200 .

+1
source share

The zope.testbrowser package can be useful in your doctrines, since you want to analyze the received HTML response from your production server.

0
source share

All Articles