Reputation: 1781
For example I have two tests:
class Test(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get("http://google.com")
def tearDown(self):
self.driver.quit()
def test_selenium_1(self):
search_field = self.driver.find_element_by_id("lst-ib")
search_field.send_keys("Test 1. Number 1")
search_field.submit()
time.sleep(2)
def test_selenium_2(self):
search_field = self.driver.find_element_by_id("lst-ib")
search_field.send_keys("Test 1. Number 2")
search_field.submit()
time.sleep(2)
if __name__ == '__main__':
unittest.main()
How can I execute these two tests in parallel with concurrent.futures.Executor?
Is it possible?
Upvotes: 1
Views: 1287
Reputation: 145
I rewrote @vadim-kovrizhkin's solution as a separate runner file that one can use to add separate test cases (importing each test case from their respective py files). This will run setUp, the unit tests in your test cases concurrently, and then tearDown.
from unittest import TestLoader, TestSuite, TextTestRunner
from concurrent.futures import ThreadPoolExecutor
from YourTestFolder.SubFolder.test_foo import Test_Foo
def suite():
loader = TestLoader()
suite = TestSuite(loader.loadTestsFromTestCase(Test_Foo))
return suite
if __name__ == "__main__":
suite = suite()
with ThreadPoolExecutor() as executor:
list_of_suites = list(suite)
for test in range(len(list_of_suites)):
test_name = str(list_of_suites[test])
executor.submit(TextTestRunner().run, list_of_suites[test])
Thanks again to Vadim for their elegant solution!
Upvotes: 0
Reputation: 1781
I created Runner for these purposes.
And now I can execute tests in parallel by modules, classes and methods.
import unittest
from concurrent.futures import ThreadPoolExecutor
class Runner():
def parallel_execution(self, *name, options='by_module'):
"""
name - name of the class with tests or module with classes that contain tests
modules - name of the module with tests or with class that contains tests
options:
by_method - gather all tests methods in the class/classes and execute in parallel
by_module - gather all tests from modules in parallel
by_class - will execute all classes (with tests) in parallel
"""
suite = unittest.TestSuite()
if (options=='by_method'):
for object in name:
for method in dir(object):
if (method.startswith('test')):
suite.addTest(object(method))
elif (options=='by_class'):
for object in name:
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(object))
elif (options=='by_module'):
for module in name:
suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
else:
raise ValueError("Parameter 'options' is incorrect."
"Available options: 'by_method', 'by_class', 'by_module'")
with ThreadPoolExecutor(max_workers=10) as executor:
list_of_suites = list(suite)
for test in range(len(list_of_suites)):
test_name = str(list_of_suites[test])
executor.submit(unittest.TextTestRunner().run, list_of_suites[test])
EXAMPLES:
#by_methods
Runner().parallel_execution(Test1.Test1, Test2.Test22, Test2.Test33, options='by_method')
#by_class
Runner().parallel_execution(Test1.Test1, Test2.Test22, Test2.Test33, options='by_class')
#by_modules
Runner().parallel_execution(Test1, Test2)
Upvotes: 3