Last active
August 28, 2024 09:58
-
-
Save pmeier/cc4d69962cd8aa812f68aec03b61072f to your computer and use it in GitHub Desktop.
Decorator for running multi threaded unittests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import unittest | |
from concurrent.futures import ThreadPoolExecutor | |
def multi_threaded(*, threads=2): | |
def decorator(test_cls): | |
for name, test_fn in test_cls.__dict__.copy().items(): | |
if not (name.startswith("test") and callable(test_fn)): | |
continue | |
def multi_threaded_test_fn(*args, __test_fn__=test_fn, **kwargs): | |
with ThreadPoolExecutor(max_workers=threads) as executor: | |
futures = [ | |
executor.submit(__test_fn__, *args, **kwargs) | |
for _ in range(threads) | |
] | |
futures = iter(futures) | |
try: | |
for future in futures: | |
future.result() | |
finally: | |
for future in futures: | |
future.cancel() | |
setattr(test_cls, f"{name}_multi_threaded", multi_threaded_test_fn) | |
return test_cls | |
return decorator | |
@multi_threaded(threads=3) | |
class TestFoo(unittest.TestCase): | |
def test_bar(self): | |
assert True | |
if __name__ == "__main__": | |
TestFoo.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment