Flask --(31)Flask 中的單元測試
為什麼要測試?
(記得某次面試,面試官一直問我這個問題 …)
Web程式開發過程一般包括以下幾個階段:[需求分析,設計階段,實現階段,測試階段]。其中測試階段通過人工或自動來執行測試某個系統的功能。目的是檢驗其是否滿足需求,並得出特定的結果,以達到弄清楚預期結果和實際結果之間的差別的最終目的。
測試的分類
測試從軟體開發過程可以分為:
- 單元測試
對單獨的程式碼塊(例如函式)分別進行測試,以保證它們的正確性
- 整合測試
對大量的程式單元的協同工作情況做測試
- 系統測試
同時對整個系統的正確性進行檢查,而不是針對獨立的片段 在眾多的測試中,與程式開發人員最密切的就是單元測試,因為單元測試是由開發人員進行的,而其他測試都由專業的測試人員來完成。
什麼是單元測試
程式開發過程中,寫程式碼是為了實現需求。當我們的程式碼通過了編譯,只是說明它的語法正確,功能能否實現則不能保證。 因此,當我們的某些功能程式碼完成後,為了檢驗其是否滿足程式的需求。可以通過編寫測試程式碼,模擬程式執行的過程,檢驗功能程式碼是否符合預期。
單元測試就是開發者編寫一小段程式碼,檢驗目的碼的功能是否符合預期。通常情況下,單元測試主要面向一些功能單一的模組進行。
舉個例子:一部手機有許多零部件組成,在正式組裝一部手機前,手機內部的各個零部件,CPU、記憶體、電池、攝像頭等,都要進行測試,這就是單元測試。
在Web開發過程中,單元測試實際上就是一些“斷言”(assert)程式碼。
斷言就是判斷一個函式或物件的一個方法所產生的結果是否符合你期望的那個結果。 python中assert斷言是宣告布林值為真的判定,如果表示式為假會發生異常。單元測試中,一般使用assert來斷言結果。
斷言語句類似於:
if not expression:
raise AssertionError
AssertionError
常用的斷言方法:
assertEqual 如果兩個值相等,則pass assertNotEqual 如果兩個值不相等,則pass assertTrue 判斷bool值為True,則pass assertFalse 判斷bool值為False,則pass assertIsNone 不存在,則pass assertIsNotNone 存在,則pass
單元測試的基本寫法
首先,定義一個類,繼承自unittest.TestCase
import unittest
class TestClass(unitest.TestCase):
pass
其次,在測試類中,定義兩個測試方法
import unittest
class TestClass(unittest.TestCase):
#該方法會首先執行,方法名為固定寫法
def setUp(self):
pass
#該方法會在測試程式碼執行完後執行,方法名為固定寫法
def tearDown(self):
pass
最後,在測試類中,編寫測試程式碼
import unittest
class TestClass(unittest.TestCase):
#該方法會首先執行,相當於做測試前的準備工作
def setUp(self):
pass
#該方法會在測試程式碼執行完後執行,相當於做測試後的掃尾工作
def tearDown(self):
pass
#測試程式碼
def test_app_exists(self):
pass
資料庫測試:
#coding=utf-8
import unittest
from author_book import *
#自定義測試類,setUp方法和tearDown方法會分別在測試前後執行。以test_開頭的函式就是具體的測試程式碼。
class DatabaseTestCase(unittest.TestCase):
def setUp(self):
app.config['TESTING'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]/test0'
self.app = app
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
#測試程式碼
def test_append_data(self):
au = Author(name='itcast')
bk = Book(info='python')
db.session.add_all([au,bk])
db.session.commit()
author = Author.query.filter_by(name='itcast').first()
book = Book.query.filter_by(info='python').first()
#斷言資料存在
self.assertIsNotNone(author)
self.assertIsNotNone(book)