肖sir__面试第一天课程__ui自动化讲解(3)

ui自动化测试

一、面试题:

1、你做过自动化测试吗?   做过,(ui自动化)(接口自动化)(app自动化)

2、你讲下你是如何做ui自动化?

(1)  按自动化线性流程 :   python+selenium库做自动化,

(2)   用的python+selenium+unittest框架做的自动化

(3)用的pom模型或者说po框架做UI自动化

 

二、自动化编写的规则

1、熟悉的场景写、不熟悉的不写

2、开始、操作、断言、校验完成性

3、尽可能结合自己项目梳理自动化场景

4、讲解时,有依据(如:用python+selenim,我拿最近做的项目xxx中,购买套餐的流程讲下:在讲流程)

===================================================================

案例1:结合python+seleuim线性脚本

结合业务写UI自动化

(1)做ui自动化用的python+selenium库。 先导入selemiun中webdriver模块和time库中sleep模块。 我做自动化都是用的chrome浏览器或(ie、火狐等),然后下载对应驱动,创建对象driver=webdriver.chrome()调用驱动,通过对象driver去操作,通过用driver.get方法打开项目首页,在将浏览器最大化maximize_window,最大化是为了防止有些元素加载不完全或者点击不到。然后我会用一个implicitly_wait隐式等待方法,因为网速追不上程序的运行速度。如果是页面不跳转在页面加载元素的话,我会选择再用个sleep方法强制等待2S左右,因为不跳转的时候implictly wait不会生效,如果需要定位这些元素就会定位不到。 进入后先登录,通过link_text定位登录这个链接元素,用click点击,然后定位用户名输入框和密码输入框,用send_keys传入账户名和密码,然后用xpath定位确认登录按钮用click点击,登录就完成了。这个时候回跳转至首页。 项目首页就有投资模块的入口,用find_element_by_link__text找到元素然后用click点击,这个时候页面会跳转,跳转完是进入标的搜索页面,选择标的类型:正常的标投资或者债权转让,标的时间,我们项目是1月,2月,12个月,标的类型是用click就可以点击实现了,时间选择我们是个下拉框,需要先导入select模块,然后先select接这个元素,然后用select by index方法,选择1个对应的值。这里说明下我为什么用index,因为有时候会换中英文,或者value值,会导致脚本失败,而index就可以避免这种情况了。选择完这两个后等待元素的加载,这里也是用sleep,选择某一个标的投资按钮,也是用xpath定位然后click点击,这个时候页面新开一个确认投资窗口,这个时候就涉及到页面的切换,这里涉及到一个利用句柄handle切换窗口,先使用browser.window_handles获取所有句柄,索引位-1就是最新的窗口的,用switch_to_window()接新窗口的句柄就可以切换窗口了。然后用send_keys传入投资金额,支付密码,然后验证码是让开发同事写成了固定的字符,短信验证码关闭了。然后点击确认投资换这个button,也是用xptah定位,click点击。这个时候页面会跳转显示投资成功,这里我会用投资完成这个文本来做断言,用的是if  not 加上assert  false做的。然后就关闭浏览器用quit。然后前台的操作就完成了,再进入数据库校验数据,这里需要导入pymysql模块,然后用connect连接项目的数据库,用cursor获取游标,(游标就是一个数据的缓存区,用execute方法就可以吧sql语句取出来的临时表放入游标中,fetchall就可以把游标内的数据都是放在toupl容器中,通过索引位就可以把真实数据取出来做断言了)用execute接sql语句来获取对应的投资者在此项目的投资金额,在用fetchall取出此数据,断言这个数据是否等于我们在前台输入的投资金额。然后就断开数据库链接,关闭浏览器。这就是我的大概流程了。

梳理流程:

导入selenium==选择浏览器==创建对象====通过对象get打开浏览器====窗口最大化====时间等待(三种)====业务场景(id、name、class、css、xpath、link_txt、js方法)===比如一些控件(farm框、弹框、按钮、切换句柄、点击、输入)==断言(通过title、text)====连接数据库区校验正确性

(2)概括性说ui自动化

用的是python+selenium+unittest单元测试框架来做的,那我大概和您讲一下我做ui自动化的流程吧

答:首先的话就是我需要打开pycharm然后新建一个py模块,然后导入selenium模块,time模块等等,然后通过from selenium import webdriver语句导入webdriver模块,然后创建一个driver对象:driver=webdriver.Chrome(),再通过driver.get方法来打开我们测试环境的地址,再使用 driver.maximize_window()最大化浏览器窗口,然后会使用driver.implicitly_wait()设置一个隐式等待,我可以通过driver.find_element_by_id,或者xpath,name,class,css等元素定位方法来进行定位到用户名和密码输入框,并且通过调用send_keys进行输入用户名和密码,最后通过调用click方法进行登录,登录之后,有一些表单的填写页面(比如主要有姓名、证件信息、手机号码、常住地址、邮箱、紧急联系人等等),如果是输入框我依旧用send_keys,如果有一些下拉框我会导入Select类,通过select_by_value方法进行定位,如果有滑动的地方我也会用window.scrollTo()方法,设置变量为js,然后通过driver.execute_script()来调用js变量来达到滑动滚动条的目的,包括如果是有iframe弹框的话,我首先会通过switch_to.frame()进入到iframe弹框,然后再进行其他的操作,如果要退出iframe框的话,直接用switch_to.default_content()方法就可以了,最后写完整个一个流程之后,我还会通过调用text方法拿到某个元素的文本值赋值给到一个变量,然后通过assert方法把预期结果和实际结果进行一个断言,以上就是我做ui自动化的一个大致流程,但是这是我们最开始做ui自动化的方法,后面因为做的时间也比较久,用例也比较多,所以后续用了一些PO设计模式和分层对用例进行了一些封装

(3)代码

from   selenium import webdriver
from  time import  sleep
d=webdriver.Chrome()#通过对象谷歌浏览区且输入网址,在用get方法打开浏览区
url="http://www.baidu.com/"
d.get(url)
sleep(2)
d.maximize_window()
sleep(3)
d.find_element_by_id("kw").send_keys("dcs")

 

====================================================================

案例2:结合unittest框架讲解

(1)我做ui自动化是通过Python+selenium+Unittest进行自动化测试,整个用例框它能帮我们比较规范的、系统的管理和执行用例,也便于后续的维护。下面我讲解下这个框架,首先需要导入unittest这个模块,我们做自动化的话还需要导入selenium这个模块,以及一些相关的模块,比方说time模块,OS模块,HTMLTestRunner报告模块。把我们需要的模块都导入,在unittest里我们需要去定义一个类,定义类名可以根据项目名定义,继承unittset.testcase,一个testcase的实例就是一个用例,类里需要有类的开始:setupclass,以及类的结束:teardownclass,在整个框架中只运行一次,然后在定义方法开始setup、方法结束teardown ,在用例每次执行中都会运行一次;然后我们需要去定义我们的用例,test1test2,注意一定要以test开头,顺序按照ascii码1-9,大写A-Z,小写a-z,写完用例以后,我们需要去调用它,我们以main作为unittest的入口,执行自动化用例我们主要有4种调用的方式

第一种用unittest.main()去运行所有用例

第二种是创建一个套件TestSuite(),然后用addtest去添加你要执行的用例,这种方法可以执行部分测试用例,

第三种就是搜索绝对路径去执行自动化,调用unittest.testloader().discover()去搜索路径下的用例,在通过unittest.TextTestRunner() .run()方法执行搜索到用例

第四种是生成html测试报告,搜索绝对路径去执行自动化,调用unittest.testloader.d()iscover方法执行用例,然后把执行结果写入我们导入的报告模板文件,执行之后就能看到我们路径下所有用例的执行结果。

以上就是unittest框架的整个基本流程

(2)案例2:

我说下电商下单自动化测试流程吧,因为是基于unittest框架进行编写所以需要用import unittest导入unittest模块还需要导入webdriver模块因为需要用webdriver方法去调用谷歌浏览器的驱动来打开浏览器,然后先定义一个类在参数中输入unittest.testcase用来继承unittest.testcase中的类,然后定义setup方法在setup中先将webdriver.Chrome赋值给self.变量chrome是我用的谷歌浏览器的驱动,并用login.dl(self.变量)来调用之前封装好的登录功能,然后再定义一个test打头的函数这里主要用于编写实际测试用例,然后在test函数中将slef.变量再次进行赋值给一个变量方便于操作。接下来进行定位搜索栏,输入商品名称,点击搜索按钮,用F12获取xpath值然后用find_element_By_xpath对搜索栏进行定位并赋值给一个变量这里这里说下为啥用xpath进行定位,因为有时候id 和name 等属性值不是唯一的或者没有,所以直接使用xpath进行定位会比较好能解决百分90的定位问题,然后使用send_keys()去进行输入操作和click()进行点击按钮操作,此时页面中会搜索出我搜索的商品,仍然通过xpath定位和click()操作搜索出的商品页面会新开窗口进入商品详情页,这时候就需要用window handles获取所有窗口的句柄并赋值给一个变量,然后使用switch to window加变量索引值切换到新窗口,有时候网页会加载比较慢所以需要使用from time import sleep导入时间模块然后使用sleep等待3秒,确保网页加载完成后进行下一步操作,然后在用find_element by xpath.click选择商品的规格型号和商品数量,接下来通过find_element_by_xpath.text获取商品详情页中我选择的规格型号、商品数量、商品单价、订单小计/合计,通过find_element_by_xpath.click点击立即购买按钮,页面进入到确认订单页,然后通过find_element_by_xpath.text获取确认订单页规格型号、商品数量、商品单价、订单小计/合计与商品详情页选择的数据使用if判断进行比较,如果一致就print 成功,否则else pirnt失败,确保订单中的数据是我在商品详情页中选择的数据,再接下来点击提交订单操作进行下单,下单后通过调用封装好的数据库读取模块传参(ip/dbuser/dbpwd/dbname/sql)进行访问数据库中order库获取我的订单数据,然后用order库中获取的数据与下单的数据进行if判断比较判断数据库中的订单数据是否正确,如果正确就print 成功,否则else pirnt失败,然后就是定义teardown方法在teardown中用close命令关闭浏览器,然后就是进行调用执行,执行方法有三种第一种unittest.main(),main的话就是执行了testloader类中的方法帮我们搜索test开头的用例并执行,执行顺序是按ascll码分布顺序运行的,第二种方法是用unittest.testsuit()方法,先将unittest.testsuit赋值给一个变量,然后通过这个变量使用addtest命令添加用例,在使用unittest.testrunner中的run方法执行这个变量。执行顺序的化是按照添加的顺序执行的。第三种方法是用unittest.default testloader.discover(加用例存放的路径,pattern等于模块名)再赋值给一个变量,然后同样通过unittest.testrunner中的run方法执行这个变量,然后为了查看执行详情结果所以需要写入执行报告。写入执行报告的话需要先导入一个HTMLtestrunnerCN 模块使用这个模块中 的htmltestrunner来写入执行报告并存放到指定的路径中

 代码:

import   unittest
class  Test(unittest.TestCase):
    @classmethod  #类方法
    def setUpClass(cls) -> None:
        print("类的开始")
    @classmethod
    def  tearDownClass(cls) -> None:
        print("类的结束")
    def setUp(self) -> None:
        print("方法开始")
    def tearDown(self) -> None:
        print("方法结束")
    def test001(self):  #测试用例1
        print(1111)
    def test002(self):  #测试用例2
        print(2222)
    def  testb(self): #测试用例3
        print('bbbb')
    def testa(self):  # 测试用例4
        print('aaaa')
    def hz(self):  # 测试用例5
        print('hz')
if __name__ == '__main__':
           unittest.main()   #unittest 单元测试调用所有

  

import unittest
from  selenium  import webdriver
from  time  import   *
from ui_zidonghua.HTMLTestRunner3_New import HTMLTestRunner  #导入报告模板
class  Test_Baidu(unittest.TestCase):
    def   setUp(self) -> None:  #方法开始
         self.driver=webdriver.Chrome()
         self.driver.get("https://www.baidu.com/")
         self.driver.implicitly_wait(3)
    def  tearDown(self) -> None:
         sleep(3)
         self.driver.close()
    def test001(self):
        self.driver.find_element_by_id("kw").send_keys("selenium")
        self.driver.find_element_by_id("su").click()
    def  test002(self):
        self.driver.find_element_by_id("kw").send_keys("python")
        sleep(2)
        self.driver.find_element_by_id("su").click()
    def  test003(self):
        self.driver.find_element_by_id("kw").send_keys("html")
        sleep(2)
        self.driver.find_element_by_id("su").click()
        title=self.driver.title
        self.assertEqual(title,"zhong")
    def  hz(self):
        self.driver.find_element_by_id("kw").send_keys("hzdcs")
        sleep(2)
        self.driver.find_element_by_id("su").click()
# def  test_all_case():  #定义一个函数
#          suit=unittest.TestSuite()  #创建一个套件或者是一个容器,作用用来装所有的测试的的对象
#          suit.addTest(Test_Baidu('test002'))   #addtest添加用例
#         #suit.addTests([Test_Baidu('test001'),Test_Baidu('test002'),Test_Baidu('test002')],)
#          return  suit

if __name__ == '__main__':
    unittest.main()   #第一种执行框架中全部用例
    # runner=unittest.TextTestRunner()
    # runner.run(test_all_case())  #第二种执行部分用例
    #执行脚本的相对路径
    # path=r"C:\Users\Administrator\PycharmProjects\untitled6\ui_zidonghua"
#     # ss=unittest.defaultTestLoader.discover(start_dir=path,pattern="test*.py")
#     # runner=unittest.TextTestRunner()
#     # runner.run(ss)  # 第三种方法  自动化搜索用例执行

      # path=r"C:\Users\Administrator\PycharmProjects\untitled6\ui_zidonghua"
      # ss=unittest.defaultTestLoader.discover(start_dir=path,pattern="test*.py")
      # bgpath=path=r"C:\Users\Administrator\PycharmProjects\untitled6\ui_zidonghua"
      # now=strftime("%Y-%m-%d-%H-%M-%S")
      # filename=bgpath+"\\"+str(now)+"_ui.html"
      # f=open(filename,"bw") #b 表示二进制的方法写入,w是写入
      # runner=HTMLTestRunner(stream=f,title="ui自动化测试报告",description="用例执行情况",
      #                   tester="hz"    )
      # runner.run(ss)  # 第三种方法  自动化搜索用例执行

  

TestCase
一个Testcase的实例就是一个测试用例,测试用例就是一个完整的测试流程,包括初始化setUp、运行run、测试后的还原tearDown(字面意思,测试用例。为一个或多个方法提供测试方法。一般是一个test)

TestSuite
对一个功能的测试往往需要多测试用例的,可以把多的测试用例集合在一起执行,这就是TestSuite的概念。常用addTest()方法将一个测试用例添加到测试套件中(测试集合,即一组测试。一个test suite是把多个相关测试归入一组的快捷方式)

TextTestRunner

是用来执行测试用例的,其中的run(test)用来执行TestSuite/TestCase。测试的结果会保存在TextTestResult实例中(测试运行器。执行test suite的程序)

TestLoader:是用来搜索所有以test开头的测试用例,然后将其加入到testsuite中

===============================================================

3、po框架

(1)参考:https://www.cnblogs.com/xiaolehua/p/14434567.html

 

 讲解:

案例1:

ui自动化测试,我是用po框架做的,对自动化用例进行分层:先创建一个项目名称xx;在项目下创建对应的包,一般我是分为6个包

(1)先创建第一个cofing包==存放所有配置文件信息(比如项目路径和数据,用例的路径)

(2)在创建第二个Data包==放数据(测试数据)

(3)在创建第三个report包==存放测试报告

(4)在创建第四个包public公共公开包(存放一些功能用例);在这个包下面在创建两个子包:
      pages包和utils包
      a、在pages包中存放元素层流程层(封装所有页面的公共方法,基类)
b、在utils包(处理公共类公共函数都存放在此)
可以在utils中来读取pages中封装的登录的流程(封装读取ini文件或者EXCEL表格的工具类和工具函数
(5)在创建一个TestCase用例包用来存放用例
(6)在创建一个run_all用来运行
通过运行测试用例中封装好的用例在运行然后在repot中生成测试报告
这就是我的框架;

案例2:我讲解下我的框架,po框架,可以分成6层:如下

第1层的话是config配置层,这个里面主要是封装了一些我们测试环境的url地址和一些连接数据库的IP地址,用户名密码等等
第2层是utils工具类层,这个里面主要封装了一些读取Excel表格的工具类,还有发邮件的工具类,还有一些读取配置文件的工具类
第3层是一个public基类,这个里面主要封装了元素定位的方法比如把id,name,class,xpath,css等等都封装在一个类方法里面了,还把一些send_keys和隐式等待和其他其他公共方法都进行了二次的封装
第4层就是testcase用例层了,这个里面主要就是通过定义一个类然后继承unittest.TestCase这个类,通过unittest单元测试框架来管理用例,在setupclass里面去创建driver对象,然后通过设置和取值的方法,拿到driver对象,先编写登录的用例,然后这个里面也用到了PO设计模式,把我们的元素定位和流程层,代码层进行了分离,最后用例写完再通过self.assertEquals进行一个断言
第5层就是run运行层,首先会通过把所有的用例加载到一个suite套件里面,然后再通过调用run方法运行这个套件
第6层就是通过HTMLtestrunner模块生成测试报告,然后最后通过Jenkins做可持续集成,在回归测试阶段,每天晚上都会运行一下我们的ui自动化用例,大致的一个框架结构就是这样的。

 案例3:

写自动化用例的时候我喜欢对用例进行分层处理。我一般会设置六个模块:公共模块、用例模块、执行模块、报告模块、数据模块、页面元素模块。
把一些公共的,经常调用的属性放到公共模块中,比如登录登退出啊,连接断开数据库等。
页面元素模块就是将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),这样的话当页面元素变动的话我们只需要更改页面元素对象即可。
把用例的具体内容放到用例模块中,比如我要借款,通过设置一些类,再把我要借款相应的用例放到这下面,这样后续我进行维护就非常的直观方便。
执行模块就是对上面各个类的执行方法,要执行哪些类里的哪些用例和对应测试报告的生成。
报告模块就是存放生成测试报告的地方,这样我们就能一目了然的看到是哪些模块下的用例的执行情况。  
数据模块的是就是存放一些数据的地方,比方说用户的账户密码,网址信息等。
就拿我要出借这个流程的举个例子讲解一下吧!首先导入相应的库 from selenium import webdriver ,import unittest。然后新建一个继承unittest.testcase类。然后在def setup里写一些前置条件:像是webdrvier.chrome()选择谷歌浏览器,用get方式?获取网址打开,用maximize.window进行浏览器最大化处理,避免出现页面中元素定位后无?法点击报错的现象,确保用例执行的准确性,因为有时候用例执行太快,而网页加载太慢会?导致报错,所以我一般都会用implicity_wait进行智能等待,确保页面加载完成。把登入写进了公共模块中直接调用他。
接下来定位我要出借,因为他是一个下拉列表,所以我们得先导入from selenium.webdriver.support.ui import Select模块,用 Select(dr.find_element_by_xpath(“   ”).select_by_index(1),通过索引位进行定位。这个时候会打开一个新页面,所以我们得定位到这个新页面。
首先我们先获取所以页面的句柄allhead=dr.window_handles,再用dr.switch_to_window(allhead[-1])定位到我要出借这个新页面,通过find_element_by_xpath定位对应的标,然后定位到投资金额框,至于输入金额的话为了提高效率,我是之前已经写好了随机生成整百金额的函数,所以我这边直接调用就可以了,至于验证码我之前就已经请开发帮我去掉了,然后定位确认投资按钮点击。接下来系统会弹出一个风险提示
揭示书,它是一个alter弹框,alter=driver.switch_to_alter()进入到alter弹框里,再用alter.accept()。
这时候为了保证用例执行的准确性,再用unittest框架中的断言,之后用if语句和assertEquals判断前后两个值是否相符如:(出借成功,出借失败),不相符的话用dr.get_screenshot_as_file("d:\\yy\\erorr1.png"),最后到执行和生成报告了,用unittest中的testloader方法。
定义一个变量接收测试用例的目录,discover=unittest.defaultTestLoader.discover(测试用例的目录,“text*.py”)加载该目录下所有以text开头。
的Py文件。
导入生成报告所需的HTMLTestRunnerCN模块,用with open打开对应的报告文件,“wb”二进制方式写入,用HTMLTestRunnerCN里的runner方法生成测试报告。最后用runnrt.run(discover)方法执行之前加 载的用例就好了。
这就是之前公司用python加selenium做自动化测试的一个基本流程。

========================================================
一、自动化中遇到哪些问题?====>肖sir_自动化遇到问题归纳

(1)定位问题:

验证码、日历控件、弹框、定位属性的空格、内嵌滚动条、切换窗口、等

如:

(1)动态元素定位不到
解决方法:尽量使用固定元素定位,如没有固定元素,则采用绝对路径进行定位,因为元素路径是唯一且不变的
(2)自动化脚本执行速度较慢
尽量使用css方法定位元素,使用等待时,少用sleep方法,尽量不用隐式等待,涉及到一些if elif条件判断时,尽量把可能发生的条件放在前面写,这样可以减少程序判断的次数,提高效率

 二、自动化面试题

 1、你有做过自动化?你用什么语言? python
2、自动化中如何使用语言打开一个网址?浏览器,浏览器对应驱动,导入库,类,get,url
3、在一个浏览器中打开多个窗口?open_windows driver.execute_script
4、在自动化中如何释放资源? 当一个注意点,经验(不去quit,close)
5、如何切换窗口? switch_to_window(handle)
6、如何获取当前句柄?如何获取所有句柄?
7、如何获取当标题?如何获取所有标题?
8、如何在自动化输入文本?
9、如何点击按钮?
10、清除当前的内容的语句?
11、为什么使用时间等待?(使用时间的优点)
12、如何窗口最大化?
13、复现框如何多选或者全选?
14、单选框如何选择?
15、说一下自动化常用的定位方法? (9种)
16、下拉框如何定位?导入Select 类
17、iframe框如何定位?进入ifrme框的语句?ifrme退出框的语句?
18、弹框的定位?(确认型弹框,输入型弹框,alert弹框,)
19、自动化中本地文件上传?
20、如何定位滚动条?

========================================================

面试题:

1、你们自动化用例有多少条?(300-600)

2、你写了多少条自动化用例?

3、全部自动化用例执行要多久?(2-5小时)

4、什么样的项目适合做自动化?

5、ui自动化中有遇到什么问题?

6、自动化用例如何维护?定期执行、做好注释、通过框架管理、加上异常机制,

7、自动化如何提高运行速度?时间等待设置成隐形、优化代码、封装代码、

8、自动化的占比?  20%-30%

9、自动化测试你做多久?

10、自动化的环境你会搭建?

11、自动化作用?用例回归测试,节省时间

 

posted @ 2022-11-16 10:20  xiaolehua  阅读(469)  评论(0编辑  收藏  举报