Unittest
1. testcase add to suite
python
# test_case.py
import unittest
class TestString(unittest.TestCase):
def test_1(self):
print('test_1')
def test_2(self):
print('test_2')
py
# test_suite1.py
import unittest
from test_case import TestString
suite = unittest.TestSuite()
suite.addTest(TestString('test_1'))
suite.addTest(TestString('test_2'))
runner = unittest.TextTestRunner()
runner.run(suite)
py
# test_suite2.py
import unittest
from test_case import TestString
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestString))
runner = unittest.TextTestRunner()
runner.run(suite)
py
# test_suite3.py
import unittest
import test_case
suite = unittest.TestSuite()
loader = unittest.TestLoader()
suite.addTests(loader.loadTestsFromModule(test_case))
runner = unittest.TextTestRunner()
runner.run(suite)
py
# test_suite4.py
import unittest
from test_case import TestString
suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestString)
runner.run(suite)
2. 命令行参数
bash
# 显示帮助信息并退出
-h, --help
# 增加输出的详细程度
-v, --verbose
# 减少输出的详细程度
-q, --quiet
# 在第一次失败后停止测试运行
-f, --failfast
# 捕获 KeyboardInterrupt 并显示故障信息
-c, --catch
# 将 stdout 和 stderr 缓存,只有测试失败时才显示
-b, --buffer
# 只运行匹配表达式的测试
-k
# 指定要开始发现测试的目录(默认是当前目录)
-s, --start-directory
指定文件名模式(默认是 test*.py)
-p, --pattern
# 指定顶层目录,以便于测试发现
-t, --top-level-directory
3. 跳过测试和预期失败
py
import unittest
class MyTestCase(unittest.TestCase):
# @unittest.skip 装饰器来跳过整个测试方法
@unittest.skip("skip")
def test_1(self):
self.assertEqual(1, 1)
# @unittest.skipIf 是当条件为真时跳过测试
@unittest.skipIf(1 == 1, "skipIf")
def test_2(self):
self.assertEqual(1, 1)
# @unittest.skipUnless 是当条件为假时跳过测试
@unittest.skipUnless(1 > 1, "skipUnless")
def test_3(self):
self.assertEqual(2, 2)
# @unittest.expectedFailure 装饰器标记预期失败的测试。如果测试失败,不会计入失败计数
@unittest.expectedFailure
def test_4(self):
self.assertEqual(1, 2)
4. 断言
方法 | 检查 |
---|---|
assertEqual(a, b) | a=b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
5. 日志配置
py
# 配置日志记录
logging.basicConfig(
level=logging.DEBUG, # 日志级别
format='%(asctime)s %(levelname)s %(message)s', # 日志格式
datefmt='%Y-%m-%d %H:%M:%S', # 日期格式
filename='test_log.log', # 日志文件名
filemode='w' # 文件写入模式
)
6. 输出报告
py
pip install html-testRunner
py
import unittest
from test_case import TestStringMethods
import HtmlTestRunner
suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestStringMethods)
# runner = unittest.TextTestRunner()
# # 运行测试并生成文本报告
# with open('test_report.txt', 'w') as f:
# runner = unittest.TextTestRunner(stream=f, verbosity=2)
# runner.run(suite)
# 运行测试并生成 HTML 报告
runner = HtmlTestRunner.HTMLTestRunner(
output='test_reports', # 报告输出目录
report_name='TestReport', # 报告文件名
combine_reports=True, # 合并报告
descriptions=True, # 是否包含测试用例描述
verbosity=2 # 测试输出详细程度
)
runner.run(suite)
7. 缓存 session 数据
INFO
- 文件系统来缓存 session 数据
- SQLite 来缓存 session 数据
公共部分
py
# test_user.py
import unittest
from session_manager import load_cached_session, login, save_session_to_cache
class TestUser(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.session = load_cached_session()
if cls.session is None:
cls.session = login()
save_session_to_cache(cls.session)
def test_user_account(self):
url = 'http://localhost:3000/user/account'
response = self.session.get(url)
def test_user_status(self):
url = 'http://localhost:3000/login/status'
response = self.session.get(url)
def test_user_level(self):
url = 'http://localhost:3000/user/level'
response = self.session.get(url)
if __name__ == '__main__':
unittest.main()
py
# test_playlist.py
import unittest
from session_manager import load_cached_session, login, save_session_to_cache
class TestPlaylist(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.session = load_cached_session()
if cls.session is None:
cls.session = login()
save_session_to_cache(cls.session)
def test_playlist_catlist(self):
url = 'http://localhost:3000/playlist/catlist'
response = self.session.post(url)
def test_playlist_hot(self):
url = 'http://localhost:3000/playlist/hot'
response = self.session.post(url)
if __name__ == '__main__':
unittest.main()
py
# suite.py
import os
import unittest
import HtmlTestRunner
from test_playlist import TestPlaylist
from test_user import TestUser
# 获取当前文件所在目录的绝对路径
current_dir = os.path.dirname(__file__)
# 创建测试套件
suite = unittest.TestSuite()
suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(TestUser))
suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(TestPlaylist))
if __name__ == '__main__':
runner = HtmlTestRunner.HTMLTestRunner(
output=os.path.abspath(os.path.join(current_dir, '..', 'report')),
# report_name='TestReport',
report_name='CombinedTestReport',
descriptions=True,
combine_reports=True, # 合并报告
verbosity=2
)
runner.run(suite)
py
# session_manager.py
import json
import os
import unittest
import requests
CACHE_FILE = '../session_cache.json'
def login():
session = requests.Session()
url = 'http://localhost:3000/login/cellphone'
params = {
'phone': '15000840699',
'password': '**********'
}
response = session.get(url, params=params)
if response.status_code == 200:
return session
else:
raise Exception("Login failed")
def load_cached_session():
if os.path.exists(CACHE_FILE):
with open(CACHE_FILE, 'r') as f:
session_data = json.load(f)
session = requests.Session()
session.cookies.update(session_data)
return session
return None
def save_session_to_cache(session):
with open(CACHE_FILE, 'w') as f:
json.dump(session.cookies.get_dict(), f)
if __name__ == '__main__':
unittest.main()
py
# session_manager.py
import json
import os
import sqlite3
import unittest
import requests
CACHE_DB = '../session_cache.db'
def login():
session = requests.Session()
url = 'http://localhost:3000/login/cellphone'
params = {
'phone': '15000840699',
'password': '*********'
}
response = session.get(url, params=params)
if response.status_code == 200:
return session
else:
raise Exception("Login failed")
def load_cached_session():
if os.path.exists(CACHE_DB):
conn = sqlite3.connect(CACHE_DB)
cursor = conn.cursor()
cursor.execute("SELECT cookies FROM session_cache WHERE id = 1")
result = cursor.fetchone()
conn.close()
if result:
session_data = json.loads(result[0])
session = requests.Session()
session.cookies.update(session_data)
return session
return None
def save_session_to_cache(session):
conn = sqlite3.connect(CACHE_DB)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS session_cache
(id INTEGER PRIMARY KEY, cookies TEXT)''')
cookies = json.dumps(session.cookies.get_dict())
cursor.execute("REPLACE INTO session_cache (id, cookies) VALUES (1, ?)", (cookies,))
conn.commit()
conn.close()
if __name__ == '__main__':
unittest.main()