如何使用py.test的skipif检查成员变量?

3 投票
2 回答
5160 浏览
提问于 2025-04-17 23:37

在我的 setUp 函数里,我设置了一个成员变量 is_type,它的值可以是 True 或 False。这个类里有几个测试,如果 is_type 是 False,就不应该运行这些测试。我不知道怎么用 skipif 功能来实现这个。

@py.test.mark.skipif( not ???.is_type )
def test_method(self):
   ...

self??? 中不管用,因为它还不在对象里。我该怎么引用 is_type 这个变量呢?


更完整的例子:

class DBTest(unittest.TestCase):
    def setUp(self):
        self.is_dynamo = os.environ.get( 'TEST_DB', '' ) == 'Dynamo'

    def test_account_ts(self):
        if not self.is_dynamo:
            return

        ...

我该怎么把 if not self.is_dynamo 转换成一个 py.test 的 skipif 条件呢?

2 个回答

3

在编程中,有时候我们需要把一些信息存储起来,以便后续使用。这个过程就像把东西放进一个盒子里,等需要的时候再拿出来。

有些时候,我们会用到“变量”这个概念。变量就像是一个可以存放信息的盒子。你可以把数字、文字或者其他类型的数据放进去,然后在需要的时候再取出来。

另外,编程语言中还有一些“函数”。函数可以理解为一个小工具,它可以完成特定的任务。比如,你可以有一个函数专门用来计算两个数字的和。每次你需要计算的时候,只要调用这个函数就可以了,省去了重复写代码的麻烦。

总之,编程就是通过这些“盒子”和“工具”来处理信息,完成各种各样的任务。

import unittest
import functools


def skipIfNotDynamo(test_method):
    @functools.wraps(test_method)
    def wrapper(self):
        if not self.is_dynamo:
            raise unittest.SkipTest("Skip because it is not dynamo")

        return test_method(self)

    return wrapper


class DBTest(unittest.TestCase):
    def setUp(self):
        self.is_dynamo = ...

    @skipIfNotDynamo        
    def test_account_ts(self):
        ...
10

正如你提到的,你不能在 skipif 标记中引用一个实例,因为这个实例还不存在。

我建议保持简单,可以这样做:

@pytest.mark.skipif(os.environ.get('TEST_DB') != 'Dynamo')
def test_dynamo():
    db = MyDatabaseWithDynamo(is_dynamo=True)
    # Some assertion or other.

你也可以在类上使用 @pytest.mark.skipif

关于这个功能的 文档中有一些不错的例子。很多例子都是检查环境的某些部分,以决定哪些测试应该跳过。这听起来和你的情况很相似,所以我觉得你并不孤单。

但是如果,正如你在下面的评论中所说的,你想避免使用全局变量,你可以在任何地方抛出一个 pytest.skip 异常。下面我是在一个夹具中这样做的,我觉得这样可以很好地将测试设置和测试案例分开。有关更多可能性,请查看 文档

这是我的测试文件:

import os
import pytest

class MyDatabaseWithDynamo(object):
    def __init__(self, is_dynamo):
        pass

@pytest.fixture
def database():
    is_dynamo = os.environ.get('TEST_DB') == 'Dynamo'
    if not is_dynamo:
        raise pytest.skip()
    return MyDatabaseWithDynamo(is_dynamo=True)

def test_db(database):
    pass

这是测试输出:

$ py.test test_foo.py
======================================= test session starts =======================================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2
collected 1 items

test_foo.py s

==================================== 1 skipped in 0.01 seconds ===================================

撰写回答