kopia lustrzana https://github.com/micropython/micropython-lib
unittest: Add subtest usage examples.
This work was funded by Planet Innovation.pull/505/merge
rodzic
e3371bef6c
commit
23018a86bf
|
@ -0,0 +1,214 @@
|
|||
"""Tests using unittest.subtest as an example reference for how it is used"""
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
def factorial(value: int) -> int:
|
||||
"""Iterative factorial algorithm implementation"""
|
||||
result = 1
|
||||
|
||||
for i in range(1, value + 1):
|
||||
result *= i
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class Person:
|
||||
"""Represents a person with a name, age, and who can make friends"""
|
||||
|
||||
def __init__(self, name: str, age: int) -> None:
|
||||
self.name = name
|
||||
self.age = age
|
||||
self.friends = set()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Person({self.name})"
|
||||
|
||||
def add_friend(self, friend):
|
||||
"""Logs that this Person has made a new friend"""
|
||||
self.friends.add(friend)
|
||||
|
||||
def has_friend(self, friend_candidate) -> bool:
|
||||
"""Determines if this Person has the friend `friend_candidate`"""
|
||||
return friend_candidate in self.friends
|
||||
|
||||
def is_oldest_friend(self) -> bool:
|
||||
"""Determines whether this Person is the oldest out of themself and their friends"""
|
||||
return self.age > max(friend.age for friend in self.friends)
|
||||
|
||||
|
||||
class TestSubtest(unittest.TestCase):
|
||||
"""Examples/tests of unittest.subTest()"""
|
||||
|
||||
def test_sorted(self) -> None:
|
||||
"""Test that the selection sort function correctly sorts lists"""
|
||||
tests = [
|
||||
{
|
||||
"unsorted": [-68, 15, 52, -54, -64, 20, 2, 66, 33],
|
||||
"sorted": [-68, -64, -54, 2, 15, 20, 33, 52, 66],
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"unsorted": [-68, 15, 52, -54, -64, 20, 2, 66, 33],
|
||||
"sorted": [-68, -54, -64, 2, 15, 20, 33, 52, 66],
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"unsorted": [-68, 15, 52, 54, -64, 20, 2, 66, 33],
|
||||
"sorted": [-68, -64, -54, 2, 15, 20, 33, 52, 66],
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"unsorted": [],
|
||||
"sorted": [],
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"unsorted": [42],
|
||||
"sorted": [42],
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"unsorted": [42],
|
||||
"sorted": [],
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"unsorted": [],
|
||||
"sorted": [24],
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"unsorted": [43, 44],
|
||||
"sorted": [43, 44],
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"unsorted": [44, 43],
|
||||
"sorted": [43, 44],
|
||||
"correct": True,
|
||||
},
|
||||
]
|
||||
|
||||
for test in tests:
|
||||
with self.subTest(): # Subtests continue to be tested, even if an earlier one fails
|
||||
if test["correct"]: # Tests that match what is expected
|
||||
self.assertEqual(sorted(test["unsorted"]), test["sorted"])
|
||||
else: # Tests that are meant to fail
|
||||
with self.assertRaises(AssertionError):
|
||||
self.assertEqual(sorted(test["unsorted"]), test["sorted"])
|
||||
|
||||
def test_factorial(self) -> None:
|
||||
"""Test that the factorial fuction correctly calculates factorials
|
||||
|
||||
Makes use of `msg` argument in subtest method to clarify which subtests had an
|
||||
error in the results
|
||||
"""
|
||||
tests = [
|
||||
{
|
||||
"operand": 0,
|
||||
"result": 1,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 1,
|
||||
"result": 1,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 1,
|
||||
"result": 0,
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"operand": 2,
|
||||
"result": 2,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 3,
|
||||
"result": 6,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 3,
|
||||
"result": -6,
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"operand": 4,
|
||||
"result": 24,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 15,
|
||||
"result": 1_307_674_368_000,
|
||||
"correct": True,
|
||||
},
|
||||
{
|
||||
"operand": 15,
|
||||
"result": 1_307_674_368_001,
|
||||
"correct": False,
|
||||
},
|
||||
{
|
||||
"operand": 11,
|
||||
"result": 39_916_800,
|
||||
"correct": True,
|
||||
},
|
||||
]
|
||||
|
||||
for test in tests:
|
||||
with self.subTest(
|
||||
f"{test['operand']}!"
|
||||
): # Let's us know we were testing "x!" when we get an error
|
||||
if test["correct"]:
|
||||
self.assertEqual(factorial(test["operand"]), test["result"])
|
||||
else:
|
||||
with self.assertRaises(AssertionError):
|
||||
self.assertEqual(factorial(test["operand"]), test["result"])
|
||||
|
||||
def test_person(self) -> None:
|
||||
"""Test the Person class and its friend-making ability
|
||||
|
||||
Makes use of subtest's params to specify relevant data about the tests, which is
|
||||
helpful for debugging
|
||||
"""
|
||||
# Create a friendship
|
||||
alice = Person("Alice", 22)
|
||||
bob = Person("Bob", 23)
|
||||
alice.add_friend(bob)
|
||||
|
||||
# Test friendship init
|
||||
with self.subTest(
|
||||
"Alice should have Bob as a friend", name=alice.name, friends=bob.friends
|
||||
): # Params `name` and `friends` provide useful data for debugging purposes
|
||||
self.assertTrue(alice.has_friend(bob))
|
||||
|
||||
with self.subTest(
|
||||
"Bob should not have Alice as a friend", name=bob.name, friends=bob.friends
|
||||
):
|
||||
self.assertFalse(bob.has_friend(alice))
|
||||
|
||||
# Friendship is not always commutative, so Bob is not implicitly friends with Alice
|
||||
with self.subTest("Alice and Bob should not both be friends with eachother"):
|
||||
with self.assertRaises(AssertionError):
|
||||
self.assertTrue(bob.has_friend(alice) and alice.has_friend(bob))
|
||||
|
||||
# Bob becomes friends with Alice
|
||||
bob.add_friend(alice)
|
||||
|
||||
with self.subTest(
|
||||
"Bob should now have Alice as a friend", name=bob.name, friends=bob.friends
|
||||
):
|
||||
self.assertTrue(bob.has_friend(alice))
|
||||
|
||||
with self.subTest(
|
||||
"Bob should be the oldest of his friends",
|
||||
age=bob.age,
|
||||
friend_ages=[friend.age for friend in bob.friends],
|
||||
): # Different params can be used for different subtests in the same test
|
||||
self.assertTrue(bob.is_oldest_friend())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Ładowanie…
Reference in New Issue