总述
在网上查看了很多coverage的教程,似乎多进程就只需要加一个 --parallel-mode参数,然而经过亲自尝试,似乎并没起什么作用。我的多进程是通过multiprocess 类实现的。coverage默认是支持thread的多线程覆盖的。
示例
这里写一个multiprocess的例子,并说明测试方法
先声明一个多进程类
在进程类里面声明两个子进程,A2文件
import multiprocessing as mp
from multiprocessing import Process,JoinableQueue
def job(q):
res = 1
q.put(res)
print("hello wrold")
def test(a,d):
if int(a) < int(d):
print('aaaa')
else:
print(int(a)+int(d))
def main():
test(1,2)
q = mp.Queue()
p1 = mp.Process(target=job,args=(q,))
p2 = mp.Process(target=job,args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
print(" the end")
可以看到,上面声明了p1,p2两个子进程,并且在job中将res加入到结果队列中。
声明测试类,B2文件:
import unittest
import sys
sys.path.append("../A/")
import A2
class TestA2(unittest.TestCase):
def test_job(self):
A2.main()
if __name__ == '__main__':
unittest.main()
然后在命令行中运行coverage run B2.py或者加上参数--parallel-mode,coverage run --parallel-mode B2.py
结果如下:
我们会发现在结果中并没有覆盖子进程代码,那么怎么办呢?我去查阅了coverage的文档,文档中有一个配置文件中,描述了一个名为concurrency的选项,选项中可以声明多进程的使用方式,默认为thread,在本例中我使用multiprocess实现。
文档地址:https://coverage.readthedocs.io/en/coverage-4.5.1a/config.html#config
新建配置文件:
那么我就需要新建一个配置文件,在我的B2.py也就是测试文件所在的目录下,新建一个文件名为setup.cfg,然后修改文件,格式样例如下:
# .coveragerc to control coverage.py
[run]
concurrency = multiprocessing #在这个地方指定你的多进程实现方式
[report]
# Regexes for lines to exclude from consideration
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain about missing debug-only code:
def __repr__
if self\.debug
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:
[html]
directory = coverage_html_report
然后保存配置文件,运行命令是加上--rcfile这个参数来指定配置文件路径,即可。如下:
coverage run --rcfile=setup.cfg B2.py
然后你会发现在B2.py,也就是测试文件所在的目录下,会多出很多以.coverage开头的文件:
这都是子进程产生的覆盖文件,我们需要把他们合并起来。运行命令:
coverage combine
可以看到这些覆盖文件合并成了一个.coverage文件,之后,就可以按照往常的coverage report -m,coverage html等命令查看覆盖率了,最后结果:
可以看到子进程已经覆盖。
最后的最后:
如果在某些情况实在不能用coverage进行整体覆盖,比如说多重进程的镶嵌使用,那么也不必要正面硬钢,我们可以直接运行多进程执行的函数呀。这样就可以保证子进程的覆盖率了。:)