搭建关键字驱动自动化测试框架(1),2024软件测试面试宝典

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
img

正文

  1. 6 def __init__(self, driver):
  2. 7 self.byDic = {
  3. 8 'id': By.ID,
  4. 9 'name': By.NAME,
  5. 10 'class_name': By.CLASS_NAME,
  6. 11 'xpath': By.XPATH,
  7. 12 'link_text': By.LINK_TEXT
  8. 13 }
  9. 14 self.driver = driver
  10. 15 self.wait = WebDriverWait(self.driver, 50)
  11. 16
  12. 17 def presenceOfElementLocated(self, by, locator):
  13. 18 '''
  14. 19 显示等待某个元素出现在dom中,不一定可见,存在返回元素对象
  15. 20 :param by:
  16. 21 :param locator:
  17. 22 :return:
  18. 23 '''
  19. 24 try:
  20. 25 if by.lower() in self.byDic:
  21. 26 self.wait.until(EC.presence_of_element_located((self.byDic[by.lower()], locator)))
  22. 27 else:
  23. 28 raise TypeError('未找到定位方式,请确保定位方式正确')
  24. 29 except Exception as e:
  25. 30 raise e
  26. 31
  27. 32 def frameToBeAvailableAndSwtichToIt(self, by, locator):
  28. 33 '''
  29. 34 检查frame是否存在,存在就切换到frame中
  30. 35 :param by:
  31. 36 :param locator:
  32. 37 :return:
  33. 38 '''
  34. 39 try:
  35. 40 if by.lower() in self.byDic:
  36. 41 self.wait.until(EC.frame_to_be_available_and_switch_to_it((self.byDic[by.lower()], locator)))
  37. 42 else:
  38. 43 raise TypeError('未找到定位方式,请确保定位方式正确')
  39. 44 except Exception as e:
  40. 45 raise e
  41. 46 def visibiltyOfElementLocated(self, by, locator):
  42. 47 '''
  43. 48 显示等待页面元素出现在dom中, 并且可见, 存在则返回该元素对象
  44. 49 :param by:
  45. 50 :param locator:
  46. 51 :return:
  47. 52 '''
  48. 53 try:
  49. 54 if by.lower() in self.byDic:
  50. 55 self.wait.until(EC.visibility_of_element_located((self.byDic[by.lower()], locator)))
  51. 56 else:
  52. 57 raise TypeError('未找到定位方式,请确保定位方式正确')
  53. 58 except Exception as e:
  54. 59 raise e
  55. 60
  56. 61 if __name__=='__main__':
  57. 62 from selenium import webdriver
  58. 63 from util.ObjectMap import *
  59. 64 driver = webdriver.Firefox()
  60. 65 driver.get('https://mail.126.com')
  61. 66
  62. 67 wait = WaitUnit(driver)
  63. 68 wait.frameToBeAvailableAndSwtichToIt('xpath', "//div[@id='loginDiv']/iframe")
  64. 69 wait.visibiltyOfElementLocated('xpath', "//input[@name='email']")
  65. 70 uname = getElement(driver, 'xpath', "//input[@name='email']")
  66. 71 uname.send_keys('python')
  67. 72 driver.quit()

3.新建ClipboardUtil.py文件,用来实现剪切版的操作(我们发送邮件时,需要添加附件,通过这个功能来实现上传附件)

    • 1 import win32clipboard as w
  • 2 import win32con
  • 3
  • 4 class Clipboard(object):
  • 5
  • 6 @staticmethod
  • 7 def getText():
  • 8 '''
  • 9 获取剪切板的内容
  • 10 :return:
  • 11 '''
  • 12
  • 13 try:
  • 14 # 打开剪切板
  • 15 w.OpenClipboard()
  • 16 # 读取数据
  • 17 value = w.GetClipboardData(win32con.CF_TEXT)
  • 18 # 关闭剪切板
  • 19 w.CloseClipboard()
  • 20 except Exception as e:
  • 21 raise e
  • 22 else:
  • 23 return value
  • 24
  • 25 @staticmethod
  • 26 def setText(value):
  • 27 '''
  • 28 设置剪切板内容
  • 29 :return:
  • 30 '''
  • 31 try:
  • 32 w.OpenClipboard()# 打开剪切板
  • 33 w.EmptyClipboard()# 清空剪切板
  • 34 w.SetClipboardData(win32con.CF_UNICODETEXT, value) # 设置内容
  • 35 w.CloseClipboard() # 关闭
  • 36 except Exception as e:
  • 37 raise e
  • 38
  • 39 if __name__=='__main__':
  • 40 from selenium import webdriver
  • 41
  • 42 value = 'python'
  • 43 driver = webdriver.Firefox()
  • 44 driver.get('http://www.baidu.com')
  • 45 query = driver.find_element_by_id('kw')
  • 46 Clipboard.setText(value)
  • 47 clValue = Clipboard.getText()
  • 48 query.send_keys(clValue.decode('utf-8'))

4.新建KeyBoardUtil.py文件,主要实现模拟键盘的操作(配合上面剪切板的功能实现,粘贴附件的路径,回车等)

  1. 1 import win32api
  2. 2 import win32con
  3. 3
  4. 4 class KeyBoardKeys(object):
  5. 5 '''
  6. 6 模拟键盘
  7. 7 '''
  8. 8 # 键盘编码
  9. 9 vk_code ={
  10. 10 'enter':0x0D,
  11. 11 'tab' : 0x09,
  12. 12 'ctrl':0x11,
  13. 13 'v':0x56
  14. 14 }
  15. 15 @staticmethod
  16. 16 def keyDown(keyName):
  17. 17 '''
  18. 18 模拟按下键
  19. 19 :param keyName:
  20. 20 :return:
  21. 21 '''
  22. 22 try:
  23. 23 win32api.keybd_event(KeyBoardKeys.vk_code[keyName],0,0,0)
  24. 24 except Exception as e:
  25. 25 raise e
  26. 26 @staticmethod
  27. 27 def keyUp(keyName):
  28. 28 '''
  29. 29 释放键
  30. 30 :param keyName:
  31. 31 :return:
  32. 32 '''
  33. 33 try:
  34. 34 win32api.keybd_event(KeyBoardKeys.vk_code[keyName],0,win32con.KEYEVENTF_KEYUP,0)
  35. 35 except Exception as e:
  36. 36 raise e
  37. 37 @staticmethod
  38. 38 def oneKey(key):
  39. 39 '''
  40. 40 模拟当个按键
  41. 41 :param key:
  42. 42 :return:
  43. 43 '''
  44. 44 try:
  45. 45 KeyBoardKeys.keyDown(key)
  46. 46 KeyBoardKeys.keyUp(key)
  47. 47 except Exception as e:
  48. 48 raise e
  49. 49
  50. 50 @staticmethod
  51. 51 def twoKeys(key1, key2):
  52. 52 '''
  53. 53 模拟组合按键
  54. 54 :param key1:
  55. 55 :param key2:
  56. 56 :return:
  57. 57 '''
  58. 58 try:
  59. 59 KeyBoardKeys.keyDown(key1)
  60. 60 KeyBoardKeys.keyDown(key2)
  61. 61 KeyBoardKeys.keyUp(key1)
  62. 62 KeyBoardKeys.keyUp(key2)
  63. 63 except Exception as e:
  64. 64 raise e
  65. 65
  66. 66 if __name__=='__main__':
  67. 67 from selenium import webdriver
  68. 68
  69. 69 driver = webdriver.Firefox()
  70. 70 driver.get('http://www.baidu.com')
  71. 71 driver.find_element_by_id('kw').send_keys('python')
  72. 72 KeyBoardKeys.oneKey('enter')

5.新建DirAndTime.py文件,主要实现获取当前时间,生成特殊路径,这里主要用来生成屏幕截图保存的路径及图片名称

    • 1 from datetime import datetime, date
  • 2 from config.VarConfig import *
  • 3
  • 4 class DirAndTime(object):
  • 5 @staticmethod
  • 6 def getCurrentDate():
  • 7 '''
  • 8 获取当前日期
  • 9 :return:
  • 10 '''
  • 11 try:
  • 12 currentDate = date.today()
  • 13 except Exception as e:
  • 14 raise e
  • 15 else:
  • 16 return str(currentDate)
  • 17 @staticmethod
  • 18 def getCurrentTime():
  • 19 '''
  • 20 获取当前时间
  • 21 :return:
  • 22 '''
  • 23 try:
  • 24 Time = datetime.now()
  • 25 currentTime = Time.strftime('%H_%M_%S')
  • 26 except Exception as e:
  • 27 raise e
  • 28 else:
  • 29 return currentTime
  • 30 @staticmethod
  • 31 def CreatePicturePath():
  • 32 '''
  • 33 创建图片存放路径路径
  • 34 :return:
  • 35 '''
  • 36 try:
  • 37
  • 38 picturePath = os.path.join(exceptionPath , DirAndTime.getCurrentDate())
  • 39 if not os.path.exists(picturePath):
  • 40 os.makedirs(picturePath) # 生成多级目录
  • 41 except Exception as e:
  • 42 raise e
  • 43 else:
  • 44 return picturePath
  • 45
  • 46 if __name__=='__main__':
  • 47 print(DirAndTime.getCurrentDate())
  • 48 print(DirAndTime.getCurrentTime())
  • 49 print(DirAndTime.CreatePicturePath())

6.新建ParseExcel.py用来解析excel文件

    • 1 from openpyxl import load_workbook
  • 2 from config.VarConfig import *
  • 3 from datetime import datetime, date
  • 4
  • 5 class ParseExcel(object):
  • 6 '''
  • 7 解析excel文件的封装
  • 8 '''
  • 9 def __init__(self):
  • 10 # 加载excel文件到内存
  • 11 self.wb = load_workbook(excelPath)
  • 12
  • 13 def getRowValue(self, sheetName, rawNo):
  • 14 '''
  • 15 获取某一行的数据
  • 16 :param sheetName:
  • 17 :param rawNo:
  • 18 :return: 列表
  • 19 '''
  • 20 sh = self.wb[sheetName]
  • 21 rowValueList = []
  • 22 for y in range(2, sh.max_column+1):
  • 23 value = sh.cell(rawNo,y).value
  • 24 rowValueList.append(value)
  • 25 return rowValueList
  • 26 def getColumnValue(self, sheetName, colNo):
  • 27 '''
  • 28 获取某一列的数据
  • 29 :param sheetName:
  • 30 :param colNo:
  • 31 :return: 列表
  • 32 '''
  • 33 sh = self.wb[sheetName]
  • 34 colValueList = []
  • 35 for x in range(2, sh.max_row +1):
  • 36 value = sh.cell(x, colNo).value
  • 37 colValueList.append(value)
  • 38 return colValueList
  • 39
  • 40 def getCellOfValue(self, sheetName, rowNo, colNo):
  • 41 '''
  • 42 获取某一个单元格的数据
  • 43 :param sheetName:
  • 44 :param rowNo:
  • 45 :param colNo:
  • 46 :return: 字符串
  • 47 '''
  • 48 sh = self.wb[sheetName]
  • 49 value = sh.cell(rowNo, colNo).value
  • 50 return value
  • 51 def writeCell(self, sheetName, rowNo, colNo, value):
  • 52 '''
  • 53 向某个单元格写入数据
  • 54 :param rowNo: 行号
  • 55 :param colNo: 列号
  • 56 :param value:
  • 57 :return: 无
  • 58 '''
  • 59 sh = self.wb[sheetName]
  • 60 sh.cell(rowNo, colNo).value = value
  • 61 self.wb.save(excelPath)
  • 62 def writeCurrentTime(self, sheetName, rowNo, colNo):
  • 63 '''
  • 64 向某个单元格写入当前时间
  • 65 :return:
  • 66 '''
  • 67 sh = self.wb[sheetName]
  • 68 Time = datetime.now()
  • 69 currentTime = Time.strftime('%Y:%m:%d %H:%M:%S')
  • 70 sh.cell(rowNo, colNo).value = currentTime
  • 71 self.wb.save(excelPath)
  • 72
  • 73 def writeTestResult(self, sheetName, rowNo, result, errorInfo = None, errorPic = None):
  • 74 ParseExcel().writeCurrentTime(sheetName, rowNo, testStep_testRunTime)
  • 75 ParseExcel().writeCell(sheetName, rowNo, testStep_testResult, result)
  • 76 if errorInfo and errorInfo:
  • 77 ParseExcel().writeCell(sheetName, rowNo, testStep_testErrorInfo, errorInfo)
  • 78 ParseExcel().writeCell(sheetName, rowNo, testStep_testErrorPic, errorPic)
  • 79 else:
  • 80 ParseExcel().writeCell(sheetName, rowNo, testStep_testErrorInfo, '')
  • 81 ParseExcel().writeCell(sheetName, rowNo, testStep_testErrorPic, '')
  • 82 if __name__=='__main__':
  • 83 p = ParseExcel()
  • 84 print(p.getRowValue('126account',2))
  • 85 print(p.getColumnValue('126account',3))
  • 86 print(p.getCellOfValue('126account', 2, 3))

7.新建Log.py文件,用来记录代码运行日志

    • 1 import logging
  • 2 import time
  • 3 from config.VarConfig import *
  • 4
  • 5 class Logger(object):
  • 6 '''
  • 7 封装的日志模块
  • 8 '''
  • 9 def __init__(self, logger, CmdLevel=logging.INFO, FileLevel=logging.INFO):
  • 10 """
  • 11
  • 12 :param logger:
  • 13 :param CmdLevel:
  • 14 :param FileLevel:
  • 15 """
  • 16 try:
  • 17 self.logger = logging.getLogger(logger)
  • 18 self.logger.setLevel(logging.DEBUG) # 设置日志输出的默认级别
  • 19 # 日志输出格式
  • 20 fmt = logging.Formatter('%(asctime)s - %(filename)s:[%(lineno)s] - [%(levelname)s] - %(message)s')
  • 21 # 日志文件名称
  • 22 # self.LogFileName = os.path.join(conf.log_path, "{0}.log.txt".format(time.strftime("%Y-%m-%d")))# %H_%M_%S
  • 23 currTime = time.strftime("%Y-%m-%d")
  • 24 self.LogFileName = logPath+currTime+'.txt'
  • 25 # 设置控制台输出
  • 26 # sh = logging.StreamHandler()
  • 27 # sh.setFormatter(fmt)
  • 28 # sh.setLevel(CmdLevel)# 日志级别
  • 29
  • 30 # 设置文件输出
  • 31 fh = logging.FileHandler(self.LogFileName)
  • 32 fh.setFormatter(fmt)
  • 33 fh.setLevel(FileLevel)# 日志级别
  • 34
  • 35 # self.logger.addHandler(sh)
  • 36 self.logger.addHandler(fh)
  • 37 except Exception as e:
  • 38 raise e
  • 39
  • 40 if __name__ == '__main__':
  • 41 logger = Logger("fox",CmdLevel=logging.DEBUG, FileLevel=logging.DEBUG)
  • 42 logger.logger.debug("debug")
  • 43 logger.logger.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error
业务操作功能模块

新建action文件夹,主要存储页面的各种操作,如点击操作,输入操作等1.文件夹下新建PageAction.py文件

    • 1 from util.ObjectMap import *
  • 2 from util.ClipboardUtil import Clipboard
  • 3 from util.KeyBoardUtil import KeyBoardKeys
  • 4 from util.WaitUntil import WaitUnit
  • 5 from util.DirAndTime import *
  • 6 from selenium import webdriver
  • 7
  • 8 driver = None
  • 9 waitUtil = None
  • 10 # 打开浏览器
  • 11 def openBrowser(browser):
  • 12 global driver, waitUtil
  • 13 try:
  • 14 if browser.lower() =='ie':
  • 15 driver = webdriver.Ie(executable_path=iePath)
  • 16 elif browser.lower() == 'chrome':
  • 17 driver = webdriver.Chrome(executable_path=chromePath)
  • 18 else:
  • 19 # driver = webdriver.Firefox(executable_path=fireFox)
  • 20 driver = webdriver.Firefox()
  • 21 except Exception as e:
  • 22 raise e
  • 23 else:
  • 24 waitUtil = WaitUnit(driver) # driver 创建之后, 创建等待类实例对象
  • 25
  • 26 # 浏览器窗口最大化
  • 27 def maximize_browser():
  • 28 try:
  • 29 driver.maximize_window()
  • 30 except Exception as e:
  • 31 raise e
  • 32 # 加载网址
  • 33 def loadUrl(url):
  • 34 try:
  • 35 driver.get(url)
  • 36 except Exception as e:
  • 37 raise e
  • 38
  • 39 # 强制等待
  • 40 def sleep(sleepSeconds):
  • 41 try:
  • 42 import time
  • 43 time.sleep(sleepSeconds)
  • 44 except Exception as e:
  • 45 raise e
  • 46 # 清除输入框的内容
  • 47 def clear(by, locator):
  • 48 try:
  • 49 getElement(driver, by, locator).clear()
  • 50 except Exception as e:
  • 51 raise e
  • 52 # 输入框中输入内容
  • 53 def inputValue(by, locator, value):
  • 54 try:
  • 55 element = getElement(driver, by, locator)
  • 56 # element.click()
  • 57 element.send_keys(value)
  • 58 except Exception as e:
  • 59 raise e
  • 60 # 点击操作
  • 61 def clickBtn(by, locator):
  • 62 try:
  • 63 getElement(driver, by, locator).click()
  • 64 except Exception as e:
  • 65 raise e
  • 66 # 断言页面的title
  • 67 def assertTitle(titleStr):
  • 68 try:
  • 69 assert titleStr in driver.title, "%s not found in title!" % titleStr
  • 70 except AssertionError as e:
  • 71 raise AssertionError(e)
  • 72 except Exception as e:
  • 73 raise e
  • 74
  • 75 # 断言目标字符串是否包含在页面源码中
  • 76 def assert_string_in_page_source(assertString):
  • 77 try:
  • 78 assert assertString in driver.page_source, "%s not found in page source!" % assertString
  • 79 except AssertionError as e:
  • 80 raise AssertionError(e)
  • 81 except Exception as e:
  • 82 raise e
  • 83
  • 84 # 获取当前页面的title
  • 85 def getTitle():
  • 86 try:
  • 87 return driver.title
  • 88 except Exception as e:
  • 89 raise e
  • 90
  • 91 # 获取页面源码
  • 92 def getPageSource():
  • 93 try:
  • 94 return driver.page_source
  • 95 except Exception as e:
  • 96 raise e
  • 97 # 切换到frame里面
  • 98 def switchToFrame(by, locator):
  • 99 try:
  • 100 driver.switch_to.frame(getElement(driver, by, locator))
  • 101 except Exception as e:
  • 102 raise e
  • 103
  • 104 # 跳到默认的frame
  • 105 def switchToDefault():
  • 106 try:
  • 107 driver.switch_to.default_content()
  • 108 except Exception as e:
  • 109 raise e
  • 110
  • 111 # 模拟ctrl+v键
  • 112 def ctrlV(value):
  • 113 try:
  • 114 Clipboard.setText(value)
  • 115 sleep(2)
  • 116 KeyBoardKeys.twoKeys('ctrl', 'v')
  • 117 except Exception as e:
  • 118 raise e
  • 119
  • 120 # 模拟tab键
  • 121 def tabKey():
  • 122 try:
  • 123 KeyBoardKeys.oneKey('tab')
  • 124 except Exception as e:
  • 125 raise e
  • 126
  • 127 # 模拟enter键
  • 128 def enterKey():
  • 129 try:
  • 130 KeyBoardKeys.oneKey('enter')
  • 131 except Exception as e:
  • 132 raise e
  • 133
  • 134 # 屏幕截图
  • 135 def saveScreenShot():
  • 136 pictureName = DirAndTime.CreatePicturePath() +'\\'+DirAndTime.getCurrentTime() + '.png'
  • 137 try:
  • 138 driver.get_screenshot_as_file(pictureName)
  • 139 except Exception as e:
  • 140 raise e
  • 141 else:
  • 142 return pictureName
  • 143
  • 144 def waitPresenceOfElementLocated(by, locator):
  • 145 '''
  • 146 显示等待页面元素出现在DOM中,单并不一定可见
  • 147 :param by:
  • 148 :param locator:
  • 149 :return:
  • 150 '''
  • 151 waitUtil.presenceOfElementLocated(by, locator)
  • 152
  • 153 def waitFrameToBeAvailableAndSwitchToIt(by, locator):
  • 154 '''
  • 155 检查frame是否存在,存在就切换到frame中
  • 156 :param by:
  • 157 :param locator:
  • 158 :return:
  • 159 '''
  • 160 waitUtil.frameToBeAvailableAndSwtichToIt(by, locator)
  • 161
  • 162 def waitVisibiltyOfElementLocated(by, locator):
  • 163 '''
  • 164 显示等待页面元素出现在DOM中,并且可见
  • 165 :param by:
  • 166 :param locator:
  • 167 :return:
  • 168 '''
  • 169 waitUtil.visibiltyOfElementLocated(by, locator)
  • 170
  • 171 # 关闭浏览器
  • 172 def quitBroswer():
  • 173 try:
  • 174 driver.quit()

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
by, locator)`

  • 161
  • 162 def waitVisibiltyOfElementLocated(by, locator):
  • 163 '''
  • 164 显示等待页面元素出现在DOM中,并且可见
  • 165 :param by:
  • 166 :param locator:
  • 167 :return:
  • 168 '''
  • 169 waitUtil.visibiltyOfElementLocated(by, locator)
  • 170
  • 171 # 关闭浏览器
  • 172 def quitBroswer():
  • 173 try:
  • 174 driver.quit()

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-Umi6x11Y-1713224656065)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值