-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_string_thing_pytest.py
106 lines (86 loc) · 4.68 KB
/
test_string_thing_pytest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Note some pytest examples have `import pytest` at start of script even when
# not needed as not used within the script and pytest only invoked at
# command line. However, sometimes is needed as functions from within
# pytest are actually used. This is the case here.
import pytest
from string_thing import StringThing
from string_thing import counterstring
# The for loops used below aren't ideal as loop will end upon first assertion failure encountered
# - only get full run if no failures. Looks like there are ways around this using some pytest
# decorators such as pytest.mark.parametrize.
def test_length_one():
value = "123456"
st = StringThing(value)
result = st.length()
assert result == 6, f"Length of {value} - actual result: {result}, expected result: 6"
def test_length_multi():
expecteds = {"a" * i: i for i in range(10)}
for value, expected in expecteds.items():
st = StringThing(value)
result = st.length()
assert result == expected, f"Length of {value} - actual result: {result}, expected result {expected}"
# Avoid for-loop problem by using pytest.mark.parametrize to create the set of values to be tested
@pytest.mark.parametrize("value, expected", [("a" * i, i) for i in range(10)])
def test_length_multi_v2(value, expected):
st = StringThing(value)
result = st.length()
assert result == expected, f"Length of {value} - actual result: {result}, expected result {expected}"
def test_substring_count():
value = "abcaabbbcccc"
st = StringThing(value)
# Note could be argued that right result for "cc" should be 3 rather than 2
expecteds = {"a": 3, "b": 4, "c": 5, "d": 0, "ab": 2, "cc": 2}
for substr, expected in expecteds.items():
result = st.substring_count(substr)
assert result == expected, f"Count of {substr} in {value} found {result} but expected {expected}"
@pytest.mark.parametrize("value", ["abcaabbbcccc"]) # need to put the string in a list otherwise will iterate over the string
@pytest.mark.parametrize("substr, expected", [("a", 3), ("b", 4), ("c", 5), ("d", 0), ("ab", 2), ("cc", 2)])
def test_substring_count_v2(value, substr, expected):
st = StringThing(value)
result = st.substring_count(substr)
assert result == expected, f"Count of {substr} in {value} found {result} but expected {expected}"
# Deliberate Exception
def test_substring_count_invalid():
st = StringThing("123456")
with pytest.raises(TypeError):
st.substring_count(1)
# Deliberate exception and check the error text
def test_substring_count_invalid_v2():
st = StringThing("123456")
with pytest.raises(TypeError) as exception_info:
st.substring_count(1)
# Below needs to be outside pytest.raises context manager otherwise will always pass
assert "must be str, not int" == str(exception_info.value), "Expected exception text not found"
def test_find_first():
value = "axbxxcxxxd"
st = StringThing(value)
expecteds = {"a": 0, "b": 2, "c": 5, "d": 9, "x": 1, "z": -1,
"ax": 0, "xb": 1, "bxx": 2, value: 0, value + " ": -1}
for letter, count in expecteds.items():
result = st.find_first(letter)
assert result == count, f"Find first {letter} in {value} - actual result: {result}, expected result: {count}"
# Using pytest.mark.parametrize here - lose ability to conveniently include "value" in expected data
@pytest.mark.parametrize("value", ["axbxxcxxxd"])
@pytest.mark.parametrize("substr, count", [("a", 0), ("b", 2), ("c", 5), ("d", 9), ("x", 1), ("z", -1),
("ax", 0), ("xb", 1), ("bxx", 2)])
def test_find_first_v2(value, substr, count):
st = StringThing(value)
result = st.find_first(substr)
assert result == count, f"Find first {substr} in {value} - actual result: {result}, expected result: {count}"
def test_find_all():
value = "abaabaaab"
expecteds = {"a": [0, 2, 3, 5, 6, 7], "b": [1, 4, 8], "ab": [0, 3, 7]}
for letter, expected in expecteds.items():
st = StringThing(value)
result = st.find_all(letter)
assert result == expected, f"Find all {letter} in {value} - actual: {result}, expected: {expected}"
@pytest.mark.parametrize("value", ["abaabaaab"])
@pytest.mark.parametrize("substr, positions", [("a", [0, 2, 3, 5, 6, 7]), ("b", [1, 4, 8]), ("ab", [0, 3, 7])])
def test_find_all_v2(value, substr, positions):
st = StringThing(value)
result = st.find_all(substr)
assert result == positions, f"Find all {substr} in {value} - actual: {result}, expected: {positions}"
def test_counterstring():
cs = counterstring(35, "#")
expected = "2#4#6#8#11#14#17#20#23#26#29#32#35#"
assert cs == expected, f"Counterstring error - expected: {expected}, actual: {cs}"