python+selenium+unittest自动化测试框架

前言

关于自动化测试的介绍,网上已有很多资料,这里不再赘述,UI自动化测试是自动化测试的一种,也是测试金字塔最上面的一层,selenium是应用于web的自动化测试工具,支持多平台、多浏览器、多语言来实现自动化,优点如下:

①开源、免费且对web界面有良好的支持;;

②多浏览器支持:chrome、Firefox、IE、Edge等;

③多平台支持:Linux、Windows、MAC;

④多语言支持:java、python、Ruby、C#、JavaScript、C++;

⑤简单(API简单)、灵活(开发语言驱动),支持分布式测试用例执行;

环境准备
  • 浏览器(Chrome)
  • Python
  • Selenium
  • chromedriver(请下载于Chrome对应版本的驱动)
  • IDE(Pycharm)

1、python、pycharm安装

2、selenium安装

pip install selenium ​

关于selenium元素定位是开展web自动化测试的基础和关键,总共有八种定位方式,包括id,class,xpath等

3、chromedriver驱动安装

驱动下载:http://chromedriver.storage.googleapis.com/index.html

然后把chromedriver.exe拷贝到到chrome的安装目录下…\Google\Chrome\Application\ ,同时把chrome的安装目录加入到path环境变量。

4、快速验证测试

自动化测试框架

  • config目录中存放的是测试配置相关的文件,文件类型ini,包括测试的网址、浏览器驱动等信息
  • framework目录中存放的是页面基础类base_page: 封装一些常用的页面操作方法;日志类 Logger: 封装日志输出及控制台输出方法
  • logs用来存放输出的日志文件
  • pageobjects目录存放的是页面对象,一个页面封装为一个类,一个元素封装为一个方法
  • screenshots目录存放的是测试过程中的相关截图
  • test_report用来存放输出的测试报告
  • testsuites目录存放测试用例,包括test_base和单个测试用例

1、config.ini配置信息如下:

2、framework目录下base_page的封装:

  1. import time

  2. from selenium.webdriver.common.action_chains import ActionChains

  3. from selenium.webdriver.support.wait import WebDriverWait

  4. from selenium.webdriver.support.select import Select

  5. import os.path

  6. from framework.logger import Logger

  7. # 创建一个日志实例

  8. logger = Logger(logger="BasePage").getlog()

  9. class BasePage(object):

  10. """

  11. 定义一个页面基类,让所有页面都继承这个类,封装一些常用的页面操作方法

  12. """

  13. def __init__(self, driver):

  14. self.driver = driver

  15. #get an url link

  16. def open(self,url):

  17. self.driver.get(url)

  18. #quit browser and end testing

  19. def quit_browser(self):

  20. self.driver.quit()

  21. # 浏览器前进操作

  22. def forward(self):

  23. self.driver.forward()

  24. logger.info("Click forward on current page.")

  25. # 浏览器后退操作

  26. def back(self):

  27. self.driver.back()

  28. logger.info("Click back on current page.")

  29. # 显示等待

  30. def wait(self,loc,seconds):

  31. try:

  32. wait_=WebDriverWait(self.driver,seconds)

  33. wait_.until(lambda driver:driver.find_element(*loc))

  34. logger.info("wait for %d seconds." % seconds)

  35. except NameError as e:

  36. logger.error("Failed to load the element with %s" % e)

  37. # 保存图片

  38. def get_windows_img(self):

  39. """

  40. 把file_path保存到我们项目根目录的一个文件夹.\Screenshots下

  41. """

  42. file_path = os.path.dirname(os.path.abspath('.')) + 'Selenium/screenshots/'

  43. rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))

  44. screen_name = file_path + rq + '.png'

  45. try:

  46. self.driver.get_screenshot_as_file(screen_name)

  47. logger.info("Had take screenshot and save to folder : /screenshots")

  48. except NameError as e:

  49. logger.error("Failed to take screenshot! %s" % e)

  50. self.get_windows_img()

  51. # 定位元素方法

  52. def find_element(self,loc):

  53. """

  54. :return: element

  55. """

  56. return self.driver.find_element(*loc)

  57. # 输入

  58. def send_keys(self, selector, text):

  59. el = self.find_element(selector)

  60. el.clear()

  61. try:

  62. el.send_keys(text)

  63. logger.info("Had type \' %s \' in inputBox" % text)

  64. except NameError as e:

  65. logger.error("Failed to select in input box with %s" % e)

  66. self.get_windows_img()

  67. # 清除文本框

  68. def clear(self, selector):

  69. el = self.find_element(selector)

  70. try:

  71. el.clear()

  72. logger.info("Clear text in input box before typing.")

  73. except NameError as e:

  74. logger.error("Failed to clear in input box with %s" % e)

  75. self.get_windows_img()

  76. # 点击元素

  77. def click(self, selector):

  78. el = self.find_element(selector)

  79. try:

  80. el.click()

  81. logger.info("The element \'%s\' was clicked." % el.text)

  82. except NameError as e:

  83. logger.error("Failed to click the element with %s" % e)

  84. #鼠标事件(左键点击)

  85. def move_element(self,loc,sloc):

  86. mouse=self.find_element(loc)

  87. try:

  88. ActionChains(self.driver).move_to_element(mouse).perform()

  89. self.click(sloc)

  90. pass

  91. except Exception as e:

  92. logger.error("Failed to click move_element with %s" % e)

  93. self.get_windows_img()

  94. # 强制等待

  95. @staticmethod

  96. def sleep(seconds):

  97. time.sleep(seconds)

  98. logger.info("Sleep for %d seconds" % seconds)

 logger日志输入方法:

  1. import logging

  2. import os.path

  3. import time

  4. class Logger(object):

  5. def __init__(self, logger):

  6. '''''

  7. 指定保存日志的文件路径,日志级别,以及调用文件

  8. 将日志存入到指定的文件中

  9. '''

  10. # 创建一个logger

  11. self.logger = logging.getLogger(logger)

  12. self.logger.setLevel(logging.DEBUG)

  13. # 创建一个handler,用于写入日志文件

  14. rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))

  15. log_path = os.path.dirname(os.path.abspath('.')) + 'Selenium/logs/'

  16. log_name = log_path + rq + '.log'

  17. fh = logging.FileHandler(log_name)

  18. fh.setLevel(logging.INFO)

  19. # 再创建一个handler,用于输出到控制台

  20. ch = logging.StreamHandler()

  21. ch.setLevel(logging.INFO)

  22. # 定义handler的输出格式

  23. formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

  24. fh.setFormatter(formatter)

  25. ch.setFormatter(formatter)

  26. # 给logger添加handler

  27. self.logger.addHandler(fh)

  28. self.logger.addHandler(ch)

  29. def getlog(self):

  30. return self.logger

3、关于页面对象的写法参考:

页面对象继承于base_page基类

  1. from framework.base_page import BasePage

  2. from selenium.webdriver.common.by import By

  3. from framework.logger import Logger

  4. logger = Logger(logger="cloud_page").getlog()

  5. class Cloud(BasePage):

  6. #定位器

  7. input_box = (By.ID,'kw')

  8. search_submit = (By.XPATH,'//*[@id="su"]')

  9. def value_input(self, text):

  10. self.wait(self.input_box,5)

  11. self.send_keys(self.input_box, text)

  12. def submit_btn(self):

  13. self.click(self.search_submit)

  14. logger.info("show results!")

  15. self.sleep(2)

4、testsuite部分,每个用例都要执行的用例前的准备setup和清理teardown写在test_base文件里,单个测试用例文件继承于它

  1. from selenium import webdriver

  2. import unittest

  3. class TestBase(unittest.TestCase):

  4. def setUp(self):

  5. self.driver=webdriver.Chrome() #驱动浏览器

  6. self.driver.implicitly_wait(10) #设置隐式等待

  7. self.driver.maximize_window() #最大化浏览器

  8. def tearDown(self):

  9. self.driver.quit()

  10. if __name__=='__main__':

  11. unittest.main()

测试用例参考,注意测试用例方法命名一定要以test开头

  1. import time

  2. from testsuites.test_base import TestBase

  3. from pageobjects.baidu_page import Cloud

  4. class BaiduSearch(TestBase):

  5. def test_baidu_search(self):

  6. """

  7. 这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。

  8. :return:

  9. """

  10. input = Cloud(self.driver)

  11. input.open('https://www.baidu.com/')

  12. input.value_input('selenium') # 调用页面对象中的方法

  13. input.submit_btn() # 调用页面对象类中的点击搜索按钮方法

  14. time.sleep(2)

  15. input.get_windows_img() # 调用基类截图方法

  16. try:

  17. assert 'selenium' in 'selenium'

  18. print('Test Pass.')

  19. except Exception as e:

  20. print('Test Fail.', format(e))

5、最后就是核心代码,testrunner.py 用来批量执行测试用例,引用HTMLTestRunner模块生成测试报告。

  1. import unittest

  2. from HTMLTestRunner import HTMLTestRunner

  3. import time

  4. import os

  5. # 定义输出的文件位置和名字

  6. DIR = os.path.dirname(os.path.abspath(__file__))

  7. now = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))

  8. filename =now+"report.html"

  9. #discover方法执行测试套件

  10. testsuite = unittest.defaultTestLoader.discover(

  11. start_dir='./testsuites',

  12. pattern='*case.py',

  13. top_level_dir=None

  14. )

  15. with open(DIR+'/test_report/'+filename,'wb') as f:

  16. runner = HTMLTestRunner(

  17. stream=f,

  18. verbosity=2,

  19. title='gateway UI report',

  20. description='执行情况',

  21. tester='tester'

  22. )

  23. runner.run(testsuite)

6、测试报告展示

基于selenium实现的web自动化框架不仅轻量级而且灵活,可以快速的开发自动化测试用例。本篇中的框架设计比较简单,希望对大家以后的web自动化框架的设计和实现有所帮助,共同交流,共同进步!

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值