Hypothesis: Property -basiertes Testen

In diesem Notebook verwenden wir Property -basierte Tests, um Probleme in unserem Code zu finden. Hypothesis ist eine Bibliothek, die Haskells Quickcheck ähnelt. Später lernen wir sie zusammen mit anderen Testbibliotheken noch genauer kennen: Hypothesis. Hypothesis kann auch Mock-Objekte und Tests für Numpy-Datentypen bereitstellen.

1. Importe

[1]:
from hypothesis import given, assume
from hypothesis.strategies import tuples, integers, emails
import re

2. Bereich finden

[2]:
def calculate_range(tuple_obj):
    return max(tuple_obj) - min(tuple_obj)

3. Test mit strategies und given

[3]:
@given(tuples(integers(), integers(), integers()))
def test_calculate_range(tup):
    result = calculate_range(tup)
    assert isinstance(result, int)
    assert result > 0
[4]:
test_calculate_range()
Falsifying example: test_calculate_range(
    tup=(0, 0, 0),
)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-4-870cdf3c4b4e> in <module>
----> 1 test_calculate_range()

<ipython-input-3-452e470cf7c7> in test_calculate_range()
      1 @given(tuples(integers(), integers(), integers()))
----> 2 def test_calculate_range(tup):
      3     result = calculate_range(tup)
      4     assert isinstance(result, int)
      5     assert result > 0

    [... skipping hidden 1 frame]

<ipython-input-3-452e470cf7c7> in test_calculate_range(tup)
      3     result = calculate_range(tup)
      4     assert isinstance(result, int)
----> 5     assert result > 0

AssertionError:

3. Test korrigieren mit >=

[5]:
@given(tuples(integers(), integers()))
def test_calculate_range(tup):
    result = calculate_range(tup)
    assert isinstance(result, int)
    assert result >= 0
[6]:
test_calculate_range()

4. Gegen Reguläre Ausdrücke prüfen

[7]:
def parse_email(email):
    result = re.match('(?P<username>\w+).(?P<domain>[\w\.]+)',
                      email).groups()
    return result
[8]:
@given(emails())
def test_parse_email(email):
    result = parse_email(email)
    #print(result)
    assert len(result) == 2
    assert '.' in result[1]
[9]:
test_parse_email()
Falsifying example: test_parse_email(
    email='/@A.ac',
)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-9-e5ad7429fbd5> in <module>
----> 1 test_parse_email()

<ipython-input-8-a21f35eebf98> in test_parse_email()
      1 @given(emails())
----> 2 def test_parse_email(email):
      3     result = parse_email(email)
      4     #print(result)
      5     assert len(result) == 2

    [... skipping hidden 1 frame]

<ipython-input-8-a21f35eebf98> in test_parse_email(email)
      1 @given(emails())
      2 def test_parse_email(email):
----> 3     result = parse_email(email)
      4     #print(result)
      5     assert len(result) == 2

<ipython-input-7-7c9f64d6175d> in parse_email(email)
      1 def parse_email(email):
      2     result = re.match('(?P<username>\w+).(?P<domain>[\w\.]+)',
----> 3                       email).groups()
      4     return result

AttributeError: 'NoneType' object has no attribute 'groups'
[10]:
def parse_email(email):
    result = re.match('(?P<username>[\.\w\-\!~#$%&\|{}\+\/\^\`\=\*\']+).(?P<domain>[\w\.\-]+)', email).groups()
    return result
[11]:
test_parse_email()

Hinwes:

Auf der Website regex101 könnt ihr zunächst eure regulären Ausdrücke ausprobieren.