我可以将nose覆盖输出限制为目录而不是包吗?
我的测试代码看起来是这样的:
foo.py
bar.py
tests/__init__.py [empty]
tests/foo_tests.py
tests/bar_tests.py
tests/integration/__init__.py [empty]
tests/integration/foo_tests.py
tests/integration/bar_tests.py
当我运行 nosetests --with-coverage
时,我会看到很多我其实不想关注的模块的详细信息。但是我不能使用 --cover-package=PACKAGE
这个选项,因为 foo.py
和 bar.py
并不在一个包里。(关于我为什么不把它们放在包里的原因,可以参考这个链接:http://lists.idyll.org/pipermail/testing-in-python/2008-November/001091.html)
我能不能把覆盖率的输出限制在只有 foo.py 和 bar.py 上呢?
更新 - 假设没有比下面 Nadia 的回答更好的答案,我又问了一个后续问题:“我该如何写一个(bash)脚本,把目录中所有匹配的文件名转换为命令行选项?”
8 个回答
4
我有很多顶层的Python文件和包,手动一个一个列出来用--cover-package实在太麻烦了,所以我给自己做了两个别名。别名nosetests_cover
会运行覆盖率测试,并自动列出你所有顶层的Python文件和包。别名nosetests_cover_sort
也会做同样的事情,还会根据覆盖率百分比对结果进行排序。
nosetests_cover_cmd="nosetests --with-coverage --cover-erase --cover-inclusive --cover-package=\$( ls | sed -r 's/[.]py$//' | fgrep -v '.' | paste -s -d ',' )"
alias nosetests_cover=$nosetests_cover_cmd
alias nosetests_cover_sort="$nosetests_cover_cmd 2>&1 | fgrep '%' | sort -nr -k 4"
注意事项:
- 这些内容来自我的.bashrc文件。如果你不使用bash,请根据自己的情况进行修改。
- 这些命令必须在你的顶层目录下运行。否则,包名会不正确,覆盖率测试会默默失败(也就是说,它不会告诉你--cover-package不正确,而是表现得好像你根本没有提供这个选项)。
- 我目前在Ubuntu 13.10上使用Python 2.7.6,nose版本是1.3.0,覆盖率版本是3.7.1。这是我测试这些命令的唯一环境。
- 在使用时,如果--cover-erase和--cover-inclusive不符合你的需求,可以去掉它们。
- 如果你想按正常顺序排序,而不是反向排序,可以把
-nr
替换成-n
。 - 这些命令假设你所有的顶层Python文件和包的名字中没有点(除了“.py”中的点)。如果不是这样,请阅读下面的详细说明,理解命令的组成部分,然后根据需要修改命令。
详细说明:
我并不认为这些是实现我想要结果的最有效命令。这只是我碰巧想到的命令。 =P
主要需要解释的是--cover-package的参数。它会生成一个以逗号分隔的顶层Python文件/包名列表(文件名中的“.py”会被去掉),具体过程如下:
\$
-- 在双引号字符串中转义$
字符。$( )
-- 插入括号内命令的结果。ls
-- 列出当前目录下的所有名字(必须是顶层Python目录)。| sed -r 's/[.]py$//'
-- 在列表中,把“foo_bar.py”替换成“foo_bar”。| fgrep -v '.'
-- 在列表中,去掉所有没有点的名字(例如,去掉foo_bar.pyc和notes.txt)。| paste -s -d ','
-- 把列表从换行分隔改成逗号分隔。
我还应该解释一下排序的部分。
2>&1
-- 合并标准错误输出和标准输出。| fgrep '%'
-- 去掉所有没有%
字符的输出行。| sort -nr -k 4
-- 按照第四列(覆盖率百分比)以反向数字顺序排序剩下的行。如果你想要正常顺序而不是反向顺序,可以把-nr
替换成-n
。
希望这对某些人有帮助! =)
15
你可以使用:
--cover-package=.
或者甚至可以设置环境变量
NOSE_COVER_PACKAGE=.
这是在nose 1.1.2版本下测试过的
22
你可以这样使用它:
--cover-package=foo --cover-package=bar
我快速查看了一下nose的源代码来确认:这一行代码
if options.cover_packages:
for pkgs in [tolist(x) for x in options.cover_packages]: