First you need to know what Selenium is.

Selenium is a browser-based test automation 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: A Firefox extension that records playback and exports recorded actions as test cases in a variety of languages such as Java, Python, and so on.

  • Selenium WebDriver: Provides apis required for Web automation, primarily 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 testing framework, write test cases for functional test cases, hoping to help you learn.

Design ideas

The framework uses PYTHON3 + SELENium3 + PO + YAML + DDT + UNITtest and other techniques to write the basic test framework, which can adapt to the needs of daily testing.

  1. Page Object mode is used to separate Page positioning and business operations, separate test objects (element objects) and test scripts (use case scripts), and build an Object class for each Page to improve the maintainability of use cases;

  2. Manage page control element data and test case data using YAML. For example, when the element ID changes, there is no need to modify the test code, just need to modify in the corresponding page element YAML file.

  3. Module management, do not affect each other, assembly at any time, take and use.

The test framework is designed in layers




Encapsulate common operations and lookups into basic classes that can be reused, no matter what the product

  • The business layer is mainly to encapsulate the object page class, a page to build a class, the business layer page inherit the base layer

  • The use case layer constructs mock execution tests against product page functionality

  • The framework layer provides basic components to support the execution and function expansion of the whole process, and provides element data of each page, test data of use cases, test report output and so on for the use case layer

Test the framework directory structure




The following mind map directory structure is introduced:




Write use case methods

If software testing, interface testing, automated testing, interview experience exchange. If you are interested, you can pay attention to our love code teacher. There will be links to free materials released from time to time in the public account. These materials are collected and sorted out from various technical websites.

Testinfo: -id: test_login001 title: login testinfo: open the home page testcase: -element_info: login-link-aFind_type: ID operate_type: click info: open the login dialog box. -element_info: mobile find_type: ID operate_type: send_keys info: -element_info: MBPWD find_type: ID operate_type: send_keys info: Password -element_info: //input[@class='keeplogin'] find_type: XPATH operate_type: click info: click to cancel automatic login. -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: hover account menu - element_info: //a[@class='logout'] find_type: XPATH operate_type: click info: exit check: -element_info: //div[@class='box-mobilelogin']/ div[1]/span find_type: XPATH info: check the input mobile phone number or password. The login error message is displayed. -element_info: userProNick find_type: ID info: Successful login - element_info: reg-link-aFind_type: ID info: checks whether login.yaml is successfully logged outCopy the code

For example, let’s add a login function test case:

First, just add a page object yaml file in the TestyAML directory and write it in the login.yaml format. These files are provided to the wrapper page object class to call and perform location recognition operations.

-id: test_login001.1 detail: Mobile phone number and password is empty login screenshot: phone_pawd_empty data: phone:""
password: ""Check: - Phone number cannot be empty - id: test_login001.2 detail: phone number is empty login screenshot: phone_empty data: phone:""Password: aa check: - Mobile phone number cannot be empty - id: test_login001.3 detail: Password is empty login screenshot: pawd_empty data: phone: 13511112222 password:""Check: - Password cannot be empty - id: test_login001.4 detail: invalid phone number login screenshot: phone_error data: phone: ABC password: Aa check: - The phone number format is not correct. - ID: test_login001.5 detail: The phone number or password does not match screenshot: pawd_error data: phone: 13511112222 password: AA check: - Account password error - ID: test_login001.6 detail: phone number and password correct screenshot: phone_pawd_success data : phone : 13865439800 password: ******** check : - yingoja login_data.yaml login_data.yamlCopy the code

Second, add a login_data.yaml file to the testdata directory to provide the testdata that the login interface transmits. The format is described in the login_data.yaml file.

#! /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)
# localizer, using element attributes to locate element objects
# 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):
"""Param username: :return:"""
self.find_element(*self.login_phone_loc).
send_keys(phone)def login_password(self,password):
"""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):
"""Login entry :param 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))
# Incorrect mobile phone number or password
def phone_pawd_error_hint(self):
return self.find_element(*self.phone_pawd_error_
hint_loc).textThe user name of the successful login
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

Copy the code

Then, add a loginpage.py file in the page_obj directory to encapsulate the loginPage object class and perform the login test flow operations.

#! /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("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):
"""Log out :return:"""
login(self.driver).login_exit()
@ddt.data(*testData)
def test_login(self,datayaml):
"""Login test :param DatayAML: Loads 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, return actual result is ->: {0}".format(po.user_login_success_hint()))
log.info("Successful login, return actual result is ->: {0}".format(po.user_login_success_hint()))
screenshot.insert_img(self.driver, datayaml
['screenshot'] + '.jpg')
log.info("-----> Start the exit process operation")
self.exit_login_check()
po_exit = login(self.driver)
log.info("Checkpoint -> Find {0} element, exit successful!".format(po_exit.exit_login_success_hint()))
self.assertEqual(po_exit.exit_login_success_hint(),
'registered'."Log out, return the actual result is ->: {0}".format(po_exit.exit_login_success_hint()))
log.info("Log out, return the actual result 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] , ->: {0}.format(po.phone_pawd_error_hint()))
log.info(->: {0}.format(po.phone_pawd_error_hint()))
screenshot.insert_img(self.driver,datayaml
['screenshot'] + '.jpg')
if __name__=='__main__':
unittest.main()
login_sta.py
Copy the code

Finally, the testcase file login_sta.py is created in the testcase directory, and the yaml test data file is read using DDT data driver

To sum up, writing a use-case method is just a matter of following these four steps: 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
Create test report folder automatically if it does not existA report directoryif 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='Automated Test Report of drawer New Hot List UI',
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 the send mail module
if __name__ =="__main__":
cases = add_case()
run_case(cases)
Copy the code

Test results presentation

HTML report log




HTML Report Click screenshot to pop up screenshot




Log that the test report passes




Automatic screenshots are saved to the specified directory




Email Test Report




Further reading

  • Learn the best books on software testing. These 8 books can help you a lot
  • At what stage are you on the path to becoming a test engineer?