您的位置:首页 > 脚本大全 > > 正文

pythonselenium接口自动测试(python3+selenium自动化测试框架详解)

更多 时间:2022-01-15 01:26:38 类别:脚本大全 浏览量:2504

pythonselenium接口自动测试

python3+selenium自动化测试框架详解

背景

为了更好的发展自身的测试技能,应对测试行业以及互联网行业的迭代变化。自学python以及自动化测试。

虽然在2017年已经开始接触了selenium,期间是断断续续执行自动化测试,因为还有其他测试任务,培训任务要执行…
前期建议大家能够学习python基本语法(python基础教程)

任务

搭建自动化测试框架,并能有效方便的进行测试,维护成本也要考虑其中。

过程

我的自动化框架可能不成熟,因为是自学的。请多包涵。也请大佬指导~

pythonselenium接口自动测试(python3+selenium自动化测试框架详解)

common

包含:基本的公共方法类,比如html报告、log处理、发送邮件、基本页面对象等

其中pageobject里面是对各个测试系统操作页面的一个封装,以后用例的方法直接继承即可。可多次调用,维护起来比较方便。

conf

基本的系统参数配置信息,可以包含url,正确用户的信息,简单日志级别,某些输出位置,邮件信息等

data

对于数据驱动或者其他测试用例中需要测试的数据,之后测试用例流程不变,可以直接在文档中进行测试数据的修改。暂时采用excel。也可以采用csv,xml等等方法

log

日志输出,暂时包括了 log输出,htmlreport输出以及img的保存。

test

其中包含testcase以及testsuite两个模块

testcase 负责编写测试用例如果某个功能有多个py文件编写可以再新建一个目录。
testsuite 就是测试套件,可以按需求进行选择需要的测试项(包含测试用例以及测试类)
注意:使用ddt则不可以再使用addtest方式单独添加测试用例了。

1

代码部分

- common中的basepage

  • ?
  • 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
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • class basepage():
  •  global logg
  •  logg = loghandler().logger
  •  def __init__(self,driver,url=none):
  •   self.wd = driver
  •   self.wd.implicitly_wait(5)
  •   self.actions = actionchains(self.wd)
  •   if url :
  •    self.url = url
  •   else:
  •    self.url = self.server_url_conf()
  •  #浏览器行为的一些方法
  •  def get_conf_url(self):
  •         self.wd.get(self.url)
  •   self.wd.maximize_window()
  •   logg.debug("enter conf_url : " + str(self.url))
  •  def brower_close(self):
  •   return self.wd.close()
  •  def brower_quit_all(self):
  •   return self.wd.quit()
  • ...     下面还有刷新,前进后退等
  •  
  •  #定位 这里通过 by.xx 方法
  •  def find_web_element(self,*loc):
  •   #self.wd.find_element(*loc)
  •   return self.wd.find_element(*loc)
  •  
  •  #元素操作
  •  def type_text(self,loc,text):
  •   return self.wd.find_element(*loc).send_keys(text)
  •   
  •  def clear_text(self,*loc):
  •   return self.wd.find_element(*loc).clear()
  •   
  •  def submit_func(self,*loc):
  •   return self.wd.find_element(*loc).submit()
  •  
  •  def click_btn(self,*loc):
  •   return self.wd.find_element(*loc).click()
  •   
  •     #鼠标相关
  •  def mouse_move_to_element(self,*loc):
  •   elem = self.find_web_element(*loc)
  •   self.actions.move_to_element(elem).perform()
  • ... 下面还有点击,双击,右击的一些方法 
  •  
  •  #获取信息行为
  •  def get_web_url(self):
  •   return self.wd.current_url
  •  def get_title(self):
  •   return self.wd.title
  •  def get_element_text(self,*loc):
  •   return self.find_web_element(*loc).text
  •  
  •  #元素是否存在 是 true
  •  def check_element_isexist(self,loc):
  •   isexist = false
  •   try:
  •    ec.presence_of_element_located(loc)(self.wd)
  •    isexist = true
  •   except exception as e:
  •    isexist = false
  •    logg.debug(' isexist or not :',exc_info = true)
  •   return isexist
  •  def check_element_has_text(self,loc,text):
  •         pass #省略
  •  
  •  def check_element_isdisplayed(self,*loc):
  •     pass #省略
  •     
  •  #生成图
  •  def __inser_img(self,passorfailed,imgname):
  •   time_loc = time.strftime("%m%d_%h%m%s",time.localtime())
  •   file_path = os.path.abspath(__file__)
  •   file_path = os.path.join(file_path+"/../../log/%s_%s.jpg" alt="pythonselenium接口自动测试(python3+selenium自动化测试框架详解)" border="0" /> %(imgname,time_loc))
  •   self.wd.get_screenshot_as_file(file_path)
  •   logg.debug('insert_%s_img %s ' %(passorfailed,(file_path)))
  •  
  •  def insert_error_img(self,imgname):
  •   self.__inser_img("error",imgname)
  •  def insert_success_img(self,imgname):
  •   self.__inser_img("success",imgname)
  •  def insert_debug_img(self,imgname):
  •   self.__inser_img("debug",imgname)
  •  
  •  
  •  def server_url_conf(self):
  •   self.host = readconfig.readconfig().getserver('host')
  •   self.port = readconfig.readconfig().getserver('port')
  •   urlvalue = self.host + ":" + self.port
  •  
  •   return urlvalue
  •  
  • if __name__ == '__main__':
  •  test = basepage(webdriver.chrome())
  •  test.get_conf_url()
  • common中登录页的页面对象

    包含了页面的一些方法比如

    输入用户名,输入密码,点击登录

    test中的 logintestcase

    则直接使用 登录页面对象的 输入用户名,输入密码,点击登录即可

    后期维护,如果元素变动,则只需要修改页面对象代码而对用例则无需修正

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • class aiologin(basepage):
  •  global logg
  •  logg = loghandler().getlog()
  •  username_loc = (by.name, "username")
  •  password_loc = (by.css_selector, "input[type='password']")
  •  login_loc = (by.class_name, "login-btn")
  •  login_loc_oem = (by.id,"submit")
  •  check_login_loc = (by.class_name,"error-tip")
  •  elements = [username_loc,password_loc,login_loc,check_login_loc]
  •  log_menu = (by.css_selector,"[name='log']")
  •  logg.debug(elements)
  •  
  •  def set_username(self,username):
  •   self.clear_text(*self.username_loc) #直接使用basepage的方法
  •   self.type_text(self.username_loc,username)
  •   logg.info('enter username: ' + username)
  •   sleep(0.1)
  • ... 其他
  • logintest

    这里使用了ddt数据驱动方法

    from ddt import data,ddt,unpack

  • ?
  • 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
  • @ddt
  • class testlogin(unittest.testcase):
  •  global logg
  •  logg = loghandler().getlog()
  •  
  •  @classmethod  #该类方法,执行中只会启动一次。区别于setup的 每个用例都执行一遍
  •  def setupclass(cls):
  •   cls.test = aiologinpage.aiologin(webdriver.chrome())
  •   cls.test.get_conf_url()
  •   # print('start testsearch')
  •   
  •  @classmethod
  •  def teardownclass(cls):
  •   # testlogin().logg.info("brower quit")
  •   testlogin().test.brower_close()
  •   pass
  •  logindata = readexcel().getvalue('login')
  •  
  •  @data(*logindata)
  •  @unpack  #当有多组数据时,需要unpack
  •  def testcase2(self,username,passwd,result):
  •   logg.info(username+" " + passwd +" " +str(result))
  •   self.test.set_username(username) #用例直接使用登录页面对象,后期除了修改测试用例,否则无需变动
  •   self.test.set_password(passwd)
  •   self.test.type_login_btn()
  •   
  •   # 断言登录结果和预期结果是否一致
  •   self.asserttrue(self.test.check_login_result(result),
  •       msg="\r login_test fail \r username :%s \r passwd : %s " %(username,passwd))
  •  
  • if __name__ == '__main__':
  •  unittest.main()
  • 其他页面

    比如我有个 创建设备分组的页面

    我必须要先登录才可以执行下面的操作

    此时,可以从conf中获取成功登录的用户名和密码,把correct_login方法写在登录页面对象中。

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • def correct_login(self):
  •   self.get_conf_url()
  •   self.userpasswd = self.correct_userpasswd_conf()
  •   self.set_username(self.userpasswd[0])
  •   self.set_password(self.userpasswd[1])
  •   self.type_login_btn()
  • 之后,其他页面初始化时候直接调用这个correct_login即可登录

    测试套件添加方法
    testsuite方法
    #添加一个类
    st1 = unittest.makesuite(testlogin)
    #单独添加多个用例
    st = unittest.testsuite(map(testclassname,[‘testcase1',‘testcase2']))
    st = unittest.testsuite(testclaseename(‘testcase1'))

    #添加一个或者多个测试用例
    st2 = unittest.testsuite()
    st2.addtests(map(testcaseclassname,[‘testcase2',‘testcase1']))
    st2.addtest(testcaseclassname(‘testcase1'))
    #添加一个类
    st2.addtest(unittest.makesuite(testclassname))

    testloader 方法
    discovery 发现脚本
    st = unittest.testloader().discovery(“dir_path”,pattern=“a*.py”)

    #loadtestfromtestcase 加载 测试类
    st1 = unittest.testloader().loadtestsfromtestcase(testlogincheck)
    st2 = unittest.testloader().loadtestsfromtestcase(testlogin)
    stt = unittest.testsuite()
    stt.addtests([st1,st2])