自学内容网 自学内容网

UI自动化接口

一、po基本介绍

(1)PO框架是Page Object的缩写

(2)po框架:业务流程与页面元素操作分离的模式,可以简单理解为每个页面下面都有一个配置class, 配置class就用来维护页面元素或操作方法
(3)提高测试用例的可维护性、可读取性
(4)对比:传统的设计测试用例存在的弊端:
1.易读性差
2.复用性差
3.可维护性差
4.扩展性差

二、po框架自动化结构

1、先创建一个cms项目
在创建一个cofing包==存放所有配置文件信息(比如项目路径和数据,用例的路径)
       可以封装路径      
在创建一个Data包==放数据(测试数据)
        在Data包中创建一个TestData目录(放测试数据)
        测试环境的一些url地址和账号密码可以放在TestDta中       
在创建一个repot包==存放测试报告
        在repot包中创建一个Testrepot目录(存放报告)      
在创建一个public公共公开的包(存放一些功能用例)
        在public包中创建pages存放元素层流程层,element元存放(封装所有页面的公共方法,基类)
        在public包中创建utils包(处理公共类公共函数都存放在此)
               可以在utils中来读取pages中封装的登录的流程(封装读取ini文件或者EXCEL表格的工具类和工具函数       
在创建一个TestCase用例包用来存放用例
        编写测试用例
在创建一个run_all用来运行
        通过运行测试用例中封装好的用例在运行然后在repot中生成测试报告

三、实战

1、新建一个项目:命名po_ui

 2、新建包6个包

 3、按照包开始编辑内容

(1)conf包

新建一个模板 ini文件:

命名:cms_conf.ini 

并编辑内容

在conf中新建一个cms_path.py ,这个文件主要将项目路径定义;

导入os 模块:代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

import  os

bash_path=os.path.dirname(os.path.dirname(__file__))

print(bash_path) #项目路径

conf_path=os.path.join(bash_path,"conf")

print(conf_path)

data_path=os.path.join(bash_path,"data")

print(data_path)

report_path=os.path.join(bash_path,"report")

print(report_path)

testcase_path=os.path.join(bash_path,"testcase")

print(testcase_path)

public_path=os.path.join(bash_path,"public")

print(public_path)

pages_path=os.path.join(bash_path,"public","pages")

print(pages_path)

utils_path=os.path.join(bash_path,"public","utils")

print(utils_path)

 (2)data包中主要存放数据:

主要excel表格

 以上提供ini文件或excel提供数据,我们要去读取

(3)在utils包下:

a、新建读取ini文件的方法

在dos窗口输入:  pip install configparser
因为读取ini文件要用到configparser

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

from configparser import ConfigParser   #导入configparser模块中ConfigParser类

from conf.cms_path import *          #从config模块导入所有的路径

import os

class Read_Ini(ConfigParser):   #定义了一个类,继承了ConfigParser类里面的方法和属性

    def __init__(self,filename):

        super(Read_Ini,self).__init__()  #继承了父类的构造方法

        self.filename=filename

        self.read(self.filename)      #读取ini文件

    def read_data_ini(self,section=None, option=None):

        '''

        封装一个获取section对应的option里面的value值

        :return:

        '''

        value = self.get(section,option)   #通对应的option拿到value值

        return value

file = os.path.join(conf_path,"cms_conf.ini")

read= Read_Ini(file)

url = read.read_data_ini("test_data","url")

print(url)

 结果:http://cms.duoceshi.cn/manage/login.do

b、 在utils中新建一个read_excel  的模块

 用到xlrd  :pip  install  xlrd==1.2.0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import xlrd

from conf.cms_path import *

import os

class Read_Excel(object):

    def __init__(self,filename,sheet_Name):

        #先打开一个excel表格

        self.workbook=xlrd.open_workbook(filename)

        #进入到sheet页面

        self.sheetName=self.workbook.sheet_by_name(sheet_Name)

    def get_excel_data(self,row,col):

        '''

        封装了一个通过行和列来获取excel表格里面数据的工具方法

        '''

        value = self.sheetName.cell(row,col).value

        return value

file = os.path.join(data_path,"data.xlsx")   #把data的路径和data.xls文件名进行拼接

excel = Read_Excel(file,"sj")

url = excel.get_excel_data(1,0)  #根据索引去取第二行第一列的url地址

print(url)

  sheet页面名

 c、在utils中导入html报告模板、邮件模板

 (4)在public中的pages新建两个模块:一个封装方法basepage和一个元素的模块page_element

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

import unittest  #导入unittest 框架

from time import *

class BasePage(unittest.TestCase):  #创建一个BasePage类,这个类继承unittest框架中TestCase这个类

    @classmethod

    def set_driver(cls,driver):  #入参是一个driver对象,把创建好的driver对象传进来,变成BasePage这个类的属性

        #把传进来的谷歌浏览器对象作为当前类、基类属性,基类的变量

        cls.driver = driver

    @classmethod

    def get_driver(cls):   #单例设计模式

        return cls.driver

    @classmethod

    def find_element(cls,element):

        type = element[0]   #id

        value = element[1]  #kw

        if type == "id":

            elem = cls.driver.find_element_by_id(value)

        elif type == "xpath":

            elem = cls.driver.find_element_by_xpath(value)

        elif type == "class":

            elem = cls.driver.find_element_by_class_name(value)

        elif type == "name":

            elem = cls.driver.find_element_by_name(value)

        elif type == "css":

            elem = cls.driver.find_element_by_css_selector(value)

        elif type == "link_text":

            elem = cls.driver.find_element_by_link_text(value)

        elif type == "partial":

            elem = cls.driver.find_element_by_partial_link_text(value)

        else:

            raise ValueError("plese input corrt paramters")

        return elem

    @classmethod   #封装输入函数

    def sendKeys(cls,elem,text):  #返回elem,根据实际业务封装

        return elem.send_keys(text)

    @classmethod   #封装点击操作

    def click(cls,elem):

        return elem.click()

    @classmethod

    def wait(cls,sec):

        '''封装一个隐式等待'''

        return cls.driver.implicitly_wait(sec)

    @classmethod

    def sleep(cls,sec):

        return sleep(sec)

    @classmethod

    def frame(cls,elem):

        '''定位iframe框'''

        return cls.driver.switch_to.frame(elem)

    @classmethod

    def outframe(cls):

        return cls.driver.switch_to.default_content()

    @classmethod

    def get_text(cls,element):

        '''封装根据网页元素拿到text值'''

        value = BasePage.find_element(element).text

        return value

# if __name__ == '__main__':

#     from selenium import webdriver

#     driver = webdriver.Chrome()

#     # baidu_input = ("id", "kw")

    # elem = BasePage.find_element(baidu_input).send_keys("多测师")

    # elem = BasePage.find_element(baidu_input)

    # BasePage.sendKeys(elem,"多测师")

  

(5)将所有的定位方法和定位的路径都写在page_element中

 定义一个存放所有元素的模块:pages_element

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Pages_Element():

    # 1.输入用户名

    userName = ("id""userAccount")

    # 2.输入密码

    passWord = ("id""loginPwd")

    # 3.点击登陆

    loginBtn = ("id""loginBtn")

    # 4.断言

    desktop = ("xpath""/html/body/div/section/div[1]/div[1]/ul/li/span")

    # 5.点击用户中心

    user_center = ("xpath"'//*[@id="menu-user"]/dt')

    # 6.点击用户管理

    user_manager = ("link_text""用户管理")

    # 7.定位外层iframe框

    iframe = ("xpath""/html/body/div/section/div[2]/div[2]/iframe")

    # 8.点击添加用户

    user_add = ("partial""添加用户")

  (5)在testcase包中新建用例包

第一个test1_login用例代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

import unittest

from  selenium import  webdriver

from public.pages.basepage import BasePage

from  public.utils.read_ini import *

from  public.pages.page_element import Pages_Element as p

from  public.utils.read_ini import *

class  Test_login(BasePage):

    @classmethod

    def setUpClass(cls-None:

        driver=webdriver.Chrome()

        BasePage.set_driver(driver)

    @classmethod

    def  tearDownClass(cls-None:

        BasePage.sleep(2)

    def  test_1_login(self):

        driver=BasePage.get_driver()

        driver.get(url)

        BasePage.wait(2)

        elem=BasePage.find_element(p.userName)

        BasePage.sendKeys(elem,zh)

        BasePage.wait(2)

        elem=BasePage.find_element(p.passWord)

        BasePage.sendKeys(elem,pwd)

        elem=BasePage.find_element(p.loginBtn)

        BasePage.click(elem)

if __name__ == '__main__':

    unittest.main()

  第二个test2_yhgl和添加用例代码

import unittest
from  selenium import  webdriver
from public.pages.basepage import BasePage
from  public.utils.read_ini import *
from  public.pages.page_element import Pages_Element as p
from  public.utils.read_ini import *
class  Test_yh(BasePage):
    @classmethod
    def setUpClass(cls) -> None:
        BasePage.sleep(2)
    @classmethod
    def  tearDownClass(cls) -> None:
        BasePage.sleep(2)
    def  test_2_yhgl(self):
        e1em=BasePage.find_element(p.user_center)
        BasePage.click(e1em)
        e1em=BasePage.find_element(p.user_manager)
        BasePage.click(e1em)
if __name__ == '__main__':
    unittest.main()

第三个用例包:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

import  time

import unittest

from  conf.cms_path import *

from public.utils.HTMLTestRunnerNew import HTMLTestRunner

from  public.utils.mail import SendMail

now=time.strftime("%y-%m-%d %H-%M-%S")

file=report_path+"/"+str(now)+"_ui_report.html"

def bg():

    d=unittest.TestLoader().discover(start_dir=testcase_path,

                                     pattern="test*.py")

    f=open(file,"bw")

    r=HTMLTestRunner(

        stream=f,title="自动化测试报告",description="用例执行情况" ,

        tester="dcs"

    )

    r.run(d)

    f.close()

def  yj():

    sm=SendMail(send_msg=file,attachment=file)

    sm.send_mail()

if __name__ == '__main__':

    bg()

    yj()

  

run包中导入邮件模板和报模板:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

import  time

import unittest

from  conf.cms_path import *

from public.utils.HTMLTestRunnerNew import HTMLTestRunner

from  public.utils.mail import SendMail

now=time.strftime("%y-%m-%d %H-%M-%S")

file=report_path+"/"+str(now)+"_ui_report.html"

def bg():

    d=unittest.TestLoader().discover(start_dir=testcase_path,

                                     pattern="test*.py")

    f=open(file,"bw")

    r=HTMLTestRunner(

        stream=f,title="自动化测试报告",description="用例执行情况" ,

        tester="dcs"

    )

    r.run(d)

    f.close()

def  yj():

    sm=SendMail(send_msg=file,attachment=file)

    sm.send_mail()

if __name__ == '__main__':

    bg()

    yj()

  

 在report中生成报告:

 1、自己通过po框架输入测试报告  2、编写自动化测试框架  3、总结测试讲解稿

讲解稿:

案例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做自动化测试的一个基本流程。


原文地址:https://blog.csdn.net/qq_49367496/article/details/145278174

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!