Python 冻结可执行文件的覆盖率
有没有办法对pyinstaller构建的可执行文件运行覆盖率?我试着像运行python脚本一样运行它,但它不喜欢将可执行文件作为输入(我真的不希望它工作),我怀疑答案是否定的,没有简单的方法可以对构建的可执行文件运行覆盖。。。。(这是在windows.exe上)Python 冻结可执行文件的覆盖率,python,windows,pyinstaller,coverage.py,Python,Windows,Pyinstaller,Coverage.py,有没有办法对pyinstaller构建的可执行文件运行覆盖率?我试着像运行python脚本一样运行它,但它不喜欢将可执行文件作为输入(我真的不希望它工作),我怀疑答案是否定的,没有简单的方法可以对构建的可执行文件运行覆盖。。。。(这是在windows.exe上) 我使用的覆盖率软件包只是普通的覆盖率软件包,您可以从nedbatchelder.com()获得“easy_install coverage”(这不是一个完整的答案,但我已经找到了答案 从我对pyinstaller工作原理的理解来看,二进
我使用的覆盖率软件包只是普通的覆盖率软件包,您可以从nedbatchelder.com()获得“easy_install coverage”(这不是一个完整的答案,但我已经找到了答案 从我对pyinstaller工作原理的理解来看,二进制代码是由一个嵌入python解释器和加载脚本的引导程序的小型C程序构造而成的。PyInstaller构造的EXE在包含python代码资源的实际二进制文件结束后包含一个归档文件。这里解释了这一点 Pyinstaller/loader/iu.py中有iu.py。您应该能够创建一个导入钩子来从二进制文件导入。谷歌搜索pyinstaller反汇编程序发现,它似乎可以提取必要的部件
另一部分是二进制存档中的所有资源都将由python代码编译。最有可能的是,coverage.py将以与在正常条件下运行时命中任何其他编译模块相同的方式为您提供无帮助的输出。突出显示使用
cover\u pylib=True
我知道你问这个问题已经很久了,但我只是想知道答案
使用coverage.py的当前bitbucket源代码,我能够成功地从PyInstaller
生成的EXE文件中收集覆盖率数据
在我的应用程序的主要来源中,我有条件地告诉coverage开始收集覆盖率,如下所示:
if os.environ.has_key('COVERAGE') and len(os.environ['COVERAGE']) > 0:
usingCoverage = True
import coverage
import time
cov = coverage.coverage(data_file='.coverage.' + version.GetFullString(), data_suffix=time.strftime(".%Y_%m_%d_%H_%M.%S", time.localtime()), cover_pylib=True)
cov.start()
cov = coverage(data_file='.coverage.' + version.GetFullString(), data_suffix='.combined')
cov.load()
cov.combine()
cov.save()
cov.load()
cov.html_report(ignore_errors=True,omit=[r'c:\python27\*', r'..\3rdParty\PythonPackages\*'])
这只在我需要时才开始覆盖收集。使用data_后缀可以更轻松地利用cov.combine()
进行后续的覆盖率文件合并<代码>版本。GetFullString()
只是我的应用程序版本号
cover\u pylib
在这里被设置为True
,因为所有标准Python库模块\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
属性都类似于…\\umeixxxxx\random.pyc
,因此在路径上与包中不存在的
当应用程序准备退出时,我有一个小片段:
if usingCoverage:
cov.stop()
cov.save()
一旦我的应用程序运行完毕,coverage.py仍然不会自动为我生成它的HTML报告。需要清理覆盖率数据,以便将..\\u MEIXXXX\..
文件引用转换为实际源代码的绝对文件路径
我通过运行以下代码片段来实现这一点:
import sys
import os.path
from coverage.data import CoverageData
from coverage import coverage
from glob import glob
def cleanupLines(data):
"""
The coverage data collected via PyInstaller coverage needs the data fixed up
so that coverage.py's report generation code can analyze the source code.
PyInstaller __file__ attributes on code objecters are all in subdirectories of the _MEIXXXX
temporary subdirectory. We need to replace the _MEIXXXX temp directory prefix with the correct
prefix for each source file.
"""
prefix = None
for file, lines in data.lines.iteritems():
origFile = file
if prefix is None:
index = file.find('_MEI')
if index >= 0:
pathSepIndex = file.find('\\', index)
if pathSepIndex >= 0:
prefix = file[:pathSepIndex + 1]
if prefix is not None and file.find(prefix) >= 0:
file = file.replace(prefix, "", 1)
for path in sys.path:
if os.path.exists(path) and os.path.isdir(path):
fileName = os.path.join(path, file)
if os.path.exists(fileName) and os.path.isfile(fileName):
file = fileName
if origFile != file:
del data.lines[origFile]
data.lines[file] = lines
for file in glob('.coverage.' + version.GetFullString() + '*'):
print "Cleaning up: ", file
data = CoverageData(file)
data.read()
cleanupLines(data)
data.write()
这里的for循环仅用于确保将合并的所有覆盖率文件都已清理
注意:默认情况下,此代码不清理的唯一覆盖率数据是PyInstaller
相关文件,这些文件在其\uuu文件属性中不包含\uxxx
数据
现在,您可以以正常方式成功生成HTML或XML(或任何内容)coverage.py
报告
在我的例子中,它看起来是这样的:
if os.environ.has_key('COVERAGE') and len(os.environ['COVERAGE']) > 0:
usingCoverage = True
import coverage
import time
cov = coverage.coverage(data_file='.coverage.' + version.GetFullString(), data_suffix=time.strftime(".%Y_%m_%d_%H_%M.%S", time.localtime()), cover_pylib=True)
cov.start()
cov = coverage(data_file='.coverage.' + version.GetFullString(), data_suffix='.combined')
cov.load()
cov.combine()
cov.save()
cov.load()
cov.html_report(ignore_errors=True,omit=[r'c:\python27\*', r'..\3rdParty\PythonPackages\*'])
在构造函数中使用data_文件是为了确保加载/合并将正确识别所有已清理的覆盖率文件
html\u报告
调用告诉coverage.py
忽略标准python库(以及签入我的版本控制树的python库),只关注我的应用程序代码
我希望这会有所帮助。对于未烘焙到可执行文件中的python脚本,您使用哪些代码覆盖率工具?编辑以包含该信息您希望覆盖率测试什么?你不仅仅有权访问你可以运行覆盖范围的未冻结脚本吗?我有。。。这有点像“我能做这个”类型的问题。。。(有时可执行文件无法通过脚本通过的测试…(不经常))我理解。您是否可以不在安装程序中包含覆盖率包,并使用运行覆盖率而不是实际脚本的交换机?