[英]Run Pytest Classes in Custom Order
I am writing tests with pytest in pycharm.我正在用 pycharm 中的 pytest 编写测试。 The tests are divided into various classes.测试分为不同的类别。
I would like to specify certain classes that have to run before other classes .我想指定必须在其他类之前运行的某些类。
I have seen various questions on stackoverflow (such as specifying pytest tests to run from a file and how to run a method before all other tests ).我已经看到有关 stackoverflow 的各种问题(例如指定 pytest 测试从文件运行以及如何在所有其他测试之前运行方法)。
These and various others questions wanted to choose specific functions to run in order.这些和其他各种问题都想选择特定的功能来按顺序运行。 This can be done, I understand, using fixtures
or with pytest ordering
.据我了解,这可以通过使用fixtures
或pytest ordering
来完成。
I don't care which functions from each class run first.我不在乎每个 class 中的哪些功能首先运行。 All I care about is that the classes run in the order I specify.我只关心这些类按照我指定的顺序运行。 Is this possible?这可能吗?
You can use the pytest_collection_modifyitems
hook to modify the order of collected tests ( items
) in place.您可以使用pytest_collection_modifyitems
挂钩来修改收集的测试( items
)的顺序。 This has the additional benefit of not having to install any third party libraries.这具有不必安装任何第三方库的额外好处。
With some custom logic, this allows to sort by class.使用一些自定义逻辑,这允许按 class 排序。
Say we have three test classes:假设我们有三个测试类:
TestExtract
TestTransform
TestLoad
Say also that, by default, the test order of execution would be alphabetical, ie:还要说,默认情况下,执行的测试顺序将按字母顺序排列,即:
TestExtract
-> TestLoad
-> TestTransform
TestExtract
-> TestLoad
-> TestTransform
which does not work for us due to test class interdependencies.由于测试 class 相互依赖关系,这对我们不起作用。
We can add pytest_collection_modifyitems
to conftest.py
as follows to enforce our desired execution order:我们可以按如下方式将pytest_collection_modifyitems
添加到conftest.py
以强制执行我们想要的执行顺序:
#conftest.py
def pytest_collection_modifyitems(items):
"""Modifies in place test items to execute test classes in a given order."""
CLASS_ORDER = ["TestExtract", "TestTransform", "TestLoad"]
# Enforce module order by iteratively pushing tests in a class to
# the end of the execution queue
sorted_items = items.copy()
for class_ in CLASS_ORDER:
items_class = [item.cls.__name__ for item in sorted_items]
first_index = items_class.index(class_)
last_index = len(items_class) - items_class[::-1].index(class_)
sorted_items = (
sorted_items[:first_index]
+ sorted_items[last_index:]
+ sorted_items[first_index:last_index]
)
items[:] = sorted_items
Some comments on the implementation details:关于实现细节的一些评论:
items_class
maps the class of each item
items_class
映射每个item
的 classfirst_index
and last_index
refer to the first and last indices of items belonging to the test class under consideration first_index
和last_index
指的是属于正在考虑的测试 class 的项目的第一个和最后一个索引CLASS_ORDER
does not have to be exhaustive. CLASS_ORDER
不必详尽无遗。 You can reorder just those classes on which to want to enforce an order (but note: if reordered, any non-reordered class will execute before any reordered class)您可以仅对要强制执行订单的类重新排序(但请注意:如果重新排序,任何未重新排序的 class 将在任何重新排序的类之前执行)items
must be modified in place, hence the final items[:]
assignment items
必须就地修改,因此最终的items[:]
分配
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.