Building a Hybrid Test Automation Framework with Python, unittest, Requests, and Selenium
Setting Up a UI Automation Test Framework
Project directory structure:
baiduTest/
├── test_baidu.py
├── __init__.py
├── main.py
└── __init__.py
test_baidu.py implementation:
import unittest
import time
from selenium import webdriver
class SearchTest(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Chrome()
self.browser.implicitly_wait(30)
self.url = "http://www.baidu.com/"
def test_search_functionality(self):
self.browser.get(self.url)
search_box = self.browser.find_element_by_id("kw")
search_box.send_keys('itesting')
search_button = self.browser.find_element_by_id("su")
search_button.click()
time.sleep(2)
result = self.browser.find_element_by_xpath('//*[@id="1"]/h3/a').get_attribute('innerHTML')
self.assertTrue('iTesting' in result)
def tearDown(self):
self.browser.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
Note: Download the appropriate ChromeDriver from https://registry.npmmirror.com/binary.html?path=chromedriver/ and place it in your Python installation directory.
Extending unittest with Custom Test Reports
Create a common directory and add html_report.py:
import os
import time
import HwTestReport
class ReportGenerator:
def __init__(self):
timestamp = time.strftime('%Y-%m-%d-%H-%M', time.localtime(time.time()))
self.report_filename = f'test_report_{timestamp}.html'
self.report_dir = os.path.dirname(os.path.dirname(__file__)) + '/report'
report_path = os.path.join(self.report_dir, self.report_filename)
if os.path.exists(report_path):
os.remove(report_path)
with open(report_path, 'wb') as f:
pass
def create_report(self, test_suites):
report_path = os.path.join(self.report_dir, self.report_filename)
with open(report_path, 'wb') as f:
runner = HwTestReport.HTMLTestReport(
stream=f,
title='Automation Test Report',
description='Detailed Test Case Results',
verbosity=1
)
runner.run(test_suites)
if __name__ == '__main__':
ReportGenerator()
Note: Download HwTestReport and place it in your Python installation directory.
main.py updated implementation:
import os
import unittest
from common.html_report import ReportGenerator
if __name__ == '__main__':
test_dir = os.path.join(os.path.dirname(__file__), "tests")
suites = unittest.defaultTestLoader.discover(
test_dir,
pattern='*.py',
top_level_dir=os.path.dirname(__file__)
)
report = ReportGenerator()
report.create_report(suites)
Integrating API Testing with unittest Framework
test_api.py implementation:
import unittest
import requests
class APITest(unittest.TestCase):
def setUp(self):
pass
def test_api_endpoint(self):
api_url = 'https://api.vvhan.com/api/love?type=json'
response = requests.get(api_url, allow_redirects=False)
print(response.text)
self.assertTrue(response.json()['success'])
def tearDown(self):
pass
if __name__ == '__main__':
unittest.main(verbosity=1)
Note: The example uses a public API endpoint that doesn't require authentication. Adjust the implementation based on your specific project requirements.
Running the Framework
Execute main.py to run all tests and generate an HTML report. The framework provides a foundation for building comprehensive test automation solutions. For production use, consider adding additional components such as:
- Element locator utilities
- API client abstractions
- Logging and screenshot capture
- Data base configuration
- Notification integrations (email, messaging platforms)
- Configuration management