当存在大量测试脚本的时候,脚本的运行耗时就会变得很长,难免需要对脚本的运行时间进行分析,而要想提高自动化脚本的运行效率,最直接最有效的就是不断的去找出耗时最大的几个脚本,然后对其进行脚本性能优化提升,那么怎么找出耗时最大的N个脚本呢。
Pytest框架提供了这样的功能,即通过 –durations 参数即可对脚本的运行时间进行分析。编写如下10个测试脚本,每个测试脚本通过使用sleep模拟脚本耗时。
import time
def test_01():
print("in test01...")
time.sleep(1)
assert 1==1
def test_02():
print("in test02...")
time.sleep(2)
assert 1==1
def test_03():
print("in test03...")
time.sleep(3)
assert 1==1
def test_04():
print("in test04...")
time.sleep(4)
assert 1==1
def test_05():
print("in test05...")
time.sleep(5)
assert 1==1
def test_06():
print("in test06...")
time.sleep(6)
assert 1==1
def test_07():
print("in test07...")
time.sleep(7)
assert 1==1
def test_08():
print("in test08...")
time.sleep(8)
assert 1==1
def test_09():
print("in test09...")
time.sleep(9)
assert 1==1
def test_10():
print("in test10...")
time.sleep(10)
assert 1==1
当使用 pytest –durations=0 的时候,会将所有脚本的耗时打印出来,执行结果如下,在执行结果的slowest durations 部分显示了所有用例的执行耗时。
(demo--ip5ZZo0) D:\demo>pytest -s --durations=0
=================== test session starts ===================
platform win32 -- Python 3.7.9, pytest-7.1.3, pluggy-1.0.0
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\demo
plugins: forked-1.4.0, picked-0.4.6, random-order-1.0.4, repeat-0.9.1, xdist-2.5.0
collected 10 items
test_demo.py in test01...
.in test02...
.in test03...
.in test04...
.in test05...
.in test06...
.in test07...
.in test08...
.in test09...
.in test10...
.
==================== slowest durations ====================
10.01s call test_demo.py::test_10
9.02s call test_demo.py::test_09
8.01s call test_demo.py::test_08
7.01s call test_demo.py::test_07
6.02s call test_demo.py::test_06
5.01s call test_demo.py::test_05
4.01s call test_demo.py::test_04
3.00s call test_demo.py::test_03
2.00s call test_demo.py::test_02
1.00s call test_demo.py::test_01
(20 durations < 0.005s hidden. Use -vv to show these durations.)
=================== 10 passed in 57.40s ===================
(demo--ip5ZZo0) D:\demo>
此时比如用例过多,我们只想找出耗时最大的五个脚本,此时只需要使用 pytest –durations=5 即可,执行结果如下,可以看出此时只显示了耗时最大的五个测试脚本的耗时,如果在实际开发应用中,则此时直接去分析这五个脚本的耗时原因,然后对其进行优化即可。
(demo--ip5ZZo0) D:\demo>pytest --durations=5
=================== test session starts ===================
platform win32 -- Python 3.7.9, pytest-7.1.3, pluggy-1.0.0
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\demo
plugins: forked-1.4.0, picked-0.4.6, random-order-1.0.4, repeat-0.9.1, xdist-2.5.0
collected 10 items
test_demo.py .......... [100%]
=================== slowest 5 durations ===================
10.01s call test_demo.py::test_10
9.02s call test_demo.py::test_09
8.00s call test_demo.py::test_08
7.01s call test_demo.py::test_07
6.01s call test_demo.py::test_06
=================== 10 passed in 55.14s ===================
(demo--ip5ZZo0) D:\demo>
这里面有个注意点,就是当脚本耗时小于0.005秒时,在使用 –durations=0 的时候也是不会显示用例执行时间的,下面将脚本中的sleep语句全部删除,即如下:
def test_01():
print("in test01...")
assert 1==1
def test_02():
print("in test02...")
assert 1==1
def test_03():
print("in test03...")
assert 1==1
def test_04():
print("in test04...")
assert 1==1
def test_05():
print("in test05...")
assert 1==1
def test_06():
print("in test06...")
assert 1==1
def test_07():
print("in test07...")
assert 1==1
def test_08():
print("in test08...")
assert 1==1
def test_09():
print("in test09...")
assert 1==1
def test_10():
print("in test10...")
assert 1==1
这里使用 –durations 执行完成后,结果也不会显示用例的执行耗时。
(demo--ip5ZZo0) D:\demo>pytest --durations=0
=================== test session starts ===================
platform win32 -- Python 3.7.9, pytest-7.1.3, pluggy-1.0.0
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\demo
plugins: forked-1.4.0, picked-0.4.6, random-order-1.0.4, repeat-0.9.1, xdist-2.5.0
collected 10 items
test_demo.py .......... [100%]
==================== slowest durations ====================
(30 durations < 0.005s hidden. Use -vv to show these durations.)
=================== 10 passed in 2.19s ====================
(demo--ip5ZZo0) D:\demo>
在执行的最后也提示了用例耗时小于0.005秒,那么如果说在这种情况下还是要显示用例的耗时时间,则可以继续加上 -vv 参数即可,执行结果如下所示:这里虽然显示了,但是都显示了0.00秒。因此在一般情况下,当耗时小于0.005秒时,基本就可以认为忽略不计了。
(demo--ip5ZZo0) D:\demo>pytest --durations=0 -vv
=================== test session starts ===================
platform win32 -- Python 3.7.9, pytest-7.1.3, pluggy-1.0.0 -- C:\Users\hitre\.virtualenvs\demo--ip5ZZo0\Scripts\python.exe
cachedir: .pytest_cache
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\demo
plugins: forked-1.4.0, picked-0.4.6, random-order-1.0.4, repeat-0.9.1, xdist-2.5.0
collected 10 items
test_demo.py::test_01 PASSED [ 10%]
test_demo.py::test_02 PASSED [ 20%]
test_demo.py::test_03 PASSED [ 30%]
test_demo.py::test_04 PASSED [ 40%]
test_demo.py::test_05 PASSED [ 50%]
test_demo.py::test_06 PASSED [ 60%]
test_demo.py::test_07 PASSED [ 70%]
test_demo.py::test_08 PASSED [ 80%]
test_demo.py::test_09 PASSED [ 90%]
test_demo.py::test_10 PASSED [100%]
==================== slowest durations ====================
0.00s call test_demo.py::test_01
0.00s call test_demo.py::test_04
0.00s call test_demo.py::test_05
0.00s call test_demo.py::test_02
0.00s call test_demo.py::test_07
0.00s call test_demo.py::test_06
0.00s call test_demo.py::test_10
0.00s call test_demo.py::test_08
0.00s call test_demo.py::test_03
0.00s call test_demo.py::test_09
0.00s teardown test_demo.py::test_01
0.00s setup test_demo.py::test_01
0.00s teardown test_demo.py::test_05
0.00s setup test_demo.py::test_04
0.00s setup test_demo.py::test_02
0.00s setup test_demo.py::test_05
0.00s setup test_demo.py::test_07
0.00s teardown test_demo.py::test_04
0.00s teardown test_demo.py::test_08
0.00s teardown test_demo.py::test_02
0.00s teardown test_demo.py::test_03
0.00s setup test_demo.py::test_06
0.00s setup test_demo.py::test_09
0.00s teardown test_demo.py::test_09
0.00s setup test_demo.py::test_08
0.00s teardown test_demo.py::test_10
0.00s setup test_demo.py::test_03
0.00s teardown test_demo.py::test_07
0.00s teardown test_demo.py::test_06
0.00s setup test_demo.py::test_10
=================== 10 passed in 0.05s ====================
(demo--ip5ZZo0) D:\demo>
此外,还可以同时指定 –durations=0 和 –durations-min=6 显示运行时间超过6秒的脚本。
(demo--ip5ZZo0) D:\demo>pytest --durations=0 --durations-min=6
=================== test session starts ===================
platform win32 -- Python 3.7.9, pytest-7.1.3, pluggy-1.0.0
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\demo
plugins: forked-1.4.0, picked-0.4.6, random-order-1.0.4, repeat-0.9.1, xdist-2.5.0
collected 10 items
test_demo.py .......... [100%]
==================== slowest durations ====================
10.01s call test_demo.py::test_10
9.02s call test_demo.py::test_09
8.00s call test_demo.py::test_08
7.01s call test_demo.py::test_07
6.00s call test_demo.py::test_06
(25 durations < 6s hidden. Use -vv to show these durations.)
=================== 10 passed in 55.15s ===================
(demo--ip5ZZo0) D:\demo>