[英]How to make py.test or nose to look for tests inside all python files?
我確實有幾個小模塊,其中測試在其中, py.test
或nose
不查找它們,因為它們的文件名中不包含test
。
我如何說服py.test
或nose
遞歸地在所有 python 文件中查找測試 - '''包括文件名中沒有test
的文件'''?
在源文件中,我確實保留了標准命名約定: class testSomeName
和方法def test_some_name
。
如果這不可能,我可以使用什么其他解決方案來獲得相同的結果。
我不想手動創建包含測試的所有文件的列表,我想要一個支持發現的解決方案。
使用py.test它很簡單。 使用此內容創建conftest.py
文件:
# content of conftest.py file at root of your project
def pytest_collect_file(path, parent):
if path.ext == ".py":
return parent.Module(path, parent)
這將擴展收集過程,為每個“.py”文件創建一個測試“模塊”節點。 將它放入conftest.py
文件使其成為特定於項目的擴展,如果您鍵入以下內容,則會自動加載:
py.test
出於提供信息的目的,您還可以鍵入:
py.test --collectonly
查看收集的測試和文件,示例輸出:
<Directory 'morecollect'>
<Module 'conftest.py'>
<Directory 'pkg'>
<Module 'test_x.py'>
<Function 'test_hello2'>
<Module 'x.py'> # this is collected because of our conftest.py extension
<Function 'test_hello'>
如果需要,您還可以將上述conftest.py
文件打包為可安裝的插件,並通過安裝插件使擴展可用。 在這種情況下,您根本不需要任何conftest.py
文件。
在項目的根目錄下放置一個“setup.cfg”文件,它包含以下兩行:
[pytest]
python_files=*.py
然后py.test從所有*.py
文件中選擇測試。 在這里解釋: pytest docs
與鼻子:
nosetests --all-modules
您還可以查看Nose ,它將發現測試而無需使用固定的文件名約定。
您可以使用以下代碼繞過用於過濾nose中文件的正則表達式。 創建一個python模塊(即my_nosetests.py
)
import nose
from nose.plugins.base import Plugin
class ExtensionPlugin(Plugin):
name = "ExtensionPlugin"
def options(self, parser, env):
Plugin.options(self,parser,env)
def configure(self, options, config):
Plugin.configure(self, options, config)
self.enabled = True
def wantFile(self, file):
return file.endswith('.py')
def wantDirectory(self,directory):
return True
def wantModule(self,file):
return True
if __name__ == '__main__':
includeDirs = ["-w", ".", ".."]
nose.main(addplugins=[ExtensionPlugin()], argv=sys.argv.extend(includeDirs))
現在運行my_nosetests.py
就像運行nosetests
,你應該運行你的測試。 請注意,您實際上正在加載所有模塊並在其中搜索測試。 注意模塊加載的任何副作用。
文檔說明了這一點
默認情況下,遍歷所有不以點開頭的目錄,查找test _ *。py和* _test.py文件。 這些Python文件是在其包名下導入的。
你能確保你的代碼是這種情況嗎?
更新
(Caveat Emptor:我沒有嘗試/測試過這個)如何使用提供的鈎子來收集目錄和文件?
py.test調用以下兩個用於收集文件和目錄的基本鈎子:
def pytest_collect_directory(path, parent):
""" return Collection node or None for the given path. """
def pytest_collect_file(path, parent):
""" return Collection node or None for the given path. """
兩者都返回給定路徑的集合節點 。 來自所有鈎子實現的所有返回節點都將參與收集和運行協議。
parent
對象是父節點,可用於通過parent.config
對象訪問命令行選項。
對於 pytest-6,我必須更改 @hpk42 答案以直接返回給定源/測試代碼布局的 Module 實例。 原始答案針對 pytest 這個主要版本提出了一個例外,因為 API 同時發生了變化。
def pytest_collect_file(path, parent):
"""Look in all Python files for test cases."""
from _pytest.python import Module
if path.ext == ".py":
return Module.from_parent(parent, fspath=path)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.