class Doubler:
def __init__(self, n):
self._n = 2 * n
def n(self):
return self._n
x = Doubler(5)
print(x.n() == 10)
assert(x.n() == 10)
y = Doubler(-4)
print(y.n() == -8)
assert(y.n() == -8)
True
True
September 15, 2025
Doubler
?class Doubler:
def __init__(self, n):
self._n = 2 * n
def n(self):
return self._n
x = Doubler(5)
print(x.n() == 10)
assert(x.n() == 10)
y = Doubler(-4)
print(y.n() == -8)
assert(y.n() == -8)
True
True
Doubler
classprint
or assert
statements?print
and assert
assert
statements that will pass and fail as expected, decide which you prefer and why! What situations warrant a print
statement and which ones require an assert
?print
statements require manual checking of outputassert
statements automatically verify correctnesspytest
or unittest
coverage.py
unittest
for DayOfTheWeek
import unittest
from dayoftheweek import DayOfTheWeek
class TestDayOfTheWeek(unittest.TestCase):
def test_init(self):
d = DayOfTheWeek('F')
self.assertEqual(d.name(), 'Friday')
d = DayOfTheWeek('Th')
self.assertEqual(d.name(), 'Thursday')
unittest.main(argv=['ignored'], verbosity=2, exit=False)
<unittest.main.TestProgram at 0x7f83f88ddcd0>
unittest.main
differently for tests outside Quartotest_dayoftheweek.py
in slides/weekfour/
OK
output in terminal confirms passing assertionsDayOfTheWeek
class DayOfTheWeek:
"""A class to represent a day of the week."""
def __init__(self, abbreviation):
"""Create a new DayOfTheWeek object."""
self.abbreviation = abbreviation
self.name_map = {
"M": "Monday",
"T": "Tuesday",
"W": "Wednesday",
"Th": "Thursday",
"F": "Friday",
"Sa": "Saturday",
"Su": "Sunday",
}
def name(self):
return self.name_map.get(self.abbreviation)
Sa
L1 = [1, 2, 3, 4, 5]
L2 = [6, 7, 8, 9, 10]
avg1 = sum(L1)/len(L1)
avg2 = sum(L2)/len(L2)
print("avg(", L1, ") -->", avg1)
print("avg(", L2, ") -->", avg2)
avg( [1, 2, 3, 4, 5] ) --> 3.0
avg( [6, 7, 8, 9, 10] ) --> 8.0
L1 = [1, 2, 3, 4, 5]
L2 = [6, 7, 8, 9, 10]
if len(L1) == 0:
avg1 = 0
else:
avg1 = sum(L1) / len(L1)
if len(L2) == 0:
avg2 = 0
else:
avg2 = sum(L2) / len(L2)
print("avg(", L1, ") -->", avg1)
print("avg(", L2, ") -->", avg2)
avg( [1, 2, 3, 4, 5] ) --> 3.0
avg( [6, 7, 8, 9, 10] ) --> 8.0
def avg(L):
if len(L) == 0:
return 0
else:
return sum(L) / len(L)
L1 = [1, 2, 3, 4, 5]
L2 = [6, 7, 8, 9, 10]
avg1 = avg(L1)
avg2 = avg(L2)
print("avg(", L1, ") -->", avg1)
print("avg(", L2, ") -->", avg2)
avg( [1, 2, 3, 4, 5] ) --> 3.0
avg( [6, 7, 8, 9, 10] ) --> 8.0
avg
function avoids the defect and is easier to read!L1
and L2
, try to find the defect. Can you make a solution that works for empty lists? How do you know it is correct?coverage.py
Software testing helps refine document engineering tool design
Interplay between testing and document tool design:
import re
from typing import Dict, Any
def document_summary(text: str) -> Dict[str, Any]:
"""Generate a comprehensive summary of document statistics."""
words = [word for word in text.split() if any(char.isalnum() for char in word)]
word_count = len(words)
sentences = re.split(r'[.!?]+', text)
sentence_count = len([s for s in sentences if s.strip()])
paragraphs = [p for p in text.split('\n\n') if p.strip()]
paragraph_count = len(paragraphs)
avg_words_per_sentence = word_count / sentence_count if sentence_count > 0 else 0
return {
'word_count': word_count, 'sentence_count': sentence_count,
'paragraph_count': paragraph_count,
'avg_words_per_sentence': round(avg_words_per_sentence, 1)
}
sample_text = "Hello world. This is a test."
result = document_summary(sample_text)
print(f"Words: {result['word_count']}, Sentences: {result['sentence_count']}")
assert result['word_count'] == 6
assert result['sentence_count'] == 2
Words: 6, Sentences: 2
document_summary
functiondocument_summary
sample_text
result
assert
statements to confirm correctness of outputpytest
! Frameworks make testing easy and repeatable.uv
to add pytest
as a project dependency!pytest
and unittest
:
pytest
hypothesis
DayOfTheWeek
with Pytestfrom daydetector.dayoftheweek import DayOfTheWeek
def test_init():
"""Test the DayOfTheWeek class."""
d = DayOfTheWeek("F")
assert d.name() == "Friday"
d = DayOfTheWeek("Th")
assert d.name() == "Thursday"
d = DayOfTheWeek("W")
assert d.name() == "Wednesday"
d = DayOfTheWeek("T")
assert d.name() == "Tuesday"
d = DayOfTheWeek("M")
assert d.name() == "Monday"
pytest
@pytest.mark.parametrize(
"abbreviation, expected",
[
("M", "Monday"),
("T", "Tuesday"),
("W", "Wednesday"),
("Th", "Thursday"),
("F", "Friday"),
("Sa", "Saturday"),
("Su", "Sunday"),
("X", None),
],
)
def test_day_name(abbreviation, expected):
"""Use parameterized testing to confirm that lookup works correctly."""
day = DayOfTheWeek(abbreviation)
assert day.name() == expected
import hypothesis.strategies as st
from hypothesis import given
import pytest
@pytest.mark.parametrize(
"valid_days",
[["Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"]],
)
@given(
st.text(alphabet=st.characters(), min_size=1, max_size=2)
)
def test_abbreviation_maps_to_name(valid_days, abbreviation):
"""Use property-based testing with Hypothesis to confirm mapping."""
day = DayOfTheWeek(abbreviation)
assert day.name() in valid_days or day.name() is None
Hypothesis
strategies generate random character inputs for the abbreviation
parameter, thereby increasing the input diversitytest_dayoftheweek.py
! Wow!What are the benefits and downsides of using artificial intelligence (AI) to generate tests?
What are situations in which you should and should not use AI to generate tests?
Tests establish a confidence in correctness!
ds2
package in the donsheehy/datastructures GitHub repositoryProsegrammers