pycharm 按自定义顺序运行Pytest类

flseospp  于 2023-03-02  发布在  PyCharm
关注(0)|答案(2)|浏览(179)

我正在pycharm中用pytest写测试,测试被分为各种类。
我想指定必须在其他类之前运行的某些类 *。
我看到过关于stackoverflow的各种问题(比如specifying pytest tests to run from a filehow to run a method before all other tests)。
这些问题和其他各种问题都是想选择特定的
函数来按顺序运行,我理解这可以用fixturespytest ordering来完成。
我不关心每个类的哪个函数先运行,我关心的是
类**按照我指定的顺序运行,这可能吗?

sxissh06

sxissh061#

方法

您可以使用pytest_collection_modifyitems钩子修改收集测试(items)的顺序,这样做的另一个好处是不必安装任何第三方库。
通过一些自定义逻辑,这允许按类排序。

完整示例

假设我们有三个测试类:

  1. TestExtract
  2. TestTransform
  3. TestLoad
    还假设,默认情况下,测试执行顺序为字母顺序,即:
    x1个月5个月1x-〉x1个月6个月1x-〉x1个月7个月1x
    这由于测试类的相互依赖性而对我们不起作用。
    我们可以将pytest_collection_modifyitems添加到conftest.py,如下所示,以强制执行所需的执行顺序:
# conftest.py
def pytest_collection_modifyitems(items):
    """Modifies test items in place to ensure test classes run in a given order."""
    CLASS_ORDER = ["TestExtract", "TestTransform", "TestLoad"]
    class_mapping = {item: item.cls.__name__ for item in items}

    sorted_items = items.copy()
    # Iteratively move tests of each class to the end of the test queue
    for class_ in CLASS_ORDER:
        sorted_items = [it for it in sorted_items if class_mapping[it] != class_] + [
            it for it in sorted_items if class_mapping[it] == class_
        ]
    items[:] = sorted_items

关于实施细节的一些意见:

  • 测试类可以存在于不同的模块中
  • CLASS_ORDER不必详尽无遗,您可以只对那些需要强制执行顺序的类进行重新排序(但请注意:如果重新排序,则任何未重新排序的类将在任何重新排序的类之前执行)
  • 类中的测试顺序保持不变
  • 假设测试类具有唯一的名称
  • items必须就地修改,因此最终的items[:]赋值
bnl4lu3b

bnl4lu3b2#

@swimmer answer很棒,我稍微修改了一下,以便测试组织成函数而不是类。

def pytest_collection_modifyitems(session, config, items):
    """Modifies test items in place to ensure test functions run in a given order"""
    function_order = ["test_one", "test_two"]
    # OR
    # function_order = ["test_one[1]", "test_two[2]"]  
    function_mapping = {item: item.name.split("[")[0] 
                        if "]" not in function_order[0] 
                        else item.name
                        for item in items}

    sorted_items = items.copy()
    for func_ in function_order:
        sorted_items = [it for it in sorted_items if function_mapping[it] != func_] + [it for it in sorted_items if function_mapping[it] == func_]
    items[:] = sorted_items

相关问题