Skip to content

Commit

Permalink
Ensure async test methods work in test classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
ntoll committed Oct 28, 2024
1 parent add20d9 commit 6b7b383
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 23 deletions.
18 changes: 9 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@

expected_results = {
"result_all": {
"passes": 11,
"fails": 9,
"skipped": 6,
"passes": 14,
"fails": 12,
"skipped": 8,
},
"result_random": {
"passes": 11,
"fails": 9,
"skipped": 6,
"passes": 14,
"fails": 12,
"skipped": 8,
},
"result_module": {
"passes": 10,
"fails": 9,
"skipped": 6,
"passes": 13,
"fails": 12,
"skipped": 8,
},
"result_class": {
"passes": 3,
Expand Down
57 changes: 49 additions & 8 deletions tests/test_core_functionality.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,37 +96,37 @@ class TestClass:
"""

@upytest.skip("This test will be skipped")
def test_skipped(self):
def test_in_class_skipped(self):
assert False # This will not be executed.

@upytest.skip(
"This test will be skipped with a skip_when condition", skip_when=True
)
def test_when_skipped(self):
def test_in_class_when_skipped(self):
assert False # This will not be executed.

@upytest.skip(
"This test will NOT be skipped with a False-y skip_when",
skip_when=False,
)
def test_when_not_skipped_passes(self):
def test_in_class_when_not_skipped_passes(self):
assert True, "This test passes"

def test_passes(self):
def test_in_class_passes(self):
assert True, "This test passes"

def test_fails(self):
def test_in_class_fails(self):
assert False, "This test will fail"

def test_raises_exception_passes(self):
def test_in_class_raises_exception_passes(self):
with upytest.raises(ValueError):
raise ValueError("This is a ValueError")

def test_does_not_raise_exception_fails(self):
def test_in_class_does_not_raise_exception_fails(self):
with upytest.raises(ValueError):
pass

def test_does_not_raise_expected_exception_fails(self):
def test_in_class_does_not_raise_expected_exception_fails(self):
with upytest.raises(ValueError, AssertionError):
raise TypeError("This is a TypeError")

Expand Down Expand Up @@ -175,3 +175,44 @@ async def test_async_does_not_raise_exception_fails():
async def test_async_does_not_raise_expected_exception_fails():
with upytest.raises(ValueError, AssertionError):
raise TypeError("This is a TypeError")


class TestAsyncClass:
"""
An asynchronous class based version of the above tests.
"""

@upytest.skip("This test will be skipped")
async def test_async_in_class_skipped(self):
assert False # This will not be executed.

@upytest.skip(
"This test will be skipped with a skip_when condition", skip_when=True
)
async def test_async_in_class_when_skipped(self):
assert False # This will not be executed.

@upytest.skip(
"This test will NOT be skipped with a False-y skip_when",
skip_when=False,
)
async def test_async_in_class_when_not_skipped_passes(self):
assert True, "This test passes"

async def test_async_in_class_passes(self):
assert True, "This test passes"

async def test_async_in_class_fails(self):
assert False, "This test will fail"

async def test_async_in_class_raises_exception_passes(self):
with upytest.raises(ValueError):
raise ValueError("This is a ValueError")

async def test_async_in_class_does_not_raise_exception_fails(self):
with upytest.raises(ValueError):
pass

async def test_async_in_class_does_not_raise_expected_exception_fails(self):
with upytest.raises(ValueError, AssertionError):
raise TypeError("This is a TypeError")
24 changes: 18 additions & 6 deletions upytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,23 @@ def parse_traceback_from_exception(ex):

def shuffle(a_list):
"""
Shuffle a list, in place.
Shuffle a list, in place.
This function is needed because MicroPython does not have a random.shuffle
function.
It falls back to random.shuffle if using CPython, otherwise it uses a
simple implementation of the Fisher-Yates in-place shuffle algorithm.
Context:
Context:
https://stackoverflow.com/questions/73143243/are-there-any-alternatives-for-the-python-module-randoms-shuffle-function-in
"""
if hasattr(random, "shuffle"):
random.shuffle(a_list)
else:
for i in range(len(a_list) - 1, 0, -1):
j = random.randrange(i+1)
j = random.randrange(i + 1)
a_list[i], a_list[j] = a_list[j], a_list[i]


Expand Down Expand Up @@ -230,8 +230,20 @@ def __init__(self, path, module, setup=None, teardown=None):
for method_name, method in item.__dict__.items():
if callable(method) or is_awaitable(method):
if method_name.startswith("test"):
if is_awaitable(method):

async def method_wrapper(
instance=instance,
method_name=method_name,
):
await getattr(instance, method_name)()

else:
method_wrapper = getattr(
instance, method_name
)
t = TestCase(
getattr(instance, method_name),
method_wrapper,
self.path,
f"{name}.{method_name}",
id(method),
Expand Down

0 comments on commit 6b7b383

Please sign in to comment.