Analysis: How to run test cases in multiple threads

unittest

First of all, it should be noted that unittest itself does not support multi-threading. Of course, if you have learned Python’s threading module, it may not be impossible. However, I searched for a long time on stackoverflow. Most of them introduced the unittest Test multi-thread module, not how unittest itself runs multi-threaded use cases.

“How do I learn the Sunflower Book” and “how do I verify that Zhang San has learned the Sunflower Book” are two different things, and the problem I obviously want to solve is the former.

I searched Baidu again and found the answer. The core uses the test library of tomorrow3 and cooperates with HTMLTestRunner to generate test reports.

https://github.com/SeldomQA/HTMLTestRunner

https://github.com/dflupu/tomorrow3

Test Cases

The test case is as follows, you can copy multiple tests.

 # test_a.py
import time
import unittest
?from selenium import webdriver
?class Test1(unittest.TestCase):
? @classmethod
? def setUpClass(cls):
 cls.driver = webdriver.Chrome()
? def test_01(self):
? self.driver.get("https://www.bing.com/?mkt=zh-CN")
elem = self.driver.find_element_by_id("sb_form_q")
? elem.send_keys("Multi-threading")
elem.submit()
time.sleep(2)
? self.assertIn("Multi-threading", self.driver.title)
? @classmethod
? def tearDownClass(cls):
? cls.driver.quit()
?if __name__ == "__main__":
unittest.main()

run file

The core threads decorator provided in tomorrow3 is used to decorate the test running method.

import unittest
import os
from TestRunner import HTMLTestRunner
from tomorrow3 import threads
# Define directory
?BASE_DIR = os.path.dirname(os.path.realpath(__file__))
?TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")
?def test_suits():
"""
Load all test cases
"""
? discover = unittest.defaultTestLoader.discover(
TEST_DIR,
pattern="test_*.py"
)
return discover
?@threads(2) # !!!Core!!!! Set the number of threads
?def run_case(all_case, nth=0):
"""
Execute all test cases and write the results into the test report
"""
report_abspath = os.path.join(REPORT_DIR, f"result{nth}.html")
? with open(report_abspath, "wb + ") as file:
runner = HTMLTestRunner(stream=file, title='Multi-threaded test report')
? # Call the test_suits function to return the value
?runner.run(all_case)
?if __name__ == "__main__":
cases = test_suits()
# Start the thread in a loop
for i, j in zip(cases, range(len(list(cases)))):
? run_case(i, nth=j) # Execute the use case and generate the report

Summary:

It is indeed possible (depending on the number of threads set) to start two browsers running at the same time, which brings two problems at the same time.

1. The program will generate multiple test reports based on the number of threads. Each test report counts the test results run by the current thread.

2. If the nth parameter is removed and set to a report, the results of the second thread running cannot be displayed correctly on a report.

3. At least the use case in each thread must ensure that the browser is started/closed.

Point 3, you may not understand. Let me give you an example. When I was a child, I saw my mother/grandma sewing clothes. Suppose a piece of clothing is sewn with a needle. The most troublesome thing in sewing is threading the needle and threading. The eye of the needle is very small and it takes half a day to do it. Children have good eyesight, so I am often asked to thread the needle and thread. So in order to save time, of course I make the thread long, preferably so that one needle and thread can sew multiple pieces of clothing.

In Selenium, the defined browser driver driver is defined once for each use case, followed by opening/closing the browser for each use case. This is of course very time-consuming. In order to shorten this time, we finally It is best to start the browser once and run all the use cases before closing it.

So here comes the problem. When we use multi-threading, it is equivalent to multiple people sewing clothes at the same time. Sharing one needle and thread will definitely not work. At least one needle and thread per person is required! Moreover, the number of people sewing clothes changes. In order to rush for time, there are two more people (open two more threads), and if the use cases are relatively small, there are fewer people (two less threads are opened). In order to adapt to this change, it is best to Each piece of clothing is equipped with a needle and thread. Each piece of clothing is the smallest unit. One person must sew a piece of clothing independently.

In order to use multi-threading, we must open/close the browser once for each use case. This is actually another waste of time. In order to make up for the waste here, you must open enough threads.

Finally, you must configure a statistician to count the number of clothes sewn by each person and sum them up into a report.

pytest

Multi-threaded running test cases are relatively easy in pytest, and the pytest-xdist plug-in can accomplish this.

https://github.com/pytest-dev/pytest-xdist

test case

The test case is as follows, you can copy multiple tests.

 # test_a.py
import time
?from selenium import webdriver
?def test_01():
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
elem = driver.find_element_by_id("kw")
elem.send_keys("unittest")
elem.submit()
time.sleep(2)
assert driver.title == "unittest_Baidu Search"
driver.quit()
?def test_02():
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
elem = driver.find_element_by_id("kw")
? elem.send_keys("python")
elem.submit()
time.sleep(2)
assert driver.title == "python_Baidu Search"
driver.quit()

run file

The core is to install the pytest-xdist plug-in and set the number of threads through the -n parameter.

import os
import pytest
# Define directory
?BASE_DIR = os.path.dirname(os.path.realpath(__file__))
?TEST_DIR = os.path.join(BASE_DIR, "test_dir")
REPORT_DIR = os.path.join(BASE_DIR, "test_report")
?if __name__ == '__main__':
report_file = os.path.join(REPORT_DIR, "result.html")
?pytest.main([
? "-n", "2", # ! ! core! ! ! Set up 2 threads
"-v", "-s", TEST_DIR,
"--html=" + report_file,
])

Summary:

Compared with unittest, it is very simple to implement multi-threading in pytest, and the test results of the final thread can also be easily displayed in a test report.

1. The problem, as I discussed above, is that you have to set on/off for each use case. In addition to consuming additional startup time, it will also be troublesome if you want to uniformly configure which browser the use case is executed through.

2. Each of your use cases should remain absolutely independent. This use case cannot depend on the execution result of the previous use case. Because these two use cases may be assigned to be executed by different threads.

3. Just like the previous point, you cannot control the execution order of use cases.

Take action, it is better to be on the road than to wait and see all the time. In the future, you will definitely thank yourself for working hard now! If you want to learn and improve but can’t find the information and there is no one to answer your questions, please join the group in time: 786229024. There are various test and development materials and technologies in which you can communicate together.

Finally: The complete software testing video tutorial below has been compiled and uploaded. Friends who need it can get it by themselves[Guaranteed 100% Free]
Software Testing Interview Document
We must study to find a high-paying job. The following interview questions are from the latest interview materials from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and some Byte bosses have given authoritative answers. After finishing this set I believe everyone can find a satisfactory job based on the interview information.