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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 单元测试_Python 单元测试(unittest)

發布時間:2025/3/12 python 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 单元测试_Python 单元测试(unittest) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

測試目錄

項目的整體結構可以參考“軟件目錄開發規范”,這里單說測試目錄。一般都是在項目里單獨創建一個測試目錄,目錄名就是“tests”。關于目錄的位置,一種建議是,在項目名(假設項目名是Foo)的一級子目錄下創建二級子目錄 “Foo/foo/tests” 。但是這樣可能是因為用起來不方便,有很多是按下面的做法。不過下面的示例我還是用這個方法來創建測試目錄。還可以把測試目錄向上移一層,作為一級子目錄,直接創建在項目之下 “Foo/tests”。參考django、scrapy、flask都是這樣的做法。

測試函數

標題的意思是對函數(def)進行測試,相對于測試類(class)。學習測試,得有要測試的代碼。下面是一個簡單的函數,接收城市名和國家名,返回一個格式為“City, Country“這樣的字符串:

# UnitTest/unit_test/utils/city_functions.py

def get_city_info(city, country):

city_info = "%s, %s" % (city, country)

return city_info.title()

接下來就對上面的這個函數進行測試。

手動測試

現在來寫一個使用這個函數的程序:

# UnitTest/unit_test/test/cities.py

try:

from unit_test.utils.city_functions import get_city_info

except ModuleNotFoundError:

import os

import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from unit_test.utils.city_functions import get_city_info

print("Enter 'q' at any time to quit.")

while True:

city = input("city name: ")

if city == 'q':

break

country = input("country name: ")

if country == 'q':

break

fullname = get_city_info(city, country)

print("city info:", fullname)

然后運行的結果:

Enter 'q' at any time to quit.

city name: shanghai

country name: china

city info: Shanghai, China

city name: q

Process finished with exit code 0

上面這樣是手動測試,還是得有一種自動測試函數輸出的高效方式。如果能夠對get_fullname()進行自動測試,就能始終確信,給這個函數提供測試過的姓名后,它能返回正確的結果。尤其是在對函數進行修改的前后。模塊導入路徑的問題PyCharm會自動把項目目錄加到環境變量里去,在PyCharm里執行都沒問題。但是如果不用PyCharm而是單獨運行,這個目錄結構應該會有點問題,會找不到需要測試的函數。簡單點就是把測試用例和被測試的函數放到同一個目錄里,然后改一下 from import 就可以正常運行了。或者自己手動添加環境變量,就像例子里那樣。

單元測試-unittest

Python標準庫中的模塊unittest提供了代碼測試工具。

創建測試用例為函數編寫測試用例,可先導入模塊unittest以及要測試的函數,再創建一個繼承unittest.TestCase的類,并編寫一系列方法對函數行為的不同方面進行測試。下面是一個只包含一個方法的測試用例:

# UnitTest/unit_test/test/test_city_functions.py

import unittest

try:

from unit_test.utils.city_functions import get_city_info

except ModuleNotFoundError:

import sys

sys.path.append('../..')

from unit_test.utils.city_functions import get_city_info

class CitiesTestCase(unittest.TestCase):

"""測試city_functions.py"""

def test_city_country(self):

city_info = get_city_info('shanghai', 'china')

self.assertEqual(city_info, 'Shanghai, China')

def test_New_York(self):

city_info = get_city_info('new york', 'America')

self.assertEqual(city_info, 'New York, America')

if __name__ == '__main__':

unittest.main()

命名的規則和建議:

類名,可以任意起名,但是最好看起來和測試有關并包含Test字樣。

方法名,名字必須以“test_”開頭,所有以“test_”開頭的方法,都會自動運行

在測試的方法的最后,使用了unittest類最有用的功能之一:一個斷言方法。來檢查得到的結果和我們預期的結果是否一致。輸出的效果最后一行?unittest.main()?讓Python運行這個文件中的測試。執行程序后得到如下的輸出:

.

----------------------------------------------------------------------

Ran 1 test in 0.000s

OK

運行測試用例時,每完成一個單元測試,Python都打印一個字符:

測試通過時打印一個句點;

測試引發錯誤時打印一個E;

測試導致斷言失敗時打印一個F。

這就是你運行測試用例時,在輸出的第一行中看到的句點和字符數量各不相同的原因。如果測試用例包含很多單元測試,需要運行很長時間,就可通過觀察這些結果來獲悉有多少個測試通過了。

PyCharm對單元測試做了自己的優化,輸出看不到上面的點,而是有更加漂亮的展示方式。

測試不通過

現在看下測試不通過的效果。這里不修改測試用例,而是對get_city_info()函數做一個update,現在還要顯示城市的人口數量:

def get_city_info(city, country, population):

city_info = "%s, %s - 人口: %d" % (city, country, population)

return city_info.title()

這次再執行測試用例,輸出如下:

E

======================================================================

ERROR: test_city_country (__main__.CitiesTestCase)

----------------------------------------------------------------------

Traceback (most recent call last):

File "test_city_functions.py", line 17, in test_city_country

city_info = get_city_info('shanghai', 'china')

TypeError: get_city_info() missing 1 required positional argument: 'population'

----------------------------------------------------------------------

Ran 1 test in 0.001s

FAILED (errors=1)

這里看的是E而不是之前的點,表示有一個錯誤。

測試未通過的處理這里不要去修改之前的測試用例。假設update之前的函數已經在項目內使用起來了,現在測試不通過,表示之前調用這個函數的代碼都有問題。如果不想改項目里其它的代碼,這里先嘗試修改get_city_info()函數,讓它能夠通過測試,也可以加上新的功能:

# UnitTest/unit_test/utils/city_functions.py

def get_city_info(city, country, population=None):

if population:

city_info = "%s, %s - 人口: %d" % (city, country, population)

else:

city_info = "%s, %s" % (city, country)

return city_info.title()

現在的各個版本的update才是兼容舊版本的代碼,這次測試用例就可以通過了。

添加新測試之前的測試用例只能驗證就的功能,現在添加了新功能,是否沒問題,還得通過測試來進行驗證:

# UnitTest/unit_test/test/test_city_functions.py

class CitiesTestCase(unittest.TestCase):

"""測試city_functions.py"""

def test_city_country(self):

city_info = get_city_info('shanghai', 'china')

self.assertEqual(city_info, 'Shanghai, China')

def test_New_York_population(self):

city_info = get_city_info('new york', 'America', 8537673)

self.assertEqual(city_info, 'New York, America - 人口: 8537673')

現在新功能的測試用例也用了,并且2個測試都能通過。以后如果還需要對get_city_info()函數進行修改,只要再運行測試就可以知道新的代碼是否會對原有的項目有影響。

斷言方法

模塊在unittest.TestCase類中提供了很多斷言方法,之前已經用一個了。下面是6個常用的斷言方法:

assertEqual(a, b) : 核實a == b

assertNotEqual(a, b) : 核實a != b

assertTrue(x) : 核實x為True

assertFalse(x) : 核實x為False

assertIn(item, list) : 核實item在list中

assertNotIn(item, list) : 核實item不在list中

你只能在繼承unittest.TestCase的類中使用這些方法。

測試類

前面的內容只是對函數進行測試。很多時候都會用到類,因為還需要能夠證明類也可以正常的運行。類的測試與函數的測試相似,其中大部分工作都是測試類中方法的行為,但存在一些不同之處。

準備要測試的類

先編寫一個類來進行測試,這個類里存儲了一個課程名,以及學習該課程的學員:

# UnitTest/unit_test/course.py

class CourseManage(object):

def __init__(self, course):

self.course = course

self.students = []

def show_course(self):

print("課程:", self.course)

def add_student(self, name):

self.students.append(name)

def show_students(self):

print("所有學員:")

for student in self.students:

print('-', student)

為證明CourseManage類工作正常,再編寫一個使用它的程序:

from unit_test.course import CourseManage

course = CourseManage("Python")

course.show_course()

print("準備錄入學員...")

print("Enter 'q' at any time to quit.

")

while True:

resp = input("Student's Name: ")

if resp == 'q':

break

if resp:

course.add_student(resp.title())

print("

錄入完畢...")

course.show_students()

這段程序定義了一門課程,并使用課程名創建了一個CourseManage對象。接下來主要就是調用對象的add_student()方法來錄入學員名字。輸入完畢后,按q能退出。最后會打印所有的學員。所有的輸入和輸出如下:

課程: Python

準備錄入學員...

Enter 'q' at any time to quit.

Student's Name: oliver queen

Student's Name: barry allen

Student's Name: kara

Student's Name: sara lance

Student's Name: q

錄入完畢...

所有學員:

- Oliver Queen

- Barry Allen

- Kara

- Sara Lance

Process finished with exit code 0

編寫類的測試用例

下面來編寫一個測試,對CourseManage類的行為的一個方面進行驗證。如果用戶輸入了某個學員的名字,這個名字可以被存儲在self.students的列表里。所以,需要做的是在學員被錄入后,使用assertIn()這個斷言方法:

# UnitTest/unit_test/test/test_course.py

import unittest

from unit_test.course import CourseManage

class TestCourseManage(unittest.TestCase):

def test_add_student(self):

course = CourseManage("Python")

name = 'snart'

course.add_student(name.title())

self.assertIn('Snart', course.students)

if __name__ == '__main__':

unittest.main()

上面的方法只驗證了錄入一個學員的情況,而大多數情況下都是有很多學員的。所以,還要添加一個方法,驗證錄入多個學員是否正常:

class TestCourseManage(unittest.TestCase):

def test_add_student(self):

course = CourseManage("Python")

name = 'snart'

course.add_student(name.title())

self.assertIn('Snart', course.students)

def test_add_students(self):

course = CourseManage("Python")

name_list = ['oliver queen', 'barry allen', 'kara', 'sara lance']

for name in name_list:

course.add_student(name.title())

for name in name_list:

self.assertIn(name.title(), course.students)

setUp() 方法

在上面的例子里,每個測試方法中都創建了一個實例。但是還有一種需求是,我希望只創建一個實例,但是要在多個方法里對這個實例進行操作來反復驗證。在unittest.TestCase類包含方法setUp(),就可以只實例化一次,并可以在每個測試方法中使用。如果在TestCase類中包含了方法setUp(),Python會先運行它,再運行各個以test_打頭的方法。簡單點說,setUp()方法就是在父類里預留的一個鉤子,會在其他測試方法運行前先運行:

import unittest

from unit_test.course import CourseManage

class TestCourseManage(unittest.TestCase):

def setUp(self):

self.course = CourseManage("Python")

self.name_list = ['oliver queen', 'barry allen', 'kara', 'sara lance']

def test_add_student(self):

name = 'snart'

self.course.add_student(name.title())

self.assertIn('Snart', self.course.students)

def test_add_students(self):

for name in self.name_list:

self.course.add_student(name.title())

for name in self.name_list:

self.assertIn(name.title(), self.course.students)

if __name__ == '__main__':

unittest.main()

測試自己編寫的類時,使用setUp()方法會讓測試方法編寫起來更容易,下面是建議的做法:在setUp()方法中創建一系列實例并設置它們的屬性,再在測試方法中直接使用這些實例。相比于在每個測試方法中都創建實例并設置其屬性,這要容易得多。

小結

如果你在項目中包含了初步測試,其他程序員將更敬佩你,他們將能夠更得心應手地嘗試使用你編寫的代碼,也更愿意與你合作開發項目。如果你要跟其他程序員開發的項目共享代碼,就必須證明你編寫的代碼通過了既有測試,通常還需要為你添加的新行為編寫測試。請通過多開展測試來熟悉代碼測試過程。對于自己編寫的函數和類,請編寫針對其重要行為的測試,但在項目早期,不要試圖去編寫全覆蓋的測試用例,除非有充分的理由這樣做。

pytest

這篇講的是Python內置的單元測試模塊。作為初學者先用著熟悉起來就很不錯了。pytest是Python最流程的單測框架之一。具體可以上GitHub參考下那些開源項目的單元測試,很多用的是這個。

文章來源:https://blog.51cto.com/steed/2316436

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩v欧美 | 痴女扩张宫交脱垂重口小说 | 日韩欧美国产亚洲 | 欧美日韩久久精品 | 国产一级免费看 | 亚洲精品国产成人 | 国产精品分类 | 国产日韩欧美不卡 | 欧美啪啪网 | 污污视频网站 | 96免费视频 | 少妇高潮久久久久久潘金莲 | av大全在线观看 | 成人精品免费看 | 精品在线你懂的 | 97公开视频 | 国产人人射 | 亚洲成a | 欧美在线观看不卡 | 国产精品人妖 | 美女毛毛片 | 少妇一级淫片免费观看 | 亚洲在线观看免费视频 | 国产成a人亚洲精品 | 香蕉av一区二区三区 | 国产91精品久久久久久久网曝门 | 日韩中文字幕在线播放 | 欧美日韩精品一区二区三区 | 成人动漫一区二区三区 | 中文字幕有码在线播放 | av av片在线看 | 日日爱夜夜操 | 夜夜看 | 亚洲一级片在线观看 | 天天爱天天做天天爽 | 91三级视频 | 黄色一级黄色片 | 91免费看片网站 | 亚洲国产精品第一页 | 毛片一区二区 | 岛国av网址 | 欧美激情图区 | re久久| 国产一级片在线播放 | 亚洲熟妇av一区二区三区 | 日韩综合中文字幕 | 国产精品国产精品国产专区 | 欧美日韩1区| 亚洲自拍图片 | 色婷婷免费视频 | 超碰夫妻 | wwwjizzzcom| 永久在线| 特黄视频在线观看 | 午夜草逼 | 噜噜噜av| 亚洲成人自拍偷拍 | 精品人妻人人做人人爽夜夜爽 | 国产精品成人久久久 | 国产美女在线观看 | 中文字幕在线观看第一页 | 国产又色又爽无遮挡免费 | av网在线观看| 午夜精品一区二区三区在线 | 国产精品无码久久久久成人app | 黄色三级免费 | 黄片毛片在线 | 三年中国片在线高清观看 | 亚洲乱熟 | 99精品乱码国产在线观看 | 黄色特级大片 | 麻豆精品a∨在线观看 | 欧美成人午夜视频 | 免费观看视频在线观看 | 中文日韩av | 国产女主播一区二区 | 啪在线视频 | 国产乡下妇女做爰视频 | 人人草人人爽 | 神马老子午夜 | 先锋影音制服丝袜 | 亚洲日本精品 | 91伊人久久 | 久久婷婷五月综合 | 色婷婷激情综合 | 久久国产网站 | 色干综合 | 亚洲欧美天堂网 | 久久精品欧美视频 | 久久综合综合 | 亚洲第一网址 | 在线观看免费福利 | 亚洲热影院 | 日日鲁鲁鲁夜夜爽爽狠狠视频97 | 欧美视频 | 91精品啪 | 成人激情视频在线观看 | 羞羞涩涩视频 | 精品国产aⅴ一区二区三区东京热 |