程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

yield(0)

面向对象(0)

标签  

字典(0)

列表(0)

日期归档  

2023-06(2)

Selenium3与Python3实战开发Web自动化测试框架(二)

发布于2019-08-22 16:18     阅读(854)     评论(0)     点赞(3)     收藏(5)


说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/94022561

目录

四丶Unittest介绍及项目实战中的运用

五丶数据驱动的介绍及使用

六丶关键字模型的介绍及运用


四丶Unittest介绍及项目实战中的运用

1.unittest介绍及运用

  • 在case包下创建一个unittest_case模块,编写如下代码,在继承unittest模块的TestCase类时,需要定义以test开头的方法才能在运行unittest测试代码时被调用执行
  1. # -*- coding: utf-8 -*-
  2. __author__ = 'cdtaogang'
  3. __date__ = '2019/7/3 18:48'
  4. import unittest
  5. class FirstCase_02(unittest.TestCase):
  6. def test_01(self):
  7. print("test_01")
  8. def test_02(self):
  9. print("test_02")
  10. def say_hello(self):
  11. print("say_hello")
  12. if __name__ == '__main__':
  13. unittest.main()
  • 运行以上代码,结果已说明一切,只调用了以test开头的方法

2.unittest前置条件和后置条件

  • 每当执行一条case前都会先去调用setUp方法,case执行完成后又会去调用tearDown方法;根据这个特性就可以与first_case中的po模型结合解决之前遗留的注册页面输入框内容清空的问题

3.unittest和po模型结合梳理执行所有case

说明:在first_case模块中让FirstCase类继承unittest.TestCase类,这样的话就可以定义setUp方法来完成创建一个全局的driver,因为其特性可以在执行每条case时候会去执行setUp方法即打开一个新的浏览器窗口,这样的话就解决了同意浏览器执行多条case时,输入框内容不清空的问题,然后再在FirstCase类中定义tearDown方法来关闭浏览器窗口,最后在执行case的时候就不需要main函数,因为我们的FirstCase类继承于unittest.TestCase类并且我们的测试方法均以test开头的,只需要在if __name__ == '__main__':中调用unittest.main()方法即可,堪称完美

  • unittest和po模型结合结合后,first_case模块中的代码如下

  • 运行代码,成功测试5个case,测试结果正确,说明一下测试结果,博主测试的数据全是回到错误提示信息,所以在以下无的结果中4个提示的是注册失败了,此条case执行成功,注册失败对应的case为test_register_success该测试条件为测试注册页面中是否存在获取得到注册功能的元素,不存在则表示注册成功反之则表示注册失败,因为验证码这块还没有加入代码中所以test_register_success这个case肯定是注册失败的

  • 为了验证打印"注册成功,此条case执行失败"即表示注册页面没有要测试的错误提示信息,所以博主将test_register_username_error这个case传入的注册数据中的name的数据改为正确格式的数据,则就会出现调用get_error_msg方法返回的text值为None,说明页面没有该错误提示信息元素了,需要注意的通过get_element获取不到页面元素时则返回None,那么在get_error_msg方法中去调用element对象的text方法则会提示错误,因为None没有任何方法,所以在get_error_msg中需要进行异常处理,当出现异常则表示无法找到页面中错误提示信息的元素,即text=None,代码如下
  1. def get_error_msg(self, info, error_msg):
  2. """获取错误信息"""
  3. try:
  4. if info == "email_error":
  5. text = self.reg_page.get_user_email_error_element().text
  6. elif info == "username_error":
  7. text = self.reg_page.get_user_name_error_element().text
  8. elif info == "password_error":
  9. text = self.reg_page.get_password_error_element().text
  10. else:
  11. text = self.reg_page.get_captcha_code_error_element().text
  12. except:
  13. text = None
  14. return text
  • 紧接着在first_case模块中的test_register_username_error方法中将传递的name值改为正确格式的数据,运行代码后,在测试结果中成功打印出"注册成功,此条case执行失败"即表示测试的用户名数据注册成功

4.unittest容器的使用

  • 使用装饰器来管理测试类中定义的方法

  • 运行代码后,从结果可以看出setUpClass方法是在所有case执行前执行,tearDownClass方法则是在所有case执行之后才执行

  • 使用unittest容器,只执行想要执行的case,只需要添加test_02到容器中,最后运行容器即可

  • 运行代码后,成功的只执行test_02的case

5.unittest用例执行顺序及case跳过

  • case执行顺序,默认是以字母或者数字的升序进行执行的,如下在代码中添加test_03查看执行顺序

  • 通过容器来控制执行的顺序

  • 如不想执行test_03这条case,可以使用unittest.skip方法进行case的跳过

6.如何大批量运行case文件

  • 如在case包下创建一个unittest_case02.py模块,模块中有与unittest_case同样的case,如何同时运行两个模块中的case

  • 要想一次运行case包下的多个模块中的case,需要在case目录下创建一个名为run_case.py模块,编写如下代码,在代码中首先需要获取当前case所在的路径,然后通过discover方法去case路径下去将以unittest_开头.py结尾的文件放到defaultTestLoader容器中,最后通过run方法运行容器中的case

  • 运行代码后,成功的将unittest_case.py以及unittest_case02.py模块中的case全部运行

7.项目中如何运用assert

  • 在first_case.py项目文件中,通过assert断言判断register_busniess模块中检查错误提示信息元素返回的是否是False,如果返回的是True表示的是页面中的检查的该输入框没有错误信息,那么断言就会提示True is not false,当返回的是False表示页面存在错误信息,则断言成功不会打印任何信息

  • 运行项目,在test_register_username_error以及test_register_success这两个case很明显返回的是True,第一个是传递的username合法导致页面检测不到错误信息元素即返回True,第二个是检验页面中是否存在注册这两个字value,因为验证码肯定还没有融入项目中,传递的验证码肯定是错误的,那么页面中是存在注册按钮的,即register_success方法返回的是True,也就是检验到了页面注册元素的,所以这两个case都是报错并提示True is not false

8.项目中如何生成测试报告

  • 要想生成Html测试报告,则需要安装HtmlTestRunner,下载此HtmlTestRunner.py文件,将其拷贝到项目环境site-packages目录下即可,需要说明的是HtmlTestRunner.py是由py2编写的,需要对其源码进行修改然后才能在py3环境中使用,博主在上个项目中Python接口自动化测试框架实战开发(一)有详细说明

  • 然后在代码中将测试结果通过HtmlTestRunner写入到项目report/first_case.html文件中

  • 运行项目first_case.py文件,查看运行结果,显示OK

  • 打开report/first_case.html文件,查看html测试报告成功,博主将HtmlTestRunner源码进行一些修改,看到如下的样式

9.项目中case运行失败截图low方法设计与封装

  • 在上一步中通过HtmlTestRunner将测试报告写入到html文件中,但是无法看到当时在注册页面输入的数据,所以需要在代码中通过driver进行截图,这样一来当case测试失败时,查看截图就知道当时具体情况了,当页面元素查找不到时,即抛出异常此时进行截图查看当时注册时的信息,所以在get_element方法中进行截图处理,代码如下

  • 为了测试通过get_element方法获取不到错误信息元素时,在first_case模块中则需要测试用户名错误信息这个case,因为这个case传递的用户名是合法的,所以再执行get_element方法时则会抛出异常,截取图片数据并命名为value值也就是ini配置文件中的错误元素id的值,保存到项目目录下的images目录中

  • 运行项目,查看images目录下的截图数据,与预期的输入的数据一致,为合法用户名

10.项目中python3如何封装失败自动截图方法

  • 在get_element方法中通过捕获异常来触发截图,这样是比较low的,为了高效完成自动截图,可以设定当程序运行过程中出现异常时,则进行截图,那么就可以放在tearDown方法中进行代码逻辑处理,遍历获取错误异常数据,当error不为空时,则说明出现了项目中某个测试方法中出现异常了,即进行截图处理

  • 在if __name__ == '__main__'启动代码中将所有的case添加到容器中进行测试,这5个case在之前的步骤中已经说过很多次了很测试用户名以及注册成功这一块断言都是失败的这两个case返回的都是True,而断言是以False作比较,所以会截取这两个case注册时的图片

  • 运行项目后,查看images下的图片,一个是检查用户名的错误提示信息元素,另一个是检查页面中是否有注册

  • 查看first_case.html测试报告

11.完整得case流程集合破解验证码

说明:在上一篇博客中通过ShowapiRequest.py接口对截取的验证码图片进行验证码识别,其中关于整个验证码这块的代码逻辑为;第一部分通过selenium保存注册页面的图片到本地,再通过driver获取验证码块在注册页面的坐标,其次通过Image.py模块中的crop方法对保存的注册页面的图片进行验证码的裁剪,最后将裁剪的验证码保存到本地;第二部分通过验证码识别网站提供的sdk工具也就是ShowapiRequest.py模块提供的方法,对指定验证码图片进行识别,然后将返回的json格式转换为字典,从字典中获取result键的值也就是识别出来的二维码值,最终返回出去

  • 在utils目录下创建get_captcha.py文件用于封装获取验证码方法,从之前的register_code.py文件中将其中验证码的获取以及识别的两个方法拷贝到get_captcha.py文件中,进行如下修改

  • 然后在register_handle.py处理层代码中找到验证码发送的核心方法send_user_captcha,在该方法中实例化get_captcha.py模块中的GetCaptcha类,并调用其获取验证码图片以及识别验证码图片的两个方法,需要注意的是这两个方法需要传递保存验证码图片以及识别验证码图片的路径filename

  • 在register_handle.py对获取页面注册按钮的文本值也就是value值进行容错处理,若注册成功则会提示None类型没有text

  • 紧接着在register_business.py模块中将之前传递的code形参,全部更改为filename

  • 跟着在first_case模块中定义setUpClass类方法来完成全局变量filename的路径

  • 最后在5个case中只有test_register_captcha_error和最后一个test_register_success的测试条件为正确但不一定注册成功,因为验证码不可能百分百正确,其余的3个case测试数据都是不正确的;换句话来说就是其余3个case在调用get_error_msg方法中都能查找到页面错误信息元素,不会出现异常返回None,则最终返回到断言时的值为False,那么表示断言成功,而test_register_captcha_error和最后一个test_register_success这两个case都是取决于验证码,test_register_success这个case如果找不到页面注册二字,则表示注册成功,即在调用get_register_button_text方法时返回None,则调用register_success方法返回False,那么就代表注册成功,相反检查到页面存在注册二字,则返回True,那么就代码注册失败

  • 运行项目,毫无疑问除了test_register_captcha_error和最后一个test_register_success这两个case其余三个肯定是断言成功,而这两个case可能断言成功取决于核心因素验证码是否识别成功,test_register_captcha_error这个case断言成功则表示注册失败,case执行成功;而test_register_success这个case断言成功表示注册成功,断言失败则表示注册失败

  • 根据以上测试结果可以看出,4个case断言成功,则除了前三个case,最后一个case断言成功则表示注册成功了,而验证码这个case断言失败,应该是注册成功了,其实并不是,原因是用户名相同导致的,我们先看以下html版的测试报告,报告上的结果与编辑器打印结果一致

  • 现在查看test_register_captcha_error和test_register_success这两个case的截图,其余三个都是断言成功则截图都是指定测试元素错误,主要是看test_register_captcha_error这个case断言失败了按理说是注册成功,但是其实并不是,大家看截图就一目了然了

五丶数据驱动的介绍及使用

1.数据驱动介绍及简单使用

  • 数据驱动无非就是以数据作为导向对结果进行处理,通俗来说就是参数化,在项目register_business模块中检测注册页面的错误元素的方法中的形参都是一样的,这样看来代码还是比较low的,即需要安装python中的ddt模块,来使用数据驱动

  • 在case目录下创建data_test.py模块,用于将数据驱动在unittest测试类中的简单使用,编写如下代码

  • 运行data_test.py模块,查看结果,从结果中可以看出执行了三个case,但是代码中只写了一个case,这就是ddt来完成数据驱动代码复用的效果

2.项目中如何构思设计数据驱动结构

  • 首先分析first_case以及register_business模块中的代码的调用和参数,在first_case模块中通过传递不同的参数来调用register_business模块中的不同的方法来检测判断页面中是否存在错误信息元素,即每个case所需的参数包括邮箱丶用户名丶密码丶验证码丶错误定位元素丶错误提示信息;在case目录下创建first_ddt_case模块来完成ddt在项目中的设计,即在first_ddt_case模块中编写如下代码,完成参数的铺垫

3.项目中实现数据驱动,重构case及business

  • 在first_ddt_case模块中,使用ddt数据驱动重构case,完成测试注册页面邮箱地址的合法性

-

  • 在first_ddt_case模块中定义的测试方法test_register_case中调用了register_business模块中的register_func方法,所以在需要在register_business模块中去定义该方法,如下

  • 在执行first_ddt_case模块之前需要将register_handle模块中的send_user_captcha方法进行如下修改,为什么要修改,原因是在最开始first_ddt_case模块中调用register_func方法传递的参数captcha,为固定值"captcha",那么就会导致send_user_captcha接收的参数filename为"captcha",原本该参数filename的值为保存图片以及验证码的路径地址,即在保存验证码图片的时候就会出现异常错误,导致case无法正常运行

  • 运行first_ddt_case模块,查看运行结果,如测试条件所示,最后一个case因为输入正确的邮箱地址,所以提示邮件检测不成功

4.项目中数据驱动实战并重构

  • 将测试结果结合HtmlTestRunner写入到html文件中

  • 运行代码后,打开report/first_case_2.html文件,查看测试报告,与预期结果一致

  • 在get_error_msg获取页面错误信息元素方法中根据传递的info参数来判断是获取哪个input的错误元素,需要将try中的判断参数修改成与LocalElement.ini文件中的键保持一致

  • 最后在first_ddt_case模块中data数据中传递的error_element的值email_error修改成user_email_error,这样代码的连贯性就很强

5.项目中如何以文件的形式实现数据驱动

  • 在config目录下创建一个名为case的xls文档,编写用于测试case所需的测试数据,这样做的话就比较方便我们修改测试的数据而不再代码中进行修改,如下

6.如何按照数据驱动格式获取excel内容

  • 在python中要操作excel文档,则需要安装xlrd这个库

  • 然后在utils目录下创建op_excel.py文件,编写如下代码,并打印出excel表中每行的数据,关于操作excel文档的方法在上个项目中有详细介绍,这里就不多说了

  • 最后将获取到excel文档中的每列数据添加到result列表中,最后再进行返回

7.项目中以文件的形式实现数据驱动

  • 在first_ddt_case模块中从工具包utils中导入OpExcel类并调用get_data方法获取excel文档数据,将数据通过数据驱动赋值给对应的变量

  • 运行代码后,查看运行结果,根据测试条件除了第二条case是测试成功的,其他都是测试失败,因为只有第二条case的邮箱地址格式是错误的

  • 打开first_case_2.html查看测试结果报告,与代码运行结果一致

六丶关键字模型的介绍及运用

1.项目中如何设计关键字模型

  • 在乐学网站不管是注册页面还是登录页面无非就是输入数据点击注册或者登录,由此可以设计关键字模型表

2.重构封装操作excel的方法

  • 在op_excel.py模块中,定义获取excel表行数方法,然后在get_data方法for循环中直接调用get_lines方法得到excel行数以此进行遍历,再定义get_col_value方法获取第4行第三列的数据,最后打印出来

3.封装写入实际结果方法,优化程序健壮性

  • 在keyword表中,添加实际结果这一列,在实际测试工作中肯定测试文档中应该存在此列

  • 在op_excel模块中定义一个方法向表中实际结果列写入数据,需要注意的是在运行代码前需要关闭keyword文档,不然会抛出异常

  • 再次打开keyword文档查看是否向第三行第7列写入测试数据test

  • 回到op_excel模块中,向方法中添加容错处理

  • 调用get_col_value方法获取单元格数据,传递不存在的行和列,通过以上的容错处理,成功返回None

4.二次封装webdriver里的方法

  • 在项目目录下创建名为keyword的python包,在包下创建action_method.py模块用于封装excel表中webdriver驱动的方法包括获取driver丶打开浏览器丶获取url地址丶获取元素丶输入元素丶点击元素丶等待时间以及关闭driver

5.如何将封装方法和excel数据结合思路分析

  • 首先修正一下excel表中的数据,增加每行case是否执行的列,将操作的元素对应修改为LocalElement.ini配置文件中的键一致,如下所示

  • 在case目录下创建keyword_case.py模块用于将上一步中封装的方法与excel表数据进行结合,在代码中需要实现如下逻辑

6.关键字模型主程序从思想到代码的实现

  • 在keyword_case.py模块中完成代码实现,也就是将上一步中的逻辑注释以代码进行实现

7.项目中运行关键字模型流程梳理及常见错误解决

  • 首先为了验证代码是否写的有问题,直接运行keyword_case.py文件,查看运行结果

  • 出现以上错误提示的原因是,在Python3中keyword是python的关键字包,所以在给包命名时应避免使用关键字进行命名,而我们在项目目录下却创建了keyword的包,所以在keyword_case模块中导入时就会出现以上错误,所以需要将项目目录下的keyword包修改为keywords,再次运行就没有报错了

  • 调用run_main方法,查看运行结果出现以下错误提示

  • 解决以上错误的方式为将ActionMethod实例对象复制给KeywordCase的self对象中作为可以在run_method以及run_mian方法中进行共用

  • 重新运行代码后,成功打印出excel表中是否执行字段的数据

  • 为了测试keyword_case模块中的代码是否能够正常执行excel表中的case,需要完善excel表数据,如下所示

  • 运行keyword_case模块,结果在执行第五个case,也就是输入password的时候报错了,错误如下

  • 以上报错,博主很清楚,因为当初在Debug调试代码的时候,出现过该错误,原因是在excel表password输入的是浮点型的数据,运行op_excel.py模块中打印出excel表的所有数据,就一目了然了

  • 在excel表中将password的数据格式修改为文本类型,如下所示

  • 再次运行代码,查看结果,所有case执行成功

  • 通过运行keyword_case模块完成自动化打开浏览器输入url地址,输入注册信息,等待等case的执行效果动图

8.如何解决项目中运行的错误

  • 在excel表格中增加关闭浏览器的case

  • 运行项目后,出现以下错误,该错误显而易见就是在run_method方法中调用getattr函数返回的对象属性中传递的参数op_element所对应的函数close_browser没有形参,导致参数传递错误导致的异常,在excel表关闭浏览器操作中的操作元素没有任何值

  • 解决以上出错的方法是在run_method方法中,对excel表中的输入数据以及操作元素进行判断,就能解决参数传递的报错问题,如下所示

9.关键字模型中如何获取测试结果

  • 首先在excel表中定义如下的测试case数据,需要说明的就是通过判断预期结果值是否存在,如存在则将预期结果值进行"="分割成功列表,通过索引来获取两边的值,分别对获取的值进行判断来调用其预期结果的方法,通过返回的结果来向实际结果列写入数据

  • 那么在keyword_case模块中的run_main方法中则需要获取预期结果方法的值以及预期结果值,来完成case测试的逻辑代码处理

  • 运行代码前首先关闭excel表,查看运行结果,出现如下错误

  • 但是打开excel文档后,发现并测试结果写错到预期结果方法中了

10.关键字模型中runmethod重构及流程梳理

  • 在上一步出现的错误,可以在Pycharm中通过Debug进行测试,测试如下

  • 根据以上结果可以看出,是在调用run_method方法时,该方法没有返回值导致的,所以result的值为None,即在run_method方法中赋值以及return返回即可

  • 重新运行代码后,从打印结果上看是成功的

  • 但是打开excel文档却发现,测试结果写在了预期结果方法列去了

  • 通过Debug断点测试,发现在op_excel模块中的write_vlaue方法中的col列的值固定写死为7,那么即死在预期结果方法列进行写入的

  • 所以将write_value方法中的列的默认值修改为9即表示在实际结果列进行数据写入,然后重新运行代码,查看excel文档成功的将测试结果写入到实际结果列中

  • 修改excel文档中的register_07的case的是否执行为yes,并增加一个打开浏览器的case设置为不执行

  • 根据以上测试文档,重新运行代码,查看register_07这条case是否写入实际结果,结果报错了,提示在执行第七条case的时候传递到read_ini.py模块中的get_value方法时的key的值为l,在LocalElement.ini配置文件RegisterElement节点下找不到这个key

  • 根据以上错误提示,直接Debug断点测试报错的代码,发现在调用run_method方法传递的op_element参数的值为except_result值的第1个索引,即为element=captcha_error_code的第1个下标为l,所以抛出异常错误信息

  • 将传递的op_element实参的值修改为except_value[1]即可

  • 再次重新运行代码,查看运行结果没有问题

  • 打开excel表查看是否将测试结果写入到实际结果列中,结果发现只写了一个pass,而register_02这个case并没有写入实际结果

11.关键字模型如何解决测试结果问题只写一行问题

  • 出现以上错误是因为在op_excel.py模块中的write_value方法在调用copy方法时没有将之前写入的数据保存后再写入第二条数据,说白了就是第一次保存的数据和第二次读取的数据是不一样的,所以需要在op_excel.py模块中进行如下的修改

  • 重新运行代码后,查看excel文档,成功的将所有存在预期结果的case的测试结果写入到实际结果对应的列中了



所属网站分类: 技术文章 > 博客

作者:goodbody

链接:https://www.pythonheidong.com/blog/article/52855/fac219c07f2536edc104/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

3 0
收藏该文
已收藏

评论内容:(最多支持255个字符)