软件测试最新软件测试项目实操【python+selenium自动化测试实战演练】,2024年最新面试流程4轮技术面+1轮HR

img
img
img

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

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

需要这份系统化的资料的朋友,可以戳这里获取

strhandle.py

 1 '''
 2 Code description: string handle
 3 Create time:
 4 Developer:
 5 '''
 6 
 7 import logging
 8 from retail.test_case.models.log import Logger
 9 
10 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
11 def strhandle(str):
12     """
13 
14     :param str:
15     :return:
16     """
17     #初始化字符、数字、空格、特殊字符的计数
18     try:
19         lowerCase = 0
20         upperCase = 0
21         number = 0
22         other = 0
23         for stritem in str:
24          #如果在字符串中有小写字母,那么小写字母的数量+1
25             if stritem.islower():
26                 lowerCase += 1
27             #如果在字符串中有数字,那么数字的数量+1
28             elif stritem.isdigit():
29                 number += 1
30             elif stritem.isupper():# 大写字母
31                 upperCase +=1
32             #如果在字符串中有空格,那么空格的数量+1
33             else:
34                 other += 1
35         return lowerCase, upperCase, number, other
36     except Exception as e:
37         log.logger.exception('string handle error , please check!', exc_info=True)
38         raise e
39 
40 
41 if __name__=='__main__':
42     list = ['qwert','erwer']
43     lowercase, uppercase, number, other = strhandle(list[0])
44     print ("该字符串中的小写字母有:%d" %lowercase)
45     print ("该字符串中的大写写字母有:%d" %uppercase)
46     print ("该字符串中的数字有:%d" %number)
47     print ("该字符串中的特殊字符有:%d" %other)

testreport.py

 1 '''
 2 Code description:test report
 3 Create time:
 4 Developer:
 5 '''
 6 
 7 
 8 import time
 9 import logging
10 import unittest
11 from BeautifulReport import BeautifulReport
12 import HTMLTestRunner
13 from retail.config import conf
14 from retail.test_case.models.log import Logger
15 
16 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
17 # 用HTMLTestRunner 实现的测试报告
18 def testreport():
19     """
20 
21     :return:
22     """
23     currTime = time.strftime('%Y-%m-%d %H_%M_%S')
24     fileName = conf.reportPath + r'\report' + currTime + '.html'
25     try:
26         fp = open(fileName, 'wb')
27     except Exception :
28         log.logger.exception('[%s] open error cause Failed to generate test report' %fileName)
29     else:
30         runner = HTMLTestRunner.HTMLTestRunner\
31             (stream=fp, title='Retail sys测试报告',
32                                                description='处理器:Intel(R) Core(TM) '
33                                                            'i5-6200U CPU @ 2030GHz 2.40 GHz '
34                                                 '内存:8G 系统类型: 64位 版本: windows 10 家庭中文版')
35         log.logger.info('successed to generate test report [%s]' %fileName)
36         return runner, fp, fileName
37 #
38 def addTc(TCpath = conf.tcPath, rule = '*TC.py'):
39     """
40 
41     :param TCpath: 测试用例存放路径
42     :param rule: 匹配的测试用例文件
43     :return:  测试套件
44     """
45     discover = unittest.defaultTestLoader.discover(TCpath, rule)
46 
47     return discover
48 # 用BeautifulReport模块实现测试报告
49 def runTc(discover):
50     """
51 
52     :param discover: 测试套件
53     :return:
54     """
55     currTime = time.strftime('%Y-%m-%d %H_%M_%S')
56     fileName = currTime+'.html'
57     try:
58         result = BeautifulReport(discover)
59         result.report(filename=fileName, description='测试报告', log_path=conf.reportPath)
60     except Exception:
61         log.logger.exception('Failed to generate test report', exc_info=True)
62     else:
63         log.logger.info('successed to generate test report [%s]' % fileName)
64         return fileName
65 
66 if __name__ == '__main__':
67     testreport()
68     suite = addTc(rule = '*TC.py')
69     runTc(suite)

driver.py

 1 '''
 2 Code description:save all driver info
 3 Create time:
 4 Developer:
 5 '''
 6 
 7 from selenium import webdriver
 8 import logging
 9 import sys
10 from retail.test_case.models.log import Logger
11 
12 
13 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
14 class WDriver(object):
15 
16     # Firefox driver
17     def fireFoxDriver(self):
18         """
19 
20         :return:
21         """
22         try:
23             self.driver = webdriver.Firefox()
24         except Exception as e:
25             log.logger.exception('FireFoxDriverServer.exe executable needs to be in PATH. Please download!', exc_info=True)
26             raise e
27         else:
28             log.logger.info('%s:found the Firefox driver [%s] successed !' %(sys._getframe().f_code.co_name,self.driver))
29             return self.driver
30 
31     # chrom driver
32     def chromeDriver(self):
33         """
34 
35         :return:
36         """
37         try:
38             # option = webdriver.ChromeOptions()# 实现不打开浏览器 执行web自动化测试脚本
39             # option.add_argument('headless')#
40             # self.driver = webdriver.Chrome(chrome_options=option)
41             self.driver = webdriver.Chrome()
42         except Exception as e:
43             log.logger.exception('ChromeDriverServer.exe executable needs to be in PATH. Please download!',
44                                  exc_info=True)
45             raise e
46         else:
47             log.logger.info('%s:found the chrome driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver))
48             return self.driver
49 
50 
51     # Ie driver
52     def ieDriver(self):
53         """
54 
55         :return:
56         """
57         try:
58             self.driver = webdriver.Ie()
59         except Exception as e:
60             log.logger.exception('IEDriverServer.exe executable needs to be in PATH. Please download!',
61                                  exc_info=True)
62             raise e
63         else:
64             log.logger.info('%s:found the IE driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver))
65             return self.driver
66 
67 
68 if __name__ == '__main__':
69     WDrive=WDriver()
70     WDrive.fireFoxDriver()

myunittest.py

 1 '''
 2 Code description:unittest framwork
 3 Create time:
 4 Developer:
 5 '''
 6 
 7 from retail.test_case.models.driver import WDriver
 8 import logging
 9 import unittest
10 from retail.test_case.page_obj.login_page import LoginPage
11 from retail.test_case.models.log import Logger
12 from selenium import webdriver
13 
14 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
15 class MyunitTest(unittest.TestCase):
16     """
17 
18     """
19 
20     # add by xuechao at 2018.09.19
21     @classmethod
22     def setUpClass(cls): # 一个测试类(文件)执行一次打开浏览器, 节约每个用例打开一次浏览器的时间
23 
24         #cls.driver = WDriver().fireFoxDriver()
25         cls.driver = WDriver().chromeDriver()
26         cls.driver.maximize_window()
27         log.logger.info('opened the browser successed!')
28     # ----------------------------
29 
30     def setUp(self):
31         """
32 
33         :return:
34         """
35         self.login = LoginPage(self.driver)
36         self.login.open()
37         log.logger.info('************************starting run test cases************************')
38 
39     def tearDown(self):
40         """
41 
42         :return:
43         """
44         self.driver.refresh()
45         log.logger.info('************************test case run completed************************')
46 
47     # add by linuxchao at 2018.09.19
48     @classmethod
49     def tearDownClass(cls):
50         cls.driver.quit()
51         log.logger.info('quit the browser success!')
52     #----------------------------
53 if __name__ == '__main__':
54     unittest.main()

目前为止,我需要的所有的公共方法都编写完了, 后期再需要别的方法可以加,下面我们就开始编写我们的测试用例,由于我们使用的是PageObject模式,那么我们需要设计一个basepage页面,所有的页面或者说模块全部继承这个basepage,basepage主要编写所有页面的公共方法

  1 '''
  2 Code description: base page 封装一些公共方法
  3 Create time:
  4 Developer:
  5 '''
  6 from selenium.webdriver.support.wait import WebDriverWait
  7 from selenium.webdriver.support import expected_conditions as EC
  8 from selenium.webdriver.common.by import By
  9 import os
 10 import logging
 11 import sys
 12 from retail.test_case.models.log import Logger
 13 from retail.config import conf
 14 from retail.test_case.models.doexcel import ReadExcel
 15 
 16 eleData = ReadExcel() # 存储系统所有的元素数据
 17 testLoginData = ReadExcel('elementDate.xlsx', 'userNamePw') # 登录模块测试数据
 18 modifyPwData = ReadExcel('elementDate.xlsx', 'modifyPw') # 修改密码模块测试数据
 19 queryData = ReadExcel('elementDate.xlsx', 'queryData')
 20 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
 21 
 22 class BasePage(object):
 23 
 24     """主菜单"""
 25     menuList = \
 26         [(By.LINK_TEXT, eleData.readExcel(7, 3)), # 权限管理
 27         (By.LINK_TEXT, eleData.readExcel(8, 3)), # 会员档案
 28         (By.LINK_TEXT, eleData.readExcel(9, 3)), # 积分消费查询
 29         (By.LINK_TEXT, eleData.readExcel(10, 3)), # 功能演示
 30         (By.LINK_TEXT, eleData.readExcel(11, 3)), # 待办工作
 31         (By.LINK_TEXT, eleData.readExcel(12, 3)), # 报表
 32         (By.LINK_TEXT, eleData.readExcel(13, 3)), # 积分规则/活动查询
 33         (By.LINK_TEXT, eleData.readExcel(14, 3))] # 积分规则/活动申请
 34 
 35     def __init__(self, driver,url='http://11.11.164.134:9081/rmms/modules/ep.rmms.portal/login/login.jsp'):
 36         """
 37 
 38         :param driver:
 39         :param url:
 40         """
 41         self.driver = driver
 42         self.base_url = url
 43     def _open(self,url):
 44         """
 45 
 46         :param url:
 47         :return:
 48         """
 49         try:
 50             self.driver.get(url)
 51             self.driver.implicitly_wait(10)
 52         except Exception as e:
 53             log.logger.exception(e, exc_info=True)
 54             raise ValueError('%s address access error, please check!' %url)
 55         else:
 56             log.logger.info('%s is accessing address %s at line[46]' %(sys._getframe().f_code.co_name,url))
 57 
 58     def open(self):
 59         """
 60 
 61         :return:
 62         """
 63 
 64         self._open(self.base_url)
 65         log.logger.info('%s loading successed!' %self.base_url)
 66         return self.base_url
 67 
 68     # *loc 代表任意数量的位置参数
 69     def findElement(self, *loc):
 70         """
 71         查找单一元素
 72         :param loc:
 73         :return:
 74         """
 75         try:
 76             WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))
 77             # log.logger.info('The page of %s had already find the element %s'%(self,loc))
 78             # return self.driver.find_element(*loc)
 79         except Exception as e:
 80             log.logger.exception('finding element timeout!, details' ,exc_info=True)
 81             raise e
 82         else:
 83             log.logger.info('The page of %s had already find the element %s' % (self, loc))
 84             return self.driver.find_element(*loc)
 85 
 86     def findElements(self, *loc):
 87         """
 88         查找一组元素
 89         :param loc:
 90         :return:
 91         """
 92         try:
 93             WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))
 94             # log.logger.info('The page of %s had already find the element %s' % (self, loc))
 95             # return self.driver.find_elements(*loc)
 96         except Exception as e:
 97             log.logger.exception('finding element timeout!, details', exc_info=True)
 98             raise e
 99         else:
100             log.logger.info('The page of %s had already find the element %s' % (self, loc))
101             return self.driver.find_elements(*loc)
102 
103     def inputValue(self, inputBox, value):
104         """
105         后期修改其他页面直接调用这个函数
106         :param inputBox:
107         :param value:
108         :return:
109         """
110         inputB = self.findElement(*inputBox)
111         try:
112             inputB.clear()
113             inputB.send_keys(value)
114         except Exception as e:
115             log.logger.exception('typing value error!', exc_info=True)
116             raise e
117         else:
118             log.logger.info('inputValue:[%s] is receiveing value [%s]' % (inputBox, value))
119 
120     # 获取元素数据
121     def getValue(self, *loc):
122         """
123 
124         :param loc:
125         :return:
126         """
127         element = self.findElement(*loc)
128         try:
129             value = element.text
130             #return value
131         except Exception:
132             #element = self.find_element_re(*loc) # 2018.09.21 for log
133             value = element.get_attribute('value')
134             log.logger.info('reading the element [%s] value [%s]' % (loc, value))
135             return value
136         except:
137             log.logger.exception('read value failed', exc_info=True)
138             raise Exception
139         else:
140             log.logger.info('reading the element [%s] value [%s]' % (loc,value))
141             return value
142 
143     def getValues(self, *loc):
144         """
145 
146         :param loc:
147         :return:
148         """
149         value_list = []
150         try:
151             for element in self.findElements(*loc):
152                 value = element.text
153                 value_list.append(value)
154         except Exception as e:
155             log.logger.exception('read value failed', exc_info=True)
156             raise e
157         else:
158             log.logger.info('reading the element [%s] value [%s]'% (loc,value_list))
159             return value_list
160 
161     # 执行js脚本
162     def jScript(self,src):
163         """
164 
165         :param src:
166         :return:
167         """
168         try:
169             self.driver.excute_script(src)
170         except Exception as e:
171             log.logger.exception('execute js script [%s] failed ' %src)
172             raise e
173         else:
174             log.logger.info('execute js script [%s] successed ' %src)
175 
176 
177     # 判断元素是否存在
178     def isElementExist(self, element):
179         """
180 
181         :param element:
182         :return:
183         """
184         try:
185             WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(element))
186         except:
187             # log.logger.exception('The element [%s] not exist', exc_info=True)
188             return False
189         else:
190             # log.logger.info('The element [%s] have existed!' %element)
191             return True
192     # 截图
193     def saveScreenShot(self, filename):
194         """
195 
196         :param filename:
197         :return:
198         """
199         list_value = []
200 
201         list = filename.split('.')
202         for value in list:
203             list_value.append(value)
204         if list_value[1] == 'png' or list_value[1] == 'jpg' or list_value[1] == 'PNG' or list_value[1] == 'JPG':
205             if 'fail' in list_value[0].split('_'):
206                 try:
207                     self.driver.save_screenshot(os.path.join(conf.failImagePath, filename))
208                 except Exception:
209                     log.logger.exception('save screenshot failed !', exc_info=True)
210                 else:
211                     log.logger.info('the file [%s]  save screenshot successed under [%s]' % (filename, conf.failImagePath))
212             elif 'pass' in list_value[0]:
213                 try:
214                     self.driver.save_screenshot(os.path.join(conf.passImagePath, filename))
215                 except Exception:
216                     log.logger.exception('save screenshot failed !', exc_info=True)
217                 else:
218                     log.logger.info(
219                         'the file [%s]  save screenshot successed under [%s]' % (filename, conf.passImagePath))
220             else:
221                 log.logger.info('save screenshot failed due to [%s] format incorrect' %filename)
222         else:
223             log.logger.info('the file name of [%s] format incorrect cause save screenshot failed, please check!' % filename)
224 
225     # 接受错误提示框
226     def accept(self, *loc):
227         """
228 
229         :return:
230         """
231         self.findElement(*loc).click()
232         log.logger.info('closed the error information fram successed!')
233 
234 if __name__ == '__main__':
235     pass
登录页面
 1 '''
 2 Code description: login page
 3 Create time:
 4 Developer:
 5 '''
 6 
 7 from selenium.webdriver.common.by import By
 8 import logging
 9 import sys
10 from retail.test_case.page_obj.base_page import BasePage, eleData, testLoginData
11 from retail.test_case.models.log import Logger
12 
13 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
14 
15 
16 class LoginPage(BasePage):
17 
18     """用户名,密码,登录按钮,保存信息,错误提示"""
19     userNameEle = (By.ID, eleData.readExcel(1, 3))
20     passWordEle = (By.ID, eleData.readExcel(2, 3))
21     loginBtnEle = (By.ID, eleData.readExcel(3, 3))
22     saveInfoEle = (By.NAME, eleData.readExcel(4, 3))
23     errorMessage = (By.ID, eleData.readExcel(5, 3))
24     quitBtn = (By.ID, eleData.readExcel(6, 3))
25 
26     # 用户名和密码
27     unpwData = \
28         [[testLoginData.readExcel(1, 0), testLoginData.readExcel(1, 1)],# 正确的用户名和正确的密码
29          [testLoginData.readExcel(2, 0), testLoginData.readExcel(2, 1)],# 错误的用户名和正确的密码
30          [testLoginData.readExcel(3, 0), testLoginData.readExcel(3, 1)],# 空的用户名和正确的密码
31          [testLoginData.readExcel(4, 0), testLoginData.readExcel(4, 1)],# 错误的用户名和错误的密码
32          [testLoginData.readExcel(5, 0), testLoginData.readExcel(5, 1)],# 正确的用户名和空密码
33          [testLoginData.readExcel(6, 0), testLoginData.readExcel(6, 1)],# 正确的用户名和错误的密码
34          [testLoginData.readExcel(7, 0), testLoginData.readExcel(7, 1)]]# 空用户名和空密码
35 
36 
37     # 登录按钮
38     def clickLoginBtn(self):
39         """
40 
41         :return:
42         """
43         element = self.findElement(*self.loginBtnEle)
44         element.click()
45         log.logger.info('%s ,logining....!' % sys._getframe().f_code.co_name)
46     # 登录失败时提示
47     def getFailedText(self):
48         """
49 
50         :return:
51         """
52         info = self.findElement(*self.errorMessage).text
53         log.logger.info('login failed : %s' %info)
54         return info
55 
56     # 登录失败时弹出的alert
57     def handleAlert(self):
58         """
59 
60         :return:
61         """
62         try:
63             alert = self.driver.switch_to_alert()
64             text = alert.text
65             alert.accept()
66         except Exception:
67             log.logger.exception('handle alert failed, please check the details' ,exc_info=True)
68             raise
69         else:
70             log.logger.info('login failed ,%s handle alert successed alert info: %s!' %(sys._getframe().f_code.co_name, text))
71             return text
72 
73     # 统一登录函数
74     def loginFunc(self, username='rmln', password='qwert1234!@#'):
75         """
76         :param username:
77         :param password:
78         :return:
79         """
80         self.inputValue(self.userNameEle, username)
81         self.inputValue(self.passWordEle, password)
82         self.clickLoginBtn()
83 
84     # 清空输入框数据
85     def clearValue(self, element):
86 
87         empty = self.findElement(*element)
88         empty.clear()
89         log.logger.info('emptying value.......')
90 
91 
92     # 推出
93     def quit(self):
94         self.findElement(*self.quitBtn).click()
95         log.logger.info('quit')
96 
97 if __name__ == '__main__':
98     pass
登录测试用例
  1 """
  2 Code description:login testcase
  3 Create time:
  4 Developer:
  5 """
  6 
  7 import unittest
  8 import time
  9 import logging
 10 import sys
 11 from retail.test_case.models.myunit import MyunitTest
 12 from retail.test_case.models.log import Logger
 13 
 14 
 15 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
 16 
 17 class Login_TC(MyunitTest):
 18 
 19     """登录模块测试用例"""
 20 
 21     def test_login_success_correct_username_password(self):
 22         """用户名正确,密码正确,登录成功"""
 23         self.login.loginFunc()
 24         currUrl = self.driver.current_url # 获取当前的url地址
 25         try:
 26             self.assertIn('main', currUrl, 'main not in current url!')
 27         except Exception:
 28             self.login.saveScreenShot('correct_username_password_fail.png')
 29             raise
 30         else:
 31             self.login.saveScreenShot('correct_username_password_pass.png')
 32             log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 33 
 34     def test_login_failed_incorrect_username(self):
 35         """用户名错误,密码正确,登录失败"""
 36 
 37         self.login.loginFunc(self.login.unpwData[1][0], self.login.unpwData[1][1])
 38         failText = self.login.getFailedText()
 39         self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')
 40         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 41 
 42     def test_login_failed_incorrect_password(self):
 43 
 44         """用户名正确,密码错误,登录失败"""
 45 
 46         self.login.loginFunc(self.login.unpwData[5][0], self.login.unpwData[5][1])
 47         failText = self.login.getFailedText()
 48         self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')
 49         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 50 
 51     def test_login_failed_username_password_blank(self):
 52         """用户名为空,密码为空,登录失败"""
 53 
 54         self.login.loginFunc(self.login.unpwData[6][0], self.login.unpwData[6][1])
 55         failText = self.login.handleAlert() # 获取alert的提示信息
 56         self.assertEqual('请填写用户名', failText, '提示信息错误')
 57         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 58 
 59     def test_login_failed_password_blank(self):
 60         """用户名正确,密码为空,登录失败"""
 61 
 62         self.login.loginFunc(self.login.unpwData[4][0], self.login.unpwData[4][1])
 63         failText = self.login.handleAlert() # 获取alert的提示信息
 64         self.assertEqual('请填写用户密码', failText, '提示信息错误')
 65         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 66 
 67     def test_login_failed_unpw_incorrect(self):
 68         """用户名错误,密码错误,登录失败"""
 69         # try:
 70         self.login.loginFunc(self.login.unpwData[3][0], self.login.unpwData[4][0])
 71         failText = self.login.getFailedText()
 72         self.assertEqual ('输入的用户名或密码错误,请重新输入!', failText, 'failed')
 73         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
 74 
 75     def test_login(self):
 76         """循环测试登录功能"""
 77         for listitem in self.login.unpwData:
 78             self.login.inputValue(self.login.userNameEle,listitem[0])
 79             time.sleep(2)
 80             self.login.inputValue(self.login.passWordEle,listitem[1])
 81             time.sleep(2)
 82             self.login.clickLoginBtn()
 83             time.sleep(2)
 84             if listitem[0] =='rmln' and listitem[1] == 'qwert1234!@#':
 85                 currUrl = self.driver.current_url
 86                 self.assertIn ('main' , currUrl)
 87                 self.login.quit()
 88             elif listitem[0] == 'rmln' and listitem[1] != 'qwert1234!@#':
 89                 if listitem[1] == '':
 90                     failText = self.login.handleAlert()  # 获取alert的提示信息
 91                     self.assertEqual('请填写用户密码', failText, '提示信息错误')
 92                 else:
 93                     failText = self.login.getFailedText()
 94                     self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')
 95             elif listitem[0] != 'rmln' and listitem[1] == 'qwert1234!@#':
 96                 if listitem[0]=='':
 97                     failText = self.login.handleAlert()  # 获取alert的提示信息
 98                     self.assertEqual('请填写用户名', failText, '提示信息错误')
 99                 else:
100                     failText = self.login.getFailedText()
101                     self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')
102             elif listitem[0] == listitem[1] == '':
103                 failText = self.login.handleAlert()  # 获取alert的提示信息
104                 self.assertEqual('请填写用户名', failText, '提示信息错误')
105             else:
106                 failText = self.login.getFailedText()
107                 self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')
108         log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))
109 
110 if __name__ == '__main__':
111     unittest.main()
修改密码页面
1 '''
  2 Code description:modify password page
  3 Create time:
  4 Developer:
  5 '''
  6 
  7 import logging
  8 import time
  9 from selenium.webdriver.common.by import By
 10 from selenium.webdriver.common.action_chains import ActionChains
 11 from retail.test_case.page_obj.base_page import BasePage, eleData, modifyPwData
 12 from retail.test_case.models.log import Logger
 13 
 14 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
 15 class PrimaryMenu(BasePage):
 16 
 17     """密码数据"""
 18     pwdList = \
 19         [[modifyPwData.readExcel(1, 0), modifyPwData.readExcel(1, 1), modifyPwData.readExcel(1, 2)],
 20          [modifyPwData.readExcel(2, 0), modifyPwData.readExcel(2, 1), modifyPwData.readExcel(2, 2)],
 21          [modifyPwData.readExcel(3, 0), modifyPwData.readExcel(3, 1), modifyPwData.readExcel(3, 2)],
 22          [modifyPwData.readExcel(4, 0), modifyPwData.readExcel(4, 1), modifyPwData.readExcel(4, 2)],
 23          [modifyPwData.readExcel(5, 0), modifyPwData.readExcel(5, 1), modifyPwData.readExcel(5, 2)]]
 24 
 25     """权限管理下拉菜单"""
 26     menuPersonal = (By.LINK_TEXT, eleData.readExcel(15, 3))
 27     menuModifyPwd = (By.LINK_TEXT, eleData.readExcel(16, 3))
 28 
 29     """密码修改"""
 30     oldPwd = (By.ID, eleData.readExcel(17, 3))
 31     newPwd = (By.ID, eleData.readExcel(18, 3))
 32     commitPwd = (By.ID, eleData.readExcel(19, 3))
 33 
 34     """错误提示框及确定"""
 35     errMessage = (By.XPATH, eleData.readExcel(20, 3))
 36     closeBtn = (By.CSS_SELECTOR, eleData.readExcel(21, 3))
 37 
 38     """密码说明"""
 39     readMe = (By.ID, eleData.readExcel(22, 3))
 40 
 41     """保存"""
 42     saveBtn = (By.XPATH, eleData.readExcel(23, 3))
 43 
 44     #   主菜单
 45     def findMenu(self,*menuList):
 46         """
 47 
 48         :param menu_list:
 49         :return:
 50         """
 51         return self.findElement(*menuList)
 52 
 53     #   旧密码输入框
 54     def inputOldPw(self, oldPwd=''):
 55         """"""
 56         try:
 57             self.findElement(*self.oldPwd).clear()
 58             self.findElement(*self.oldPwd).send_keys(oldPwd)
 59         except Exception:
 60             log.logger.exception('input Pw [%s] for oldPw [%s] fail' %(oldPwd, self.oldPwd))
 61             raise
 62         else:
 63             log.logger.info('inputing Pw [%s] for oldPw [%s] ' % (oldPwd, self.oldPwd))
 64     #   新密码输入框
 65     def inputNewPw(self, newPwd=''):
 66         """
 67 
 68         :param newPwd:
 69         :return:
 70         """
 71         try:
 72             self.findElement(*self.newPwd).clear()
 73             self.findElement(*self.newPwd).send_keys(newPwd)
 74         except Exception:
 75             log.logger.exception('input Pw [%s] for newPw [%s] fail' % (newPwd, self.newPwd))
 76             raise
 77         else:
 78             log.logger.info('inputing Pw [%s] for newPw [%s] ' % (newPwd, self.newPwd))
 79     #   确认密码输入框
 80     def inputConfirmPw(self, confirmPwd=''):
 81         """
 82 
 83         :param confirmPwd:
 84         :return:
 85         """
 86         try:
 87             self.findElement(*self.commitPwd).clear()
 88             self.findElement(*self.commitPwd).send_keys(confirmPwd)
 89         except Exception:
 90             log.logger.exception('input Pw [%s] for commitPw [%s] fail' %(confirmPwd, self.commitPwd))
 91             raise
 92         else:
 93             log.logger.info('inputing Pw [%s] for commitPw [%s] ' %(confirmPwd, self.commitPwd))
 94     #   保存
 95     def saveButton(self):
 96         """
 97 
 98         :return:
 99         """
100         try:
101             self.driver.implicitly_wait(5)
102             clickbutton = self.findElement(*self.saveBtn)
103             time.sleep(1)
104             clickbutton.click()
105         except Exception:
106             log.logger.exception('click save button fail')
107             raise
108         else:
109             log.logger.info('clciking the button')
110 
111     #   修改密码功能菜单
112     def modifyPwMenu(self):
113         """
114 
115         :return:
116         """
117         try:
118             self.findElement(*self.menuList[0]).click()
119             self.findElement(*self.menuPersonal).click()
120             self.findElement(*self.menuModifyPwd).click()
121         except Exception:
122             log.logger.exception('not found menu [%s]-[%s]-[%s]' %(self.menuList[0], self.menuPersonal, self.menuModifyPwd))
123             raise
124         else:
125             log.logger.info('finding menu [%s]-[%s]-[%s]' %(self.menuList[0], self.menuPersonal, self.menuModifyPwd))
126             self.driver.implicitly_wait(2)
127 
128     #   修改密码
129     def modifyPw(self, list):
130         """
131 
132         :param list:
133         :return:
134         """
135         try:
136             self.inputOldPw(list[0])
137             self.inputNewPw(list[1])
138             self.inputConfirmPw(list[2])
139             self.saveButton()
140         except Exception:
141             log.logger.exception('input oldpw/newpw/commitpw [%s]/[%s]/[%s] fail' %(list[0], list[1], list[2]))
142             raise
143         else:
144             log.logger.info('modifing pw [%s]/[%s]/[%s]' %(list[0], list[1], list[2]))
145 
146     #   错误提示框
147     def errorDialog(self, commit_btn = (By.ID,'unieap_form_Button_1_unieap_input')):
148         """
149         :type commit_btn: 元祖
150         """
151 
152         try:
153             messages_frame = self.findElement(*self.errMessage)
154             text = messages_frame.text
155             element = self.findElement(*commit_btn)
156             time.sleep(2)
157             action = ActionChains(self.driver)
158             action.move_to_element(element).perform()
159             time.sleep(2)
160             element.click()
161             action.reset_actions() # 释放鼠标
162         except Exception:
163             log.logger.exception('close errMsgFram [%s] or get text [%s]fail' %(self.errMessage))
164             raise
165         else:
166             log.logger.info('close errMsgFram [%s] and get text [%s] success' %(self.errMessage, text))
167             return text
168 
169     # 关闭提示框
170     def closeErrMsg(self, element):
171         try:
172             ele = self.findElement(*element)
173             action = ActionChains(self.driver)
174             action.move_to_element(ele).perform()
175             time.sleep(2)
176             ele.click()
177             action.reset_actions()
178         except Exception:
179             log.logger.exception('close the err msg ifram fail', exc_info=True)
180             raise
181         else:
182             log.logger.info('closing the err msg ifram success!')
183 
184 if __name__ == '__main__':
185     pass
修改密码测试用例
1 '''
  2 Code description:权限管理/个人设置/密码修改 testcase
  3 Create time:
  4 Developer:
  5 '''
  6 
  7 import time
  8 from retail.test_case.models.myunit import MyunitTest
  9 from retail.test_case.page_obj.modifypw_page import PrimaryMenu
 10 from retail.test_case.models.strhandle import strhandle
 11 
 12 class ModifyPw_TC(MyunitTest):
 13 
 14     """权限管理/个人设置/密码修改模块测试用例"""
 15 
 16     def test_menu_is_display(self):
 17         """主菜单校验"""
 18         self.login.loginFunc()
 19         menu = PrimaryMenu(self.driver)
 20         time.sleep(4)
 21         num = 0
 22         for menu_item in menu.menuList: # 循环遍历并断言菜单是否正确
 23             self.assertEqual(menu.menuList[num][1],(menu.findMenu(*menu_item).text),'菜单不存在')
 24             num=num+1
 25 
 26     def test_modify_password_len(self):
 27         """旧密码非空,新密码长度小于4位,确认密码非空,修改密码失败,弹窗提示"""
 28         self.login.loginFunc()
 29         menu = PrimaryMenu(self.driver)
 30         menu.modifyPwMenu() # 查找修改密码页面
 31         menu.modifyPw(menu.pwdList[0]) # 修改密码
 32         text = menu.errorDialog(menu.closeBtn)
 33         self.assertIn('密码长度至少 4 位!', text, '提示信息错误') # 密码长度不满足时断言提示信息
 34 
 35     def test_modify_password_strebgth(self):
 36         """旧密码非空,新密码长度大于4且强度不够,确认密码非空,修改密码失败,弹窗提示"""
 37         self.login.loginFunc()
 38         menu = PrimaryMenu(self.driver)
 39         menu.modifyPwMenu() # 查找修改密码页面
 40         menu.modifyPw(menu.pwdList[1]) # 修改密码
 41         text = menu.errorDialog(menu.closeBtn)
 42         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!') # 密码强度不满足时断言提示信息
 43 
 44     def test_modify_password_incorrect(self):
 45         """旧密码不正确非空,新密码等于确认密码且满足条件,修改密码失败,弹窗提示"""
 46         self.login.loginFunc()
 47         menu = PrimaryMenu(self.driver)
 48         menu.modifyPwMenu() # 查找修改密码页面
 49         menu.modifyPw(menu.pwdList[2]) # 修改密码
 50         text = menu.errorDialog(menu.closeBtn)
 51         self.assertIn('旧密码输入错误!', text, '旧密码输入错误!') # 新密码和确认码不同时断言提示信息
 52 
 53     def test_modify_password_difference(self):
 54         """旧密码非空,新密码不等于确认密码且新密码满足条件,修改密码失败,弹窗提示"""
 55         self.login.loginFunc()
 56         menu = PrimaryMenu(self.driver)
 57         menu.modifyPwMenu() # 查找修改密码页面
 58         menu.modifyPw(menu.pwdList[3]) # 修改密码
 59         text = menu.errorDialog(menu.closeBtn)
 60         self.assertIn('两次输入的新密码不同!', text, '两次输入的新密码不同!') # 新密码和确认码不同时断言提示信息
 61 
 62     def test_modify_password_all_blank(self):
 63         """旧密码,新密码,确认密码任意为空,修改密码失败,弹窗提示"""
 64         self.login.loginFunc()
 65         menu = PrimaryMenu(self.driver)
 66         menu.modifyPwMenu() # 查找修改密码页面
 67         menu.modifyPw(menu.pwdList[4]) # 修改密码
 68         text = menu.errorDialog(menu.closeBtn)
 69         self.assertIn('该输入项的值不能为空!', text, ' 该输入项的值不能为空!') # 所有密码均为空时断言提示信息
 70 
 71     def test_modify_password(self):
 72         """循环校验提示信息"""
 73         self.login.loginFunc()
 74         menu = PrimaryMenu(self.driver)
 75         menu.modifyPwMenu() # 查找修改密码页面
 76         error_list = []
 77         for list in range(len(menu.pwdList)):
 78             menu.modifyPw(menu.pwdList[list])
 79             if menu.isElementExist(menu.errMessage):
 80                 text = menu.errorDialog(menu.closeBtn) # 这里只判断是否有提示框弹出,如有说明修改失败,没有或者其他提示框默认为修改成功
 81                 error_list.append(text)
 82             else:
 83                 self.assertTrue(menu.isElementExist(*menu.errMessage), 'error fram not exist, please open bug')
 84         self.assertEqual('密码长度至少 4 位!',error_list[0],'log infomation error!')
 85         self.assertEqual('密码强度不够,请重新输入密码!', error_list[1], 'log infomation error!')
 86         self.assertEqual('旧密码输入错误!', error_list[2], 'log infomation error!')
 87         self.assertEqual('两次输入的新密码不同!', error_list[3], 'log infomation error!')
 88         self.assertEqual('该输入项的值不能为空!', error_list[4], 'log infomation error!')
 89 
 90     def test_modifypw(self):
 91         """循环测试修改密码功能"""
 92         self.login.loginFunc()# 登录
 93         menu = PrimaryMenu(self.driver)
 94         menu.modifyPwMenu()  # 查找修改密码页面
 95         for item in menu.pwdList:
 96             menu.modifyPw(item)
 97             if menu.isElementExist(menu.errMessage):  # 如果存在提示框 再断言提示信息是否正确
 98                 if item[0] != '' and len(item[1]) < 4  and item[2] !='': # 新密码长度校验
 99                     text = menu.errorDialog(menu.closeBtn)
100                     try:
101                         self.assertEqual('密码长度至少 4 位!',text,'the message incorrect!')
102                     except Exception:
103                         menu.saveScreenShot('fail_密码长度.png')
104                         raise
105                 elif item[0] != '' and len(item[1]) >= 4 and item[2] !='': # 新密码强度校验 ['a', 'qwert', 'qwert'],
106                     lowercase, uppercase, number, other=strhandle(item[1])
107                     if lowercase > 0 and uppercase > 0 and number == 0 and other == 0: # 小写 大写
108                         text = menu.errorDialog(menu.closeBtn)
109                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
110                     elif uppercase > 0 and other > 0 and number == 0 and lowercase == 0: # 大写 特殊字符
111                         text = menu.errorDialog(menu.closeBtn)
112                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
113                     elif lowercase >0 and other > 0 and number == 0 and uppercase == 0: # 小写 特殊字符
114                         text = menu.errorDialog(menu.closeBtn)
115                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
116                     elif lowercase == 0 and other == 0 and number > 0 and uppercase > 0:  # 大写 数字
117                         text = menu.errorDialog(menu.closeBtn)
118                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
119                     elif lowercase > 0 and other == 0 and number > 0 and uppercase == 0:  # 小写 数字
120                         text = menu.errorDialog(menu.closeBtn)
121                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
122                     elif lowercase > 0 and other == 0 and number == 0 and uppercase == 0:
123                         text = menu.errorDialog(menu.closeBtn)
124                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
125                     elif lowercase == 0 and other > 0 and number == 0 and uppercase == 0:
126                         text = menu.errorDialog(menu.closeBtn)
127                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
128                     elif lowercase == 0 and other == 0 and number > 0 and uppercase == 0:
129                         text = menu.errorDialog(menu.closeBtn)
130                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
131                     elif lowercase == 0 and other == 0 and number == 0 and uppercase > 0:
132                         text = menu.errorDialog(menu.closeBtn)
133                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')
134                     elif item[0] != 'qwert1234!@#' and item[1] == item[2]:# >= 4
135                         lowercase, uppercase, number, other = strhandle(item[1])
136                         if (lowercase > 0 and uppercase > 0 and number > 0) or (
137                                     lowercase > 0 and uppercase > 0 and other > 0) or (
138                                     number > 0 and other > 0 and lowercase > 0) or (
139                                     number > 0 and other > 0 and uppercase > 0):
140                             text = menu.errorDialog(menu.closeBtn)
141                             self.assertIn('旧密码输入错误!', text, '旧密码输入错误!')  # 新密码和确认码不同时断言提示信息
142                     elif item[0] == 'qwert1234!@#$' and item[1] != item[2]:# and item[1] >= 4:
143                         lowercase, uppercase, number, other = strhandle(item[1])
144                         if (lowercase > 0 and uppercase > 0 and number > 0) or (
145                                             lowercase > 0 and uppercase > 0 and other > 0) or (
146                                             number > 0 and other > 0 and lowercase > 0) or (
147                                             number > 0 and other > 0 and uppercase > 0):
148                             text = menu.errorDialog(menu.closeBtn)
149                             self.assertIn('两次输入的新密码不同!', text, ' 两次输入的新密码不同!')
150                     else:
151                         print('test value incorrect! please check it')
152                 elif item[0] == '' or item[1] =='' or item[2] =='': # 输入项为空校验
153                     text = menu.errorDialog(menu.closeBtn)
154                     self.assertIn('该输入项的值不能为空!', text, ' 该输入项的值不能为空!')  # 所有密码均为空时断言提示信息
155             else:
156                 self.assertTrue(menu.isElementExist(menu.errMessage), 'error fram not exist, please check the test value or file bug')
157 
158 if __name__=='__main__':
159     pass
会员档案查询页面
 1 '''
  2 Code description:会员档案查询 page
  3 Create time:
  4 Developer:
  5 '''
  6 
  7 from retail.test_case.page_obj.base_page import queryData
  8 import time
  9 from selenium.webdriver.common.by import By
 10 import logging
 11 import sys
 12 from retail.test_case.page_obj.modifypw_page import PrimaryMenu, eleData
 13 from retail.test_case.models.log import Logger
 14 
 15 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)
 16 
 17 
 18 class MemberQuery(PrimaryMenu):
 19     """
 20 
 21     """
 22     # 测试数据: 会员编码, 会员姓名, 手机号码
 23     valuesList = [queryData.readExcel(1, 1), int(queryData.readExcel(2, 1)), queryData.readExcel(3, 1)]
 24 
 25     # 会员档案下拉菜单
 26     memberMenu = (By.LINK_TEXT, eleData.readExcel(24, 3))
 27 
 28     # 会员查询页面的3个列表(查询条件,会员信息明细,积分变化明细)
 29     uiElements = (By.XPATH, eleData.readExcel(25, 3))
 30     # 会员类型
 31     memberTypeBtn = (By.ID, eleData.readExcel(26, 3))
 32     # 会员类型下拉选项
 33     memberTypeNum = [(By.XPATH, eleData.readExcel(27, 3)), (By.XPATH, eleData.readExcel(28, 3)),
 34                      (By.XPATH, eleData.readExcel(29, 3))]
 35 
 36     # 会员级别
 37     memberLevelBtn = (By.ID, eleData.readExcel(30, 3))
 38     # 会员级别下拉选项
 39     memberLevelNum = [(By.XPATH, eleData.readExcel(31, 3)), (By.XPATH, eleData.readExcel(32, 3)),
 40                       (By.XPATH, eleData.readExcel(33, 3)), (By.XPATH, eleData.readExcel(34, 3))]
 41 
 42     # 会员编号,会员姓名,手机号码
 43     memberNumNamePhone = [(By.ID, eleData.readExcel(35, 3)), (By.ID, eleData.readExcel(36, 3)),
 44                           (By.ID, eleData.readExcel(37, 3))]
 45     # 查询异常提示框
 46     qFailerr = (By.XPATH, eleData.readExcel(38, 3))  # 查询失败弹出的错误提示框
 47 
 48     confirmBtn = (By.XPATH, eleData.readExcel(39, 3))
 49 
 50     # 查询与重置
 51     queryResetBtn = [(By.ID, eleData.readExcel(40, 3)), (By.ID, eleData.readExcel(41, 3))]
 52 
 53     # 点击会员类型
 54     def selectMemberType(self):
 55         """
 56 
 57         :return:
 58         """
 59         try:
 60             self.findElement(*self.memberTypeBtn).click()
 61             self.driver.implicitly_wait(2)
 62         except Exception:
 63             log.logger.exception('selecting member type fail ')
 64             raise
 65         else:
 66             log.logger.info('---selecting member type ')
 67 
 68     # 点击会员级别
 69     def selectMemberLevel(self):
 70         """
 71 
 72         :return:
 73         """
 74         try:
 75             self.findElement(*self.memberLevelBtn).click()
 76             self.driver.implicitly_wait(2)
 77         except Exception:
 78             log.logger.exception('selecting member level fail ')
 79             raise
 80         else:
 81             log.logger.info('---selecting member level ')
 82 
 83     # 查找会员档案查询菜单
 84     def memberQueryMenu(self):
 85         """
 86 
 87         :return:
 88         """
 89         self.findElement(*self.menuList[1]).click()
 90         self.findElement(*self.memberMenu).click()
 91         time.sleep(4)
 92         log.logger.info('page [%s] :found the menu [%s] and [%s]' % (
 93             sys._getframe().f_code.co_name, self.menuList[1], self.memberMenu))
 94 
 95     # 会员类型/会员级别下拉选项
 96     def memberTypeLevelOption(self, *xpathList):
 97         """
 98 
 99         :param xpath_list:
100         :return:
101         """
102         try:
103             member_type_level = self.findElement(*xpathList)
104             text = member_type_level.text
105         except Exception:
106             log.logger.exception('get element member type/level item text fail', exc_info=True)
107             raise
108         else:
109             log.logger.info('get element [%s] member type/level item text [%s] fail' % (xpathList, text))
110             return text, member_type_level
111 
112     # 点击查询和重置按钮
113     def cQueryResetBtn(self, *queryResetBtn):
114         """
115 
116         :param query_reset_btn:
117         :return:
118         """
119         try:
120             self.findElement(*queryResetBtn).click()
121         except Exception:
122             log.logger.exception('query/reset button not click', exc_info=True)
123             raise
124         else:
125             log.logger.info('clicking query/reset button ')
126 
127     # 输入查询条件
128     def iQueryCondition(self, numNamePhone, value):
129         """
130 
131         :param numNamePhone:
132         :param value:
133         :return:
134         """
135         number_name_phone = self.findElement(*numNamePhone)
136         try:
137             number_name_phone.clear()
138             number_name_phone.send_keys(value)
139         except Exception:
140             log.logger.exception('input value error', exc_info=True)
141             raise
142         else:
143             log.logger.info('[%s] is typing value [%s] ' % (numNamePhone, value))
144 
145     # 获取条件输入框的内容
146     def getInputboxValue(self, *memberNumNamePhone):
147         """
148 
149         :param memberNumNamePhone:
150         :return:
151         """
152         try:
153             get_member_number_name_phone_text = self.findElement(*memberNumNamePhone)
154             text = get_member_number_name_phone_text.get_attribute('value')
155         except Exception:
156             log.logger.exception('get value of element fail', exc_info=True)
157             raise
158         else:
159             log.logger.info('get value [%s] of element [%s] success' % (memberNumNamePhone, text))
160             return text
161 
162     # 重置功能的重写
163     def reset(self):
164         """
165 
166         :return:
167         """
168         try:
169             self.findElement(*self.memberNumNamePhone[0]).clear()
170             self.findElement(*self.memberNumNamePhone[1]).clear()
171             self.findElement(*self.memberNumNamePhone[2]).clear()
172         except Exception:
173             log.logger.exception('reset fail', exc_info=True)
174             raise
175         else:
176             log.logger.info('reset [%s]-[%s]-[%s] success' % (
177                 self.memberNumNamePhone[0], self.memberNumNamePhone[1], self.memberNumNamePhone[2]))
178 
179 
180 if __name__ == '__main__':
181     pass
会员档案查询用例
 1 '''
  2 Code description:会员档案查询 testcase
  3 Create time:
  4 Developer:
  5 '''
  6 
  7 import random
  8 import time
  9 from selenium.webdriver.common.action_chains import ActionChains
 10 from retail.test_case.models.myunit import MyunitTest
 11 from retail.test_case.page_obj.memeberquery_page import MemberQuery
 12 
 13 class MemberQuery_TC(MyunitTest):
 14 
 15     """会员档案查询模块测试用例"""
 16 
 17     #@unittest.skip('dont run the test case')
 18     def test_member_check_ui(self):
 19         """会员档案查询页面显示正确"""
 20         menu = MemberQuery(self.driver) # 实例化会员查询页面
 21         self.login.loginFunc()
 22         menu.memberQueryMenu()  # 查找会员档案查询菜单
 23         elements = menu.findElements(*menu.uiElements)
 24         ele_list = []
 25         for eles in elements:
 26             if eles.text !='':
 27                 ele_list.append(eles.text)
 28         self.assertEqual('查询条件', ele_list[0])
 29         self.assertEqual('会员信息明细', ele_list[1])
 30         self.assertEqual('积分变化明细', ele_list[2])
 31 
 32 
 33     def test_member_type(self):
 34         """会员类型下拉列表项正确"""
 35         menu = MemberQuery(self.driver)  # 实例化会员查询页面
 36         self.login.loginFunc()# 登录
 37         menu.memberQueryMenu()  # 查找会员档案查询菜单
 38         menu.selectMemberType()
 39         list_type = []
 40         for member_type in menu.memberTypeNum:  # 循环遍历会员类型下拉列表
 41             text, memeber_type_level = menu.memberTypeLevelOption(*member_type)
 42             list_type.append(text)
 43         self.assertEqual('个人会员', list_type[0])
 44         self.assertEqual('企业会员', list_type[1])
 45         self.assertEqual('其它', list_type[2])
 46 
 47     def test_member_level(self):
 48         """会员级别下拉列表项正确"""
 49         menu = MemberQuery(self.driver)  # 实例化会员查询页面
 50         self.login.loginFunc()  # 登录
 51         menu.memberQueryMenu() # 查找会员档案查询菜单
 52         menu.selectMemberLevel()
 53         list_level = []
 54         for member_level in menu.memberLevelNum: # 循环遍历会员级别下拉列表
 55             text, memeber_type_level = menu.memberTypeLevelOption(*member_level)
 56             list_level.append(text)
 57         self.assertEqual('标准会员', list_level[0])
 58         self.assertEqual('黄金会员', list_level[1])
 59         self.assertEqual('铂金会员', list_level[2])
 60         self.assertEqual('钻石会员', list_level[3])
 61 
 62     # ............................................................................................#
 63     # 对页面的条件进行组合后单击查询按钮。这是一个大数据量的操作,因此不对返回数据做校验,只看本次组合的条件在页面是否可正常使用。
 64     # 如果查询失败,系统会有弹出框提示失败原因,这个应该很好理解的。
 65     # 我们抓取这个框是否在一定的时间内出现,如果出现则判定本次查询失败,记录用例结果。
 66     # ............................................................................................#
 67 
 68     def test_member_query_failed(self):
 69         """默认条件查询成功"""
 70         menu = MemberQuery(self.driver)  # 实例化会员档案查询页面
 71         self.login.loginFunc()  # 登录
 72         menu.memberQueryMenu()  # 找到会员查询页面
 73         menu.cQueryResetBtn(*menu.queryResetBtn[0])  # 点击[查询]
 74         flag = menu.isElementExist(menu.qFailerr)  # 断言错误提示框
 75         self.assertFalse(flag, msg='查询失败')  # flag为false时,断言成功, 无提示框,说明默认查询成功
 76 
 77     def test_alone_query_1(self):
 78         """按会员编号,会员姓名,手机号码单一条件查询"""
 79         menu = MemberQuery(self.driver)  # 实例化会员档案查询页面
 80         self.login.loginFunc()  # 登录
 81         menu.memberQueryMenu()  # 找到会员档案查询页面
 82         for num_name_phone in menu.memberNumNamePhone:
 83             menu.reset()  # 重置
 84             for value in menu.valuesList:
 85                 menu.iQueryCondition(num_name_phone,value)
 86                 menu.cQueryResetBtn(*menu.queryResetBtn[0]) # 点击[查询]
 87                 time.sleep(3)
 88                 flag = menu.isElementExist(menu.qFailerr)
 89                 if flag:
 90                     self.assertTrue(flag, '提示框不存在,查询成功')
 91                     menu.accept(*menu.confirmBtn)
 92                 else:
 93                     self.assertFalse(flag, '提示框存在,查询失败')
 94 
 95     def test_alone_query_2(self):
 96         """按会员类型单一查询"""
 97         menu = MemberQuery(self.driver) # 实例化会员档案查询页面
 98         self.login.loginFunc() # 登录
 99         menu.memberQueryMenu() # 找到会员档案查询页面
100         for me_type in menu.memberTypeNum:
101             menu.selectMemberType() # 点击[会员类型]
102             text, member_type_level = menu.memberTypeLevelOption(*me_type) # 遍历每一个下拉选项
103             ActionChains(self.driver).move_to_element(member_type_level).perform() # 鼠标移动到下拉选项上
104             member_type_level.click() # 选中下拉选项
105             menu.cQueryResetBtn(*menu.queryResetBtn[0])  # 点击[查询]
106             time.sleep(3)
107             flag = menu.isElementExist(menu.qFailerr) # 判断查询成功
108             self.assertFalse(flag, '提示框存在,查询失败')
109 
110     def test_alone_query_3(self):
111         """按会员级别单一查询"""
112         menu = MemberQuery(self.driver)  # 实例化会员档案查询页面
113         self.login.loginFunc()  # 登录
114         menu.memberQueryMenu()  # 找到会员档案查询页面
115         for me_level in menu.memberLevelNum:
116             menu.selectMemberLevel() # 点击[会员级别]
117             text, member_level = menu.memberTypeLevelOption(*me_level)  # 遍历每一个下拉选项
118             ActionChains(self.driver).move_to_element(member_level).perform()  # 鼠标移动到下拉选项上
119             member_level.click()  # 选中下拉选项
120             menu.cQueryResetBtn(*menu.queryResetBtn[0])  # 点击[查询]
121             time.sleep(3)
122             flag = menu.isElementExist(menu.qFailerr)  # 判断查询成功
123             self.assertFalse(flag, '提示框存在,查询成功')
124 
125     def test_reset(self):
126         """重置功能校验"""
127         menu = MemberQuery(self.driver) # 实例化会员档案查询页面
128         self.login.loginFunc() # 登录
129         menu.memberQueryMenu() # 找到会员档案查询页面
130         # 3个条件输入框随机输入数据
131         for inputBox in menu.memberNumNamePhone:
132             menu.iQueryCondition(inputBox,random.choice(menu.valuesList))
133         #会员类型下拉列表中随机选择一项
134         menu.selectMemberType()
135         text_type, member_type = menu.memberTypeLevelOption(*(random.choice(menu.memberTypeNum)))
136         ActionChains(self.driver).move_to_element(member_type).perform()  # 鼠标移动到下拉选项上
137         member_type.click()
138 
139         # menu.selectMemberLevel()
140         # text_level, member_level = menu.memberTypeLevelOption(*(random.choice(menu.member_level_num)))
141         # #ActionChains(self.driver).move_to_element(member_level).perform()
142         # member_level.click()
143 
144 
145         # 点击【重置】
146         menu.cQueryResetBtn(*menu.queryResetBtn[1])
147         # 获取前3个输入框的内容
148         text_list = []
149         for input_box in menu.memberNumNamePhone:
150             text = menu.getInputboxValue(*input_box)
151             text_list.append(text)
152         # 获取会员类型
153         type_type_text = menu.getInputboxValue(*menu.memberTypeBtn)
154         text_list.append(type_type_text)
155 
156         # type_level_text = menu.getInputboxValue(*menu.member_level_btn)
157         # text_list.append(type_level_text)
158 
159         # 断言每一个条件框是否为空 为空就通过
160         for get_attr in text_list:
161             self.assertEqual('',get_attr)
162 
163 if __name__ == '__main__':
164     pass
执行测试用例
 1 #! user/bin/python
 2 
 3 '''                                                           
 4 Code description:auto run test case
 5 Create time:
 6 Developer:
 7 '''
 8 
 9 import unittest
10 import time
11 from BeautifulReport import BeautifulReport
12 from retail.config.conf import *
13 from retail.test_case.models.testreport import testreport
14 
15 # TODO : will be use jenkins continuous intergration teachnology manage the auto project
16 if __name__ == '__main__':
17 
18     # currTime = time.strftime('%Y-%m-%d %H_%M_%S')
19     # filename = currTime + '.html'
20     # # 第一种测试报告
21     # test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='*Tc.py')
22     # result = BeautifulReport(test_suite)
23     # result.report(filename= filename, description='test report', log_path=reportPath)
24 
25     # # 第二种测试报告
26     runner, fp, fileName = testreport()
27     test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='LoginTc.py')
28     runner.run(test_suite)
29     fp.close()

from BeautifulReport import BeautifulReport 这个报告需要自己网上找一下(很多类似的测试报告源码,不一定非使用本案例中的报告模板)

报告展示

有付出才有汇报,接下来看下们的成果

1.截图:

创建规则失败时截图

登录成功截图

用例执行日志:

2018-10-12 15:39:17,916 - doconfIni.py:[36] - [INFO] - read excel value [D:\Petrochina_Retail_Test_Project] successed! 
2018-10-12 15:39:19,119 - testreport.py:[35] - [INFO] - successed to generate test report [D:\Petrochina_Retail_Test_Project\retail\report\TestReport\report2018-10-12 15_39_19.html]
2018-10-12 15:39:21,469 - doexcel.py:[31] - [INFO] - initing class ReadExcel
2018-10-12 15:39:21,481 - doexcel.py:[31] - [INFO] - initing class ReadExcel
2018-10-12 15:39:21,493 - doexcel.py:[31] - [INFO] - initing class ReadExcel
2018-10-12 15:39:21,504 - doexcel.py:[31] - [INFO] - initing class ReadExcel
2018-10-12 15:39:21,505 - doexcel.py:[46] - [INFO] - reading value [权限管理] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,538 - doexcel.py:[46] - [INFO] - reading value [会员档案] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,538 - doexcel.py:[46] - [INFO] - reading value [积分消费查询] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,539 - doexcel.py:[46] - [INFO] - reading value [功能演示] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,539 - doexcel.py:[46] - [INFO] - reading value [待办工作] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,539 - doexcel.py:[46] - [INFO] - reading value [报表] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,539 - doexcel.py:[46] - [INFO] - reading value [积分规则/活动查询] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,540 - doexcel.py:[46] - [INFO] - reading value [积分规则/活动申请] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,540 - doexcel.py:[46] - [INFO] - reading value [username] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,540 - doexcel.py:[46] - [INFO] - reading value [password] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,541 - doexcel.py:[46] - [INFO] - reading value [loginSubmitButton] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,541 - doexcel.py:[46] - [INFO] - reading value [checkcookie] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,541 - doexcel.py:[46] - [INFO] - reading value [inputTdRight] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,541 - doexcel.py:[46] - [INFO] - reading value [logout] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,541 - doexcel.py:[46] - [INFO] - reading value [rmln] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [qwert1234!@#] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [rmlv] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [qwert1234!@#] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [qwert1234!@#] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [rml] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [qwert1234!@] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,542 - doexcel.py:[46] - [INFO] - reading value [rmln] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,543 - doexcel.py:[46] - [INFO] - reading value [] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,543 - doexcel.py:[46] - [INFO] - reading value [rmln] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,543 - doexcel.py:[46] - [INFO] - reading value [quert1234] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,543 - doexcel.py:[46] - [INFO] - reading value [] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:21,543 - doexcel.py:[46] - [INFO] - reading value [] from excel file [D:\Petrochina_Retail_Test_Project\retail\data\TestData\elementDate.xlsx] completed
2018-10-12 15:39:41,168 - driver.py:[27] - [INFO] - fireFoxDriver:found the Firefox driver [<selenium.webdriver.firefox.webdriver.WebDriver (session="d446da40-ae28-4fff-bfd3-2c9045a5c4cc")>] successed !
2018-10-12 15:39:44,832 - myunit.py:[25] - [INFO] - opened the browser successed!
2018-10-12 15:39:45,541 - base_page.py:[56] - [INFO] - _open is accessing address http://11.11.164.134:9081/rmms/modules/ep.rmms.portal/login/login.jsp at line[46]
2018-10-12 15:39:45,541 - base_page.py:[65] - [INFO] - http://11.11.164.134:9081/rmms/modules/ep.rmms.portal/login/login.jsp loading successed!
2018-10-12 15:39:45,542 - myunit.py:[35] - [INFO] - ************************starting run test cases************************
2018-10-12 15:39:45,594 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:39:45,719 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value [rmln]
2018-10-12 15:39:47,798 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:39:47,866 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value [qwert1234!@#]
2018-10-12 15:39:49,923 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:39:51,173 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:39:53,227 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'logout')
2018-10-12 15:39:53,624 - login_page.py:[95] - [INFO] - quit
2018-10-12 15:39:53,674 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:39:53,726 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value [rmlv]
2018-10-12 15:39:55,785 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:39:55,846 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value [qwert1234!@#]
2018-10-12 15:39:57,906 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:39:58,103 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:40:00,143 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'inputTdRight')
2018-10-12 15:40:00,189 - login_page.py:[53] - [INFO] - login failed : 输入的用户名或密码错误,请重新输入!
2018-10-12 15:40:00,213 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:40:00,248 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value []
2018-10-12 15:40:02,291 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:40:02,339 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value [qwert1234!@#]
2018-10-12 15:40:04,364 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:40:04,439 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:40:06,484 - login_page.py:[70] - [INFO] - login failed ,handleAlert handle alert successed alert info: 请填写用户名!
2018-10-12 15:40:06,525 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:40:06,565 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value [rml]
2018-10-12 15:40:08,611 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:40:08,659 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value [qwert1234!@]
2018-10-12 15:40:10,708 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:40:10,878 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:40:12,958 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'inputTdRight')
2018-10-12 15:40:12,982 - login_page.py:[53] - [INFO] - login failed : 输入的用户名或密码错误,请重新输入!
2018-10-12 15:40:13,006 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:40:13,048 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value [rmln]
2018-10-12 15:40:15,116 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:40:15,148 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value []
2018-10-12 15:40:17,200 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:40:17,248 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:40:19,313 - login_page.py:[70] - [INFO] - login failed ,handleAlert handle alert successed alert info: 请填写用户密码!
2018-10-12 15:40:19,351 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')


![img](https://img-blog.csdnimg.cn/img_convert/11459e40bd3a8360d672450d06aa19de.png)
![img](https://img-blog.csdnimg.cn/img_convert/25a103eca4eb57180e240f3d26a98c1a.png)

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

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618608311)**

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

gin_page.py:[53] - [INFO] - login failed : 输入的用户名或密码错误,请重新输入!
2018-10-12 15:40:13,006 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')
2018-10-12 15:40:13,048 - base_page.py:[118] - [INFO] - inputValue:[('id', 'username')] is receiveing value [rmln]
2018-10-12 15:40:15,116 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'password')
2018-10-12 15:40:15,148 - base_page.py:[118] - [INFO] - inputValue:[('id', 'password')] is receiveing value []
2018-10-12 15:40:17,200 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'loginSubmitButton')
2018-10-12 15:40:17,248 - login_page.py:[45] - [INFO] - clickLoginBtn ,logining....!
2018-10-12 15:40:19,313 - login_page.py:[70] - [INFO] - login failed ,handleAlert handle alert successed alert info: 请填写用户密码!
2018-10-12 15:40:19,351 - base_page.py:[83] - [INFO] - The page of <retail.test_case.page_obj.login_page.LoginPage object at 0x0000022A19CDE828> had already find the element ('id', 'username')


[外链图片转存中...(img-7glAzTpJ-1714887822923)]
[外链图片转存中...(img-PyW85oUk-1714887822923)]

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

**[需要这份系统化的资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618608311)**

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

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值