从0到1搭建测试自动化框架

发表于:2021-10-19 09:47

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Snake    来源:知乎

  我们在做自动化测试过程中,需要对我们的自动化用例,以及代码进行管理,使其更加结构化,模块化。从而更方便扩展以及维护。好的测试框架,让自动化更加省时省力。
  当我们的自动化用例和代码写得多的时候,需要用一种方式来管理。就像我们建房子,当建的房子不是高层的时候,可以用一砖一瓦来建设。当建摩天大厦时,这种方式不牢靠,且效率及其低下。现在建筑业都是用框架式来建设,然后填充,最后装修。
  软件工程也是如此。
  小杰是一名软件测试工程师。每天的工作就是理解产品需求,写测试用例,以及手工执行测试用例。他希望减少一遍又一遍的重复劳动,于是就自学了web自动化。
  第一次写出的用例如下:
  from selenium import webdriver
  from selenium.webdriver.support.ui import WebDriverWait
  def open_home():
      driver = webdriver.Firefox()
      driver.get("https://testerhome.com/")
      driver.implicitly_wait(5)
      driver.find_element_by_link_text("Sign In").click()
      driver.implicitly_wait(3)
      username = WebDriverWait(driver, 5).until(lambda x: x.find_element_by_id("user_login"))
      username.clear()
      username.send_keys("XXX")
      password = WebDriverWait(driver, 5).until(lambda x: x.find_element_by_id("user_password"))
      password.clear()
      password.send_keys("XXX")
      driver.find_element_by_name("commit").click()
      driver.implicitly_wait(3)
      driver.quit()
  if __name__ == "__main__":
      open_home()
  他很激动,虽然是一小步,毕竟自动化起来了。他满心欢喜的show给测试老鸟小明看。
  小明当场给他浇了一盆冷水。 “你这都不能算自动化测试用例,连个验证点都没有。”
  于是在小明的指点下,通过改进,终于完成了一版像那么回事自动化用例。
  import unittest
  from selenium import webdriver
  from selenium.webdriver.support.ui import WebDriverWait
  class Login(unittest.TestCase):
      def setUp(self):
          self.driver = webdriver.Firefox()
          self.driver.implicitly_wait(5)
          self.base_url = "https://testerhome.com/"
      def test_open_home(self):
          driver = self.driver
          driver.get(self.base_url)
          driver.implicitly_wait(5)
          driver.find_element_by_link_text("Sign In").click()
          driver.implicitly_wait(3)
          username = WebDriverWait(driver, 5).until(lambda x: x.find_element_by_id("user_login"))
          username.clear()
          username.send_keys("beerbox")
          password = WebDriverWait(driver, 5).until(lambda x: x.find_element_by_id("user_password"))
          password.clear()
          password.send_keys("Good_Luck888")
          driver.find_element_by_name("commit").click()
          driver.implicitly_wait(3)
          self.assertIn("TesterHome",driver.title)
      def tearDown(self):
          self.driver.quit()
  if __name__ == "__main__":
      suite = unittest.TestSuite()
      suite.addTest(Login('test_open_home'))
      unittest.TextTestRunner().run(suite)
  小杰很激动,想这回你小明应该表扬下我了吧。你看我验证点也有了,还有一个这么漂亮的报告。
  谁知小明仅仅对小杰的进步表示了赞赏,但仍然对小杰的代码不满意。
  “你这像录制的代码。你这写一个用例容易,如果写多个用例,维护起来非常麻烦。你需要一个框架来优化你的代码,我建议你学学page object的思想”。
  于是乎,小杰积极捣鼓,优化版也成型了。
  cases/login.py
  import unittest
  from frame3.pages.loginpage import login_page
  class caselogin(unittest.TestCase):
      def setUp(self):
          self.username = "XXX"
          self.password = "XXX"
          self.login = login_page()
      def test_login_with_correct_account(self):
          '''检查正确账号密码能登陆'''
          self.login.login_action(self.username,self.password)
          self.assertIn("TesterHome",self.login.driver.title)
      def tearDown(self):
          self.login.driver.quit()
  pages/login_page.py
  from selenium.webdriver.common.by import By
  from frame3.basepage import page
  class login_page(page):
      # 定位器,通过元素属性定位元素对象
      username_loc = (By.ID, "user_login")
      password_loc = (By.ID, "user_password")
      submit_loc = (By.NAME, "commit")
      # 调用send_keys对象,输入用户名
      def input_username(self, username):
          self.find_element(*self.username_loc).send_keys(username)
      # 调用send_keys对象,输入密码
      def input_password(self, password):
          self.find_element(*self.password_loc).send_keys(password)
      # 调用send_keys对象,点击登录
      def click_submit(self):
          self.find_element(*self.submit_loc).click()
      def login_action(self,username,password):
          self.open(self.base_url)
          self.input_username(username)
          self.input_password(password)
          self.click_submit()
  BasePage.py
  from selenium.webdriver.support.wait import WebDriverWait
  from selenium import webdriver
  class page(object):
      def __init__(self):
          self.driver = webdriver.Firefox()
          self.base_url = "https://XXX/account/sign_in"
      # 打开页面,校验页面链接是否加载正确
      def _open(self, url):
          # 使用get打开访问链接地址
          self.driver.get(url)
          self.driver.maximize_window()
          #
          # # 使用assert进行校验,打开的链接地址是否与配置的地址一致。调用on_page()方法
          # assert self.on_page(pagetitle), u"打开开页面失败 %s" % url
      # 重写元素定位方法
      def find_element(self, *loc):
          # return self.driver.find_element(*loc)
          try:
              WebDriverWait(self.driver, 10).until(lambda driver: driver.find_element(*loc).is_displayed())
              return self.driver.find_element(*loc)
          except:
              print(u"%s 页面中未能找到 %s 元素" % (self, loc))
      # 重写switch_frame方法
      def switch_frame(self, loc):
          return self.driver.switch_to.frame(loc)
      # 定义open方法,调用_open()进行打开链接
      def open(self,url):
          self._open(url)
      # 使用current_url获取当前窗口Url地址,进行与配置地址作比较,返回比较结果(True False)
      def on_page(self, pagetitle):
          return pagetitle in self.driver.title
      # 定义script方法,用于执行js脚本,范围执行结果
      def script(self, src):
          self.driver.execute_script(src)
      # 重写定义send_keys方法
      def send_keys(self, loc, vaule, clear_first=True, click_first=True):
          try:
              loc = getattr(self, "_%s" % loc)
              if click_first:
                  self.find_element(*loc).click()
              if clear_first:
                  self.find_element(*loc).clear()
                  self.find_element(*loc).send_keys(vaule)
          except AttributeError:
              print(u"%s 页面中未能找到 %s 元素" % (self, loc))
  小明对此版本还算满意,表示这里面hard code太多,小杰在小明的帮助下,终于搭建了一款自己还比较满意的框架。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号