First of all, you have to know what is Selenium?
Selenium is a browser-based automated testing tool that provides a cross-platform, cross-browser end-to-end web automation solution. Selenium mainly includes three parts: Selenium IDE, Selenium WebDriver and Selenium Grid.
- Selenium IDE: An extension of Firefox, it can record and play back, and export the recorded operations into test cases in multiple languages (such as java, python, etc.).
- Selenium WebDriver: Provides the API required for Web automation, mainly used for browser control, page element selection and debugging. Different browsers require different WebDrivers.
- Selenium Grid: Provides the ability to run selenium tests on different browsers on different machines.
Next, I will use the mind map directory structure to introduce the basic test framework, and write test cases for functional test cases. I hope it will be helpful to your study.
Design ideas
The framework uses python3 + selenium3 + PO + yaml + ddt + unittest and other technologies to write a basic test framework, which can meet the needs of daily testing work.
1. Use the Page Object mode to separate page positioning and business operations, separate test objects (element objects) and test scripts (use case scripts), build an object class for each page, and improve the maintainability of use cases;
2. Use yaml to manage page control element data and test case data. For example, when the element ID changes, you don’t need to modify the test code, you only need to modify it in the corresponding page element yaml file;
3. Sub-module management, independent of each other, assembled at any time, ready to use.
Layered Design of Test Framework
Encapsulate common operations and searches into basic classes, no matter what product it is, it can be reused directly
- The business layer mainly encapsulates the object page class, one class is built for each page, and the business layer page inherits the base layer
- The use case layer constructs the simulation execution test for the product page function
- The framework layer provides basic components to support the entire process execution and function expansion, and provides the use case layer with element data of each page, use case test data, test report output, etc.
Test framework directory structure
The directory structure of the mind map is introduced as follows:
Writing a use case method
testinfo: - id: test_login001 title: Login Test info: open drawer home page testcase: - element_info: login-link-a find_type: ID operate_type: click info: open the login dialog - element_info: mobile find_type: ID operate_type: send_keys info: enter the phone number - element_info: mbpwd find_type: ID operate_type: send_keys info: enter password - element_info: //input[@class='keeplogin'] find_type: XPATH operate_type: click info: Click to cancel the automatic login radio box - element_info: //span[text()='login'] find_type: XPATH operate_type: click info: click the login button - element_info: userProNick find_type: ID operate_type: perform info: mouseover account menu - element_info: //a[@class='logout'] find_type: XPATH operate_type: click info: opt out check: - element_info: //div[@class='box-mobilelogin'] /div[1]/span find_type: XPATH info: check input mobile phone number or password, log in abnormal prompt - element_info: userProNick find_type: ID info: successfully logged in - element_info: reg-link-a find_type: ID info: Check if the logout is successful login.yaml
For example, we want to add a login function test case:
First of all, just add a page object yaml file in the testyaml directory, and write it with reference to the login.yaml format. These files are provided to encapsulate page object classes to call and perform location recognition operations.
- id: test_login001.1 detail : mobile phone number and password are empty to log in screenshot : phone_pawd_empty data: phone: "" password: "" check: - Mobile phone number cannot be empty - id: test_login001.2 detail : mobile phone number is empty to log in screenshot : phone_empty data: phone: "" password : aa check: - Mobile phone number cannot be empty - id: test_login001.3 detail : the password is empty to log in screenshot : pawd_empty data: phone: 13511112222 password: "" check: - password can not be blank - id: test_login001.4 detail : Illegal phone number login screenshot : phone_error data: phone: abc password: aa check: - The format of the mobile phone number is wrong - id: test_login001.5 detail : phone number or password does not match screenshot : pawd_error data: phone: 13511112222 password: aa check: - Wrong account password - id: test_login001.6 detail : The phone number and password are correct screenshot : phone_pawd_success data: phone: 13865439800 password: ******** check: - yingoja login_data.yaml login_data.yaml
Secondly, add a login_data.yaml file in the testdata directory to provide the test data for the login interface to pass parameters, and refer to the login_data.yaml file for the writing format.
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = 'YinJia' import os,sys sys.path.append(os.path.dirname(os.path.dirname (os. path. dirname(__file__)))) from config import setting from selenium.webdriver.support.select import Select from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from public.page_obj.base import Page from time import sleep from public.models.GetYaml import getyaml testData = getyaml(setting.TEST_Element_YAML + '/' + 'login.yaml') class login(Page): """ User login page """ url = '/' dig_login_button_loc = (By.ID, testData. get_elementinfo(0)) def dig_login(self): """ Home Login :return: """ self. find_element(*self. dig_login_button_loc) .click() sleep(1) # Locator, locate the element object through the element attribute # Mobile phone number input box login_phone_loc = (By.ID,testData. get_elementinfo(1)) # password input box login_password_loc = (By.ID,testData. get_elementinfo(2)) # cancel automatic login keeplogin_button_loc = (By.XPATH,testData. get_elementinfo(3)) # click login login_user_loc = (By.XPATH,testData. get_elementinfo(4)) # log out login_exit_loc = (By.ID, testData. get_elementinfo(5)) # opt out login_exit_button_loc = (By.XPATH,testData. get_elementinfo(6)) def login_phone(self, phone): """ log in with phone number :param username: :return: """ self. find_element(*self. login_phone_loc). send_keys(phone) def login_password(self, password): """ login password :param password: :return: """ self. find_element(*self. login_password_loc). send_keys(password) def keeplogin(self): """ Cancel radio automatic login :return: """ self. find_element(*self. keeplogin_button_loc). click() def login_button(self): """ login button :return: """ self.find_element(*self.login_user_loc).click() def login_exit(self): """ Exit system :return: """ above = self. find_element(*self. login_exit_loc) ActionChains(self. driver). move_to_element(above). perform() sleep(2) self. find_element(*self. login_exit_button_loc) .click() def user_login(self, phone, password): """ Log entry :param username: username :param password: password :return: """ self. open() self. dig_login() self. login_phone(phone) self. login_password(password) sleep(1) self. keeplogin() sleep(1) self. login_button() sleep(1) phone_pawd_error_hint_loc = (By.XPATH,testData. get_CheckElementinfo(0)) user_login_success_loc = (By.ID,testData. get_CheckElementinfo(1)) exit_login_success_loc = (By.ID,testData. get_CheckElementinfo(2)) # Phone number or password error prompt def phone_pawd_error_hint(self): return self.find_element(*self.phone_pawd_error_ hint_loc).text# login success username def user_login_success_hint(self): return self.find_element(*self.user_login_ success_loc).text # log out def exit_login_success_hint(self): return self.find_element(*self.exit_login_ success_loc).textloginPage.py
Then, add a loginPage.py file under the page_obj directory, which is used to encapsulate the login page object class and execute the login test process operation.
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = 'YinJia' import os,sys sys.path.append(os.path.dirname(os.path. dirname(__file__))) import unittest,ddt,yaml from config import setting from public.models import myunit, screenshot from public.page_obj.loginPage import login from public.models.log import Log try: f =open(setting.TEST_DATA_YAML + '/' + 'login_data.yaml',encoding='utf-8') testData = yaml. load(f) except FileNotFoundError as file: log = Log() log.error("The file does not exist: {0}".format(file)) @ddt.ddt class Demo_UI(myunit. MyTest): """Drawer new hot list login test""" def user_login_verify(self, phone, password): """ User login :param phone: phone number :param password: password :return: """ login(self.driver).user_login(phone,password) def exit_login_check(self): """ sign out :return: """ login(self. driver). login_exit() @ddt.data(*testData) def test_login(self, datayaml): """ login test :param datayaml: load login_data login test data :return: """ log = Log() log.info("currently executing test case ID-> {0} ; test point-> {1}".format(datayaml['id'],datayaml['detail'])) # Call the login method self.user_login_verify(datayaml['data']['phone'], datayaml['data']['password']) po = login(self. driver) if datayaml['screenshot'] == 'phone_pawd_success': log.info("Checkpoint -> {0}".format (po. user_login_success_hint())) self.assertEqual(po.user_login_success_hint(), datayaml['check'][0], "Successful login, the actual result returned is ->: {0}".format(po.user_login_success_hint())) log.info("Successful login, the actual result returned is ->: {0}".format(po.user_login_success_hint())) screenshot.insert_img(self.driver, datayaml ['screenshot'] + '.jpg') log.info("-----> Start to execute exit process operation") self. exit_login_check() po_exit = login(self. driver) log.info("Checkpoint -> found {0} element, indicating successful exit!".format(po_exit.exit_login_success_hint())) self.assertEqual(po_exit.exit_login_success_hint(), 'Register',"Exit login, the actual result returned is ->: {0}".format(po_exit.exit_login_success_hint())) log.info("Exit login, the actual result returned is ->: {0}".format(po_exit.exit_login_success_hint())) else: log.info("Checkpoint -> {0}".format(po.phone _pawd_error_hint())) self.assertEqual(po.phone_pawd_error_hint(), datayaml['check'][0] , "Abnormal login, the actual result returned is ->: {0}".format(po.phone_pawd_error_hint())) log.info("Abnormal login, the actual result returned is ->: {0}".format(po.phone_pawd_error_hint())) screenshot.insert_img(self.driver,datayaml ['screenshot'] + '.jpg') if __name__=='__main__': unittest. main() login_sta.py
Finally, create a test case file login_sta.py in the testcase directory, and use the ddt data driver to read the yaml test data file
To sum up, writing a use case method only needs to follow the above four steps to create -> write.
Execute the following main program, you can see the actual output results.
#!/usr/bin/env python # _*_ coding:utf-8 _*_ __author__ = 'YinJia' import os,sys sys.path.append(os.path.dirname(__file__)) from config import setting import unittest,time from package.HTMLTestRunner import HTMLTestRunner from public.models.newReport import new_report from public.models.sendmail import send_mail # Test report storage folder, if it does not exist, it will be created automatically A report directory if not os.path.exists(setting.TEST_REPORT):os.makedirs (setting.TEST_REPORT + '/' + "screenshot") def add_case(test_path=setting.TEST_DIR): """Load all test cases""" discover = unittest.defaultTestLoader.discover (test_path, pattern='*_sta.py') return discover def run_case(all_case, result_path=setting.TEST_REPORT): """Execute all test cases""" now = time.strftime("%Y-%m-%d %H_%M_%S") filename = result_path + '/' + now + 'result.html' fp = open(filename,'wb') runner = HTMLTestRunner(stream=fp,title=' Drawer New Hot List UI Automation Test Report', description='Environment: windows 7 browser: chrome', tester='Jason') runner. run(all_case) fp. close() report = new_report(setting.TEST_REPORT) #Call the module to generate the latest report send_mail(report) #call send mail module if __name__ =="__main__": cases = add_case() run_case(cases)
Test result display
HTML report log
Click on the screenshot of the HTML report, and the screenshot will pop up
Test report passed log
Automatic screenshots are stored in the specified directory
Email test report
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledgePython entry skill treeWeb crawlerSelenium298966 people are studying systematically