当前位置:网站首页>Selenium+pytest automated test framework practice
Selenium+pytest automated test framework practice
2022-07-06 09:00:00 【Automated test seventh uncle】
Preface
Today, I want to talk with you selenium automation + pytest The test framework , In this article, you need to know something python Basics —— At least understand classes and objects , Encapsulation inheritance ; definite selenium Basics . This article will not selenium, No, you can see it yourself selenium Chinese Translation Network .

One 、 Introduction to test framework
What are the advantages of a testing framework :
- High code reuse rate , If you don't use a framework , The code will be redundant
- You can assemble logs 、 The report 、 Some advanced functions such as email
- Improve the maintainability of data such as elements , When the elements change , Just update the configuration file
- Use more flexible PageObject Design patterns
- The overall directory of the test framework
- Catalog / Whether the document description is python package common This package contains common general classes , If reading the configuration file is config The profile directory is logs Log directory page Yes selenium The depth of packaging is page_element Page element storage directory page_object Page object POM Design patterns ,TestCase All test case sets are utils The tool class is script Script files conftest.pypytest Glue files pytest.inipytest The configuration file , Such a simple frame structure is clear .
Knowing all this, let's start !
In the project, we first follow the above framework guidelines , Build every directory .
Be careful :python The package is yes , You need to add one __init__.py File to identify this directory as a python package .
Two 、 Manage time
First of all , Because many of our modules use time stamps , Or date string , So let's encapsulate time into a module .
Then let other modules call . stay utils New directory times.py modular
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import time
import datetime
from functools import wraps
def timestamp():
""" Time stamp """
return time.time()
def dt_strftime(fmt="%Y%m"):
"""
datetime Format time
:param fmt "%Y%m%d %H%M%S
"""
return datetime.datetime.now().strftime(fmt)
def sleep(seconds=1.0):
"""
Sleep time
"""
time.sleep(seconds)
def running_time(func):
""" Function run time """
@wraps(func)
def wrapper(*args, **kwargs):
start = timestamp()
res = func(*args, **kwargs)
print(" Check element done! when %.3f second !" % (timestamp() - start))
return res
return wrapper
if __name__ == '__main__':
print(dt_strftime("%Y%m%d%H%M%S"))
3、 ... and 、 Add configuration file
Configuration files are an essential part of the project !
Centralize fixed information in fixed files
3.1conf.py
There should be a file in the project to manage the overall Directory , I'm here, too python This file is set in the project .
In the project config directories creating conf.py file , All directory configuration information is written in this file .
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import os
from selenium.webdriver.common.by import By
from utils.times import dt_strftime
class ConfigManager(object):
# Project directory
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Page element directory
ELEMENT_PATH = os.path.join(BASE_DIR, 'page_element')
# The report file
REPORT_FILE = os.path.join(BASE_DIR, 'report.html')
# The type of element location
LOCATE_MODE = {
'css': By.CSS_SELECTOR,
'xpath': By.XPATH,
'name': By.NAME,
'id': By.ID,
'class': By.CLASS_NAME
}
# Email messages
EMAIL_INFO = {
'username': '[email protected]', # Switch to your own address
'password': 'QQ Email authorization code ',
'smtp_host': 'smtp.qq.com',
'smtp_port': 123
}
# The recipient
ADDRESSEE = [
'[email protected]',
]
@property
def log_file(self):
""" Log directory """
log_dir = os.path.join(self.BASE_DIR, 'logs')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
return os.path.join(log_dir, '{}.log'.format(dt_strftime()))
@property
def ini_file(self):
""" The configuration file """
ini_file = os.path.join(self.BASE_DIR, 'config', 'config.ini')
if not os.path.exists(ini_file):
raise FileNotFoundError(" The configuration file %s non-existent !" % ini_file)
return ini_file
cm = ConfigManager()
if __name__ == '__main__':
print(cm.BASE_DIR)
Be careful :QQ How to generate email authorization code? Go to Baidu by yourself
This conf I copied the file Django Of settings.py The setting style of the file , But there are some differences .
In this file, we can set our own directories , You can also view your current directory .
Followed the agreement : Invariant constant names are all capitalized , Function names are lowercase . It looks beautiful as a whole .
3.2config.ini
In the project config Create a new directory config.ini file , For the time being, we need to put what we need to test URL
[HOST]
HOST = https://www.baidu.comFour 、 Read configuration file
The configuration file is created , Next, we need to read the configuration file and use the information in it .
We are common Create a new one in the directory readconfig.py file
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import configparser
from config.conf import cm
HOST = 'HOST'
class ReadConfig(object):
""" The configuration file """
def __init__(self):
self.config = configparser.RawConfigParser() # When there is % Please use the symbol of Raw Read
self.config.read(cm.ini_file, encoding='utf-8')
def _get(self, section, option):
""" obtain """
return self.config.get(section, option)
def _set(self, section, option, value):
""" to update """
self.config.set(section, option, value)
with open(cm.ini_file, 'w') as f:
self.config.write(f)
@property
def url(self):
return self._get(HOST, HOST)
ini = ReadConfig()
if __name__ == '__main__':
print(ini.url)
You can see that we use python Built in configparser The module of config.ini The file was read .
about url Extraction of values , I used higher-order grammar @property Property value , It's easier to write .
5、 ... and 、 Record operation log
journal , Everyone should be familiar with the term , Is to record the actions in the code .
stay utils Create a new logger.py file .
This file is what we use to record some operation steps in the process of automated testing .
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import logging
from config.conf import cm
class Log:
def __init__(self):
self.logger = logging.getLogger()
if not self.logger.handlers:
self.logger.setLevel(logging.DEBUG)
# Create a handle write file
fh = logging.FileHandler(cm.log_file, encoding='utf-8')
fh.setLevel(logging.INFO)
# Create a handle Output to console
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# Define the format of the output
formatter = logging.Formatter(self.fmt)
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# Add to handle
self.logger.addHandler(fh)
self.logger.addHandler(ch)
@property
def fmt(self):
return '%(levelname)s\t%(asctime)s\t[%(filename)s:%(lineno)d]\t%(message)s'
log = Log().logger
if __name__ == '__main__':
log.info('hello world')
Run the file in the terminal , You can see that the command line prints out :
INFO 2022-06-15 16:00:05,467 [logger.py:38] hello worldAnd then in the project logs The log file of the current month is generated under the directory .
6、 ... and 、 Simple understanding POM Model
Because we'll talk about elements related , So first understand POM Model
Page Object Mode has the following advantages .
This view comes from 《Selenium automated testing —— be based on Python Language 》
- Abstracting out objects can minimize the impact of developers modifying page code on testing , therefore , You just need to page
Adjust to the elephant , It has no effect on the test ; - You can reuse part of the test code in multiple test cases ;
- Test code becomes more readable 、 flexible 、 Maintainable
Page Object Pattern

- basepage ——selenium Base class of , Yes selenium To encapsulate
- pageelements—— Page elements , Extract the page elements separately , Put it in a file
- searchpage —— Page object class , hold selenium Methods and page elements
- testcase —— Use pytest For integration searchpage Write test cases
We can see from the picture above , adopt POM Model thinking , We put :
- selenium Method
- Page elements
- Page object
- The test case
The above four code bodies are split , Although doing it with few use cases will increase the code , But when there are many use cases, it makes a lot of sense , The amount of code will decrease significantly as use cases increase . Our maintenance code becomes more intuitive and obvious , Code readability has also become much better than factory mode , The code reuse rate has also been greatly improved .
This article is here for the time being , I'll talk about it later .

边栏推荐
- [Hacker News Weekly] data visualization artifact; Top 10 Web hacker technologies; Postman supports grpc
- Li Kou daily question 1 (2)
- Digital people anchor 618 sign language with goods, convenient for 27.8 million people with hearing impairment
- LeetCode:498. Diagonal traversal
- 在QWidget上实现窗口阻塞
- 多元聚类分析
- Pytest之收集用例规则与运行指定用例
- BN folding and its quantification
- 自动化测试框架有什么作用?上海专业第三方软件测试公司安利
- [OC-Foundation框架]--<Copy对象复制>
猜你喜欢

数学建模2004B题(输电问题)
![[MySQL] multi table query](/img/eb/9d54df9a5c6aef44e35c7a63b286a6.jpg)
[MySQL] multi table query

ESP8266-RTOS物联网开发
![[OC]-<UI入门>--常用控件-UIButton](/img/4d/f5a62671068b26ef43f1101981c7bb.png)
[OC]-<UI入门>--常用控件-UIButton

Advanced Computer Network Review(4)——Congestion Control of MPTCP

The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower

Esp8266-rtos IOT development

Chapter 1 :Application of Artificial intelligence in Drug Design:Opportunity and Challenges

LeetCode:124. Maximum path sum in binary tree
![[MySQL] limit implements paging](/img/94/2e84a3878e10636460aa0fe0adef67.jpg)
[MySQL] limit implements paging
随机推荐
【剑指offer】序列化二叉树
Tdengine biweekly selection of community issues | phase III
Esp8266-rtos IOT development
LeetCode:836. Rectangle overlap
Excellent software testers have these abilities
Intel distiller Toolkit - Quantitative implementation 1
LeetCode:34. 在排序数组中查找元素的第一个和最后一个位置
CUDA realizes focal_ loss
What is the role of automated testing frameworks? Shanghai professional third-party software testing company Amway
Improved deep embedded clustering with local structure preservation (Idec)
如何正确截取字符串(例:应用报错信息截取入库操作)
注意力机制的一种卷积替代方式
可变长参数
Ijcai2022 collection of papers (continuously updated)
Pytorch view tensor memory size
Intel distiller Toolkit - Quantitative implementation 2
pytorch查看张量占用内存大小
R language ggplot2 visualization: place the title of the visualization image in the upper left corner of the image (customize Title position in top left of ggplot2 graph)
Deep anatomy of C language -- C language keywords
Super efficient! The secret of swagger Yapi