flowchart LR A[Think] --> B[Red] B --> C[Green] C --> D[Refactor] D --> C D --> A style B stroke:#f00 style C stroke:#04B46D
Initial plan
Reality
flowchart LR A[Think] --> B[Red] B --> C[Green] C --> D[Refactor] D --> C D --> A style B stroke:#f00 style C stroke:#04B46D
Make it green, then make it clean!
Test Zero, then One, then Many. While you test, pay attention to Boundaries, Interfaces, and Exceptions, all while keeping test scenarios and solutions Simple.
Create a ROT-13 encoding function, a simple Caesar cipher where “abc” becomes “nop” and vice versa.
## test_rot13.py
from tdd_toy_example import rot13
def test_transform():
assert rot13.transform("") == ""
## test_rot13.py
from tdd_toy_example import rot13
def test_transform_with_empty_string():
assert rot13.transform("") == "", \
"Empty string should return empty string"
## rot13.py
def transform(input):
if input == "":
return ""
char_code = ord(input[0])
char_code += 13
return chr(char_code)
## rot13.py
def transform(input):
if input == "":
return ""
# get unicode code point of first character
char_code = ord(input[0])
char_code += 13
return chr(char_code)
## test_rot13.py
import pytest
from tdd_toy_example import rot13
def test_transform_empty_string():
assert rot13.transform("") == "", \
"Empty string should return empty string"
@pytest.mark.parametrize(
"test_input, expected",
[
("a", "n"),
("n", "a"),
],
ids=["forward", "backward"],
)
def test_transform_lowercase_letters(test_input, expected):
assert rot13.transform(test_input) == expected
@pytest.mark.parametrize(
"test_input, expected",
[
("A", "N"),
("N", "A"),
],
ids=["forward", "backward"],
)
def test_transform_uppercase_letters(test_input, expected):
assert rot13.transform(test_input) == expected
@pytest.mark.parametrize(
"test_input,expected",
[
("`", "`"),
("{", "{"),
("@", "@"),
("[", "["),
],
)
def test_transform_symbols(test_input, expected):
assert rot13.transform(test_input) == expected
## rot13.py
def transform(input):
if input == "":
return ""
output = ""
for letter in input:
output += transform_letter(letter)
return output
def transform_letter(letter):
if not letter.isalpha():
return letter
# convert input to lowercase
input_lower = letter.lower()
# get unicode code point of first character
char_code = ord(input_lower)
if char_code >= ord("n"):
char_code -= 13
else:
char_code += 13
output = chr(char_code)
return output.upper() if letter.isupper() else output
…repeat
## test_rot13.py
import pytest
from tdd_toy_example import rot13
def test_transform_empty_string():
assert rot13.transform("") == "", \
"Empty string should return empty string"
@pytest.mark.parametrize(
"test_input, expected",
[
("a", "n"),
("n", "a"),
("abcdefghijklmnopqrstuvwxyz", "nopqrstuvwxyzabcdefghijklm"),
],
ids=["forward", "backward", "string"],
)
def test_transform_lowercase_letters(test_input, expected):
assert rot13.transform(test_input) == expected
@pytest.mark.parametrize(
"test_input, expected",
[
("A", "N"),
("N", "A"),
("ABCDEFGHIJKLMNOPQRSTUVWXYZ", "NOPQRSTUVWXYZABCDEFGHIJKLM"),
],
ids=["forward", "backward", "string"],
)
def test_transform_uppercase_letters(test_input, expected):
assert rot13.transform(test_input) == expected
@pytest.mark.parametrize("test_input", ["`", "{", "@", "[", "`{@["])
def test_transform_symbols(test_input):
assert rot13.transform(test_input) == test_input
def test_transform_numbers():
assert rot13.transform("0123456789") == "0123456789"
@pytest.mark.parametrize("test_input", ["äöüßéñç", "ÄÖÜẞÉÑÇ"])
def test_transform_non_english_letters(test_input):
assert rot13.transform(test_input) == test_input
@pytest.mark.parametrize("test_input", ["👍", "💁", "👌", "😍"])
def test_transform_emoji_string(test_input):
assert rot13.transform(test_input) == test_input
def test_transform_no_parameter():
with pytest.raises(TypeError, match="Expected string parameter"):
rot13.transform()
def test_transform_wrong_parameter_type():
with pytest.raises(TypeError, match="Expected string parameter"):
rot13.transform(1)
## rot13.py
def transform(input=None):
print(type(input))
if input is None or not isinstance(input, str):
raise TypeError("Expected string parameter")
if input == "":
return ""
output = ""
for letter in input:
output += transform_letter(letter)
return output
def transform_letter(letter):
if is_non_english_letter(letter):
return letter
# convert input to lowercase
input_lower = letter.lower()
# get unicode code point of first character
char_code = ord(input_lower)
if char_code >= ord("n"):
char_code -= 13
else:
char_code += 13
output = chr(char_code)
return output.upper() if letter.isupper() else output
def is_non_english_letter(letter):
return not letter.isascii() or not letter.isalpha()
NIU team meeting | 2023-10-27