I am trying to test my Django views. This view passes a QuerySet to the template:
def merchant_home(request, slug): merchant = Merchant.objects.get(slug=slug) product_list = merchant.products.all() return render_to_response('merchant_home.html', {'merchant': merchant, 'product_list': product_list}, context_instance=RequestContext(request))
and test:
def test(self): "Merchant home view should send merchant and merchant products to the template" merchant = Merchant.objects.create(name='test merchant') product = Product.objects.create(name='test product', price=100.00) merchant.products.add(product) test_client = Client() response = test_client.get('/' + merchant.slug) # self.assertListEqual(response.context['product_list'], merchant.products.all()) self.assertQuerysetEqual(response.context['product_list'], merchant.products.all())
EDIT I am using self.assertQuerysetEqua
l instead of self.assertListEqual
. Unfortunately this still doesn't work, and the terminal displays this: ['<Product: Product object>'] != [<Product: Product object>]
assertListEqual
raises: 'QuerySet' object has no attribute 'difference'
and assertEqual
does not work either, although self.assertSetEqual(response.context['product_list'][0], merchant.products.all()[0])
does pass.
I assume this is because the QuerySets are different objects even though they contain the same model instances.
How do I test that two QuerySets contain the same data? I am even testing this correctly? This is my 4th day learning Django so I would like to know best practices, if possible. Thanks.
The preferred way to write tests in Django is using the unittest module built-in to the Python standard library. This is covered in detail in the Writing and running tests document. You can also use any other Python test framework; Django provides an API and tools for that kind of integration.
With Django's Test Runner. If you're using manage.py test , you need to change the way you run it. You need to wrap it with three coverage commands like so: $ coverage erase # Remove any coverage data from previous runs $ coverage run manage.py test # Run the full test suite Creating test database for alias 'default'.. ...
As discussed above, we should test anything that is part of our design or that is defined by code that we have written, but not libraries/code that is already tested by Django or the Python development team. For example, consider the Author model below.
Automated Testing is a widely used tool that uses a collection of predefined test cases. Learn how Django and Selenium to ensure a bug free system. Table of contents.
By default assertQuerysetEqual
uses repr()
on the first argument. This is why you were having issues with the strings in the queryset comparison.
To work around this you can override the transform
argument with a lambda
function that doesn't use repr()
:
self.assertQuerysetEqual(queryset_1, queryset_2, transform=lambda x: x)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With