Build the test framework and analyze the framework directory
config: configuration file. Put all project related configurations in this folder. python supports yaml and ini
ini file introduction
Start with [section]
End with [option=value]
Remarks in; start
The section name cannot be duplicated
Introduction to yaml file
Starting with --- indicates the beginning of the file
All members in the list start at the same indentation level and start with a "-" (a horizontal bar and a space)
A dictionary consists of a simple key: the form of a value (this colon must be followed by a space)
ini read file encapsulation, yaml read file encapsulation
configutil.py
import configparser import os import yaml class ReadIni(): def read_ini(file, section, option): conf = configparser.ConfigParser() conf.read(file) res=conf.get(section, option) print(res) return res class ReafYaml(): def read_yaml(file,key): f=open(file,encoding='utf-8') file_data =f.read() res=yaml.load(file_data,Loader=yaml.FullLoader) print(res.get(key)) return res.get(key) if __name__ == '__main__': current_path = os.path.dirname(os.path.realpath(__file__)) config_path = os.path.dirname(current_path) + os.sep + "config" yaml_file = os.path.join(config_path, 'test.yaml') ReafYaml.read_yaml(yaml_file, 'username')
Data: data file. Put the test case parameterization related files here, xlsx,csv,json
Driver: driver file
Log: log files, such as test log and error log
report: Test report
Test: test file
Case test case
test.py
import unittest from selenium import webdriver from test.locators import * from utils.configutil import ReadIni,ReafYaml from test.page import * from utils.excelutil import * from selenium.webdriver.common.action_chains import ActionChains import yaml import os from utils.logutil import * current_path = os.path.dirname(os.path.realpath(__file__)) config_path = os.path.dirname(current_path) + os.sep + "config" ini_file = os.path.join(config_path, 'test.ini') ip = ReadIni.read_ini(ini_file, 'ip_address', 'ip') # print(ip) url = '{}user/login?redirect=http%3A%2F%2Fmis-next.aunbox.ce%2FuserDetail'.format(ip) excel_file = os.path.join(os.path.dirname(current_path) + os.sep + "data", 'case.xlsx') username = ReadExcel.read_excel(excel_file,'Sheet1','A') class LoginTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.maximize_window() self.driver.implicitly_wait(10) self.driver.get(url) def test_login(self): Logger('C:\\Users\\Administrator\\PycharmProjects\\yunding\\log\\test.log','info').info('add project') for user in username: loginpage=LoginPage(self.driver) loginpage.enter_username(user) loginpage.enter_password() loginpage.click_login_button() self.assertEqual('Super administrator',loginpage.get_login_name()) quitlogin=self.driver.find_element_by_xpath('//*[@id="root"]/section/section/header/div[2]/span') ActionChains(self.driver).move_to_element(quitlogin).perform() self.driver.find_element_by_class_name('ant-dropdown-menu-item').click() self.driver.get(url) # self.driver.find_element(*LoginLocators.username).send_keys("{}".format(user)) # self.driver.find_element(*LoginLocators.password).send_keys("{}".format(pad)) # self.driver.find_element(*LoginLocators.loginbutton).click() # id=self.driver.find_element(*LoginLocators.loginname) # self.assertEqual('Super administrator ', id.text) def tearDown(self): self.driver.quit() if __name__ == '__main__': unittest.main()
Common - test related abstract common code
Page page class
Element positioning
locators.py
from selenium.webdriver.common.by import By # Page element class LoginLocators(): username=(By.ID,'account') password=(By.ID,'password') loginbutton=(By.CLASS_NAME,'ant-btn') loginname=(By.CLASS_NAME,'userName___fQOhV')
Element operation
page.py
from test.locators import * # Operation of page elements class BasePage(): def __init__(self,driver): self.driver = driver class LoginPage(BasePage): ''' Operation of user login page element,,,Disappear here ''' UserName = (By.XPATH,'//*[@ id="username"]) # login def enter_username(self,name): ele = self.driver.find_element(*LoginLocators.username) # ele.clear() ele.send_keys(name) #Enter the user name element def enter_password(self): ele = self.driver.find_element(*LoginLocators.password) ele.send_keys('123456') #Input password def click_login_button(self): ele = self.driver.find_element(*LoginLocators.loginbutton) ele.click() #Click the login button def get_login_name(self): ele = self.driver.find_element(*LoginLocators.loginname) return ele.text #Return login
utils: public method
config class
log class
logutil.py
import logging from logging import handlers class Logger(object): level_relations = { 'debug':logging.DEBUG, 'info':logging.INFO, 'warning':logging.WARNING, 'error':logging.ERROR, 'critical':logging.CRITICAL } def __init__(self,fp='d:\\Project_Redmine_01\\log\\test.log',level='info'): self.level = self.level_relations.get(level) self.logger = logging.getLogger(fp) self.logger.setLevel(self.level) formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') th = handlers.TimedRotatingFileHandler(fp) th.setFormatter(formatter) th.setLevel(self.level) self.logger.addHandler(th) def debug(self,msg): self.logger.debug(msg) def info(self,msg): self.logger.info(msg) def warning(self,msg): self.logger.warning(msg) def error(self,msg): self.logger.error(msg) def critical(self,msg): self.logger.critical(msg) if __name__ == '__main__': log = Logger('abcd.log','debug') log.info('this is info msg') log.critical('this is critical msg')
Read and write excel classes
excelutil.py
import configparser import os import yaml class ReadIni(): def read_ini(file, section, option): conf = configparser.ConfigParser() conf.read(file) res=conf.get(section, option) print(res) return res class ReafYaml(): def read_yaml(file,key): f=open(file,encoding='utf-8') file_data =f.read() res=yaml.load(file_data,Loader=yaml.FullLoader) print(res.get(key)) return res.get(key) if __name__ == '__main__': current_path = os.path.dirname(os.path.realpath(__file__)) config_path = os.path.dirname(current_path) + os.sep + "config" yaml_file = os.path.join(config_path, 'test.yaml') ReafYaml.read_yaml(yaml_file, 'username')
The class that generates the report
run.py
import os import time import unittest import HTMLTestRunner current_path = os.path.dirname(os.path.realpath(__file__)) # print(current_path) report_path = os.path.join(current_path,'report') # print(report_path) case_path = os.path.join(current_path,'test') # print(case_path) report_name = time.strftime('%Y%m%d%H%M%S',time.localtime((time.time()))) testsuite = unittest.TestLoader().discover(case_path) filename = "{}\\{}.html".format(report_path,report_name) f = open(filename,'wb') runner = HTMLTestRunner.HTMLTestRunner(stream=f,title='report',description='this is a report') runner.run(testsuite) f.close()
Finally, I would like to thank everyone who carefully reads my article. Watching the rise and attention of fans all the way, reciprocity is always necessary. Although it is not very valuable, you can take it directly if you can use it:
These materials should be the most comprehensive and complete preparation warehouse for [software testing] friends. This warehouse also accompanies tens of thousands of test engineers through the most difficult journey. I hope it can also help you!
In my QQ technology exchange group (technology exchange and resource sharing, advertising do not disturb)
You can take it away yourself, group number: free information in 175317069 groups is the essence of the author's more than 10 year test career. And the great gods of the same industry exchange technology together
If it helps you a little, your "praise" is the biggest driving force for Xiaobian's creation. See you in the next article!