Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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

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.

like image 203
Ryan M Avatar asked Dec 01 '22 02:12

Ryan M


1 Answers

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.

like image 88
Bruno Oliveira Avatar answered Dec 05 '22 12:12

Bruno Oliveira