自动化测试平台

自动化测试平台

1.效果展示

用例管理(思维导图)在这里插入图片描述
用例管理(表格)在这里插入图片描述

自动化(列表)在这里插入图片描述

接口自动化在这里插入图片描述
接口编辑在这里插入图片描述
ui自动化在这里插入图片描述
测试报告(仿allure样式自开发)在这里插入图片描述

2.框架概述

框架模型前端(vue)+后端(django)+数据库(mysql、redis)+nginx(代理服务器)+uwsgi(web服务器)

3. 功能概述

一.自动化类

Ⅰ.界面自动化(ui)

模块:selenium、Selenium Grid、Remote、redis、mysql、log、apscheduler、django_apscheduler、

getattr 反射实现

python内置模块

time模块
time.time() # 时间戳
time.gmtime() # 转换时区

datatime模块
datetime.datetime.now() # 获取当前时间

random模块
random.randint(1, 3)
random.randrange(1, 3)
random.choice([1, '23', [4, 5]])

sys模块
os模块
json模块
pickle模块
shelve模块
xml模块
re模块
logging模块
uuid模块
base64模块
configparser解析配置文件模块

hashlib、md5模块
hashlib.md5(‘md5_str‘).hexdigest() 对指定字符串md5加密
md5.md5(‘md5_str‘).hexdigest() 对指定字符串md5加密

math模块

selenium

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动浏览器
# 普通模式
driver = webdriver.Chrome(driver)
driver.implicitly_wait(10)
driver.maximize_window()
# 远程模式
chrome_options = webdriver.ChromeOptions()
BaseUi.driver = webdriver.Remote(command_executor=command_executor, options=chrome_options)
BaseUi.driver.maximize_window()
BaseUi.driver.implicitly_wait(10)
# 无界面模式
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument("window-size=1920,1080")
chrome_options.add_argument("--no-sandbox")
BaseUi.driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=self.driver_path_local)
BaseUi.driver.implicitly_wait(10)
BaseUi.driver.maximize_window()
WebDriverWait(self.driver, secs).until(EC.invisibility_of_element_located(element)) # 显示等待

# 常用方法
# 定位元素方法
id、name、class_name、css_selector、tag_name、link_text、partial_link_text、xpath
# css和xpath的区别
1.语法格式不一样:
	xpath直接元素用/, 内部元素用//
	css直接元素用>, 内部元素用空格
2.定位常规属性的区别:
	xpath用@属性名
	css中id'#', class'.',name用'[name]' 
	xpath多个属性用'and', css用'[属性]'
	xpath有文本属性, css没有文本属性
	xpath索引用'[num]', css用'(num)'
	xpath不能直接操作select, css可以
	xpath找父元素用'/..', 
	xpath可以通过元素文本模糊匹配'contains(text(), '模糊匹配')'
# 浏览器操作
maximize_window()
set_window_size(wide, high)
close()
quit()
forward()
back()
refresh()
# 属性
title
current_url
text
# 操作元素
get()
send_keys()
click()
context_click()
double_click()
move_to_element() # 鼠标移动到元素上方,并保持悬浮
drag_and_drop() # 拖拽一个元素到另一个元素
ActionChains(driver)
submit() # 提交表单
execute_script() # 执行js代码
get_attribute() # 获取元素属性的值
page_source() # 获取页面源代
is_displayed() # 判断元素是否可见
switch_to.frame # 切入iframe框架里边
switch_to.parent_frame() # 退出当前iframe
switch_to.default_content() # 切出iframe,回到主界面
switch_to.window(handle) # 切换到名字为title的窗口
get_screenshot_as_file(file_path) # 截图(类型为文件)

定时任务

from apscheduler.triggers.cron import CronTrigger
from utils.common.cron_trigger import MyCronTrigger
from django_apscheduler.jobstores import DjangoJobStore
from apscheduler.schedulers.background import BackgroundScheduler

# 实例化定时任务对象
scheduler = BackgroundScheduler() # [ˈʃedjuːl]
scheduler.add_jobstore(DjangoJobStore(), "default")
scheduler.start()
# 任务的方法
新增任务:add_job(fun_name, trigger=MyCronTrigger.my_from_crontab(cron), id=name, kwargs={"task_data": task_data}, timezone=pytz.utc, max_instances=4)
删除任务:remove_job(job_name)
暂停任务:pause_job(job_name) #  [pɔːz] 
恢复任务:resume_job(job_name) # [rɪˈzjuːm]
修改任务:reschedule_job(job_id, trigger=CronTrigger(second=str(trigger)))
获取单个任务:get_job(job_id)
获取所有任务:get_jobs()

redis

import redis

# rs = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True)
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True)
rs = redis.Redis(connection_pool=pool)

1.字符串的操作
rs.set(name, value, ex=None, px=None, nx=False, xx=False) # 批量设置值
  ex,过期时间(秒)
  px,过期时间(毫秒)
  nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value)
  xx,如果设置为True,则只有name存在时,当前set操作才执行
rs.mset(name1='zhangsan', name2='lisi') # 批量获取
rs.getset(name, value) # getset 设置新值,打印原值
rs.type(name) # 查看类型
rs.keys() # 获取所有的key值
rs.delete(name) # 删除指定的key-value值
rs.flushall() # 清除redis里面的所有key-value

2.列表操作
rs.rpush('list',1,2,3) # 尾部添加
rs.lpush('list',0) # 头部添加
rs.llen('list') # 返回列表的长度
rs.lrange('list',0,-1) # 获取list全部内容
rs.lindex('list',1) # 获取索引元素

3.Set 操作
rs.sadd(name,values) # 给name对应的集合中添加元素
rs.smembers('set_name') # 获取name对应的集合的所有成员
rs.scard("set_name") # 获取name对应的集合中的元素个数

4.哈希表操作
rs.hset('price','cake',5) # 添加映射
rs.hget('price','cake') # 根据键获取数据
rs.hmset('price',{'banana':2,'apple':3,'pear':6,'orange':7}) # 批量添加映射
rs.hmget('price',['apple','orange']) # 批量获取
rs.hexists('price','banana') # 在price中banana是否存在  返回True
rs.hdel('price','banana') # 从price中删除banana 返回1
rs.hlen('price') # 输出price的长度
rs.hkeys('price') # 输出所有的映射键名
rs.hvals('price') # 输出所有的映射键值
rs.hgetall('price') # 输出所有的映射键对

随机函数

import random
import string
import pinyin

random.random() # 用于生成一个[0,1)范围的浮点数
random.uniform(10, 20) # 生成一个指定范围内的随机符点数
random.randint(12, 20) # 生成一个指定范围内的整数
random.choice(string) # 随机选取一个字符

yaml配置文件

import yaml

with open(yaml_path, 'r', encoding='utf-8') as f:
	content = yaml.load(f.read(), Loader=yaml.FullLoader)
return content

日志

import logging

logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
root_path = os.path.realpath("./report/log/")

# 定义日志级别(一般日志)
handler = TimedRotatingFileHandler(root_path + 'info.log'.format(now_ymd()), when='d', interval=1, backupCount=30, encoding='utf-8')
handler.setLevel(logging.INFO) # 日志级别INFO、ERROR、DEBUG
formatter = logging.Formatter('%(levelname)s - %(asctime)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

发送邮件

import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

message = MIMEText('接口自动化发送邮件测试...', 'plain', 'utf-8') # 文本邮件
message = MIMEText(mail_msg, 'html', 'utf-8') # 网页邮件
# 发送附件
att = MIMEText(open('../../Report/Log/error.log', 'rb').read(), 'base64', 'utf-8')
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="error.log"'

smtp = smtplib.SMTP()
smtp.connect(mail_host, 25)  # 设置服务器, 25为SMTP端口号
smtp.login(mail_user, mail_pass)  # 登录验证(pass口令)
smtp.sendmail(sender, receivers, message.as_string()) # 发件人,收件人,消息内容

图片接口

def img(request, folder_name, name):
    return HttpResponse(open(str("./report/image/" + folder_name + '/' + name) + ".png", "rb"), content_type="image/png")

上传文件

driver_file = request.FILES.get('files')
driver_form = request.POST.get('driverForm').split(',')
file_exists = os.path.exists(driver_file_path)
os.mkdir(driver_file_path)
destination = open(driver_file_path + '/' + driver_file.name, 'wb+')  # 打开特定的文件进行二进制的写操作
for chunk in driver_file.chunks():  # 分块写入文件
	destination.write(chunk)

Ⅱ.接口自动化(api)
Ⅲ.定时任务()

二.工具类

Ⅰ.版本验证

模块:requests、bs4、re

soup = BeautifulSoup(page_html_text, 'html.parser')
soup.find_all('tbody')[0])

Ⅱ.幂等验证

模块:grequests

request_list = [
   grequests.post(url, json=data, cookies=cookies),
   grequests.post(url, json=data, cookies=cookies),
   grequests.post(url, json=data, cookies=cookies),
   grequests.post(url, json=data, cookies=cookies),
   grequests.post(url, json=data, cookies=cookies),
]
grequests.map(request_list)

Ⅲ.服务数据

模块:requests

# 求取并集
list(set(sprint_list).union(set(swagger_list)).union(set(sky_walking_list)))

Ⅳ.思维导图

模块:MindElixir

Ⅴ.在线文档

模块:Luckysheet

4. 技术概述

前端(vue)

1.视图,数据,结构分离
2.数据双向绑定
3.Vue的响应式原理
4.vue中created与mounted区别
5.watch来监听数据的变化

1.监听的数据后面可以写成对象形式,包含handler方法,immediate和deep。
2.immediate表示在watch中首次绑定的时候,是否执行handler,值为true则表示在watch中声明的时候,就立即执行handler方法,值为false,则和一般使用watch一样,在数据发生变化的时候才执行handler。
3.当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。
watch: {
    name: {
      handler(newName, oldName) {
      
      },
      deep: true,
      immediate: true
    }
  } 

6.插槽slot
7.vue中常用的一些指令
8.v-show和v-if

1.v-model指令:用于表单输入,实现表单控件和数据的双向绑定。
2.v-on:简写为@,基础事件绑定
3.v-bind:简写为:,动态绑定一些元素的属性,类型可以是:字符串、对象或数组。
4.v-if指令:取值为true/false,控制元素是否需要被渲染
5.v-else指令:和v-if指令搭配使用,没有对应的值。当v-if的值false,v-else才会被渲染出来。
6.v-show指令:指令的取值为true/false,分别对应着显示/隐藏。
7.v-for指令:遍历data中存放的数组数据,实现列表的渲染。
8.v-once: 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新

9.vue的生命周期

生命周期通俗说就是Vue实例从创建到销毁的过程,就是生命周期。
beforecreate (初始化界面前)
created (初始化界面后)
beforemount (渲染界面前)
mounted (渲染界面后)
beforeUpdate (更新数据前)
updated (更新数据后)
beforedestory (卸载组件前)
destroyed (卸载组件后)

10.axios 是什么

1.Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,
2.react/vue 官方都推荐使用 axios 发 ajax 请求
特点:
1.基于 promise 的异步 ajax 请求库,支持promise所有的API
2.浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests
3.支持请求/响应拦截器
4.支持请求取消
5.可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
6.批量发送多个请求
7.安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。

后端(django)
数据库(mysql、redis)
nginx(代理服务器)
uwsgi(web服务器)
docker容器(集装箱)

1.基础命令

systemctl stop docker # 启动
systemctl restart docker # 关闭
systemctl enable docker # 重启
systemctl status docker # 设置随服务启动而自启动
netstat -untlp # 监控TCP/IP网络

2.镜像命令

docker images
docker pull 镜像名:tag
docker run 镜像名:Tag
docker rmi -f 镜像名/镜像ID # 删除镜像,当前镜像没有被任何容器使用才可以删除
docker image rm 镜像名称/镜像ID # 强制删除镜像
docker save 镜像名/镜像ID -o 镜像保存在哪个位置与名字 # 保存镜像

3.容器命令

docker ps # 查看正在运行容器列表
docker ps -a # 查看所有容器

# -it 表示 与容器进行交互式启动 -d 表示可后台运行容器 (守护式运行) 
# --name 给要运行的容器 起的名字  /bin/bash  交互路径
docker run -it -d --name 要取的别名 镜像名:Tag /bin/bash
docker run -it -d --name redis001 redis:5.0.5 /bin/bash # 启动容器
docker run -itd --name redis002 -p 8888:6379 redis:5.0.5 /bin/bash # 容器端口映射
docker exec -it 容器名/容器ID /bin/bash # 进入容器
docker attach 容器名/容器ID # 进入容器
Ctrl + p + q # 退出
docker stop 容器ID/容器名 # 停止容器
docker restart 容器ID/容器名 # 重启容器
docker start 容器ID/容器名 # 启动容器
docker kill 容器ID/容器名 # kill 容器

5.线上部署

uwsgi配置

[uwsgi]
#配置和nginx接的socket接
socket=127.0.0.1:8000
master = true
processes = 1
threads = 2
chdir = /www/wwwroot/test_platform
wsgi-file= /www/wwwroot/test_platform/test_platform
# http = 0.0.0.0:8000
logto = /www/wwwroot/test_platform/logs/error.log
chmod-socket = 660
vacuum = true
master = true
max-requests = 1000

nginx配置

server
{
	listen 80;
    server_name 10.1.201.1;
    index index.php index.html index.htm default.php default.htm default.html;
    root /www/wwwroot/test_platform/templates/dist/;
    
    location / {
     include uwsgi_params;
     uwsgi_pass 127.0.0.1:8000;  #端口要和uwsgi里配置的一样
     uwsgi_param UWSGI_SCRIPT test_platform.wsgi;  #wsgi.py所在的目录名+.wsgi
     uwsgi_param UWSGI_CHDIR /www/wwwroot/test_platform/; #项目路径
     proxy_connect_timeout 600;
    }
    
    location /static/ {
      root /www/wwwroot/test_platform/templates/dist/; #静态资源路径
    }

    location /favicon.ico {
      root /www/wwwroot/test_platform/templates/dist/; #静态资源路径
    }
}
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
自动化测试平台是一种用于执行和管理软件测试的工具,它可以帮助开发团队提高测试效率和质量。自动化测试平台的源代码通常包含以下几个主要组件: 1. 测试框架:测试框架是自动化测试平台的核心部分,它提供了执行测试用例、收集测试结果和生成报告的功能。测试框架通常包含测试执行引擎、测试用例管理和调度模块等。 2. 测试脚本:测试脚本是自动化测试平台中的关键部分,它用于描述和执行具体的测试步骤和验证逻辑。测试脚本可以使用不同的编程语言编写,如Python、Java等。 3. 测试数据:测试数据是用于驱动测试脚本执行的输入数据,它可以包括测试用例的输入参数、预期结果等。测试数据可以通过配置文件、数据库或者其他方式进行管理。 4. 测试环境:测试环境是指用于执行自动化测试的硬件和软件环境。测试环境需要提供合适的操作系统、数据库、网络等基础设施,并确保测试环境的稳定性和一致性。 5. 测试报告:测试报告是自动化测试平台生成的结果文档,它包含了测试执行的详细信息、测试结果和问题记录等。测试报告可以以文本、HTML、PDF等格式输出,并提供可视化的图表和统计信息。 以上是自动化测试平台源代码的一般组成部分,具体实现方式和细节可能因不同的平台而有所差异。如果你对某个具体的自动化测试平台感兴趣,可以提供更多详细信息,我可以给出更具体的介绍。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值