日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django单元测试

發(fā)布時間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django单元测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一.前言/準備

? 測Django的東西僅限于在MTV模型。哪些可以測?哪些不可以。

1.html里的東西不能測。
①Html里的HTML代碼大部分都是寫死的
②嵌套在html中的Django模板語言也不能測,即使有部分邏輯。
但寫測試用例時至少要調(diào)用一個類或者方法。模板語言沒有出參也沒有入?yún)?#xff0c;不能測
2.models模型可測。屬于數(shù)據(jù)庫層
3.views,視圖層可以測。有入?yún)ⅰ⒂蟹椒ā?br style="margin:0px; padding:0px" />綜上:根據(jù)Django語言特點,可測models和views

二.Django單元測試具體步驟----【測試模型models中的內(nèi)容】

# coding=utf-8
from django.test import TestCase #導入Django測試包
from sign.models import Guest, Event #導入models中的發(fā)布會、嘉賓類

#首先創(chuàng)建測試類
class ModelTest(TestCase):

#初始化:分別創(chuàng)建一條發(fā)布會(Event)和一條嘉賓(Guest)的數(shù)據(jù)。
def setUp(self):
Event.objects.create(id=1, name="oneplus 3 event", status=True, limit=2000,
address='shenzhen', start_time='2016-08-31 02:18:22')
Guest.objects.create(id=1, event_id=1, realname='alen',
phone='13711001101', email='alen@mail.com', sign=False)

#下面開始寫測試用例了
#1.通過get的方法,查詢插入的發(fā)布會數(shù)據(jù),并根據(jù)地址判斷
def test_event_models(self):
result = Event.objects.get(name="oneplus 3 event")
self.assertEqual(result.address, "shenzhen")
self.assertTrue(result.status)

#2.通過get的方法,查詢插入的嘉賓數(shù)據(jù),并根據(jù)名字判斷
def test_guest_models(self):
result = Guest.objects.get(phone='13711001101')
self.assertEqual(result.realname, "alen")
self.assertFalse(result.sign)

#寫完測試用例后,執(zhí)行測試用例。這里與unittest的運行方法也不一樣。
#Django提供了“test”命令來運行測試。(用cmd執(zhí)行 見下截圖)

注意:剛剛在setup()部分操作時,其實并不會真正向數(shù)據(jù)庫表中插入數(shù)據(jù)。所以,不用擔心測試完后產(chǎn)生垃圾數(shù)據(jù)的問題。

如果:插入了表中沒有定義的字段時,也是會報錯提醒的!?

三。Django測試框架首選方法是使用python標準庫中的unittest模塊。




盡早進行單元測試(UnitTest)是比較好的做法,極端的情況甚至強調(diào)“測試先行”。現(xiàn)在我們已經(jīng)有了第一個model類和Form類,是時候開始寫測試代碼了。

Django支持python的單元測試(unit test)和文本測試(doc test),我們這里主要討論單元測試的方式。這里不對單元測試的理論做過多的闡述,假設(shè)你已經(jīng)熟悉了下列概念:test suite, test case, test/test action,? test data, assert等等。

在單元測試方面,Django繼承python的unittest.TestCase實現(xiàn)了自己的django.test.TestCase,編寫測試用 例通常從這里開始。測試代碼通常位于app的tests.py文件中(也可以在models.py中編寫,但是我不建議這樣做)。在Django生成的 depotapp中,已經(jīng)包含了這個文件,并且其中包含了一個測試用例的樣例:

depot/depotapp/tests.py

?
1 2 3 4 5 6 7 from django.test import TestCase class SimpleTest(TestCase): def test_basic_addition(self): """ Tests that 1 + 1 always equals 2. """ self.assertEqual(1+ 1,2)

你可以有幾種方式運行單元測試:

  • python manage.py test:執(zhí)行所有的測試用例
  • python manage.py test app_name, 執(zhí)行該app的所有測試用例
  • python manage.py test app_name.case_name: 執(zhí)行指定的測試用例

用第三種方式執(zhí)行上面提供的樣例,結(jié)果如下:

?
1 $ python manage.pytest depotapp.SimpleTest
?
1 2 3 4 5 6 7 Creating test database for alias 'default'... . ---------------------------------------------------------------------- Ran 1 test in 0.012s ?? OK Destroying test database for alias 'default'...

你可能會主要到,輸出信息中包括了創(chuàng)建和刪除數(shù)據(jù)庫的操作。為了避免測試數(shù)據(jù)造成的影響,測試過程會使用一個單獨的數(shù)據(jù)庫,關(guān)于如何指定測試數(shù)據(jù)庫 的細節(jié),請查閱Django文檔。在我們的例子中,由于使用sqlite數(shù)據(jù)庫,Django將默認采用內(nèi)存數(shù)據(jù)庫來進行測試。

下面就讓我們來編寫測試用例。在《Agile Web Development with Rails 4th》中,7.2節(jié),最終實現(xiàn)的ProductTest代碼如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 class ProductTest < ActiveSupport::TestCase test "product attributes must not be empty"do product =Product.new assert product.invalid? assert product.errors[:title].any? assert product.errors[:description].any? assert product.errors[:price].any? assert product.errors[:image_url].any? end test "product price must be positive"do product =Product.new(:title =>"My Book Title", :description => "yyy", :image_url => "zzz.jpg") product.price = -1 assert product.invalid? assert_equal "must be greater than or equal to 0.01", product.errors[:price].join('; ') product.price = 0 assert product.invalid? assert_equal "must be greater than or equal to 0.01", product.errors[:price].join('; ') product.price = 1 assert product.valid? end def new_product(image_url) Product.new(:title=> "My Book Title", :description => "yyy", :price =>1, :image_url => image_url) end test "image url"do ok =%w{ fred.gif fred.jpg fred.png FRED.JPG FRED.Jpg http://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" end bad.eachdo |name| assert new_product(name).invalid?, "#{name} shouldn't be valid" end end test "product is not valid without a unique title"do product =Product.new(:title => products(:ruby).title, :description => "yyy", :price =>1, :image_url => "fred.gif") assert !product.save assert_equal "has already been taken", product.errors[:title].join('; ') end test "product is not valid without a unique title - i18n"do product =Product.new(:title => products(:ruby).title, :description => "yyy", :price =>1, :image_url => "fred.gif") assert !product.save assert_equal I18n.translate('activerecord.errors.messages.taken'), product.errors[:title].join('; ') end end

對Product測試的內(nèi)容包括:

1.title,description,price,image_url不能為空;

2. price必須大于零;

3. image_url必須以jpg,png,jpg結(jié)尾,并且對大小寫不敏感;

4. titile必須唯一;

讓我們在Django中進行這些測試。由于ProductForm包含了模型校驗和表單校驗規(guī)則,使用ProductForm可以很容易的實現(xiàn)上述測試:

depot/depotapp/tests.py

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #/usr/bin/python #coding: utf8 """ This file demonstrates writing tests using the unittest module. These will pass when you run "manage.py test". Replace this with more appropriate tests for your application. """ from django.test import TestCase from forms import ProductForm class 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':1 } f =ProductForm(self.product) f.save() self.product['title']= 'My Another Book Title' #### title,description,price,image_url不能為空 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必須大于零 def test_price_positive(self): f =ProductForm(self.product) self.assertTrue(f.is_valid()) self.product['price']= 0 f =ProductForm(self.product) self.assertFalse(f.is_valid()) self.product['price']= -1 f =ProductForm(self.product) self.assertFalse(f.is_valid()) self.product['price']= 1 ####? image_url必須以jpg,png,jpg結(jié)尾,并且對大小寫不敏感; 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+endwith f =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+endwith f =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必須唯一 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'

然后運行 python manage.py test depotapp.ProductTest。如同預想的那樣,測試沒有通過:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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_endwiths self.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.055s ?? FAILED (failures=1) Destroying test database for alias 'default'...

因為我們之前并沒有考慮到image_url的圖片擴展名可能會大寫。修改ProductForm的相關(guān)部分如下:

?
1 2 3 4 5 def clean_image_url(self): url =self.cleaned_data['image_url'] ifnot endsWith(url.lower(),'.jpg', '.png','.gif'): raise forms.ValidationError('圖片格式必須為jpg、png或gif') return url

然后再運行測試:

?
1 $ python manage.pytest depotapp.ProductTest
?
1 2 3 4 5 6 7 Creating test database for alias 'default'... .... ---------------------------------------------------------------------- Ran 4 tests in 0.060s ?? OK Destroying test database for alias 'default'...

測試通過,并且通過單元測試,我們發(fā)現(xiàn)并解決了一個bug。


總結(jié)

以上是生活随笔為你收集整理的Django单元测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。