Skip to main content

SeleniumBoot: make an easy way (yaml) to web automation testing

Project description

SeleniumBoot - yaml驱动Selenium测试

概述

Selenium是基于浏览器的自动化测试工具,但是要写python代码;

考虑到部分测试伙伴python能力不足,因此扩展Selenium,支持通过yaml配置测试步骤;

框架通过编写简单的yaml, 就可以执行一系列复杂的浏览器操作步骤, 如填充表单/提交表单/上传文件/下载文件/识别验证码/校验响应/提取变量/打印变量等,极大的简化了伙伴编写自动化测试脚本的工作量与工作难度,大幅提高人效;

框架通过提供类似pythonfor/if/break语义的步骤动作,赋予伙伴极大的开发能力与灵活性,能适用于广泛的测试场景。

框架提供include机制,用来加载并执行其他的步骤yaml,一方面是功能解耦,方便分工,一方面是功能复用,提高效率与质量,从而推进测试整体的工程化。

特性

  1. 基于 selenium 的webdriver
  2. 使用 selenium-requests 扩展来处理post请求与上传请求
  3. 支持通过yaml来配置执行的步骤,简化了自动化测试开发: 每个步骤可以有多个动作,但单个步骤中动作名不能相同(yaml语法要求); 动作代表webdriver上的一种操作,如goto/get/post/upload/submit_form等等;
  4. 支持提取器
  5. 支持校验器
  6. 支持识别验证码(使用有道ocr)
  7. 支持类似pythonfor/if/break语义的步骤动作,灵活适应各种场景
  8. 支持include引用其他的yaml配置文件,以便解耦与复用

todo

  1. 支持更多的动作

安装依赖

pip3 install -r requirements.txt

步骤配置文件

用于指定多个步骤, 示例如 step.yml;

顶级的元素是步骤;

每个步骤里有多个动作(如goto/sleep/submit_form),如果动作有重名,就另外新开一个步骤写动作,这是由yaml语法限制导致的,但不影响步骤执行。

- # 登录
  goto:
    url: http://admin.jym1.com/login
  sleep: 5 # 浏览器F12打开开发者模式,切network,打开Preserve log,来监听提交登录验证的请求,以便检查识别的验证码参数是否有问题
  # 识别验证码, 验证码会写到变量captcha
  recognize_captcha:
    url: http://admin.jym1.com/login/verify_image
  # 提交表单
  submit_form:
    account: '18877310999'
    passwd: '123456'
    verify_text: $captcha # 验证码
- # 商品列表
  goto:
    url: http://admin.jym1.com/goods/goods_service_list
    # 网页中html的提取变量
    extract_by_xpath:
      goods_id: //table/tbody/tr[1]/td[1] # 第一行第一列
  #  extract_by_css:
  #    goods_id: table>tbody>tr:nth-child(1)>td:nth-child(1) # 第一行第一列
- # 商品详情
  goto:
    url: http://admin.jym1.com/goods/goods_info?id=$goods_id&type=1
  download_img_tag_by:
    xpath: //img[@class="layui-upload-img"] # 过滤<img>标签的xpath路径, 与css属性只能二选一
    #css: img.layui-upload-img # 过滤<img>标签的css selector模式, 与xpath属性只能二选一
- # 新建门店
  goto:
    url: http://admin.jym1.com/store/add_store
  upload: # 上传文件/图片
    url: http://admin.jym1.com/upload/common_upload_img/store_img
    files: # 上传的多个文件
      # 参数名:文件本地路径
      file: /home/shi/fruit.jpeg
    extract_by_jsonpath:
      img: $.data.url
  # 提交新建门店,不要用 submit_form,ui中太麻烦了太复杂了(如三级地址要逐级动态加载)
  post:
    url: http://admin.jym1.com/store/add_store
    is_ajax: true
    data: # post的参数
      # 参数名:参数值
      store_name: teststore-${random_str(6)}
      store_logo_url: '$img'
      store_img_urls: '["$img"]'
      province: 450000
      city: 450100
      district: 450102
      address: testadd
      phone: 1347115${random_int(4)}
      business_day_from: 1
      business_day_to: 1
      work_start_time: 09:00:00 - 20:00:00
      store_type: 0
      licence_url: '$img'
      license_code: 91450100788439413D
      card_true_name: shi
      bank_name: 中国工商银行
      bank_card_num: 6222024100018669328
      store_work_time: '["{\"date_from\":\"1\",\"date_to\":\"1\",\"work_start_time\":\"09:00:00\",\"work_end_time\":\"20:00:00\"}"]'
- # 门店列表,查看新建门店
  goto:
    url: http://admin.jym1.com/store/store_list
  sleep: 2

运行

python boot.py 步骤配置文件

配置详解

支持通过yaml来配置执行的步骤;

每个步骤可以有多个动作,但单个步骤中动作名不能相同(yaml语法要求);

动作代表webdriver上的一种操作,如goto/get/post/upload/submit_form等等;

下面详细介绍每个动作:

  1. sleep: 线程睡眠;
sleep: 2 # 线程睡眠2秒
  1. print: 打印, 支持输出变量/函数;
# 调试打印
print: "总申请数=${dyn_data.total_apply}, 剩余份数=${dyn_data.quantity_remain}"

变量格式:

$msg 一级变量, 以$为前缀
${data.msg} 多级变量, 用 ${ 与 } 包含

函数格式:

${random_str(6)} 支持调用函数,目前仅支持3个函数: random_str/random_int/incr

函数罗列:

random_str(n): 随机字符串,参数n是字符个数
random_int(n): 随机数字,参数n是数字个数
incr(key): 自增值,从1开始,参数key表示不同的自增值,不同key会独立自增
  1. goto: 浏览器跳转;
goto:
    url: http://admin.jym1.com/goods/goods_service_list # url,支持写变量
    extract_by_xpath: # 网页中html的提取变量
      goods_id: //table/tbody/tr[1]/td[1] # 第一行第一列
  1. get: 发get请求, 但无跳转;
get:
    url: $dyn_data_url # url,支持写变量
    extract_by_eval:
      dyn_data: "json.loads(response.text[16:-1])" # 变量response是响应对象
  1. post: 发post请求, 但无跳转;
post:
    url: http://admin.jym1.com/store/add_store # url,支持写变量
    is_ajax: true
    data: # post的参数
      # 参数名:参数值
      store_name: teststore-${random_str(6)}
      store_logo_url: '$img'
  1. upload: 上传文件;
upload: # 上传文件/图片
    url: http://admin.jym1.com/upload/common_upload_img/store_img
    files: # 上传的多个文件
      # 参数名:文件本地路径
      file: /home/shi/fruit.jpeg
    extract_by_jsonpath:
      img: $.data.url
  1. submit_form: 提交表单; 是 input_by_nameclick_by({'css':'[type=submit]'}) 的结合
submit_form:
  # 输入框name: 填充的值(支持写变量)
  account: '18877310999'
  passwd: '123456'
  1. input_by_name: 填充 name 指定的输入框;
input_by_name:
  # 输入框name: 填充的值(支持写变量)
  account: '18877310999'
  1. input_by_css: 填充 css selector 指定的输入框;
input_by_css:
  # 输入框css selector模式: 填充的值(支持写变量)
  '#account': '18877310999'
  1. input_by_xpath: 填充 xpath 指定的输入框;
input_by_xpath:
  # 输入框xpath路径: 填充的值(支持写变量)
  "//input[@id='account']": '18877310999'
  1. download: 下载文件; 变量download_file记录最新下载的单个文件
download:
    url: https://img.alicdn.com/tfscom/TB1t84NPuL2gK0jSZPhXXahvXXa.jpg_q90.jpg
    save_dir: downloads # 保存的目录,默认为 downloads
    save_file: test.jpg # 保存的文件名,默认为url中最后一级的文件名
  1. download_img_tag_by: 下载单个<img>标签中加载的图片; 变量download_file记录最新下载的单个图片
download_img_tag_by:
    xpath: //img[@class="pro-img"] # 过滤<img>标签的xpath路径,与css属性只能二选一
    #css: img.pro-img # 过滤<img>标签的css selector模式,与xpath属性只能二选一
    save_dir: downloads # 保存的目录,默认为 downloads
    #save_file: test.jpg # 保存的文件名,默认为url中最后一级的文件名
  1. download_img_tags_by: 下载多个<img>标签中加载的图片; 变量download_files记录最新下载的多个图片
download_img_tags_by:
    xpath: '//a[@class="pic J_ImgLoad"]/img'
    save_dir: downloads
  1. recognize_captcha: 识别验证码; 参数同 download 动作, 因为内部就是调用 download; 而变量captcha记录识别出来的验证码
recognize_captcha:
    url: http://admin.jym1.com/login/verify_image
    # save_dir: downloads # 保存的目录,默认为 downloads
    # save_file: test.jpg # 保存的文件名,默认为url中最后一级的文件名
  1. recognize_captcha_tag: 识别验证码标签中的验证码; 参数同 download_img_tag_by 动作, 因为内部就是调用 download_img_tag_by; 而变量captcha记录识别出来的验证码
recognize_captcha_tag:
    xpath: //img[@class="pro-img"] # 过滤<img>标签的xpath路径, 与css属性只能二选一
    #css: img.pro-img # 过滤<img>标签的css selector模式, 与xpath属性只能二选一
    #save_dir: downloads # 保存的目录,默认为 downloads
    #save_file: test.jpg # 保存的文件名,默认为url中最后一级的文件名
  1. click_by: 点击指定的按钮;
click_by:
  css: 'button[type=submit]' # 按钮的css selector模式,与xpath属性只能二选一
  #xpath: '//button[@type="submit"]' # 按钮的xpath路径,与css属性只能二选一
  1. right_click_by: 右击指定的按钮;
right_click_by:
  css: 'button[type=submit]' # 按钮的css selector模式,与xpath属性只能二选一
  #xpath: '//button[@type="submit"]' # 按钮的xpath路径,与css属性只能二选一
  1. double_click_by: 双击指定的按钮;
double_click_by:
  css: 'button[type=submit]' # 按钮的css selector模式,与xpath属性只能二选一
  #xpath: '//button[@type="submit"]' # 按钮的xpath路径,与css属性只能二选一
  1. alert_accept: 点击弹框的确定按钮;
alert_accept: 
  1. alert_dismiss: 取消弹框;
alert_dismiss: 
  1. max_window: 最大化窗口;
max_window: 
  1. resize_window: 调整窗口大小;
resize_window: 100,200 # 宽,高
  1. switch_to_frame_by: 切换进入iframe;
switch_to_frame_by:
  css: 'iframe#main' # iframe的css selector模式,与xpath属性只能二选一
  #xpath: '//iframe[@id="main"]' # iframe的xpath路径,与css属性只能二选一
  1. switch_to_frame_out: 跳回到主框架页;
switch_to_frame_out: 
  1. switch_to_window: 切到第几个窗口;
switch_to_window: 1 # 切到第1个窗口
  1. screenshot: 整个窗口截图存为png;
screenshot:
    save_dir: downloads # 保存的目录,默认为 downloads
    save_file: test.png # 保存的文件名,默认为:时间戳.png
  1. screenshot_tag_by: 对某个标签截图存为png;
screenshot_tag_by
    css: 'iframe#main' # iframe的css selector模式,与xpath属性只能二选一
    #xpath: '//iframe[id="main"]' # iframe的xpath路径,与css属性只能二选一
    save_dir: downloads # 保存的目录,默认为 downloads
    save_file: test.png # 保存的文件名,默认为:时间戳.png
  1. execute_js: 执行js;
execute_js: alert('hello world')
  1. scroll: 滚动到指定位置;
scroll: 100,200
  1. scroll_top: 滚动到顶部;
scroll_top: 
  1. scroll_bottom: 滚动到底部;
scroll_bottom: 
  1. refresh: 刷新网页;
refresh: 
  1. for: 循环; for动作下包含一系列子步骤,表示循环执行这系列子步骤;变量for_i记录是第几次迭代
# 循环3次
for(3) :
  # 每次迭代要执行的子步骤
  - scroll_bottom:
    sleep: 2

# 无限循环,直到遇到跳出动作
# 有变量for_i记录是第几次迭代
for:
  # 每次迭代要执行的子步骤
  - break_if: for_i>2 # 满足条件则跳出循环
    scroll_bottom:
    sleep: 2
  1. once: 只执行一次,等价于 for(1); once 结合 moveon_if,可以模拟 python 的 if 语法效果
once:
  # 每次迭代要执行的子步骤
  - moveon_if: for_i<=2 # 满足条件则往下走,否则跳出循环
    scroll_bottom:
    sleep: 2
  1. break_if: 满足条件则跳出循环; 只能定义在for循环的子步骤中
break_if: for_i>2 # 条件表达式,python语法
  1. moveon_if: 满足条件则往下走,否则跳出循环; 只能定义在for循环的子步骤中
moveon_if: for_i<=2 # 条件表达式,python语法
  1. include: 包含其他步骤文件,如记录公共的步骤,或记录配置数据(如用户名密码);
include: step-common.yml
  1. set_vars: 设置变量;
set_vars:
  name: shi
  password: 123456
  birthday: 5-27
  1. print_vars: 打印所有变量;
print_vars:

校验器

只针对 goto/get/post/upload 有发送http请求的动作, 主要是为了校验响应的内容

  1. validate_by_xpath: 从html的响应中解析 xpath 路径对应的元素的值
validate_by_xpath:
  "//div[@id='goods_id']": # 元素的xpath路径
    '>': 0 # 校验符号或函数: 校验的值, 即 id 元素的值>0
  "//div[@id='goods_title']":
    contains: 衬衫 # 即 title 元素的值包含'衬衫'
  1. validate_by_css: 从html的响应中解析 css selector 模式对应的元素的值
validate_by_css:
  '#id': # 元素的css selector 模式
    '>': 0 # 校验符号或函数: 校验的值, 即 id 元素的值>0
  '#goods_title':
    contains: 衬衫 # 即 title 元素的值包含'衬衫'
  1. validate_by_jsonpath: 从json响应中解析 多层属性 的值
validate_by_jsonpath:
  '$.data.goods_id':
     '>': 0 # 校验符号或函数: 校验的值, 即 id 元素的值>0
  '$.data.goods_title':
    contains: 衬衫 # 即 title 元素的值包含'衬衫'

校验符号或函数

  1. =: 相同
  2. >: 大于
  3. <: 小于
  4. >=: 大于等于
  5. <=: 小于等于
  6. contains: 包含子串
  7. startswith: 以子串开头
  8. endswith: 以子串结尾
  9. regex_match: 正则匹配

提取器

只针对 goto/get/post/upload 有发送http请求的动作, 主要是为了从响应中提取变量

  1. extract_by_xpath: 从html的响应中解析 xpath 路径指定的元素的值
extract_by_xpath:
  # 变量名: xpath路径
  goods_id: //table/tbody/tr[1]/td[1] # 第一行第一列
  1. extract_by_css: 从html的响应中解析 css selector 模式指定的元素的值
extract_by_css:
  # 变量名: css selector 模式
  goods_id: table>tbody>tr:nth-child(1)>td:nth-child(1) # 第一行第一列
  1. extract_by_jsonpath: 从json响应中解析 多层属性 的值
extract_by_jsonpath:
  # 变量名: json响应的多层属性
  img: $.data.url
  1. extract_by_eval: 使用 eval(表达式) 执行表达式, 并将执行结果记录到变量中
extract_by_eval:
    # 变量名: 表达式(python语法)
    dyn_data: "json.loads(response.text[16:-1])" # 变量response是响应对象

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

SeleniumBoot-1.0.0.tar.gz (21.5 kB view details)

Uploaded Source

Built Distribution

SeleniumBoot-1.0.0-py3-none-any.whl (20.0 kB view details)

Uploaded Python 3

File details

Details for the file SeleniumBoot-1.0.0.tar.gz.

File metadata

  • Download URL: SeleniumBoot-1.0.0.tar.gz
  • Upload date:
  • Size: 21.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.7.3

File hashes

Hashes for SeleniumBoot-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f67d515c2687be7672b9d1f7b77108c7f7754c539704ab248224fa0007aeb6f1
MD5 8eba751ba8480c452f024cb81885b365
BLAKE2b-256 ea5ca345833332267e313b9888df83924ddc75b018239187c5e77dd2362eaa9e

See more details on using hashes here.

File details

Details for the file SeleniumBoot-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for SeleniumBoot-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a22e78b857a06fbbdfdc69e95bf990f99779072a35692c2c2f3421565b7a8345
MD5 e3f5be951459b80df8dbd1fbe1686d15
BLAKE2b-256 7e60d6277d82e170e6be01817e044b7106f20afbae019239da1f943796d7ee0f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page