快速开始
基本规范
seldom
继承unittest
单元测试框架,所以他的编写规范与unittest基本保持一致。
# test_sample.py
import seldom
class YouTest(seldom.TestCase):
def test_case(self):
"""a simple test case """
self.assertEqual(1+1, 2)
if __name__ == '__main__':
seldom.main()
基本规范:
- 创建测试类
YouTest
并继承seldom.TestCase
类。 - 创建测试方法
test_case
, 必须以test
开头。 seldom.mian()
是框架运行的入口方法,接下来详细介绍。
main()
方法
main()
方法是seldom运行测试的入口, 它提供了一些最基本也是最重要的配置。
import seldom
# ...
if __name__ == '__main__':
seldom.main(path="./",
case="test_file.MyClassTest.test_case",
browser="chrome",
base_url=None,
debug=False,
timeout=10,
app_server=None,
app_info=None,
report=None,
title="百度测试用例",
tester="虫师",
description="测试环境:chrome",
rerun=0,
language="en",
whitelist=[],
blacklist=[],
open=True,
extensions=None,
failfast=False
)
参数说明
- path : 指定测试目录或文件, 与
case
参数互斥。seldom > 3.7.0 支持 list 传多个目录或文件
。 - case : 指定测试用例, 与
path
参数互斥。 - browser : 指定浏览器("chrome"、"firefox" 等), Web测试。
- base_url : 设置全局的基本URL, HTTP测试。
- app_info : app 启动信息,参考
desired_capabilities
配置, app测试。 - app_server : appium server 启动地址(默认 http://127.0.0.1:4723), app测试。
- report : 自定义测试报告的名称,默认格式为
2020_04_04_11_55_20_result.html
。 - title : 指定测试报告标题。
- tester : 指定测试人员, 默认
Anonymous
。 - description : 指定测试报告描述。
- debug : debug模式,设置为True不生成测试HTML测试,默认为
False
。 - rerun : 设置失败重新运行次数,默认为
0
。 - language : 设置HTML报告中英文,默认
en
, 中文zh-CN
。 - timeout : 设置超时时间,默认
10
秒。 - whitelist : 用例标签(label)设置白名单。
- blacklist : 用例标签(label)设置黑名单。
- open : 是否使用浏览器自动打开测试报告,默认
True
。 - extensions: 加载扩展,appium使用。
- failfast: 当执行到失败的用例时,停止执行,仅在
debug=True
时有效。
confrun.py
配置文件
seldom 3.1.0 提供过了
confrun.py
用于配置运行环境。 配置函数与seldom.main()
的参数一致。
在这个文件中可以定义运行相关的钩子函数。
"""
seldom confrun.py hooks function
"""
from seldom.appium_lab.android import UiAutomator2Options
def start_run():
"""
Test the hook function before running
"""
...
def end_run():
"""
Test the hook function after running
"""
...
def browser():
"""
Web UI test:
browser: gc(google chrome)/ff(firefox)/edge/ie/safari
"""
return "gc"
def base_url():
"""
http test
api base url
"""
return "http://httpbin.org"
def app_info():
"""
app UI test
appium app config
"""
capabilities = {
"automationName": "UiAutomator2",
"platformName": "Android",
"appPackage": "com.meizu.flyme.flymebbs",
"appActivity": "com.meizu.myplus.ui.splash.SplashActivity",
"noReset": True,
}
options = UiAutomator2Options().load_capabilities(capabilities)
return options
def app_server():
"""
app UI test
appium server/desktop address
"""
return "http://127.0.0.1:4723"
def debug():
"""
debug mod
"""
return False
def rerun():
"""
error/failure rerun times
"""
return 0
def report():
"""
setting report path
Used:
return "d://mypro/result.html"
return "d://mypro/result.xml"
"""
return None
def timeout():
"""
setting timeout
"""
return 10
def title():
"""
setting report title
"""
return "seldom test report"
def tester():
"""
setting report tester
"""
return "bugmaster"
def description():
"""
setting report description
"""
return ["windows", "jenkins"]
def language():
"""
setting report language
return "en"
return "zh-CN"
"""
return "en"
def whitelist():
"""test label white list"""
return []
def blacklist():
"""test label black list"""
return []
def mock_url():
"""
Replace the fixed url with the mock url
:return:
"""
config = {
"http://httpbin.org/get": "http://127.0.0.1:8000/api/data",
}
return config
def failfast():
"""Use case exe failed to stop, only support debug=True"""
return False
以上配置根据需求自动化项目类型配置,相互可能冲突的钩子函数:
- Web UI测试:
browser()
- http 接口测试:
base_url()
- app UI测试:
app_info()
,app_server()
参数表格:
seldom.main() (参数) | confrun.py (函数) | 类型 | 说明 |
---|---|---|---|
path | N/A | 通用 | 指定测试目录或文件, 与case 参数互斥。 |
case | N/A | 通用 | 指定测试用例, 与path 参数互斥。 |
browser | browser() | Web | 指定web测试运行的浏览器。 |
base_url | base_url() | HTTP | 指定HTTP接口测试的基本URL。 |
app_info | app_info() | App | app 启动信息,参考appium desired_capabilities 配置, app测试。 |
app_server | app_server() | App | appium server 启动地址(默认 http://127.0.0.1:4723), app测试。 |
report | report() | 通用 | 自定义测试报告的名称,例如result.html/result.xml 。 |
title | title() | 通用 | 指定HTML报告标题。 |
tester | tester() | 通用 | 指定HTML报告测试人员。 |
description | description() | 通用 | 指定HTML报告描述。 |
language | language() | 通用 | 设置HTML报告中英文,默认en , 中文zh-CN 。 |
debug | debug() | 通用 | debug模式,设置为True不生成测试HTML测试,默认为False 。 |
rerun | rerun() | 通用 | 设置失败重新运行次数。 |
timeout | timeout() | 通用 | 设置自动化全局超时时间,默认10 秒。作用于元素定位、断言等。 |
whitelist | whitelist() | 通用 | 用例标签(label)设置白名单。 |
blacklist | blacklist() | 通用 | 用例标签(label)设置黑名单。 |
open | N/A | 通用 | 是否使用浏览器自动打开测试报告,默认True 。 |
N/A | mock_url() | HTTP | 定义mock URL 映射。 |
运行测试
seldom 的运行有三种方式:
main()
方法:在.py
文件中使用seldom.main()
方法。seldom
命令:通过sedom
命令指定要运行的目录&文件&类&方法。pycharm
右键执行:这种方式无法读取到配置,有严重缺陷。
强烈建议使用前两种!!
1. main()
方法运行测试
- 目录结构
mypro/
├── test_dir/
│ ├── __init__.py
│ ├── test_sample.py
└── run.py # 运行配置文件
创建 test_sample.py
文件,在测试文件中使用main()
方法,如下:
# test_sample.py
import seldom
from seldom import data
class YouTest(seldom.TestCase):
def test_case(self):
"""a simple test case """
self.assertEqual(1 + 1, 2)
@data([
("case1", "seldom"),
("case2", "XTestRunner"),
])
def test_ddt(self, name, search):
""" ddt case """
print(f"name: {name}, search_key: {search}")
if __name__ == '__main__':
# 运行当前文件中的用例
seldom.main() # 默认运行当前文件中所有用例
seldom.main(case="test_sample") # 指定当前文件
seldom.main(case="test_sample.YouTest") # 指定测试类
seldom.main(case="test_sample.YouTest.test_case") # 指定测试用例
# 使用参数化的用例
seldom.main(case="test_sample.YouTest.test_ddt") # 错误用法
seldom.main(case="test_sample.YouTest.test_ddt_0") # 正确用法,0表示第一条数据用例
创建 run.py
文件,用于全局的指定要运行的用例。
import seldom
if __name__ == '__main__':
# 指定运行其他目录&文件
seldom.main(path="./") # 指定当前文件所在目录下面的用例。
seldom.main(path="./test_dir/") # 指定当前目录下面的test_dir/ 目录下面的用例。
seldom.main(path="./test_dir/test_sample.py") # 指定测试文件中的用例。
seldom.main(path="D:/seldom_sample/test_dir/test_sample.py") # 指定文件的绝对路径。
seldom.main()
提供哪些参数,请参考前面的文档。
- 运行测试文件
> cd mypro/ # 进入项目根目录
> python ./test_dir/test_sample.py # 运行指定测试文件
> python run.py # 运行run.py文件
2. seldom命令执行
- 目录结构
mypro/
├── test_dir/
│ ├── __init__.py
│ ├── test_sample.py
└── confrun.py # 运行配置文件
seldom -p
命令指定目录和文件。
seldom -m
命令可以提供更细粒度的运行。
> cd mypro/ # 进入项目根目录
> seldom -p test_dir # 运行目录
> seldom -p test_dir/test_sample.py # 运行文件
> seldom -m test_dir.test_sample # 运行文件
> seldom -m test_dir.test_sample.YouTest # 运行 SampleTest 测试类
> seldom -m test_dir.test_sample.YouTest.test_case # 运行 test_case 测试方法
运行相关的配置,可以在confrun.py
文件中配置。
3. 在pyCharm中运行测试
强烈不建议这种方式,除非你的测试用例没有任何依赖。
步骤一:配置测试用例通过 unittest 运行。
步骤二:在文件中选择测试类或用例执行。
警告:运行用例打开的浏览器,需要手动关闭, seldom不做用例关闭操作。
失败重跑
Seldom支持错误
&失败
重跑。
# test_sample.py
import seldom
class YouTest(seldom.TestCase):
def test_error(self):
"""error case"""
self.assertEqual(a, 2)
def test_fail(self):
"""fail case """
self.assertEqual(1 + 1, 3)
if __name__ == '__main__':
seldom.main(rerun=3)
参数说明:
- rerun: 指定重跑的次数,默认为
0
。
运行日志:
> python test_sample.py
__ __
________ / /___/ /___ ____ ____
/ ___/ _ \/ / __ / __ \/ __ ` ___/
(__ ) __/ / /_/ / /_/ / / / / / /
/____/\___/_/\__,_/\____/_/ /_/ /_/ v3.x.x
-----------------------------------------
@itest.info
XTestRunner Running tests...
----------------------------------------------------------------------
ERetesting... test_error (test_sample.YouTest)..1
ERetesting... test_error (test_sample.YouTest)..2
ERetesting... test_error (test_sample.YouTest)..3
EFRetesting... test_fail (test_sample.YouTest)..1
FRetesting... test_fail (test_sample.YouTest)..2
FRetesting... test_fail (test_sample.YouTest)..3
Generating HTML reports...
F2022-07-12 00:22:52 log.py | SUCCESS | generated html file: file:///D:\github\seldom\reports\2022_07_12_00_22_51_result.html
2022-07-12 00:22:52 log.py | SUCCESS | generated log file: file:///D:\github\seldom\reports\seldom_log.log
测试报告
seldom 默认生成HTML测试报告,在运行测试文件下自动创建reports
目录。
- 运行测试用例前
mypro/
└── test_sample.py
- 运行测试用例后
mypro/
├── reports/
│ ├── 2020_01_01_11_20_33_result.html
│ ├── seldom_log.log
└── test_sample.py
通过浏览器打开 2020_01_01_11_20_33_result.html
测试报告,查看测试结果。
debug模式
如果不想每次运行都生成HTML报告,可以打开debug
模式。
import seldom
seldom.main(debug=True)
定义测试报告
import seldom
seldom.main(report="./report.html",
title="百度测试用例",
tester="虫师",
description="测试环境:windows 10/ chrome")
- report: 配置报告名称和路径。
- title: 自定义报告的标题。
- tester: 指定自动化测试工程师名字。
- description: 添加报告信息,支持列表, 例如:["OS: windows","Browser: chrome"]。
XML测试报告
如果需要生成XML格式的报告,只需要修改报告的后缀名为.xml
即可。
import seldom
seldom.main(report="report.xml")
多线程运行
多线程无疑可以缩短用例的运行时间,一般由两种方式实现。
- 设置线程数,交由框架去分配用例,或按照测试用例、测试类、测试模块分配给线程执行。
- 优点:简单,例如 pytest-xdist ,只需要指定
线程数
即可。 - 缺点:无法控制用例的拆分粒度,如果在设计用例时,不同的用例有依赖,刚好被分到的不同的线程,那么必定导致用例失败。
- 自己分好线程,分别调用框架执行。
- 优点:手动划分线程,可以按照目录、文件、甚至测试类或方法 拆分线程。
- 缺点:首先会比较麻烦,而且多个线程的执行结果无法很好的合并到一起。
seldom 推荐第二种方法,把线程的划分方式交给用户,无疑是更灵活的方法。至于报告的合并统计就每有什么好办法了。
- 用例维度使用多线程。
import seldom
from seldom.extend_lib import threads
class MyTest(seldom.TestCase):
def test_baidu(self):
self.open("https://www.baidu.com")
self.sleep(3)
def test_bing(self):
self.open("https://www.bing.com")
self.sleep(4)
@threads(2) # !!!核心!!!! 设置线程数
def run_case(case: str, browser: str):
"""
根据传入的case执行用例
"""
seldom.main(case=case, browser=browser, debug=True)
if __name__ == "__main__":
# 将两条用例拆分,分别用不同的浏览器执行
cases = {
"test_thread_case.MyTest.test_baidu": "chrome",
"test_thread_case.MyTest.test_bing": "edge"
}
for key, value in cases.items():
run_case(key, value)
- 目录或文件维度使用多线程。
import seldom
from seldom.extend_lib import threads
@threads(3) # !!!核心!!!! 设置线程数
def run_case(path: str):
"""
根据传入的path执行用例
"""
seldom.main(path=path, debug=True)
if __name__ == "__main__":
# 定义3个测试文件,分别丢给3个线程执行。
paths = [
"./test_dir/more_case/test_case1.py",
"./test_dir/more_case/test_case2.py",
"./test_dir/more_case/test_case3.py"
]
for p in paths:
run_case(p)