Python and selenium realize Web automation: read ini configuration files, element packaging, code packaging, exception handling, compatible with multi-browser execution

If this article still doesn’t make you understand, you can take a look at the following article, which is very detailed, and tens of thousands of people have watched this video!

A web automation testing tutorial from a boss who has worked in Huawei for 10 years, a tutorial on Huawei’s current technology! _哔哩哔哩_bilibili has worked in Huawei for 10 years, a web automation testing tutorial, Huawei’s current technology tutorial! A total of 16 videos, including: 1. [web automation] comparison of mainstream web automation testing technologies, 2. [web automation] one-click setup of Selenium automation test environment, 3. [web automation] detailed explanation of Selenium’s eight positioning strategies, etc., UP master update What a wonderful video, please pay attention to the UP account. https://www.bilibili.com/video/BV1sM4y1d7tq/?spm_id_from=333.337.search-card.all.click

1. Foreword

There are indeed a lot of people asking me about automation recently. I have a whim: I want to explain python + selenium from 0 to realize web automation testing. Please pay attention to the blog for continuous updates!

This is the fifth blog post of python + selenium to realize web automation

2. Selenium – read element configuration file

After the previous study, we can already write some simple automated test cases, but do you feel that we have written a lot of repetitive code. For example: the search and value transfer of key elements in the page. For an automated test page, the elements of the page are relatively stable, so we can encapsulate these repetitive codes and directly read the relatively stable elements in the page. We can Written in the configuration file, when the page elements change, you only need to modify the corresponding page element information, instead of modifying the code every time, so as to avoid introducing bugs as much as possible.

1. Create a configuration file

Before reading the configuration file, write it into the configuration file according to the characteristics of the page elements.

[RegisterElement]
register_email = id>register_email
register_nickname = id>register_nickname
register_password = id>register_password
getcode_num = id>getcode_num
captcha_code = id>captcha_code

2. Read configuration file

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
@Desc : None
"""
 
import configparser
 
 
class ReadIni(object):
    # Initialize configuration file path and node loading
    def __init__(self, file_name=None, node=None):
        if file_name is None:
            self.file_name = '../data/RegisterElement.ini'
        if node is None:
            self.node = 'RegisterElement'
        else:
            self.node = node
 
        self.cf = self.load_ini()
 
    # load configuration file
    def load_ini(self):
        cf = configparser. ConfigParser()
        cf. read(self. file_name)
        return cf
 
    # Get the value of each configuration item
    def get_value(self, key):
        data = self.cf.get(self.node, key)
        return data
 
 
if __name__ == "__main__":
    ri = ReadIni()
    print(ri.get_value('register_nickname'))

3. Selenium-element encapsulation

Find page element code wrappers.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
@Desc : None
"""
 
 
from util.read_ini import ReadIni
 
 
class FindElement(object):
    def __init__(self, driver):
        self.driver = driver
 
    def get_element(self, key):
        ri = ReadIni()
        data = ri. get_value(key=key)
        by = data. split('>')[0]
        value = data. split('>')[1]
        try:
            if by == 'id':
                return self.driver.find_element_by_id(value)
            elif by == 'name':
                return self.driver.find_element_by_name(value)
            elif by == 'className':
                return self.driver.find_element_by_className(value)
            else:
                return self.driver.find_element_by_xpath(value)
        except:
            file_path = '../image/no_element.png'
            self.driver.save_screenshot(file_path)
 
 
if __name__ == "__main__":
    fe = FindElement()
    fe.get_element('register_nickname')

4. Selenium-code encapsulation

Do you feel that although the code is written here, it is very unorganized. Yes, modularize your code now so that each module does a part of it.

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@Desc : None
"""
 
from selenium import webdriver
from time import sleep
from util.read_ini import ReadIni
from basic.find_element import FindElement
import random
from PIL import Image
from api import ShowapiRequest
 
 
class Register(object):
    def __init__(self, url):
        self. driver = self. get_driver(url=url)
 
    # Start the browser and open the target test page url
    def get_driver(self, url):
        driver = webdriver.Chrome('../tools/chromedriver.exe')
        driver. get(url=url)
        driver. maximize_window()
        return driver
 
    # Locate user information and get element element
    def get_user_element(self, key):
        find_element = FindElement(self.driver)
        user_element = find_element. get_element(key=key)
        return user_element
 
    # Enter user information
    def send_user_info(self, key, data):
        self.get_user_element(key=key).send_keys(data)
 
    # get random number
    def get_range(self):
        number = ''.join(random.sample('abcdefg123456', 8))
        return number
 
    # Get the verification code image
    def get_captcha_image(self, file_name):
        self.driver.save_screenshot(filename=file_name)
        captcha_element = self. get_user_element('getcode_num')
        left = captcha_element. location['x']
        top = captcha_element. location['y']
        right = captcha_element. size['width'] + left
        height = captcha_element.size['height'] + top
        image = Image.open(file_name)
        img = image.crop((left, top, right, height))
        img. save(file_name)
 
    # Identify image verification code
    def discern_captcha_image(self, file_name):
        self.get_captcha_image(file_name=file_name)
        # Parse the text in the verification code picture (use the third-party picture verification code to identify the interface ShowApiRequest)
        r = ShowapiRequest("http://route.showapi.com/184-4", "48120", "12c017278c0845c2bcda177212d2d2ac")
        r.addBodyPara("img_base64", "")
        r.addBodyPara("typeId", "35")
        r.addBodyPara("convert_to_jpg", "0")
        r.addBodyPara("needMorePrecise", "0")
        r.addFilePara("image", file_name) # set when uploading files
        res = r. post()
        text = res.json()["showapi_res_body"]["Result"]
        return text
 
    # main function
    def main(self):
        register_nickname = self. get_range()
        register_email = self.get_range() + '@163.com'
        register_password = self.get_range() + '@123'
        file_name = '../image/code_image.png'
        captcha_code = self.discern_captcha_image(file_name=file_name)
        self.send_user_info('register_nickname', register_nickname)
        self.send_user_info('register_email', register_email)
        self.send_user_info('register_password', register_password)
        self.send_user_info('captcha_code', captcha_code)
        self.get_user_element('register-btn').click()
        sleep(5)
        self. driver. close()
 
 
if __name__ == "__main__":
    register_url = 'http://www.5itest.cn/register'
    r = Register(register_url)
    r. main()

5. Selenium – exception handling

During the test, we must let the program run smoothly, but also pay attention to handling the exception of the program. For example: because the third-party interface called is the picture of the verification code, it is inevitable that it will not be recognized. In order not to block the normal operation of the program, when the recognition error occurs, the error recognition can be handled abnormally.

# Add the wrong element id of the verification code in the [RegisterElement.ini] file
captcha_code_error = id>captcha_code-error
# Add exception handling on the basis of package.py code
# Exception handling: Take a screenshot if the registration fails, which is convenient for troubleshooting
        captcha_code_error = self. get_user_element('captcha_code_error')
        if captcha_code_error is None:
            print("...Congratulations on your successful registration...")
        else:
            self.driver.save_screenshot('../image/captcha_code_error.png')
        sleep(5)

6. Selenium-Compatible with multi-browser execution

In the actual test, due to the differences in the technical standards of different browsers, the same code has inconsistent expressions in different browsers, so it is unavoidable to execute test cases in multiple browsers.

Note: The FireFox driver is configured differently from the Chrome driver
Download address: https://github.com/mozilla/geckodriver/releases
After downloading (choose according to the system version):
    (1) Unzip and take out geckodriver.exe (take 64x as an example);
    (2) Put geckodriver.exe in the Firefox installation directory, such as: (D:\Firefox\Mozilla Firefox);
    (3) Add the Firefox installation directory (D:\Firefox\Mozilla Firefox) to the environment variable path;
    (4) Restart IDEA, remember to
# Compatible with multi-browser execution tests
    def get_more_driver(self, url, browser):
        if browser == 'chrome':
            # Driver corresponding to version 76.0.3809.100 (64-bit)
            driver = webdriver.Chrome('../tools/chromedriver.exe')
        elif browser == 'firefox':
            # The driver corresponding to FireFox 68.0.2 (64-bit) is different from the chrome driver
            driver = webdriver. Firefox()
        driver. get(url=url)
        driver. maximize_window()
        return driver

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledgePython entry skill treeWeb crawlerSelenium258551 People are studying systematically