selenium python 实现基本自动化测试的示例代码


Posted in Python onFebruary 25, 2019

安装selenium

打开命令控制符输入:pip install -U selenium

火狐浏览器安装firebug:www.firebug.com,调试所有网站语言,调试功能

Selenium IDE 是嵌入到Firefox 浏览器中的一个插件,实现简单的浏览器操 作的录制与回放功能,IDE 录制的脚本可以可以转换成多种语言,从而帮助我们快速的开发脚本,下载地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/

如何使用IDE录制脚本:点击seleniumIDE——点击录制——开始录制——录制完成后点击文件Export Test Case——python/unittest/Webdriver——保存;

安装python

安装的时候,推荐选择“Add exe to path”,将会自动添加Python的程序到环境变量中。然后可以在命令行输入 python -V 检测安装的Python版本。

浏览器内壳:IE、chrome、FireFox、Safari

1、webdriver:用unittest框架写自动化用例(setUp:前置条件,tearDown清场) 

import unittest
from selenium import webdriver

class Ranzhi(unittest.TestCase):
  def setUp(self):
    self.driver = webdriver.Firefox() #选择火狐浏览器
  def test_ranzhi(self):
    pass
  def tearDown(self):
    self.driver.quit()#退出浏览器

2、断言,检查跳转的网页是否和实际一致

断言网址时需注意是否为伪静态(PATH_INFO)或者GET,前者采用路径传参数(sys/user-creat.html),后者通过字符查询传参数(sys/index.php?m=user&f=index)

当采用不同方式校验网址会发现变化。

self.assertEqual("http://localhost:8080/ranzhi/www/s/index.php?m=index&f=index",
         self.driver.current_url, "登录跳转失败")

 selenium python 实现基本自动化测试的示例代码

3、定位元素,在html里面,元素具有各种各样的属性。我们可以通过这样唯一区别其他元素的属性来定位到这个元素.

  WebDriver提供了一系列的元素定位方法。常见的有以下几种:id,name,link text,partial link text,xpath,css seletor,class,tag.

self.driver.find_element_by_xpath('//*[@id="s-menu-superadmin"]/button').click()
self.driver.find_element_by_id('account').send_keys('admin')
self.driver.find_element_by_link_text(u'退出').click()

定位元素需注意的问题:

a.时间不够,采用两种方式(self.implicitly_wait(30),sleep(2))

b.函数嵌套(<iframe></iframe>)

# 进入嵌套
 self.driver.switch_to.frame('iframe-superadmin')
#退出嵌套
 self.driver.switch_to.default_content()

c.flash,验证码(关闭验证码或使用万能码)

d.xpath问题:最好采用最简xpath,当xpath中出现li[10]等时需注意,有时页面定位会出现问题

4、采用CSV存数据

CSV:以纯文本形式存储表格数据(数字和文本),CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。大量程序都支持某种CSV变体,至少是作为一种可选择的输入/输出格式。

melody101,melody101,m,1,3,123456,@qq.com
melody102,melody101,f,2,5,123456,@qq.com
melody103,melody101,m,3,2,123456,@qq.com
import csv
# 读取CSV文件到user_list字典类型变量中
user_list = csv.reader(open("list_to_user.csv", "r"))
# 遍历整个user_list
for user in user_list:
  sleep(2)
  self.logn_in('admin', 'admin')
  sleep(2)
  # 读取一行csv,并分别赋值到user_to_add 中
  user_to_add = {'account': user[0],
          'realname': user[1],
          'gender': user[2],
          'dept': user[3],
          'role': user[4],
           'password': user[5],
           'email': user[0] + user[6]}
   self.add_user(user_to_add)

5、对下拉列表的定位采用select标签

from selenium.webdriver.support.select import Select
# 选择部门
dp =self.driver.find_element_by_id('dept')
Select(dp).select_by_index(user['dept'])
# 选择角色
Select(self.driver.find_element_by_id('role')).select_by_index(user['role'])

 6、模块化代码

需要对自动化重复编写的脚本进行重构(refactor),将重复的脚本抽取出来,放到指定的代码文件中,作为共用的功能模块。使用模块化代码注意需倒入该代码。

#模块化代码后引用,需导入代码模块
from ranzhi_lib import RanzhiLib
self.lib = RanzhiLib(self.driver)
# 点击后台管理
self.lib.click_admin_app()
sleep(2)
# 点击添加用户
self.lib.click_add_user()
# 添加用户
self.lib.add_user(user_to_add)
sleep(1)
# 退出
self.lib.logn_out()
sleep(2)
class RanzhiLib():
   # 构造方法
   def __init__(self, driver):
    self.driver = driver

7、自定义函数运行的先后顺序:完整的单元测试很少只执行一个测试用例,开发人员通常都需要编写多个测试用例才能对某一软件功能进行比较完整的测试,这些相关的测试用例称为一个测试用例集,在PyUnit中是用TestSuite类来表示,采用unittest.TestSuite()。

PyUnit使用TestRunner类作为测试用例的基本执行环境,来驱动整个单元测试过程。Python开发人员在进行单元测试时一般不直接使用TestRunner类,而是使用其子类TextTestRunner来完成测试。

# 构造测试集
suite = unittest.TestSuite()
suite.addTest(RanzhiTest("test_login"))
suite.addTest(RanzhiTest("test_ranzhi"))
  
# 执行测试
runner = unittest.TextTestRunner()
runner.run(suite)

以下代码为登录“然之系统”,进入添加用户,循环添加用户并检测添加成功,再退出的过程。以下程序分别为主程序,模块化程序,执行程序,CSV文件

import csv
import unittest
from time import sleep

from selenium import webdriver
# 模块化代码后引用需导入代码模块
from ranzhi_lib import RanzhiLib


class Ranzhi(unittest.TestCase):
  def setUp(self):
    self.driver = webdriver.Firefox()
    self.lib = RanzhiLib(self.driver)

  # 主函数
  def test_ranzhi(self):
    # 读取CSV文件到user_list字典类型变量中
    user_list = csv.reader(open("list_to_user.csv", "r"))
    # 遍历整个user_list
    for user in user_list:
      sleep(2)
      self.lib.logn_in('admin', 'admin')
      sleep(2)
      # 断言
      self.assertEqual("http://localhost:8080/ranzhi/www/sys/index.html",
               self.driver.current_url,
               '登录跳转失败')
      # 读取一行csv,并分别赋值到user_to_add 中
      user_to_add = {'account': user[0],
              'realname': user[1],
              'gender': user[2],
              'dept': user[3],
              'role': user[4],
              'password': user[5],
              'email': user[0] + user[6]}
      # 点击后台管理
      self.lib.click_admin_app()
      # 进入嵌套
      self.lib.driver.switch_to.frame('iframe-superadmin')
      sleep(2)
      # 点击添加用户
      self.lib.click_add_user()
      # 添加用户
      self.lib.add_user(user_to_add)
      # 退出嵌套
      self.driver.switch_to.default_content()
      sleep(1)
      # 退出
      self.lib.logn_out()
      sleep(2)
      # 用新账号登录
      self.lib.logn_in(user_to_add['account'], user_to_add['password'])
      sleep(2)
      self.lib.logn_out()
      sleep(2)

  def tearDown(self):
    self.driver.quit()
from time import sleep

from selenium.webdriver.support.select import Select


class RanzhiLib():
  # 构造方法
  def __init__(self, driver):
    self.driver = driver

  # 模块化添加用户
  def add_user(self, user):
    driver = self.driver
    # 添加用户名
    ac = driver.find_element_by_id('account')
    ac.send_keys(user['account'])
    # 真实姓名
    rn = driver.find_element_by_id('realname')
    rn.clear()
    rn.send_keys(user['realname'])
    # 选择性别
    if user['gender'] == 'm':
      driver.find_element_by_id('gender2').click()
    elif user['gender'] == 'f':
      driver.find_element_by_id('gender1').click()
    # 选择部门
    dp = driver.find_element_by_id('dept')
    Select(dp).select_by_index(user['dept'])
    # 选择角色
    role = driver.find_element_by_id('role')
    Select(role).select_by_index(user['role'])
    # 输入密码
    pwd1 = driver.find_element_by_id('password1')
    pwd1.clear()
    pwd1.send_keys(user['password'])

    pwd2 = driver.find_element_by_id('password2')
    pwd2.send_keys(user['password'])
    # 输入邮箱
    em = driver.find_element_by_id('email')
    em.send_keys(user['email'])
    # 点击保存
    driver.find_element_by_id('submit').click()
    sleep(2)

  # 登录账号
  def logn_in(self, name, password):
    driver = self.driver
    driver.get('http://localhost:8080/ranzhi/www')
    sleep(2)

    driver.find_element_by_id('account').clear()
    driver.find_element_by_id('account').send_keys(name)
    driver.find_element_by_id('password').clear()
    driver.find_element_by_id('password').send_keys(password)
    driver.find_element_by_id('submit').click()
    sleep(2)

  # 退出账号
  def logn_out(self):
    self.driver.find_element_by_id('start').click()
    sleep(4)
    self.driver.find_element_by_link_text(u'退出').click()
    sleep(3)

  # 点击后台管理
  def click_admin_app(self):
    self.driver.find_element_by_xpath('//*[@id="s-menu-superadmin"]/button').click()
    sleep(1)

  def click_add_user(self):
    self.driver.find_element_by_xpath('//*[@id="shortcutBox"]/div/div[1]/div/a/h3').click()
    sleep(3)
import unittest

from ranzhi import Ranzhi


class RanzhiTestRunner():
  def run_tests(self):
    suite = unittest.TestSuite()
    suite.addTest(Ranzhi('test_ranzhi'))
    runner = unittest.TextTestRunner()
    runner.run(suite)


if __name__ == "__main__":
  ranzhi_test_runner = RanzhiTestRunner()
  ranzhi_test_runner.run_tests()
melody109,melody101,m,1,3,123456,@qq.com
melody106,melody101,f,2,5,123456,@qq.com
melody107,melody101,m,3,2,123456,@qq.com

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现简单遗传算法
Mar 19 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
May 24 Python
对pandas的行列名更改与数据选择详解
Nov 12 Python
基于Python批量生成指定尺寸缩略图代码实例
Nov 20 Python
python函数声明和调用定义及原理详解
Dec 02 Python
Python.append()与Python.expand()用法详解
Dec 18 Python
Python爬取腾讯视频评论的思路详解
Dec 19 Python
Python中的整除和取模实例
Jun 03 Python
浅谈keras2 predict和fit_generator的坑
Jun 17 Python
Django跨域请求原理及实现代码
Nov 14 Python
Python页面加载的等待方式总结
Feb 28 Python
python实现监听键盘
Apr 26 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
Feb 25 #Python
Python3.5实现的罗马数字转换成整数功能示例
Feb 25 #Python
Python爬虫beautifulsoup4常用的解析方法总结
Feb 25 #Python
python3实现指定目录下文件sha256及文件大小统计
Feb 25 #Python
Python常用爬虫代码总结方便查询
Feb 25 #Python
Python使用paramiko操作linux的方法讲解
Feb 25 #Python
详解Django中CBV(Class Base Views)模型源码分析
Feb 25 #Python
You might like
无数据库的详细域名查询程序PHP版(5)
2006/10/09 PHP
Dedecms常用函数解析
2008/02/01 PHP
php学习之 数组声明
2011/06/09 PHP
WordPress分页伪静态加html后缀
2016/06/08 PHP
php简单解析mysqli查询结果的方法(2种方法)
2016/06/29 PHP
详谈配置phpstorm完美支持Codeigniter(CI)代码自动完成(代码提示)
2017/04/07 PHP
PHP大文件分片上传的实现方法
2018/10/28 PHP
JavaScript原生对象之Number对象的属性和方法详解
2015/03/13 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
AngularJS实用基础知识_入门必备篇(推荐)
2017/07/10 Javascript
使用JS组件实现带ToolTip验证框的实例代码
2017/08/23 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
微信小程序实现上传图片裁剪图片过程解析
2019/08/22 Javascript
原生javascript制作贪吃蛇小游戏的方法分析
2020/02/26 Javascript
[03:09]DOTA2亚洲邀请赛 LGD战队出场宣传片
2015/02/07 DOTA
[48:54]VGJ.T vs infamous Supermajor小组赛D组败者组第一轮 BO3 第二场 6.3
2018/06/04 DOTA
使用Python编写Linux系统守护进程实例
2015/02/03 Python
Python使用turtule画五角星的方法
2015/07/09 Python
详解python eval函数的妙用
2017/11/16 Python
python读取xlsx的方法
2018/12/25 Python
Python整数对象实现原理详解
2019/07/01 Python
Django上使用数据可视化利器Bokeh解析
2019/07/31 Python
详解Python中的format格式化函数的使用方法
2019/11/20 Python
python读取Kafka实例
2019/12/23 Python
在Python中利用pickle保存变量的实例
2019/12/30 Python
pytorch: Parameter 的数据结构实例
2019/12/31 Python
Python如何给你的程序做性能测试
2020/07/29 Python
日本索尼音乐商店:Sony Music Shop
2018/07/17 全球购物
澳大利亚领先的折扣药房:Chemist Direct(有中文站)
2018/11/24 全球购物
Java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
2012/05/30 面试题
起诉离婚协议书样本
2014/11/25 职场文书
运动会运动员赞词
2015/07/22 职场文书
sql通过日期判断年龄函数的示例代码
2021/07/16 SQL Server
Rhit高效可视化Nginx日志查看工具
2021/11/01 Servers
Redis 限流器
2022/05/15 Redis