简体   繁体   English

使用py.test在Python中测试正则表达式

[英]Testing regexes in Python using py.test

Regexes are still something of a dark art to me, but I think that's one of those things that just takes practice. 对我来说,正则表达式仍然是一种黑暗艺术,但我认为这只是需要练习的事情之一。 As such, I'm more concerned with being able to produce py.test functions that show me where my regexes are failing. 因此,我更关心的是能够生成py.test函数,向我展示我的正则表达式失败的地方。 My current code is something like this: 我目前的代码是这样的:

my_regex = re.compile("<this is where the magic (doesn't)? happen(s)?>")

def test_my_regex():
    tests = ["an easy test that I'm sure will pass",
             "a few things that may trip me up",
             "a really pathological, contrived example",
             "something from the real world?"]

    test_matches = [my_regex.match(test) for test in tests]

    for i in range(len(tests)):
        print("{}: {!r}".format(i, tests[i]))
        assert test_matches[i] is not None

for which the output when I run py.test myfile.py is something like 当我运行py.test myfile.py时输出的是类似的

0: "an easy..."
1: "a few things..."
2: "a really pathological..."

where the last one is the first (only?) one to have not passed the test. 最后一个是第一个(仅?)没有通过测试的那个。

I suppose I could do something like an 我想我可以做一些像

assertSequenceEqual(test_matches, [not None]*len(test_matches))

but that seems gross, and I was under the impression that <object> is not None is the preferred way of checking that an object isn't None rather than <object> != None . 但这似乎很严重,而且我的印象是<object> is not None是检查对象不是None而不是<object> != None的首选方法。

Another approach is to use parametrize . 另一种方法是使用参数化

my_regex = re.compile("<this is where the magic (doesn't)? happen(s)?>")

@pytest.mark.parametrize('test_str', [
    "an easy test that I'm sure will pass",
    "a few things that may trip me up",
    "a really pathological, contrived example",
    "something from the real world?",
])
def test_my_regex(test_str):
     assert my_regex.match(test_str) is not None

This will produce an independent test case for each test string. 这将为每个测试字符串生成一个独立的测试用例。 This IMO is cleaner, easier to add new cases and also has the advantage of allowing each test_str to fail individually without affecting the others. 此IMO更清晰,更容易添加新案例,并且还具有允许每个test_str单独失败而不影响其他IMO的优点。

You could use all : 你可以all使用:

assert all([my_regex.match(test) for test in goodinputs])

You might also want to test inputs that should NOT match, and test those with a negated any . 您可能还希望测试不应与投入,并测试那些具有否定any

assert not any([my_regex.match(test) for test in badinputs])

If you want to see which matches fail, you could reorganise your existing code slightly, something like: 如果您想查看哪些匹配失败,您可以稍微重新组织现有代码,例如:

for test in tests:
    assert my_regex.match(test), test

which should print out the value of test if the assertion fails. 如果断言失败,应该打印出test的值。

However, this will only print out the details of the first failure. 但是,这只会打印出第一次失败的细节。

If you want to see all failures, you could do: 如果你想看到所有的失败,你可以这样做:

failures = [test for test in tests if not my_regex.match(test)]
assert len(failures) == 0, failures

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM