先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
正文
6 def __init__(self, driver):
7 self.byDic = {
8 'id': By.ID,
9 'name': By.NAME,
10 'class_name': By.CLASS_NAME,
11 'xpath': By.XPATH,
12 'link_text': By.LINK_TEXT
13 }
14 self.driver = driver
15 self.wait = WebDriverWait(self.driver, 50)
16
17 def presenceOfElementLocated(self, by, locator):
18 '''
19 显示等待某个元素出现在dom中,不一定可见,存在返回元素对象
20 :param by:
21 :param locator:
22 :return:
23 '''
24 try:
25 if by.lower() in self.byDic:
26 self.wait.until(EC.presence_of_element_located((self.byDic[by.lower()], locator)))
27 else:
28 raise TypeError('未找到定位方式,请确保定位方式正确')
29 except Exception as e:
30 raise e
31
32 def frameToBeAvailableAndSwtichToIt(self, by, locator):
33 '''
34 检查frame是否存在,存在就切换到frame中
35 :param by:
36 :param locator:
37 :return:
38 '''
39 try:
40 if by.lower() in self.byDic:
41 self.wait.until(EC.frame_to_be_available_and_switch_to_it((self.byDic[by.lower()], locator)))
42 else:
43 raise TypeError('未找到定位方式,请确保定位方式正确')
44 except Exception as e:
45 raise e
46 def visibiltyOfElementLocated(self, by, locator):
47 '''
48 显示等待页面元素出现在dom中, 并且可见, 存在则返回该元素对象
49 :param by:
50 :param locator:
51 :return:
52 '''
53 try:
54 if by.lower() in self.byDic:
55 self.wait.until(EC.visibility_of_element_located((self.byDic[by.lower()], locator)))
56 else:
57 raise TypeError('未找到定位方式,请确保定位方式正确')
58 except Exception as e:
59 raise e
60
61 if __name__=='__main__':
62 from selenium import webdriver
63 from util.ObjectMap import *
64 driver = webdriver.Firefox()
65 driver.get('https://mail.126.com')
66
67 wait = WaitUnit(driver)
68 wait.frameToBeAvailableAndSwtichToIt('xpath', "//div[@id='loginDiv']/iframe")
69 wait.visibiltyOfElementLocated('xpath', "//input[@name='email']")
70 uname = getElement(driver, 'xpath', "//input[@name='email']")
71 uname.send_keys('python')
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 import win32api
2 import win32con
3
4 class KeyBoardKeys(object):
5 '''
6 模拟键盘
7 '''
8 # 键盘编码
9 vk_code ={
10 'enter':0x0D,
11 'tab' : 0x09,
12 'ctrl':0x11,
13 'v':0x56
14 }
15 @staticmethod
16 def keyDown(keyName):
17 '''
18 模拟按下键
19 :param keyName:
20 :return:
21 '''
22 try:
23 win32api.keybd_event(KeyBoardKeys.vk_code[keyName],0,0,0)
24 except Exception as e:
25 raise e
26 @staticmethod
27 def keyUp(keyName):
28 '''
29 释放键
30 :param keyName:
31 :return:
32 '''
33 try:
34 win32api.keybd_event(KeyBoardKeys.vk_code[keyName],0,win32con.KEYEVENTF_KEYUP,0)
35 except Exception as e:
36 raise e
37 @staticmethod
38 def oneKey(key):
39 '''
40 模拟当个按键
41 :param key:
42 :return:
43 '''
44 try:
45 KeyBoardKeys.keyDown(key)
46 KeyBoardKeys.keyUp(key)
47 except Exception as e:
48 raise e
49
50 @staticmethod
51 def twoKeys(key1, key2):
52 '''
53 模拟组合按键
54 :param key1:
55 :param key2:
56 :return:
57 '''
58 try:
59 KeyBoardKeys.keyDown(key1)
60 KeyBoardKeys.keyDown(key2)
61 KeyBoardKeys.keyUp(key1)
62 KeyBoardKeys.keyUp(key2)
63 except Exception as e:
64 raise e
65
66 if __name__=='__main__':
67 from selenium import webdriver
68
69 driver = webdriver.Firefox()
70 driver.get('http://www.baidu.com')
71 driver.find_element_by_id('kw').send_keys('python')
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 (备注软件测试)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!