草庐IT

Python+Selenium自动化测试项目实战

春天播种秋天收获 2023-12-06 原文

第 1 章 自动化测试

1.1、自动化测试介绍

自动化测试就是通过自动化测试工具帮我们打开浏览器,输入网址,输入账号密码登录,及登录后的操作,总的说来自动化测试就是通过自动化测试脚本来帮我们从繁琐重复的手工测试里面解脱出来,把时间和精力花到更好的地方去,去挖掘更多的产品缺陷。

例如网上有一些人提供智慧树网、学习通等网课的刷课及答题的服务就是通过写自动化测试程序去完成的。还有一些高速抢票平台也是通过定时执行自动化程序脚本代替人工去抢票。

1.2、自动化测试优点

1. 更好的利用资源,节约人力成本;

2. 覆盖更全,提高工作效率;

3. 产品规格统一标准,增加软件的稳定性。

1.3、自动化测试缺点

问题:是不是自动化测试一定会取代手工测试?

答:不一定的,自动化测试只是帮我们从繁琐重复的手工测试里面解脱出来,把时间和精力花到更好的地方去,去挖掘更多的产品缺陷。因凡事都有利弊,自动化测试适合的场景是软件需求变更少,周期长,稳定性较强的项目。如果需求变更多,软件经常进行改版就不适合做整个系统的自动化测试了,因为每一次改版都要去维护测试脚本,但可以抽取部分稳定的功能做自动化测试。

1.4、自动化测试能解决的问题

  1. 高效完成回归测试。回归测试就项目在发新版本之后,对项目之前的功能进行验证;每一次小迭代,加了一个小功能可能会影响整个系统的功能,比如淘宝、京东等大型商城有几十万个商品列表,这样手工去回归验证就会非常麻烦。而使用自动化测试脚本,就可以根据迭代功能修改自动化测试的脚本去验证,没问题就上线,有问题就让开发改完再上线,这样就不用手工去一个个验证,这就是自动化测试的好处。

  1. 解决-兼容性测试,更换不同浏览器的驱动就可以解决兼容性测试。

  1. 提高测试效率,保证产品质量。

第 2 章 Python基础

2.1、Python常用快捷键

2.2、函数

在开发程序时,使用函数可以提高编写的效率以及代码的重用。

(1)函数的使用包含两个步骤:

1. 定义函数 —— 封装独立的功能;

2. 调用函数 —— 执行函数的代码;

(2)定义函数的格式如下:

函数名称应该能够表达函数封装代码的功能,方便后续的调用。

(3)变量作用域:

1. 局部变量只能在函数内部使用,局部变量从调用函数的时候开始在内存出现,函数调用完毕,局部变量从内存消失;

2. 全局变量从定义变量开始在内存中出现,一直到程序运行完成,和程序一起从内存中消失。

在其他的开发语言中,大多不推荐使用全局变量,因为可变范围太大,导致程序不好维护!

2.3、面向对象编程

面向对象就是将世间万物抽象成一个类,然后形成相应的对象。

(1)类

类就是一个模板,是对一群具有相同特征或者行为的事物的一个统称,是抽象的模板,不能直接使用。

1.类的特性----属性;

2.类中行为----方法;

比如猫这个类有年龄,姓名,主人等属性,有学习、跑步、吃饭、睡觉等方法。

(2)对象

对象就是类的实例化,比如猫这个类可以实例化,具体是什么猫。

(3)面向对象程序设计三大特性:

  1. 封装:根据职责将属性和方法封装到一个抽象的类中,需要用到的时候导包,就可以调用属性和方法了;

  1. 继承:实现代码的重用,子类继承父类就可以拥有父类的属性和方法,这样相同的代码不需要重复的编写;

  1. 多态:不同的对象调用相同的方法,产生不同的执行结果,这样可以增加代码的灵活度。

第 3 章 元素定位方式

3.1、Selenium3.x提供了八种定位元素方式

1. id

2. name

3. class_name

4. tag_name

5. link_text

6. partial_link_text

7. CSS选择器

8. XPath

3.2、id选择器

#找到输入框id后,选中输入框,输入"鹰迅课堂"关键词。

driver.find_element_by_id("kw").send_keys("鹰迅课堂")

3.3、name选择器

driver.find_element_by_name("wd")).send_keys("鹰迅课堂")

3.4、class_name选择器

driver.find_element_by_class_name("s_ipt").send_keys("鹰迅课堂")

3.5、tag_name标签名选择器

ind_element_by_tag_name() 通过标签名去定位,页面相同的标签名重复率多,基本不用。

3.6、link_text超链接内容选择器

driver.find_element_by_link_text("点击进入所有课程").click()

3.7、partial_link_text模糊查询

driver.find_element_by_partial_link_text("所有课程").click()

3.8、CSS选择器

driver.find_element_by_css_selector("div.row:nth-child(5) > div:nth-child(2) > div:nth-child(1) > div:nth-child(2) > div:nth-child(3) > div:nth-child(1) > a:nth-child(1)").click()

3.9、XPath定位方式

driver.find_element_by_xpath("/html/body/div/main/div/div/div[4]/div[2]/div/div/div/div[1]/a").click()

3.10、总结

  1. 定位到一个网页元素后,有输入框使用send_keys(),没有输入框,如果是按钮就用click()进行点击。

  1. 很多时候页面的元素可能是没有id的,没有唯一标识,需求评审的时候可以跟开发约定,网页的元素尽量要有唯一的id和name。

3.11、selenium4定位方式新写法

第 4 章

元素 | 浏览器操作方法

4.1、元素常用操作方法

4.2、操作浏览器常用方法

第 5 章 元素等待

元素等待就是——在定位页面元素时如果未找到,会在指定时间内一直等待的过程。

5.4、为什么要设置元素等待

  1. 网络速度慢

  1. 电脑配置低

  1. 服务器处理请求慢

5.4、强制等待

from time import sleep

sleep(10)

强制等待10秒,再执行下一步,缺点是不管资源是不是完成,都必须等待指定的时间。

5.4、隐式等待

(1)概念:定位元素时,如果能定位到元素则直接返回该元素,不触发等待,执行下一步;如果不能定位到该元素,则间隔一段时间后再去定位元素;如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的异常 NoSuchElementException 。

(2)方法:driver.implicitly_wait(timeout) (timeout:为等待最大时长,单位:秒) ,driver.implicitly_wait(10) ,最长等待10秒。

(3)说明:隐式等待只需要设置一次,就会作用于全局所有的元素。

5.4、显式等待

概念:定位指定元素时,如果能定位到元素则直接返回该元素,不触发等待;如果不能定位到该元素,则程序每隔N秒检查一次,如果检查到目标元素,加载完成,执行下一步,否则继续等待,直到超过设置的最长时间,则抛出超时异常 TimeoutException 。

在Selenium中把显式等待的相关方法封装在WebDriverWait类中。

练习题:打开百度,使用显性等待定位百度输入框,如果元素存在,就输入"www.yxclass.net"。

5.4、隐性等待与显性等待的区别

  1. 作用域不同:隐式为全局元素,是设置全局的等待,显式等待为单个元素有效。

  1. 使用方法不同:隐式等待直接通过驱动对象调用,而显式等待方法封装在WebDriverWait类中。

  1. 达到最大超时时长后抛出的异常不同:隐式等待默认检测频率为0.5s,超时异常为NoSuchElementException;显式等待超时异常为TimeoutException。

第 6 章

鼠标和键盘操作

6.1、鼠标操作

常见的鼠标操作有:点击、右击、双击、悬停、拖拽等,对于这些鼠标操作Selenium都封装了相应的操作方法。

6.2、鼠标操作的方法

(1)说明:

在Selenium中将操作鼠标的方法封装在ActionChains类中。

(2)实例化对象:

action = ActionChains(driver)

(3)执行鼠标事件原理:

在ActionChains类中所有提供的鼠标事件方法,在调用的时候,所有的行为都存储在ActionChains对象中,调用ActionChains的方法时不会立即执行,会将所有的操作按顺序存放在一个队列里,当调用perform()方法时,队列中的事件会依次执行,先进先出,后进后出。

(4)强调:必须调用perform()方法才能执行鼠标事件。

(5)支持链式写法或者分步写:

ActionChains(driver).click(ele).perform()

(6)鼠标和键盘常用方法列表:

(7)鼠标和键盘常用方法:

(8)例题

6.3、键盘操作练习题

(1)Selenium中把键盘的按键都封装在Keys类中,使用时要导包。

(2)导包:from selenium.webdriver.common.keys import Keys

6.4、常用的键盘操作

练习题:在百度浏览器搜索框输入www.yxclass.net,然后粘贴到搜狗浏览器的搜索框进行搜索。

6.5、自动化测试答题

单选框是这样答,多选题也是一样的回答方法。

6.6、弹窗处理

应用场景:

  1. 删除在线商城购物车的商品,在删除时,需要选择是否删除。

  1. 在播放视频课程中也会有一些答题窗口,答题后才能继续播放视频。

弹出框处理方法:

  1. 获取弹出框对象:alert = driver.switch_to.alert

  1. 调用:

  • alert.text --> 返回alert/confirm/prompt中的文字信息

  • alert.accept() --> 接受对话框选项

  • alert.dismiss() --> 取消对话框选项

练习题:点击confirm后,弹出页面提示框选择“确定”。

答了一题没法自动切换到下一题的话,就要调用switch_to_alert()方法切换窗口。

6.7、下拉选择框

(1)说明:

Select类是Selenium为操作select标签特殊封装的。

(2)实例化对象:

select = Select(element)

element: <select>标签对应的元素,通过元素定位方式获取,

例如:driver.find_element_by_id("index")

(3)操作方法:

(4)Select类实现步骤分析:

(5)示例代码:

6.8、滚动条

selenium中并没有直接提供操作滚动条的方法,但是它提供了可执行JavaScript脚本的方法,所以我们可以通过JavaScript脚本来达到操作滚动条的目的。

1.设置JavaScript脚本控制滚动条

js = "window.scrollTo(0,1000)"

#(0:左边距;1000:上边距;单位像素)

示例:滑动到最底层

js1 = "window.scrollTo(0,10000)"

driver.execute_script(js1)

2. selenium调用执行JavaScript脚本的方法

driver.execute_script(js)

示例:滑动到最顶层

js2 = "window.scrollTo(0,0)"

driver.execute_script(js2)

练习题:滑动到鹰迅课堂网站的最底层。

6.9、窗口截图

说明:在Selenium中,提供了截图方法,需要进行截图时我们只需要调用即可方法:driver.get_screenshot_as_file(imgpath) #imgpath:图片保存路径。

6.10、跳过验证码

(1)验证码说明:一种随机生成的信息(数字、字母、汉字、图片、算术题)等为了防止恶意的请求行为,增加应用的安全性。

(2)解决验证码问题的几种常用处理方式:

  1. 去掉验证码:测试环境下采用;

  1. 设置万能验证码:开发环境和测试环境下采用;

  1. 验证码识别技术:通过Python-tesseract来识别图片类型验证码;识别率很难达到100%;

  1. 记录cookie:通过记录cookie进行跳过登录。

(3)跳过验证码登录百度

BDUSS是登录百度后的唯一身份凭证(*.baidu.com),拿到BDUSS就等于拿到账号的控制权。

第 7 章 UnitTest+PyTest

7.1、UnitTest介绍

UnitTest是python自带的自动化测试框架;

UnitTest主要包含的内容:

  • TestCase(测试用例)

  • TestSuite(测试套件,把多个TestCase集成到一个测试TestSuite中,按照从上往下顺序执行)

  • TestRunner(执行测试用例)

  • TestLoader(自动从代码中加载多个测试用例TestCase)

  • Fixture(UnitTest特性)

7.2、PyTest

pytest 是 python 的一种单元测试框架,同自带的 UnitTest 测试框架类似,相比于 UnitTest 框架使用起来更简洁,效率更高

pytest 在运行自动化脚本的前后会执行两个特殊的方法,分别是 setup 和 teardown 。在执行脚本之前会执行 setup 方法,在执行脚本之后会执行 teardown 方法。有了这两个方法,我们可以在 setup 中进行获取驱动对象的操作,在 teardown 中进行关闭驱动对象的操作。

第 8 章 项目实战并自动发送测试报告邮件

需求:测试鹰迅课堂所有已经上线了的课程。

代码:

自动发送测试邮件

测试用例设计应该解耦,独立运行,脚本应该按照模块化分层。这样在软件每次迭带的时候,就可以根据迭带情况快速修改对应模块的自动化测试脚本了。

执行用例时就会进行截图。

脚本执行结束后,就自动发送测试报告邮件了。

· 往期回顾 ·

Postman接口测试项目实战

Excel函数公式汇总

Oracle数据库和PLSQL可视化工具学习笔记

Jmeter非GUI压测项目实战笔记

有关Python+Selenium自动化测试项目实战的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  8. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  9. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  10. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

随机推荐