Python automated test series [v1.0.0][Common page operation processing with source code]

[Smart waiting]

# 用于实现智能等待页面元素的出现
# encoding = utf-8
"""
__title__ = ''
__author__ = 'davieyang'
__mtime__ = '2018/4/21'
"""
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import difflib


class Smart_Waiting:

    def __init__(self, driver):
        self.locationTypeDict = {
    
    
            "xpath": By.XPATH,
            "id": By.ID,
            "name": By.NAME,
            "css_selector": By.CSS_SELECTOR,
            "class_name": By.CLASS_NAME,
            "tag_name": By.TAG_NAME,
            "link_text": By.LINK_TEXT,
            "partial_link_text": By.PARTIAL_LINK_TEXT
        }
        self.driver = driver
        self.wait = WebDriverWait(self.driver, 30)

    def presence_of_element_located(self, location_type, locator_expression, *args):
        """
        显示等待页面元素出现在DOM中,但并不一定可见,存在则返回该页面元素对象
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            if location_type.lower() in self.locationTypeDict:
                # if self.locationTypeDict.has_key(locatorMethod.lower()):
                self.wait.until(
                    EC.presence_of_element_located((
                        self.locationTypeDict[location_type.lower()], locator_expression)))
            else:
                raise TypeError(u"未找到定位方式,请确认定位方法是否正确")
        except Exception as e:
            raise e

    def frame_to_be_available_and_switch_to_it(self, location_type, locator_expression, *args):
        """
        判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            self.wait.until(
                EC.frame_to_be_available_and_switch_to_it((
                    self.locationTypeDict[location_type.lower()], locator_expression)))
        except Exception as e:
            # 抛出异常信息给上层调用者
            raise e

    def visibility_element_located(self, location_type, locator_expression, *args):
        """
        判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.visibility_of_element_located((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element
        except Exception as e:
            raise e

    def wait_title_is(self, string, location_type, locator_expression, *args):
        """
        当页面标题是string时对页面元素进行定位,并返回页面元素对象
        :param string:
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            if self.driver.title == string:
                element = self.wait.until(
                    EC.visibility_of_element_located((self.locationTypeDict[location_type.lower()], locator_expression)))
                return element
        except Exception as e:
            raise e

    def wait_title_contain(self, string, location_type, locator_expression, *args):
        """
         当页面标题与string进行比较相似度大于0.8时对页面元素进行定位,并返回页面元素对象
        :param string:
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        page_tile = driver.title
        similarity = difflib.SequenceMatcher(None, page_tile, string).quick_ratio()
        try:
            if similarity >= 0.8:
                element = self.wait.until(
                    EC.visibility_of_element_located((self.locationTypeDict[location_type.lower()], locator_expression)))
                return element
        except Exception as e:
            raise e

    def visibility_of_element(self, location_type, locator_expression, *args):
        """
        判断元素是否可见,如果可见就返回这个元素
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.visibility_of((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element
        except Exception as e:
            raise e

    def presence_of_all_elements_located(self, location_type, locator_expression, *args):
        """
        判断是否至少有1个元素存在于dom树中,如果定位到就返回列表
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element_list = self.wait.until(
                EC.presence_of_all_elements_located((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element_list
        except Exception as e:
            raise e

    def visibility_of_any_elements_located(self, location_type, locator_expression, *args):
        """
        判断是否至少有一个元素在页面中可见,如果定位到就返回列表
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element_list = self.wait.until(
                EC.visibility_of_any_elements_located((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element_list
        except Exception as e:
            raise e

    def text_to_be_present_in_element(self, string, location_type, locator_expression, *args):
        """
        判断指定的元素中是否包含了预期的字符串,返回布尔值
        :param string:
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            self.wait.until(
                EC.text_to_be_present_in_element((self.locationTypeDict[location_type.lower()], locator_expression), string))
        except Exception as e:
            raise e

    def text_to_be_present_in_element_value(self, string, location_type, locator_expression, *args):
        """
        判断指定元素的属性值中是否包含了预期的字符串,返回布尔值
        :param string:
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            self.wait.until(
                EC.text_to_be_present_in_element_value((self.locationTypeDict[location_type.lower()], locator_expression), string))
        except Exception as e:
            raise e

    def invisibility_of_element_located(self, location_type, locator_expression, *args):
        """
        判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.invisibility_of_element_located((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element
        except Exception as e:
            raise e

    def element_to_be_clickable(self, location_type, locator_expression, *args):
        """
        判断某个元素中是否可见并且是enable的,代表可点击
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.element_to_be_clickable((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element
        except Exception as e:
            raise e

    def element_to_be_selected(self, location_type, locator_expression, *args):
        """
        判断某个元素是否被选中了,一般用在下拉列表
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.element_to_be_selected((self.locationTypeDict[location_type.lower()], locator_expression)))
            return element
        except Exception as e:
            raise e

    def element_selection_state_to_be(self, location_type, locator_expression, *args):
        """
        判断某个元素的选中状态是否符合预期
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.element_selection_state_to_be((self.locationTypeDict[location_type.lower()], locator_expression), True))
            return element
        except Exception as e:
            raise e

    def element_located_selection_state_to_be(self, location_type, locator_expression, *args):
        """
        判断某个元素的定位状态是否符合预期
        :param location_type:
        :param locator_expression:
        :param args:
        :return:
        """
        try:
            element = self.wait.until(
                EC.element_located_selection_state_to_be((self.locationTypeDict[location_type.lower()], locator_expression), True))
            return element
        except Exception as e:
            raise e

    def alert_is_present(self):
        """
        判断页面上是否存在alert,如果有就切换到alert并返回alert的内容
        """
        try:
            alert_instance = self.wait.until(EC.alert_is_present())
            print(alert_instance.text)
            alert_instance.accept()
        except Exception as e:
            raise e


if __name__ == "__main__":
    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get("http://mail.126.com")
    # 实例化WaitUtil类
    waitUtil = Smart_Waiting(driver)
    # 判断如果id = x-URS-iframe的iframe存在则切换进去
    wf = waitUtil.frame_to_be_available_and_switch_to_it("id", "x-URS-iframe")
    # 等待页面元素xpath = //input[@name='email']的出现
    wv = waitUtil.visibility_element_located("xpath", "//input[@name='email']")
    # 显示等待页面元素出现在DOM中,但并不一定可见,存在则返回该页面元素对象
    wp = waitUtil.presence_of_element_located("xpath", "//input[@name='email']")
    driver.quit()

[Win32 simulated keyboard]

In the actual process of automated code debugging, the methods provided by Selenium are often not sufficient for automation tasks. For example, if you want to position a button to complete the click operation, the positioning is correct but the click cannot be completed. At this time, if you master the method of simulating the keyboard, it can help us Automation helps a lot.

Install Pywin32

To simulate keyboard operations, you need to first install the relevant modules for Python, start the command line, and then execute the command "pip install –U pywin32" on the command line. The execution results are as follows

C:\Users\davieyang>pip install pywin32
Collecting pywin32
  Using cached https://files.pythonhosted.org/packages/a3/8a/eada1e7990202cd27e58eca2a278c344fef190759bbdc8f8f0eb6abeca9c/pywin32-224-cp37-cp37m-win_amd64.whl
Installing collected packages: pywin32
Successfully installed pywin32-224

Seeing Successfully installed pywin32-xxx means the installation is successful.

Unable to import module

If after using pip to install, win32apiand cannot be win32conintroduced into the project, you can also directly download the installation file. The download address is
pywin32 . It must be pointed out that only Build 222the previous version can be found at this address. The new version has been moved to pywin32 . The file is .exe, just double-click to install it

Method encapsulation

Create a new Python file under the Util path in the PO project and name it Keyboard_Simulation, and then write the following code in the file.

# 用于实现模拟键盘单个或多个组合键操作
# encoding = utf-8
import win32api
import win32con
class Simulate_Keyboard:
    """
    定义字典,字典内容为键盘上的按键与VkCode的键值对
    """
    VK_CODE = {
    
    
        'backspace': 0x08,
        'tab': 0x09,
        'clear': 0x0C,
        'enter': 0x0D,
        'shift': 0x10,
        'ctrl': 0x11,
        'alt': 0x12,
        'pause': 0x13,
        'caps_lock': 0x14,
        'esc': 0x1B,
        'spacebar': 0x20,
        'page_up': 0x21,
        'page_down': 0x22,
        'end': 0x23,
        'home': 0x24,
        'left_arrow': 0x25,
        'up_arrow': 0x26,
        'right_arrow': 0x27,
        'down_arrow': 0x28,
        'select': 0x29,
        'print': 0x2A,
        'execute': 0x2B,
        'print_screen': 0x2C,
        'ins': 0x2D,
        'del': 0x2E,
        'help': 0x2F,
        '0': 0x30,
        '1': 0x31,
        '2': 0x32,
        '3': 0x33,
        '4': 0x34,
        '5': 0x35,
        '6': 0x36,
        '7': 0x37,
        '8': 0x38,
        '9': 0x39,
        'a': 0x41,
        'b': 0x42,
        'c': 0x43,
        'd': 0x44,
        'e': 0x45,
        'f': 0x46,
        'g': 0x47,
        'h': 0x48,
        'i': 0x49,
        'j': 0x4A,
        'k': 0x4B,
        'l': 0x4C,
        'm': 0x4D,
        'n': 0x4E,
        'o': 0x4F,
        'p': 0x50,
        'q': 0x51,
        'r': 0x52,
        's': 0x53,
        't': 0x54,
        'u': 0x55,
        'v': 0x56,
        'w': 0x57,
        'x': 0x58,
        'y': 0x59,
        'z': 0x5A,
        'numpad_0': 0x60,
        'numpad_1': 0x61,
        'numpad_2': 0x62,
        'numpad_3': 0x63,
        'numpad_4': 0x64,
        'numpad_5': 0x65,
        'numpad_6': 0x66,
        'numpad_7': 0x67,
        'numpad_8': 0x68,
        'numpad_9': 0x69,
        'multiply_key': 0x6A,
        'add_key': 0x6B,
        'separator_key': 0x6C,
        'subtract_key': 0x6D,
        'decimal_key': 0x6E,
        'divide_key': 0x6F,
        'F1': 0x70,
        'F2': 0x71,
        'F3': 0x72,
        'F4': 0x73,
        'F5': 0x74,
        'F6': 0x75,
        'F7': 0x76,
        'F8': 0x77,
        'F9': 0x78,
        'F10': 0x79,
        'F11': 0x7A,
        'F12': 0x7B,
        
        'num_lock': 0x90,
        'scroll_lock': 0x91,
        'left_shift': 0xA0,
        'right_shift ': 0xA1,
        'left_control': 0xA2,
        'right_control': 0xA3,
        'left_menu': 0xA4,
        'right_menu': 0xA5,
        'browser_back': 0xA6,
        'browser_forward': 0xA7,
        'browser_refresh': 0xA8,
        'browser_stop': 0xA9,
        'browser_search': 0xAA,
        'browser_favorites': 0xAB,
        'browser_start_and_home': 0xAC,
        'volume_mute': 0xAD,
        'volume_Down': 0xAE,
        'volume_up': 0xAF,
        'next_track': 0xB0,
        'previous_track': 0xB1,
        'stop_media': 0xB2,
        'play/pause_media': 0xB3,
        'start_mail': 0xB4,
        'select_media': 0xB5,
        'start_application_1': 0xB6,
        'start_application_2': 0xB7,
        'attn_key': 0xF6,
        'crsel_key': 0xF7,
        'exsel_key': 0xF8,
        'play_key': 0xFA,
        'zoom_key': 0xFB,
        'clear_key': 0xFE,
        '+': 0xBB,
        ',': 0xBC,
        '-': 0xBD,
        '.': 0xBE,
        '/': 0xBF,
        '`': 0xC0,
        ';': 0xBA,
        '[': 0xDB,
        '\\': 0xDC,
        ']': 0xDD,
        "'": 0xDE,
    }
    @staticmethod
    def press_key (keyName):
        # 按下按键
        win32api.keybd_event(Simulate_Keyboard.VK_CODE[keyName], 0, 0, 0)
    @staticmethod
    def release_key (keyName):
        # 释放按键
        win32api.keybd_event(Simulate_Keyboard
.VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
    @staticmethod
    def click_onekey(key):
        # 模拟单个按键
        Simulate_Keyboard.press_key(key)
        Simulate_Keyboard.release_key(key)
    @staticmethod
    def click_twokey(first_key, second_key):
        # 模拟两个组合键
        Simulate_Keyboard.press_key(first_key)
        Simulate_Keyboard.press_key(second_key)
        Simulate_Keyboard.release_key(second_key)
        Simulate_Keyboard.release_key(first_key)

method call

When you need to call one of the methods, introduce it into the test code. When calling the method in the class, just pass the desired key to the corresponding method. Add the following test method in the test_advanced_application file to verify the encapsulated method. If available, the code is as follows.

from Util.Keyboard_Simulation import Simulate_Keyboard
def test_simulate_keyboard(self):
    Simulate_Keyboard.oneKey('enter')
    Simulate_Keyboard.oneKey('ctrl', 'v')
    Simulate_Keyboard.oneKey('enter')

[PyUserInput simulates keyboard]

PyUserInput installation

To install PyUserInput under Python 3.7 version, you need to install PyHook first. Use a browser to open the link PyHook . You can find many third-party extensions for Python on this page. Readers may wish to save them. We found a link that pyHook is compatible with the Python 3.7 version. Click the link directly to download
and then start the command line and guide the command line to the path where the file is located. Execute the command pip install pyHook-1.5.1-cp37-cp37m-win_amd64. whl, the following execution process means the installation is successful.

C:\Users\Administrator\Downloads>pip install pyHook-1.5.1-cp37-cp37m-win_amd64.whl
Processing c:\users\administrator\downloads\pyhook-1.5.1-cp37-cp37m-win_amd64.whl
Installing collected packages: pyHook
Successfully installed pyHook-1.5.1

After installing pyHook, you can install the PyUserInput module and continue to execute pip install PyUserInput on the command line. As shown below, PyUserInput is successfully installed.

C:\Users\Administrator\Downloads>pip install PyUserInput
Collecting PyUserInput
Usingcachedhttps://files.pythonhosted.org/packages/d0/09/17fe0b16c7eeb52d6c14e904596ddde82503aeee268330120b595bf22d7b/PyUserInput-0.1.11.tar.gz
Requirement already satisfied: pyHook in c:\python37\lib\site-packages (from PyUserInput) (1.5.1)
Requirement already satisfied: pywin32 in c:\python37\lib\site-packages (from PyUserInput) (223)
Installing collected packages: PyUserInput
Running setup.py install for PyUserInput ... done
Successfully installed PyUserInput-0.1.11

simulate keyboard

Start the command line tool, enter the Python command line, introduce the pykeyboard class into the environment, and then call the PyKeyboard() function, which returns the keyboard object and assigns it to pk

>>> import pykeyboard
>>> pk = pykeyboard.PyKeyboard()

Once we have the mouse and keyboard objects, we can simulate some actual mouse and keyboard operations. Type the letter "D" on the keyboard.

pk.press_key('D')
pk.release_key('D')

We see that tapping a letter requires the use of two methods, one is press_key() and the other is release_key(). Just as the operations on our keyboard are pressing the button and releasing the button, we can also use the method tap_key() instead. press_key() and release_key()

pk.tap_key('D')

At the same time, tap_key() also supports multiple taps at a specified interval, as shown in the following command, where 10 represents the number of keyboard taps, and 1 represents the tap interval.

pk.tap_key('D', 10, 1) 

And you can also use the method type_string() to simulate tapping the entire string

pk.type_string('__davieyang__')

Next, let’s take a look at how to complete the simulation of key combinations and function keys. As shown in the following command line, hit Ctrl+A.

pk.press_key(pk.control_key)
pk.tap_key(‘a’)
pk.release_key(pk.control_key)

Press function key F5

pk.tap_key(pk.function_keys[5])

Press the Home key on the keypad

pk.tap_key(pk.numpad_keys['Home'])

Press 3 on the keypad 8 times

pk.tap_key(pk.numpad_keys[3], n=8)

We can also use the press_keys() method and then pass it a list to complete the key combination. As shown in the following code, hit Ctrl+A on the keyboard.

pk.press_keys([pk.control_key,'a'])

[PyUserInput simulates mouse]

PyUserInput installation

To install PyUserInput under Python 3.7 version, you need to install PyHook first. Use a browser to open the link: PyHook . You can find many third-party extensions for Python on this page. Readers may wish to save them. We found a link that pyHook is compatible with the Python 3.7 version. Click the link directly to download
and then start the command line and guide the command line to the path where the file is located. Execute the command pip install pyHook-1.5.1-cp37-cp37m-win_amd64. whl, the following execution process means the installation is successful.

C:\Users\Administrator\Downloads>pip install pyHook-1.5.1-cp37-cp37m-win_amd64.whl
Processing c:\users\administrator\downloads\pyhook-1.5.1-cp37-cp37m-win_amd64.whl
Installing collected packages: pyHook
Successfully installed pyHook-1.5.1

After installing pyHook, you can install the PyUserInput module and continue to execute pip install PyUserInput on the command line. As shown below, PyUserInput is successfully installed.

C:\Users\Administrator\Downloads>pip install PyUserInput
Collecting PyUserInput
Usingcachedhttps://files.pythonhosted.org/packages/d0/09/17fe0b16c7eeb52d6c14e904596ddde82503aeee268330120b595bf22d7b/PyUserInput-0.1.11.tar.gz
Requirement already satisfied: pyHook in c:\python37\lib\site-packages (from PyUserInput) (1.5.1)
Requirement already satisfied: pywin32 in c:\python37\lib\site-packages (from PyUserInput) (223)
Installing collected packages: PyUserInput
Running setup.py install for PyUserInput ... done
Successfully installed PyUserInput-0.1.11

simulate mouse

Start the command line tool, enter the Python command line, introduce the pymouse class into the environment, and then call the PyMouse() function, which returns the mouse object, and we assign it to pm

>>> import pymouse
>>> pm = pymouse.PyMouse()

Get the coordinates of the current location of the mouse pointer

>>> mouse_position = pm.position()
>>> print(mouse_position)
(849, 589)

Obtain the current position and simulate the mouse to slide from the current position to the coordinates (300, 400) while holding down the left mouse button.

>>> pm.drag(300,400)

Simulate mouse movement to coordinates (300, 500)

>>> pm.move(300,500)

Simulate the mouse to click and hold the left button at coordinates (300, 500), where 1 represents the left button, 2 represents the right button, and 3 represents the middle button in the table.

>>> pm.press(300,500,1)

To simulate pressing and holding, there must be a way to release the button.

>>> pm.release(300,500,1)

Simulate mouse wheel scrolling, as shown in the following command line, where the parameter vertical is a negative number, which means scrolling down, and a positive number, which means scrolling up. A negative number, horizontal, means scrolling left and vice versa.

pm.scroll(vertical = -30, horizontal = -40)

Simulate the mouse to click the right mouse button 5 times at the coordinates (300, 500), as shown in the following command line. 2 represents the right mouse button, 1 represents the left button, and 3 represents the middle button. 5 in the command line represents the number of clicks. The default is 1. .

>>> pm.click(300,500,2,5)

Get screen size

>>> screen_x, screen_y = pm.screen_size()
>>> print(screen_x, screen_y)
3360 1080

Simulate the mouse to click the left and right buttons or click the scroll wheel at coordinates (300, 500). The following two commands are equivalent

>>> pm.click(300,500, 1|2)
>>> pm.click(300,500, 3)

[ActionChains simulates mouse]

In actual tests, mouse operations also occur frequently. The idea is the same as encapsulating methods to control browsers. In this section, the author will introduce in detail how to encapsulate methods to simulate mouse operations and how to call our encapsulated methods.

Method encapsulation

In actual automated testing, it is often necessary to simulate some mouse operations to assist us in completing some special operations on the page. For example, some require the mouse to drag page elements, move page elements, hover the mouse over page elements, etc., so we Encapsulate some tool classes so that we can call them directly when writing test code.

# encoding = utf-8
from selenium.webdriver.common.action_chains import ActionChains
class Simulate_Mouse:
    def __init__(self, driver):
        self.driver = driver
        self.actions = ActionChains(self.driver)
    # 单击鼠标左键
    def left_click(self, element):
        self.actions.click(element).perform()
    # 双击鼠标左键
    def double_left_click(self, element):
        self.actions.double_click(element).perform()
    #  单击鼠标右键
    def right_click(self, element):
        self.actions.context_click(element).perform()
    #  移动鼠标到element
    def move_mouse(self, element):
        self.actions.move_to_element(element).perform()
    #  从source移动鼠标到target
    def move_mouse_source_target(self, source, target):
        self.actions.drag_and_drop(source, target).perform()
    #  从source移动鼠标到target
    def move_source_target(self, source, target):
        self.actions.click_and_hold(source).release(target).perform()
    #  拖拽元素到坐标xy
    def drag_element(self, element, x, y):
        self.actions.click_and_hold(element).move_by_offset(x, y).release().perform()
    #  点击并且不释放
    def click_hold(self, element):
        self.actions.click_and_hold(element)

method call

When you need to call a method, introduce it into the test code. When calling a method in the class, just pass the parameters according to the parameters required by the method.
Add the following test method in the test_advanced_application file to verify whether the encapsulated method is available. The code is as follows.

from Util.Mouse_Simulation import Simulate_Mouse  # 引入我们封装好的工具类
import time # 引入time模块用于等待
def test_simulate_mouse(self):  # 定义测试方法
    chr_driver = webdriver.Chrome()  # 启动谷歌浏览器 
    chr_driver.get(self.url)  # 打开url
    element = chr_driver.find_element_by_link_text("设置") # 获取页面元素
    Simulate_Mouse(chr_driver).move_mouse(element)  # 鼠标悬停动作
    time.sleep(5)  # 强制等待5秒

[Compatibility Test]

In the actual automated testing process, some products must be tested for compatibility, which means executing the same test cases in different environments, and this should be a very important battlefield to take advantage of automated testing.
Automation is slightly different when writing compatibility test cases. We need to define a test method and then call the method when executing different environments, so as to execute the same test in different environments, as shown in the following code.

# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
import unittest
class Compatibility_Test(unittest.TestCase):
    def setUp(self):
        self.base_url = "https://admin.leadscloud.com/Front-breeze/#/home"
    def login_leadscloud(self, driver):
        '''
        定义测试方法
        :param driver:
        :return:
        '''
        driver.get(self.base_url)
        sleep(5)
        driver.find_element_by_xpath("//*[@id='main']/div/div[1]/div/div[2]/form/div[1]/div/div/input").send_keys('xxxxxx')
        driver.find_element_by_xpath("//*[@id='main']/div/div[1]/div/div[2]/form/div[2]/div/div/input").send_keys('xxxxxx')
        driver.find_element_by_xpath("//*[@id='main']/div/div[1]/div/div[2]/form/div[3]/div/button").click()
        driver.quit()
    def test_chrome(self):
        '''
        启动chrome浏览器执行测试用例
        :return:
        '''
        chrome_driver = webdriver.Chrome()
        self.login_leadscloud(chrome_driver)
    def test_firefox(self):
        '''
        启动firefox执行测试用例
        :return:
        '''
        firefox_driver = webdriver.Firefox()
        self.login_leadscloud(firefox_driver)
    def test_ie(self):
        '''
        启动IE执行测试用例
        :return:
        '''
        ie_driver = webdriver.Ie()
        self.login_leadscloud(ie_driver)
if __name__ == '__main__':
    unittest.main(verbosity=2)

[Kill browser process]

Although Webdriver has quit() method and close() to close the browser, sometimes the browser process cannot be completely closed. We need to master the method of killing the process. The code example is as follows:

# encoding = utf-8
from selenium import webdriver
import unittest
import os
from time import sleep
class Test_Kill_Browser(unittest.TestCase):

    def test_kill_browser_process(self):
        # 启动浏览器
        chrome_driver = webdriver.Chrome()
		sleep(5)
        firefox_driver = webdriver.Firefox()
		sleep(5)
        ie_driver = webdriver.Ie()
        sleep(5)
		# 杀chrome浏览器进程
        code = os.system("taskkill /F /iM chrome.exe")
        if code ==0:
            print(u"Kill Firefox Successfully")
        else:
            print(u"Kill Firefox Failed")
        # 杀firefox浏览器进程
        code = os.system("taskkill /F /iM firefox.exe")
        if code ==0:
            print(u"Kill Firefox Successfully")
        else:
            print(u"Kill Firefox Failed")
        # 杀ie浏览器进程
        code = os.system("taskkill /F /iM ie.exe")
        if code ==0:
            print(u"Kill Firefox Successfully")
        else:
            print(u"Kill Firefox Failed")

if __name__ == '__main__':
    unittest.main(verbosity=2)

Results of the

Insert image description here
Garbled characters appear in the execution results because the File Encodings setting of our code file is UTF-8 by default. To solve this garbled code problem, we can modify the settings of Pycharm, find Settings, or directly use the shortcut key Ctrl+Alt+S Open Settings
Insert image description here
and search for encoding in the search bar, you can find the File Encodings option.
Insert image description here
After changing the Global Encoding to GBK, execute the code here. The execution result is as shown in the figure.
Insert image description here

[Start browser silent mode]

In actual automated testing, in order to prevent the browser from frequently starting and closing, you can execute it in silent mode. The code example is as follows.

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
# 创建chrome的Option对象
chrome_options = Options()
# 添加静默参数
chrome_options.add_argument('--headless')
for i in range(100000):
    # 静默模式启动浏览器
    chrome_driver = webdriver.Chrome(options=chrome_options)
    # 打开页面 
    chrome_driver.get("http://www.yialife.co.za/contact.html")
    chrome_driver.maximize_window()
    chrome_driver.find_element_by_class_name("xhl-button-text").click()
    # 获取当前时间
    current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
    chrome_driver.find_element_by_id("messageText").send_keys("audio notification testing at " + current_time)
    time.sleep(1)
    chrome_driver.find_element_by_id("sendBtn").click()
    print(current_time)
    time.sleep(5)
    # 删掉所有cookie
    chrome_driver.delete_all_cookies()
chrome_driver.quit()

[Handling Cookies]

In some scenarios, it is necessary to process browser cookies. For example, you can often see that some websites provide a consultation window inside the page. You can click on the window to talk to customer service. However, when you talk to customer service for the first time, the customer service side The displayed conversation name is assumed to be Visitor A. When we open the website again half an hour later and continue chatting, the customer service side will still show that it is Visitor A. However, if we clear the cookies and open the website to talk to the customer service, the customer service side will show that we may be the same person. new visitors.
The author just cites a common scenario in Internet product systems. If automated testing is needed in this scenario, we will undoubtedly need to master the method of handling cookies. In this section, the author will introduce the method of encapsulating and operating cookies, and how to use the encapsulated method to Handling cookies.

Method encapsulation

def delete_current_cookie(self):  # 封装删除当前所有cookie的方法
    """
    删除所有cookie
    :return:
    """
    self.driver.delete_all_cookies()
def get_current_cookies(self):  # 封装获取当前cookies的方法
    """
    获取当前cookies
    :return:
    """
    current_cookie = self.driver.get_cookies()
    return current_cookie
def get_current_cookie_value(self, key):  # 获取当前name为key的cookie信息
    """
    获取key为key的cookie信息
    :param key:
    :return:
    """
    key_cookie = self.driver.get_cookie(key)
    return key_cookie
def add_key_value_to_cookie(self, cookie_dict):  # 添加cookie,参数为字典
    """
    添加cookie
    :return:
    """
    self.driver.add_cookie(cookie_dict)

method call

Then see how to call it. Add the following test method in the test_advanced_application file to verify whether the encapsulated method is available. The code is as follows.

def test_cookies(self):  # 定义新的测试方法
    cookie_dict = {
    
    'name': 'name_yang', 'value': 'cookie_yang'}  # 定义字典 
    chrome_driver = webdriver.Chrome()  # 启动浏览器
    chrome_driver.get("https://www.baidu.com")
    time.sleep(10)
	# 获取当前所有cookie
    current_cookie = Browser_Controller(chrome_driver).get_current_cookies()
    # 打印当前cookie
	print(current_cookie)
    # 将之前定义的字典添加到cookie中去
	Browser_Controller(chrome_driver).add_key_value_to_cookie(cookie_dict)
    # 获取name为name_yang的cookie信息
	key_cookie = Browser_Controller(chrome_driver).get_current_cookie_value('name_yang')
    # 打印cookie信息
	print(key_cookie)
    # 删除当前cookie
	Browser_Controller(chrome_driver).delete_current_cookie()
    # 删除后再次获取cookie
	current_cookie_2 = Browser_Controller(chrome_driver).get_current_cookies()
    # 将当前cookie转换成字符串打印到控制台
	print(str(current_cookie_2) + "只有这几个字没有cookie了")

[Handling iframe]

If there is an iframe on the page, then we cannot directly locate the page elements under the iframe node. We need to switch to the iframe first, and then locate the page elements in the iframe. However, if we switch to the iframe, we cannot locate it. For elements outside the iframe, you need to switch out to position the elements outside the iframe.
After experiencing the previous encapsulation of various operations, iframe encapsulation is much simpler. Next, the author will introduce the encapsulated method and how to call it.

Method encapsulation

def switch_to_iframe(self, frame):
    """
    用于切换进页面的iframe控件
    :param iframe:
    :return:
    """
    self.driver.switch_to.frame(frame)
def switch_to_default_content(self):
    """
    从iframe中切换回主页页面
    :return:
    """
    self.driver.switch_to.default_content()

method call

def test_switch_iframe(self):  # 定义测试方法
    chrome_driver = webdriver.Chrome()
    chrome_driver.get("https://mail.163.com")
    time.sleep(10)
    frame = chrome_driver.find_element_by_xpath("//*[@id='loginDiv']/iframe")
    # 调用封装好的方法切换进iframe控件
    Browser_Controller(chrome_driver).switch_to_iframe(frame)  
    time.sleep(5)
    chrome_driver.find_element_by_name("email").send_keys("邮箱账号")
    chrome_driver.find_element_by_name("password").send_keys("邮箱密码")
    chrome_driver.find_element_by_id("dologin").click()

[Handle pop-up windows]

Our common pop-up windows are generally divided into three styles, namely alert/prompt/confirm. Similarly, to locate the elements in the pop-up window control or operate the control, you must first switch into the control.

Tested page

<html>  
	<head>  
		<title>For Test Alert</title>  
	</head>  
	<body>  
		<input id = "alert" value = "alert" type = "button" onclick = "alert('您点击了alert按钮');"/>  
		<input id = "confirm" value = "confirm" type = "button" onclick = "confirm('您点击了confirm按钮');"/>  
		<input id = "prompt" value = "prompt" type = "button" onclick = "var name = prompt('您点击了prompt按钮:','Prompt'); document.write(name) "/>    
	</body>   
</html>  

Method encapsulation

def switch_to_alert(self):
    """
    切换进alert控件
    :return:
    """
    pop_dailog = self.driver.switch_to.alert
    return pop_dailog

method call

def test_switch_to_alert(self):
    chrome_driver = webdriver.Chrome()
    # 浏览器打开我们刚才新建的html文件
    chrome_driver.get("file:///C:/Users/davieyang/Desktop/test_alert.html")
    time.sleep(3)
    #  点击alert按钮
    chrome_driver.find_element_by_id("alert").click()
    time.sleep(3)
    #  调用我们封装好的方法
    al = Browser_Controller(chrome_driver).switch_to_alert()
    print(al.text)  #  打印弹窗中的文本
    # 相当于点击弹窗中的确定按钮,但实际并不是点击只是弹窗对象提供的方法,效果一样
    al.accept()
def test_switch_to_confirm(self):
    chrome_driver = webdriver.Chrome()
    # 浏览器打开我们刚才新建的html文件
    chrome_driver.get("file:///C:/Users/davieyang/Desktop/test_alert.html")
    time.sleep(3)
    #  点击alert按钮
    chrome_driver.find_element_by_id("confirm").click()
    time.sleep(3)
    #  调用我们封装好的方法
    al = Browser_Controller(chrome_driver).switch_to_alert()
    print(al.text)  #  打印弹窗中的文本
    # 相当于点击弹窗中的取消按钮,但实际并不是点击只是弹窗对象提供的方法,效果一样
    al.dismiss()
def test_switch_to_prompt(self):
    chrome_driver = webdriver.Chrome()
    # 浏览器打开我们刚才新建的html文件
    chrome_driver.get("file:///C:/Users/davieyang/Desktop/test_alert.html")
    time.sleep(3)
    #  点击alert按钮
    chrome_driver.find_element_by_id("prompt").click()
    time.sleep(3)
    #  调用我们封装好的方法
    al = Browser_Controller(chrome_driver).switch_to_alert()
    print(al.text)  #  打印弹窗中的文本
    # 相当于点击弹窗中的确定按钮,但实际并不是点击只是弹窗对象提供的方法,效果一样
    al.accept()

[Handling drop-down menus]

Selenium provides 3 methods for selecting options in the drop-down menu. Next, these three methods are encapsulated and called.

Method encapsulation

from selenium.webdriver.support.select import Select
def select_by_index(self, element, index):
    """
    通过下拉菜单的索引,完成对选项的选择
    :param element:
    :param value:
    :return:
    """
    Select(element).select_by_index(index)
def select_by_value(self, element, value):
    """
    通过选项值,完成对选项的选择
    :param element:
    :param value:
    :return:
    """
    Select(element).select_by_value(value)
def select_by_text(self, element, text):
    """
    通过选项的文本,完成对选项的选择
    :param element:
    :param text:
    :return:
    """
    Select(element).select_by_visible_text(text)

method call

def test_select(self):
    chrome_driver = webdriver.Chrome()
    chrome_driver.get("http://www.baidu.com")
    chrome_driver.implicitly_wait(30)
    mouse = chrome_driver.find_element_by_link_text("设置")
    ActionChains(chrome_driver).move_to_element(mouse).perform()
    chrome_driver.find_element_by_link_text("搜索设置").click()
    time.sleep(5)
    chrome_driver.find_element_by_name("NR").click()
    time.sleep(5)
    select = chrome_driver.find_element_by_name("NR")
    Browser_Controller(chrome_driver).select_by_value(select, "20")
    time.sleep(5)
    Browser_Controller(chrome_driver).select_by_index(select, 1)
    time.sleep(5)
    Browser_Controller(chrome_driver).select_by_text(select, "每页显示50条")
    time.sleep(5)

method extension

In fact, Selenium provides more than the three methods we encapsulated to handle drop-down menu options, and there is also a method to cancel option selection as shown below.

deselect_by_index(index)  # 根据索引取消选择
deselect_by_value(value)  # 根据value取消选择 
deselect_by_visible_text(text)  # 根据文本取消选择 
deselect_all()  # 取消所有选择

[upload files]

Uploading attachments is a function we often encounter when testing BS systems. However, the automated code for processing uploaded attachments is not always effective. Therefore, we need to master multiple methods of uploading attachments. In this section, the author will introduce several uploading attachments. method should be able to satisfy most situations.

Tested page

<html>
	<head>
		<meta http-equiv="content-type" content="text/html;charset=utf-8" />
		<title>上传文件</title>
	</head>
	<body>
		<div class="row-fluid">
			<div class="span6 well">
			<h3>选择文件</h3>
			<input type="file" name="fileupload" />
			</div>
		</div>
	</body>
</html>

test code

def test_upload_by_sendkeys(self):
    chrome_driver = webdriver.Chrome()
    chrome_driver.get("file:///C:/Users/Administrator/Desktop/fileupload.html")
    chrome_driver.find_element_by_name("fileupload").send_keys("E:\\test_upload_file.txt")
    time.sleep(10)
    chrome_driver.quit()

Uploading with AutoIt

If the page tag is not of input type, you can use a third-party tool to complete the upload operation.

  • First, download the AutoIt tool in the first step. Visit https://www.autoitscript.com/files/autoit3/autoit-v3-setup.exe with your browser to download it directly. After the download is complete, double-click the autoit-v3-setup.exe file. , you can install it with the default options. After the installation is completed, you can see the relevant menu items in the start menu of the operating system.
    Insert image description here
  • Use a browser to open the fileupload.html file created in the previous section, and then click "Select File" on the opened page. A window to select the file will pop up.
    Insert image description here
  • Click AutoIt Window Info in the start menu. There are two versions of the program (x86) indicating the 32-bit version, and (x64) indicating the 64-bit version. Readers can start the corresponding AutoIt version according to their own operating system version. After successful startup
    Insert image description here
  • There are several tabs in the middle of the AutoIt Window Info window. Then drag the Finder Tool to the "Open" button to obtain the window information of the control.
    Insert image description here
  • Start SciTE Script Editor and you can find it in the AutoIt v3 path of the start menu.
    Insert image description here
  • Write a script and write the following content in the SciTE Script Editor. Then, with the file selection window open, press the F5 key on the keyboard in the SciTE Script Editor window to execute the script. The script runs normally and can be saved to our PO project. In the Util path, name it upload_file. After successful saving, a file upload_file.au3 will be generated.
; ControlFocus("title", "text", "ClassnameNN") ControlFocus函数的用法
ControlFocus("打开", "", "Edit1")
; 等待10秒
 WinWait("[CLASS:#32770]", "", 10)
; 在文件名控件里设置要上传的文件全路径
 ControlSetText("打开", "", "Edit1", "E:\test_upload_file.txt")
 Sleep(2000)
; 点击打开按钮
 ControlClick("打开", "", "Button1")
  • However, this upload_file.au3 file cannot be executed by Python. It needs to be compiled into an .exe file for Python to call. Start Compile Script to .exe. You can find it in the Auto v3 path of the start menu. Start (x86) or (x64 )Select accordingly according to your operating system version
    Insert image description here
  • Select the previously saved au3 file and click the Convert button to convert it to an .exe file
    Insert image description here
  • The Python script calls the .exe to complete the file upload.
import os  # 引入os模块用于调用.exe文件执行
def test_upload_by_autoit(self):  # 定义测试方法
    chrome_driver = webdriver.Chrome()  # 启动浏览器
	#打开我们的html文件
    chrome_driver.get("file:///C:/Users/Administrator/Desktop/fileupload.html")
	chrome_driver.find_element_by_name("fileupload").click()
    os.system("E:\\PO\\Util\\upload_file.exe")  # 调用我们编译好的.exe文件
    time.sleep(10)  # 强制等待10秒  
    chrome_driver.quit()

Simulate keyboard to upload

Packaging operation clipboard method
# encoding = utf-8
import win32clipboard as wc
import win32con
class Simulate_Clipboard:
    # 读取剪切板
    @staticmethod
    def get_clipboard():
        # 打开剪切板
        wc.OpenClipboard()
        # 获取剪切板中的数据
        data = wc.GetClipboardData(win32con.CF_TEXT)
        # 关闭剪切板
        wc.CloseClipboard()
        # 返回剪切板数据给调用者
        return data
    # 设置剪切板内容
    @staticmethod
    def set_clipboard(content):
        # 打开剪切板
        wc.OpenClipboard()
        # 清空剪切板
        wc.EmptyClipboard()
        # 将数据astring写入剪切板
        wc.SetClipboardData(win32con.CF_UNICODETEXT, content)
        # 关闭剪切板
        wc.CloseClipboard()
method call
# 将模拟剪切板的类引入到测试代码文件中
from Util.Clipboard_Simulation import Simulate_Clipboard  
def test_simulate_clipboard(self):  # 定义测试方法
    Simulate_Clipboard.set_clipboard("set clipboard")  # 设置剪切板内容
    str = Simulate_Clipboard.get_clipboard()  # 获取剪切板内容并赋给str
    print(str)  # 将剪切板内容打印到控制台

Cutting board and keyboard are used to upload
def test_upload_by_simulation(self):  # 定义测试方法 
	# 设置剪切板内容,将文件全路径放到剪切板中
    Simulate_Clipboard.set_clipboard("E:\\test_upload_file.txt")      
	chrome_driver = webdriver.Chrome()  # 启动浏览器
	# 打开我们的html文件
    chrome_driver.get("file:///C:/Users/Administrator/Desktop/fileupload.html")
	chrome_driver.find_element_by_name("fileupload").click()
	time.sleep(5)
    Simulate_Keyboard.click_twokey('ctrl', 'v')  # 模拟键盘Ctrl+V组合键,黏贴剪切板内容
    time.sleep(5)
    Simulate_Keyboard.click_onekey('enter')  # 模拟键盘回车键
    time.sleep(20)

[JS completes the task]

Sometimes Selenium cannot help us complete all operations on the page. For example, the control of the scroll bar is more difficult to handle, and sometimes the click() method will fail. Even if we have no problem positioning the button, there are cases where we cannot click it. In these cases, we We can use Python's mechanism to execute JS and use JS to assist us in completing some tasks.

Method encapsulation

class JS_Assistance:  # 定义类
def __init__(self, driver):
    self.driver = driver
def single_click(self, element):
    try:
        #  判断页面元素状态
            if element.is_enabled() and element.is_displayed():
                #  调用js单击元素
                self.driver.execute_script("arguments[0].click();", element)
            else:
                print("该元素不可点击")
        except Exception as e:
            raise e
    def scroll_to_bottom(self):
        """
        滚动条滚动到页面底部
        :return:
        """
        self.driver.execute_script("document.documentElement.scrollTop=10000")
    def scroll_to_top(self):
        """
        滚动条滚动到页面顶部
        :return:
        """
        self.driver.execute_script("document.documentElement.scrollTop=0")
    def scrolltobottom(self):
        """
        滚动条滚动到页面底部
        :return:
        """
        self.driver.execute_script("window.scrollTo(0,100000)")
def scrolltotop(self):
        """
        滚动条滚动到页面顶部
        :return:
        """
        self.driver.execute_script("window.scrollTo(0,1)")
def vertical_to_middle(self):
        """
        纵向滚动条滚动到页面中部
        :return:
        """
        self.driver.execute_script("window.scrollBy(0, 0-document.body.scrollHeight *1/2)")
def horizontal_to_middle(self):
        """
        滚动水平滚动条到页面中部
        :return:
        """
        self.driver.execute_script("window.scrollBy(0, 0-document.body.scrollWidht *1/2)")
    def scroll_to_element(self, element):
        """
        滚动到具体页面元素可见位置
        :param element:
        :return:
        """
        self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
    def scroll_to_bottom_page(self):
        """
        滚动条滚动到页面底部
        :return:
        """
        self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")

method call

def test_js(self):  # 定义测试方法
chrome_driver = webdriver.Chrome()
chrome_driver.get("http://www.baidu.com")
chrome_driver.find_element_by_id("kw").send_keys("davieyang")
chrome_driver.find_element_by_id("su").click()
    JS_Assistance(chrome_driver).scroll_to_bottom()  #滚动页面到底部 
    time.sleep(3)
    JS_Assistance(chrome_driver).scroll_to_top() #滚动页面到顶部
    time.sleep(3)
    JS_Assistance(chrome_driver).scroll_to_bottom_page()  #滚动页面到底部
    time.sleep(3)
    JS_Assistance(chrome_driver).scrolltotop()  #滚动页面到顶部
    time.sleep(3)
    JS_Assistance(chrome_driver).scrolltobottom()  #滚动页面到底部
    time.sleep(3)
    element = chrome_driver.find_element_by_xpath("//*[@id='help']/a[3]")
    JS_Assistance(chrome_driver).single_click(element)  # 单击该页面元素
    time.sleep(3)

[handle]

During the actual automated testing process, we often encounter that after our product clicks on an element on the page, a new browser tab will be launched. Note that the browser tab mentioned here is not a tab in our system, but is launched. After the second tab of the browser, it means that our automated program needs to switch between the two tabs to complete some interactions, so switching tabs has become a topic.

def test_switch_window_handle(self):  # 定义测试方法
	chrome_driver = webdriver.Chrome()  #启动浏览器
	chrome_driver.get("http://www.baidu.com")  #打开百度首页
	baidu_main_handle = chrome_driver.current_window_handle  # 获取当前浏览器句柄 
	print(baidu_main_handle)  # 为方便调试,将句柄打印到控制台 
	time.sleep(5) # 等待5秒
	chrome_driver.find_element_by_link_text("登录").click()  # 点击登录按钮
	time.sleep(5)  # 等待5秒
	chrome_driver.find_element_by_link_text("立即注册").click()  # 在弹出窗口中点击立即注册
	all_handles = chrome_driver.window_handles  # 获取所有句柄
	print(all_handles)  # 打印所有句柄到控制台
	for handle in all_handles: # 在所有句柄中进行循环
        try:
            if handle != baidu_main_handle:  # 判断是否句柄不等于百度首页的句柄,如不等于
                chrome_driver.switch_to.window(handle)  # 则切换句柄 
                print("进入新窗口....")
                chrome_driver.switch_to.window(baidu_main_handle)  #再切换回百度首页句柄
                chrome_driver.refresh() # 刷新页面
			  # 输入检索内容到输入框
                chrome_driver.find_element_by_id("kw").send_keys("__davieyang__") 
                time.sleep(5)
			  # 点击百度一下按钮
                chrome_driver.find_element_by_id("su").click()
                time.sleep(5)
        except Exception as e:
            raise e
	chrome_driver.quit()  # 关闭浏览器

[log]

In the actual debugging process of automated test code, we often need to record some logs. On the one hand, it is printed to the console so that we can debug the code. If the continuous integration environment is unattended, it is also a recording process of the test execution process.

Method encapsulation

Create a new Python file and name it ConstantConfig, and then write the following code in the file.

# 用于定义整个框架中所需要的全局常量值
# encoding = utf-8
import os
# 获取当前文件所在目录的父目录的绝对路径
parent_directory_path = os.path.abspath('..')
print(parent_directory_path)
# encoding = utf-8
import time
import logging
from Configuration.ConstantConfig import parent_directory_path
class Logger(object):
    def __init__(self, logger):
        """
        指定保存日志的文件路径,日志级别,以及调用文件
            将日志存入到指定的文件中
        :param logger:
        """
        # 创建一个logger
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)
        # 创建一个handler,用于写入日志文件
        rq = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
        log_path = parent_directory_path + '/TestResult/TestLog/'
        log_name = log_path + rq + '.log'
        filehandler = logging.FileHandler(log_name)
        filehandler.setLevel(logging.INFO)
        # 再创建一个handler,用于输出到控制台
        consolehandler = logging.StreamHandler()
        consolehandler.setLevel(logging.INFO)
        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
        filehandler.setFormatter(formatter)
        consolehandler.setFormatter(formatter)
        # 给logger添加handler
        self.logger.addHandler(filehandler)
        self.logger.addHandler(consolehandler)
    def getlog(self):
        return self.logger

Create a new folder named TestLog to store the generated log files
Insert image description here

method call

testlogger = GetLog.Logger('Test_Advanced_Application').getlog()
class Test_Advanced_Application(unittest.TestCase): 
	def test_get_log(self):
    	testlogger.info("打开浏览器")
    	driver = webdriver.Chrome()
    	driver.maximize_window()
    	testlogger.info("最大化浏览器窗口。")
    	driver.implicitly_wait(10)
    	testlogger.info("打开百度首页。")
    	driver.get("https://www.baidu.com")
    	testlogger.info("暂停3秒。")
    	time.sleep(3)
    	testlogger.info("关闭并退出浏览器")
    	driver.quit()
    	with self.assertLogs(testlogger, level=20) as log:
        	testlogger.error("打开浏览器")
        	testlogger.info('关闭并退出浏览器')
        	self.assertEqual(log.output,
            	             ['ERROR:Test_Advanced_Application:打开浏览器',
                	          'INFO:Test_Advanced_Application:关闭并退出浏览器']
                    	     )

Results of the

Insert image description here
You can see the process of printing our logs to the console one by one during the execution process,
Insert image description here
and then go to the TestLog folder we created to view the log file. If you encounter garbled characters, as shown in Figure 11.13, don't panic, it is because the encoding does not match. Caused by this, click Reload in 'GBK' and convert the encoding format to GBK to display it normally.
Insert image description here
Insert image description here
The reason for the garbled code is that in the File Encodings in the project settings, the Global Encoding is UTF-8.
Insert image description here

Guess you like

Origin blog.csdn.net/dawei_yang000000/article/details/135133591