Unit Test Method for projects in the Python Django framework, pythondjango

Source: Internet
Author: User

Unit Test Method for projects in the Python Django framework, pythondjango

Unit Test in Python

Let's review the unit test method in Python.
The following is a simple Python unit test example:

If we develop a division function, some people may think it is very simple and the code is as follows:

def division_funtion(x, y):  return x / y

But is this correct? Some students can test the Code as follows:

def division_funtion(x, y):  return x / y  if __name__ == '__main__':  print division_funtion(2, 1)  print division_funtion(2, 4)  print division_funtion(8, 3)

However, it is inconvenient to check the result obtained after this operation. There is a unittest module in Python, which can be easily tested. For details, see the final link of the article, go to the official website for a detailed introduction.

The following is a simple example:

import unittest  def division_funtion(x, y):  return x / y  class TestDivision(unittest.TestCase):  def test_int(self):    self.assertEqual(division_funtion(9, 3), 3)   def test_int2(self):    self.assertEqual(division_funtion(9, 4), 2.25)   def test_float(self):    self.assertEqual(division_funtion(4.2, 3), 1.4)  if __name__ == '__main__':  unittest.main()


I simply wrote three test examples (not necessarily comprehensive, just demonstration, for example, without considering that the divisor is 0). After running the test, I found that:

F.F======================================================================FAIL: test_float (__main__.TestDivision)----------------------------------------------------------------------Traceback (most recent call last): File "/Users/tu/YunPan/mydivision.py", line 16, in test_float  self.assertEqual(division_funtion(4.2, 3), 1.4)AssertionError: 1.4000000000000001 != 1.4 ======================================================================FAIL: test_int2 (__main__.TestDivision)----------------------------------------------------------------------Traceback (most recent call last): File "/Users/tu/YunPan/1.py", line 13, in test_int2  self.assertEqual(division_funtion(9, 4), 2.25)AssertionError: 2 != 2.25 ----------------------------------------------------------------------Ran 3 tests in 0.001s FAILED (failures=2)

Khan! No, but both failed. The test found that:

4.2 divided by 3 equals 1.4000000000000001 not equal to expected value 1.4

9 divided by 4 equals 2, not equal to the expected 2.25

We will fix these problems and run the test again until no error is reported.

For example, assume that we only need to retain the last six digits of the decimal point according to the actual situation. You can change the number as follows:

def division_funtion(x, y):  return round(float(x) / y, 6)

No error will be reported when you run it again:

...----------------------------------------------------------------------Ran 3 tests in 0.000s

 
OK

Unit Test in Django

Early UnitTest is a good practice. In extreme cases, we even emphasize "test first ". Now we have the first model class and Form class. It is time to write the test code.

Django supports unit test and doc test in python. Here we mainly discuss the unit test method. I will not elaborate too much on the unit test theory here. Suppose you are familiar with the following concepts: test suite, test case, test/test action, test data, assert, etc.

In terms of unit testing, Django inherits the python unittest. TestCase to implement its own django. test. TestCase. The compiling test examples usually start from here. The test code is usually located in the app's tests. py file (you can also write it in models. py, but I do not recommend this ). This file is already included in the depotapp generated by Django and contains a test case example:

Depot/depotapp/tests. py

from django.test import TestCaseclass SimpleTest(TestCase):def test_basic_addition(self):"""Tests that 1 + 1 always equals 2."""self.assertEqual(1 + 1, 2)

You can run unit tests in several ways:

  • Python manage. py test: Execute all test cases
  • Python manage. py test app_name: Run all test cases of the app
  • Python manage. py test app_name.case_name: run the specified test case.

Run the example provided above in the third method. The result is as follows:

$ python manage.py test depotapp.SimpleTest
Creating test database for alias 'default'....----------------------------------------------------------------------Ran 1 test in 0.012sOKDestroying test database for alias 'default'...

You may focus on creating and deleting databases in the output information. To avoid the impact of test data, a separate database is used during the test. For details about how to specify a test database, see the Django documentation. In our example, since the sqlite database is used, Django uses the memory database by default for testing.

Next let's write test cases. In section 7.2 Agile Web Development with Rails 4th, the final ProductTest code is as follows:

class ProductTest < ActiveSupport::TestCasetest "product attributes must not be empty"doproduct = Product.newassert product.invalid?assert product.errors[:title].any?assert product.errors[:description].any?assert product.errors[:price].any?assert product.errors[:image_url].any?endtest "product price must be positive"doproduct = Product.new(:title => "My Book Title",:description => "yyy",:image_url => "zzz.jpg")product.price = -1assert product.invalid?assert_equal "must be greater than or equal to 0.01",product.errors[:price].join('; ')product.price = 0assert product.invalid?assert_equal "must be greater than or equal to 0.01",product.errors[:price].join('; ')product.price = 1assert product.valid?enddef new_product(image_url)Product.new(:title => "My Book Title",:description => "yyy",:price => 1,:image_url => image_url)endtest "image url"dook = %w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpghttp://a.b.c/x/y/z/fred.gif }bad = %w{ fred.doc fred.gif/more fred.gif.more }ok.eachdo |name|assert new_product(name).valid?, "#{name} shouldn't be invalid"endbad.eachdo |name|assert new_product(name).invalid?, "#{name} shouldn't be valid"endendtest "product is not valid without a unique title"doproduct = Product.new(:title => products(:ruby).title,:description => "yyy",:price => 1,:image_url => "fred.gif")assert !product.saveassert_equal "has already been taken", product.errors[:title].join('; ')endtest "product is not valid without a unique title - i18n"doproduct = Product.new(:title => products(:ruby).title,:description => "yyy",:price => 1,:image_url => "fred.gif")assert !product.saveassert_equal I18n.translate('activerecord.errors.messages.taken'),product.errors[:title].join('; ')endend

The content of the Product test includes:

1. title, description, price, image_url cannot be blank;

2. The price must be greater than zero;

3. image_url must end with jpg, png, and jpg, and is case insensitive;

4. The titile must be unique;

Let's perform these tests in Django. Because ProductForm contains model validation and Form validation rules, using ProductForm can easily implement the above tests:

Depot/depotapp/tests. py

#/Usr/bin/python # coding: utf8 "This file demonstrates writing tests using the unittest module. these will passwhen you run "manage. py test ". replace this with more appropriate tests for your application. "from django. test import TestCasefrom forms import ProductFormclass SimpleTest (TestCase): def test_basic_addition (self): "" Tests that 1 + 1 always equals 2. "self. assertEqual (1 + 1, 2) class ProductTest (TestCase): def setUp (self): self. product = {'title': 'My Book title', 'description': 'yyy', 'image _ url': 'http: // google.com/logo.png', 'price':1366f = ProductForm (self. product) f. save () self. product ['title'] = 'my Another Book title' #### title, description, price, image_url cannot be empty def test_attrs_cannot_empty (self): f = ProductForm ({}) self. assertFalse (f. is_valid () self. assertTrue (f ['title']. errors) self. assertTrue (f ['description']. errors) self. assertTrue (f ['price']. errors) self. assertTrue (f ['image _ url']. errors) #### price must be greater than zero def test_price_positive (self): f = ProductForm (self. product) self. assertTrue (f. is_valid () self. product ['price'] = 0f = ProductForm (self. product) self. assertFalse (f. is_valid () self. product ['price'] =-1f = ProductForm (self. product) self. assertFalse (f. is_valid () self. product ['price'] = 1 #### image_url must end with jpg, png, and jpg and is case insensitive. def test_imgae_url_endwiths (self): url_base = 'HTTP: // google.com/'oks = ('fred.gif ', 'fred.jpg', 'fred.png ', 'fred. JPG ', 'fred. jpg ') bads = ('fred.doc', 'fred.gif/more', 'fred.gif. more ') for endwith in oks: self. product ['image _ url'] = url_base + endwithf = ProductForm (self. product) self. assertTrue (f. is_valid (), msg = 'error when image_url endwith' + endwith) for endwith in bads: self. product ['image _ url'] = url_base + endwithf = ProductForm (self. product) self. assertFalse (f. is_valid (), msg = 'error when image_url endwith' + endwith) self. product ['image _ url'] = 'HTTP: // google.com/logo.png'{}# titile must be unique def test_title_unique (self): self. product ['title'] = 'My Book title' f = ProductForm (self. product) self. assertFalse (f. is_valid () self. product ['title'] = 'my Another Book title'

Then run python manage. py test depotapp. ProductTest. As expected, the test fails:

Creating test database for alias 'default'....F..======================================================================FAIL: test_imgae_url_endwiths (depot.depotapp.tests.ProductTest)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/holbrook/Documents/Dropbox/depot/../depot/depotapp/tests.py", line 65, in test_imgae_url_endwithsself.assertTrue(f.is_valid(),msg='error when image_url endwith '+endwith)AssertionError: False is not True : error when image_url endwith FRED.JPG----------------------------------------------------------------------Ran 4 tests in 0.055sFAILED (failures=1)Destroying test database for alias 'default'...

Because we didn't consider that the image extension of image_url may be capitalized. The following section describes how to modify ProductForm:

Def clean_image_url (self): url = self. cleaned_data ['image _ url'] ifnot endsWith (url. lower (), '.jpg ', '.png', '.gif '): raise forms. validationError ('image format must be jpg, png, or gif ') return url

Then run the test:

$ python manage.py test depotapp.ProductTest
Creating test database for alias 'default'.......----------------------------------------------------------------------Ran 4 tests in 0.060sOKDestroying test database for alias 'default'...

After passing the test and passing the unit test, we found and solved a bug.

 

Articles you may be interested in:
  • Use the Python Django framework and jQuery to implement the AJAX shopping cart page
  • Serialization, request, and return in the Django REST framework of Python
  • Details about the templates settings in the Python Django framework
  • How to obtain the IP address of a user using django in Python
  • Analyze the running mode and processing process of the Python Django framework
  • How to configure mysql database in Django1.7 + python 2.78 + pycharm
  • Share the simple Performance Test Results of common python web frameworks (including django, flask, bottle, tornado)
  • Python django integrated cas Verification System
  • How to Make Sublime 3 a powerful tool for Python/Django IDE development
  • How to Use and extend manage commands in Python Django framework

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.