簡體   English   中英

如何讓 py.test 或 nose 在所有 python 文件中尋找測試?

[英]How to make py.test or nose to look for tests inside all python files?

我確實有幾個小模塊,其中測試在其中, py.testnose不查找它們,因為它們的文件名中不包含test

我如何說服py.testnose遞歸地在所有 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM