Selenium UI自动化实战过程记录

一.前言

1.1项目框架

项目如何使用框架: 本项目采用unitest框架

设计模式是如何应用:本项目采用pageobject设计模式

UI对象库思想

项目设计

一个模块(被测项目的页面)对应一个py文件及一个测试类(测试文件)

每一个测试页面(系统的页面)中存储页面元素及此页面中涉及到的功能

每一个用例组合在一个测试类里面生成一个py文件

项目目标

我们在写自动化测试项目的时候一定要想好你的脚本都要哪些功能,页面元素平凡改动的时候是否需要大批量的修改脚本,及测试不同数据时是否也要修改脚本,那么能想到这些我们的初始目标差不多就有了

1.生成测试用例执行结果报告

2.生成测试用例执行日志

3.用例执行失败或者执行完成后自动发送邮件报告

用例执行失败或者成功时截取图片

5.数据驱动(读取测试数据,减少脚本维护成本)

更多资料

1.2项目目录结构

Retail_TestPro

    Docs# 存放项目的相关文档        

        01测试计划

        02测试大纲

        03测试用例

        04测试报告

        05测试进度

        06技术文档

        07测试申请

    Package# 存放第三方插件

        HTMLTestRunner.py

    Retail

        Config

            __init__.py

            Conf.py# 读配置文件获取项目跟目录路径 并获取所有欲使用的目录文件的路径

            Config.ini# 存放项目跟目录的路径

        Data

            TestData

                __init__.py

                elementDate.xlsx# 存放项目中所有的元素信息及测试数据

                Email_receiver.txt# 存放邮件的接受者信息

        Report# 测试报告

            Image

                Fail# 存放用例执行失败时的截图

                Pass# 存放用例执行成功时的截图

            Log# 存放用例执行过程中的log信息

            TestReport# 存放测试用例执行完成后生成的测试报告

        Test_case# 测试用例信息

            Models # 存放一些公共方法

                Doconfini.py# 读配置文件

                Doexcel.py# 读excel文件

                Driver.py# 存放driver

                Log.py# 生成log

                Myunit.py# 继承unittest.Testcase

                Sendmail.py# 发送邮件

                Strhandle.py# 字符串处理

                Tcinfo.py# 测试用例基本信息

                Testreport.py# 测试报告

            Page_obj# 测试模块

                Activerule_page.py

                Base_page.py

                Company_page.py

                Createrule_page.py

                Memberquery_page.py

                Modifypw_page.py

                Pointquery_page.py

                ActiveRuleTc.py

                CompanyQueryTc.py

                CreateRuleTc.py

                LoginTc.py

                MemberQueryTc.py

                ModifyPwTc.py

                PointQueryTc.py

        runTc.py# 执行测试用例         

 

二.项目代码

1.config.ini (存放项目跟路径)

1

2

[project]

project_path = D:\Petrochina_Retail_Test_Project

2.conf.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

'''

 Code description:read config.ini, get path

 Create time:

 Developer:

 '''

 import os

 import sys

 from retail.test_case.models.doconfIni import DoConfIni

  

 # 获取当前路径

 currPath= \

     os.path.split(os.path.realpath(__file__))[0]

  

 # 读配置文件获取项目路径

 readConfig = \

     DoConfIni()

 proPath = \

     readConfig.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path')

  

 # 获取日志路径

 logPath= \

     os.path.join(proPath,'retail','report','Log')

  

 # 测试用例路径

 tcPath = \

     os.path.join(proPath,'retail','test_case')

  

 # 获取报告路径

 reportPath= \

     os.path.join(proPath,'retail','report','TestReport')

  

 # 获取测试数据路径

 dataPath= \

     os.path.join(proPath,'retail','data','TestData')

  

 # 保存截图路径

 # 错误截图

 failImagePath = os.path.join(proPath, 'retail', 'report', 'image','fail')

 # 成功截图

 passImagePath = os.path.join(proPath, 'retail', 'report', 'image','pass')

  

 # 被调函数名称

 funcName = sys._getframe().f_code.co_name

 # 被调函数所在行号

 funcNo = sys._getframe().f_back.f_lineno

  

 # 被调函数所在文件名称

 funcFile= sys._getframe().f_code.co_filename

3.elementData.xlsx(json与yaml替换)

存放测试数据

4.公共方法models下面的文件

4.1doconfini.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

'''

Code description:read conf file

Create time:

Developer:

'''

import logging

import configparser

from retail.config.conf import *

from retail.test_case.models.log import Logger

log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

class DoConfIni(object):

    def __init__(self):

        """

        :param filename:

        """

        self.cf = configparser.ConfigParser()

    # 从ini文件中读数据

    def getConfValue(self,filename,section,name):

        """

        :param config:

        :param name:

        :return:

        """

        try:

            self.cf.read(filename)

            value = self.cf.get(section,name)

        except Exception as e:

            log.logger.exception('read file [%s] for [%s] failed , did not get the value' %(filename,section))

            raise e

        else:

            log.logger.info('read excel value [%s] successed! ' %value)

            return value

    # 向ini文件中写数据

    def writeConfValue(self,filename, section, name, value):

        """

        :param section: section

        :param name: value name

        :param value:  value

        :return: none

        """

        try:

            self.cf.add_section(section)

            self.cf.set(section, name, value)

            self.cf.write(open(filename, 'w'))

        except Exception :

            log.logger.exception('section %s has been exist!' %section)

            raise configparser.DuplicateSectionError(section)

        else:

            log.logger.info('write section'+section+'with value '+value+' successed!')

if __name__ == '__main__':

    file_path = currPath

    print(file_path)

    read_config = DoConfIni()

    value = read_config.getConfValue(os.path.join(currPath,'config.ini'),'project','project_path')

    print(value)

    read_config.writeConfValue(os.path.join(currPath,'config.ini'),'tesesection', 'name', 'hello word')

4.2doexcel.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

'''

 Code description:read excel.xlsx, get values

 Create time:

 Developer:

 '''

  

 import xlrd

 import os

 import logging

 from retail.config import conf

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

  

 class ReadExcel(object):

  

     def __init__(self,fileName='elementDate.xlsx',sheetName='elementsInfo'):

         """

  

         :param fileName:

         :param sheetName:

         """

         try:

             self.dataFile = os.path.join(conf.dataPath, fileName)

             self.workBook = xlrd.open_workbook(self.dataFile)

             self.sheetName = self.workBook.sheet_by_name(sheetName)

         except Exception:

             log.logger.exception('init class ReadExcel fail', exc_info=True)

             raise

         else:

             log.logger.info('initing class ReadExcel')

     # 读excel中的数据

     def readExcel(self,rownum,colnum):

         """

  

         :param rownum:

         :param colnum:

         :return:

         """

         try:

             value = self.sheetName.cell(rownum,colnum).value

         except Exception:

             log.logger.exception('read value from excel file fail', exc_info=True)

             raise

         else:

             log.logger.info('reading value [%s] from excel file [%s] completed' %(value, self.dataFile))

             return value

  

 if __name__ == '__main__':

     cellValue = ReadExcel().readExcel(1,3)

     print((cellValue))

4.3log.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

'''

 Code description:log info

 Create time:

 Developer:

 '''

  

 import logging

 import time

  

 class Logger(object):

     def __init__(self, logger, CmdLevel=logging.INFO, FileLevel=logging.INFO):

         """

  

         :param logger:

         :param CmdLevel:

         :param FileLevel:

         """

         self.logger = logging.getLogger(logger)

         self.logger.setLevel(logging.DEBUG)  # 设置日志输出的默认级别

         # 日志输出格式

         fmt = logging.Formatter('%(asctime)s - %(filename)s:[%(lineno)s] - [%(levelname)s] - %(message)s')

         # 日志文件名称

         # self.LogFileName = os.path.join(conf.log_path, "{0}.log".format(time.strftime("%Y-%m-%d")))# %H_%M_%S

         currTime = time.strftime("%Y-%m-%d")

         self.LogFileName = r'D:\Petrochina_Retail_Test_Project\retail\report\Log\log'+currTime+'.log'

         # 设置控制台输出

         # sh = logging.StreamHandler()

         # sh.setFormatter(fmt)

         # sh.setLevel(CmdLevel)# 日志级别

  

         # 设置文件输出

         fh = logging.FileHandler(self.LogFileName)

         fh.setFormatter(fmt)

         fh.setLevel(FileLevel)# 日志级别

  

         # self.logger.addHandler(sh)

         self.logger.addHandler(fh)

  

     # def debug(self, message):

     #     """

     #

     #     :param message:

     #     :return:

     #     """

     #     self.logger.debug(message)

     #

     # def info(self,message):

     #     """

     #

     #     :param message:

     #     :return:

     #     """

     #     self.logger.info(message)

     #

     # def warn(self,message):

     #     """

     #

     #     :param message:

     #     :return:

     #     """

     #     self.logger.warning(message)

     #

     # def error(self,message):

     #     """

     #

     #     :param message:

     #     :return:

     #     """

     #     self.logger.error(message)

     #

     # def criti(self,message):

     #     """

     #

     #     :param message:

     #     :return:

     #     """

     #     self.logger.critical(message)

  

 if __name__ == '__main__':

     logger = Logger("fox",CmdLevel=logging.DEBUG, FileLevel=logging.DEBUG)

     logger.logger.debug("debug")

     logger.logger.log(logging.ERROR,'%(module)s %(info)s',{'module':'log日志','info':'error'}) #ERROR,log日志 error

4.4sendmail.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

'''

 Code description:send email

 Create time:

 Developer:

 '''

  

 import smtplib

 from email.mime.text import MIMEText

 from email.header import Header

 import os

 from retail.config import conf

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__)

 #   邮件发送接口

 class SendMail(object):

     '''

     邮件配置信息

     '''

     def __init__(self,

                  receiver,

                  subject='Retail 系统测试报告',

                  server='smtp.qq.com',

                  fromuser='281754043@qq.com',

                  frompassword='gifhhsbgqyovbhhc',

                  sender='281754043@qq.com'):

         """

  

         :param receiver:

         :param subject:

         :param server:

         :param fromuser:

         :param frompassword:

         :param sender:

         """

  

         self._server = server

         self._fromuser = fromuser

         self._frompassword = frompassword

         self._sender = sender

         self._receiver = receiver

         self._subject = subject

  

     def sendEmail(self, fileName):

         """

  

         :param filename:

         :return:

         """

         #   打开报告文件读取文件内容

         try:

             f = open(os.path.join(conf.reportPath, fileName), 'rb')

             fileMsg = f.read()

         except Exception:

             log.logger.exception('open or read file [%s] failed,No such file or directory: %s' %(fileName, conf.reportPath))

             log.logger.info('open and read file [%s] successed!' %fileName)

         else:

             f.close()

             #   邮件主题

             subject = 'Python test report' #

             #   邮件设置

             msg = MIMEText(fileMsg, 'html', 'utf-8')

             msg['subject'] = Header(subject, 'utf-8')

             msg['from'] = self._sender

         #   连接服务器,登录服务器,发送邮件

             try:

                 smtp = smtplib.SMTP()

                 smtp.connect(self._server)

                 smtp.login(self._fromuser, self._frompassword)

             except Exception:

                 log.logger.exception('connect [%s] server failed or username and password incorrect!' %smtp)

             else:

                 log.logger.info('email server [%s] login success!' %smtp)

                 try:

                     smtp.sendmail(self._sender, self._receiver, msg.as_string())

                 except Exception:

                     log.logger.exception('send email failed!')

                 else:

                     log.logger.info('send email successed!')

  

 #   从文件中读取邮件接收人信息

 def getReceiverInfo(fileName):

     '''

     :param filename: 读取接收邮件人信息

     :return: 接收邮件人信息

     '''

     try:

         openFile = open(os.path.join(conf.dataPath, fileName))

     except Exception:

         log.logger.exception('open or read file [%s] failed,No such file or directory: %s' %(fileName, conf.dataPath))

     else:

         log.logger.info('open file [%s] successed!' %fileName)

         for line in openFile:

             msg = [i.strip() for i in line.split(',')]

             log.logger.info('reading [%s] and got receiver value is [%s]' %(fileName, msg))

             return msg

  

 if __name__ == '__main__':

     readMsg=getReceiverInfo('mail_receiver.txt')

     sendmail = SendMail(readMsg)

     sendmail.sendEmail('2021-04-21 17_44_04.html')

4.5strhandle.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

'''

 Code description: string handle

 Create time:

 Developer:

 '''

  

 import logging

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

 def strhandle(str):

     """

  

     :param str:

     :return:

     """

     #初始化字符、数字、空格、特殊字符的计数

     try:

         lowerCase = 0

         upperCase = 0

         number = 0

         other = 0

         for stritem in str:

          #如果在字符串中有小写字母,那么小写字母的数量+1

             if stritem.islower():

                 lowerCase += 1

             #如果在字符串中有数字,那么数字的数量+1

             elif stritem.isdigit():

                 number += 1

             elif stritem.isupper():# 大写字母

                 upperCase +=1

             #如果在字符串中有空格,那么空格的数量+1

             else:

                 other += 1

         return lowerCase, upperCase, number, other

     except Exception as e:

         log.logger.exception('string handle error , please check!', exc_info=True)

         raise e

  

 if __name__=='__main__':

     list = ['qwert','erwer']

     lowercase, uppercase, number, other = strhandle(list[0])

     print ("该字符串中的小写字母有:%d" %lowercase)

     print ("该字符串中的大写写字母有:%d" %uppercase)

     print ("该字符串中的数字有:%d" %number)

     print ("该字符串中的特殊字符有:%d" %other)

4.6testreport.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

'''

 Code description:test report

 Create time:

 Developer:

 '''

  

 import time

 import logging

 import unittest

 from BeautifulReport import BeautifulReport

 import HTMLTestRunner

 from retail.config import conf

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

 # 用HTMLTestRunner 实现的测试报告

 def testreport():

     """

  

     :return:

     """

     currTime = time.strftime('%Y-%m-%d %H_%M_%S')

     fileName = conf.reportPath + r'\report' + currTime + '.html'

     try:

         fp = open(fileName, 'wb')

     except Exception :

         log.logger.exception('[%s] open error cause Failed to generate test report' %fileName)

     else:

         runner = HTMLTestRunner.HTMLTestRunner\

             (stream=fp, title='Retail sys测试报告',

                                                description='处理器:Intel(R) Core(TM) '

                                                            'i5-6200U CPU @ 2030GHz 2.40 GHz '

                                                 '内存:8G 系统类型: 64位 版本: windows 10 家庭中文版')

         log.logger.info('successed to generate test report [%s]' %fileName)

         return runner, fp, fileName

 #

 def addTc(TCpath = conf.tcPath, rule = '*TC.py'):

     """

  

     :param TCpath: 测试用例存放路径

     :param rule: 匹配的测试用例文件

     :return:  测试套件

     """

     discover = unittest.defaultTestLoader.discover(TCpath, rule)

  

     return discover

 # 用BeautifulReport模块实现测试报告

 def runTc(discover):

     """

  

     :param discover: 测试套件

     :return:

     """

     currTime = time.strftime('%Y-%m-%d %H_%M_%S')

     fileName = currTime+'.html'

     try:

         result = BeautifulReport(discover)

         result.report(filename=fileName, description='测试报告', log_path=conf.reportPath)

     except Exception:

         log.logger.exception('Failed to generate test report', exc_info=True)

     else:

         log.logger.info('successed to generate test report [%s]' % fileName)

         return fileName

  

 if __name__ == '__main__':

     testreport()

     suite = addTc(rule = '*TC.py')

     runTc(suite)

4.7driver.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

'''

 Code description:save all driver info

 Create time:

 Developer:

 '''

  

 from selenium import webdriver

 import logging

 import sys

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

 class WDriver(object):

  

     # Firefox driver

     def fireFoxDriver(self):

         """

  

         :return:

         """

         try:

             self.driver = webdriver.Firefox()

         except Exception as e:

             log.logger.exception('FireFoxDriverServer.exe executable needs to be in PATH. Please download!', exc_info=True)

             raise e

         else:

             log.logger.info('%s:found the Firefox driver [%s] successed !' %(sys._getframe().f_code.co_name,self.driver))

             return self.driver

  

     # chrom driver

     def chromeDriver(self):

         """

  

         :return:

         """

         try:

             # option = webdriver.ChromeOptions()# 实现不打开浏览器 执行web自动化测试脚本

             # option.add_argument('headless')#

             # self.driver = webdriver.Chrome(chrome_options=option)

             self.driver = webdriver.Chrome()

         except Exception as e:

             log.logger.exception('ChromeDriverServer.exe executable needs to be in PATH. Please download!',

                                  exc_info=True)

             raise e

         else:

             log.logger.info('%s:found the chrome driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver))

             return self.driver

  

     # Ie driver

     def ieDriver(self):

         """

  

         :return:

         """

         try:

             self.driver = webdriver.Ie()

         except Exception as e:

             log.logger.exception('IEDriverServer.exe executable needs to be in PATH. Please download!',

                                  exc_info=True)

             raise e

         else:

             log.logger.info('%s:found the IE driver [%s] successed !' % (sys._getframe().f_code.co_name, self.driver))

             return self.driver

  

 if __name__ == '__main__':

     WDrive=WDriver()

     WDrive.fireFoxDriver()

4.8myunittest.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

'''

 Code description:unittest framwork

 Create time:

 Developer:

 '''

  

 from retail.test_case.models.driver import WDriver

 import logging

 import unittest

 from retail.test_case.page_obj.login_page import LoginPage

 from retail.test_case.models.log import Logger

 from selenium import webdriver

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

 class MyunitTest(unittest.TestCase):

     """

  

     """

  

     # add by xuechao at 2018.09.19

     @classmethod

     def setUpClass(cls): # 一个测试类(文件)执行一次打开浏览器, 节约每个用例打开一次浏览器的时间

  

         #cls.driver = WDriver().fireFoxDriver()

         cls.driver = WDriver().chromeDriver()

         cls.driver.maximize_window()

         log.logger.info('opened the browser successed!')

     # ----------------------------

  

     def setUp(self):

         """

  

         :return:

         """

         self.login = LoginPage(self.driver)

         self.login.open()

         log.logger.info('************************starting run test cases************************')

  

     def tearDown(self):

         """

  

         :return:

         """

         self.driver.refresh()

         log.logger.info('************************test case run completed************************')

  

     # add by linuxchao at 2018.09.19

     @classmethod

     def tearDownClass(cls):

         cls.driver.quit()

         log.logger.info('quit the browser success!')

     #----------------------------

 if __name__ == '__main__':

     unittest.main()

4.9结束语

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

5.base_page.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

'''

Code description: base page 封装一些公共方法

Create time:

Developer:

'''

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.common.by import By

import os

import logging

import sys

from retail.test_case.models.log import Logger

from retail.config import conf

from retail.test_case.models.doexcel import ReadExcel

eleData = ReadExcel() # 存储系统所有的元素数据

testLoginData = ReadExcel('elementDate.xlsx', 'userNamePw') # 登录模块测试数据

modifyPwData = ReadExcel('elementDate.xlsx', 'modifyPw') # 修改密码模块测试数据

queryData = ReadExcel('elementDate.xlsx', 'queryData')

log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

class BasePage(object):

    """主菜单"""

    menuList = \

        [(By.LINK_TEXT, eleData.readExcel(7, 3)), # 权限管理

        (By.LINK_TEXT, eleData.readExcel(8, 3)), # 会员档案

        (By.LINK_TEXT, eleData.readExcel(9, 3)), # 积分消费查询

        (By.LINK_TEXT, eleData.readExcel(10, 3)), # 功能演示

        (By.LINK_TEXT, eleData.readExcel(11, 3)), # 待办工作

        (By.LINK_TEXT, eleData.readExcel(12, 3)), # 报表

        (By.LINK_TEXT, eleData.readExcel(13, 3)), # 积分规则/活动查询

        (By.LINK_TEXT, eleData.readExcel(14, 3))] # 积分规则/活动申请

    def __init__(self, driver,url='http://11.11.164.134:9081/rmms/modules/ep.rmms.portal/login/login.jsp'):

        """

        :param driver:

        :param url:

        """

        self.driver = driver

        self.base_url = url

    def _open(self,url):

        """

        :param url:

        :return:

        """

        try:

            self.driver.get(url)

            self.driver.implicitly_wait(10)

        except Exception as e:

            log.logger.exception(e, exc_info=True)

            raise ValueError('%s address access error, please check!' %url)

        else:

            log.logger.info('%s is accessing address %s at line[46]' %(sys._getframe().f_code.co_name,url))

    def open(self):

        """

        :return:

        """

        self._open(self.base_url)

        log.logger.info('%s loading successed!' %self.base_url)

        return self.base_url

    # *loc 代表任意数量的位置参数

    def findElement(self, *loc):

        """

        查找单一元素

        :param loc:

        :return:

        """

        try:

            WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))

            # log.logger.info('The page of %s had already find the element %s'%(self,loc))

            # return self.driver.find_element(*loc)

        except Exception as e:

            log.logger.exception('finding element timeout!, details' ,exc_info=True)

            raise e

        else:

            log.logger.info('The page of %s had already find the element %s' % (self, loc))

            return self.driver.find_element(*loc)

    def findElements(self, *loc):

        """

        查找一组元素

        :param loc:

        :return:

        """

        try:

            WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))

            # log.logger.info('The page of %s had already find the element %s' % (self, loc))

            # return self.driver.find_elements(*loc)

        except Exception as e:

            log.logger.exception('finding element timeout!, details', exc_info=True)

            raise e

        else:

            log.logger.info('The page of %s had already find the element %s' % (self, loc))

            return self.driver.find_elements(*loc)

    def inputValue(self, inputBox, value):

        """

        后期修改其他页面直接调用这个函数

        :param inputBox:

        :param value:

        :return:

        """

        inputB = self.findElement(*inputBox)

        try:

            inputB.clear()

            inputB.send_keys(value)

        except Exception as e:

            log.logger.exception('typing value error!', exc_info=True)

            raise e

        else:

            log.logger.info('inputValue:[%s] is receiveing value [%s]' % (inputBox, value))

    # 获取元素数据

    def getValue(self, *loc):

        """

        :param loc:

        :return:

        """

        element = self.findElement(*loc)

        try:

            value = element.text

            #return value

        except Exception:

            #element = self.find_element_re(*loc) # 2018.09.21 for log

            value = element.get_attribute('value')

            log.logger.info('reading the element [%s] value [%s]' % (loc, value))

            return value

        except:

            log.logger.exception('read value failed', exc_info=True)

            raise Exception

        else:

            log.logger.info('reading the element [%s] value [%s]' % (loc,value))

            return value

    def getValues(self, *loc):

        """

        :param loc:

        :return:

        """

        value_list = []

        try:

            for element in self.findElements(*loc):

                value = element.text

                value_list.append(value)

        except Exception as e:

            log.logger.exception('read value failed', exc_info=True)

            raise e

        else:

            log.logger.info('reading the element [%s] value [%s]'% (loc,value_list))

            return value_list

    # 执行js脚本

    def jScript(self,src):

        """

        :param src:

        :return:

        """

        try:

            self.driver.excute_script(src)

        except Exception as e:

            log.logger.exception('execute js script [%s] failed ' %src)

            raise e

        else:

            log.logger.info('execute js script [%s] successed ' %src)

    # 判断元素是否存在

    def isElementExist(self, element):

        """

        :param element:

        :return:

        """

        try:

            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(element))

        except:

            # log.logger.exception('The element [%s] not exist', exc_info=True)

            return False

        else:

            # log.logger.info('The element [%s] have existed!' %element)

            return True

    # 截图

    def saveScreenShot(self, filename):

        """

        :param filename:

        :return:

        """

        list_value = []

        list = filename.split('.')

        for value in list:

            list_value.append(value)

        if list_value[1] == 'png' or list_value[1] == 'jpg' or list_value[1] == 'PNG' or list_value[1] == 'JPG':

            if 'fail' in list_value[0].split('_'):

                try:

                    self.driver.save_screenshot(os.path.join(conf.failImagePath, filename))

                except Exception:

                    log.logger.exception('save screenshot failed !', exc_info=True)

                else:

                    log.logger.info('the file [%s]  save screenshot successed under [%s]' % (filename, conf.failImagePath))

            elif 'pass' in list_value[0]:

                try:

                    self.driver.save_screenshot(os.path.join(conf.passImagePath, filename))

                except Exception:

                    log.logger.exception('save screenshot failed !', exc_info=True)

                else:

                    log.logger.info(

                        'the file [%s]  save screenshot successed under [%s]' % (filename, conf.passImagePath))

            else:

                log.logger.info('save screenshot failed due to [%s] format incorrect' %filename)

        else:

            log.logger.info('the file name of [%s] format incorrect cause save screenshot failed, please check!' % filename)

    # 接受错误提示框

    def accept(self, *loc):

        """

        :return:

        """

        self.findElement(*loc).click()

        log.logger.info('closed the error information fram successed!')

if __name__ == '__main__':

    pass

6.login_page.py(登陆页面)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

'''

 Code description: login page

 Create time:

 Developer:

 '''

  

 from selenium.webdriver.common.by import By

 import logging

 import sys

 from retail.test_case.page_obj.base_page import BasePage, eleData, testLoginData

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

  

 class LoginPage(BasePage):

  

     """用户名,密码,登录按钮,保存信息,错误提示"""

     userNameEle = (By.ID, eleData.readExcel(1, 3))

     passWordEle = (By.ID, eleData.readExcel(2, 3))

     loginBtnEle = (By.ID, eleData.readExcel(3, 3))

     saveInfoEle = (By.NAME, eleData.readExcel(4, 3))

     errorMessage = (By.ID, eleData.readExcel(5, 3))

     quitBtn = (By.ID, eleData.readExcel(6, 3))

  

     # 用户名和密码

     unpwData = \

         [[testLoginData.readExcel(1, 0), testLoginData.readExcel(1, 1)],# 正确的用户名和正确的密码

          [testLoginData.readExcel(2, 0), testLoginData.readExcel(2, 1)],# 错误的用户名和正确的密码

          [testLoginData.readExcel(3, 0), testLoginData.readExcel(3, 1)],# 空的用户名和正确的密码

          [testLoginData.readExcel(4, 0), testLoginData.readExcel(4, 1)],# 错误的用户名和错误的密码

          [testLoginData.readExcel(5, 0), testLoginData.readExcel(5, 1)],# 正确的用户名和空密码

          [testLoginData.readExcel(6, 0), testLoginData.readExcel(6, 1)],# 正确的用户名和错误的密码

          [testLoginData.readExcel(7, 0), testLoginData.readExcel(7, 1)]]# 空用户名和空密码

  

     # 登录按钮

     def clickLoginBtn(self):

         """

  

         :return:

         """

         element = self.findElement(*self.loginBtnEle)

         element.click()

         log.logger.info('%s ,logining....!' % sys._getframe().f_code.co_name)

     # 登录失败时提示

     def getFailedText(self):

         """

  

         :return:

         """

         info = self.findElement(*self.errorMessage).text

         log.logger.info('login failed : %s' %info)

         return info

  

     # 登录失败时弹出的alert

     def handleAlert(self):

         """

  

         :return:

         """

         try:

             alert = self.driver.switch_to_alert()

             text = alert.text

             alert.accept()

         except Exception:

             log.logger.exception('handle alert failed, please check the details' ,exc_info=True)

             raise

         else:

             log.logger.info('login failed ,%s handle alert successed alert info: %s!' %(sys._getframe().f_code.co_name, text))

             return text

  

     # 统一登录函数

     def loginFunc(self, username='rmln', password='qwert1234!@#'):

         """

         :param username:

         :param password:

         :return:

         """

         self.inputValue(self.userNameEle, username)

         self.inputValue(self.passWordEle, password)

         self.clickLoginBtn()

  

     # 清空输入框数据

     def clearValue(self, element):

  

         empty = self.findElement(*element)

         empty.clear()

         log.logger.info('emptying value.......')

  

     # 推出

     def quit(self):

         self.findElement(*self.quitBtn).click()

         log.logger.info('quit')

  

 if __name__ == '__main__':

     pass

7.LoginTC.py(登陆测试用例)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

"""

Code description:login testcase

Create time:

Developer:

"""

import unittest

import time

import logging

import sys

from retail.test_case.models.myunit import MyunitTest

from retail.test_case.models.log import Logger

log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

class Login_TC(MyunitTest):

    """登录模块测试用例"""

    def test_login_success_correct_username_password(self):

        """用户名正确,密码正确,登录成功"""

        self.login.loginFunc()

        currUrl = self.driver.current_url # 获取当前的url地址

        try:

            self.assertIn('main', currUrl, 'main not in current url!')

        except Exception:

            self.login.saveScreenShot('correct_username_password_fail.png')

            raise

        else:

            self.login.saveScreenShot('correct_username_password_pass.png')

            log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login_failed_incorrect_username(self):

        """用户名错误,密码正确,登录失败"""

        self.login.loginFunc(self.login.unpwData[1][0], self.login.unpwData[1][1])

        failText = self.login.getFailedText()

        self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login_failed_incorrect_password(self):

        """用户名正确,密码错误,登录失败"""

        self.login.loginFunc(self.login.unpwData[5][0], self.login.unpwData[5][1])

        failText = self.login.getFailedText()

        self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login_failed_username_password_blank(self):

        """用户名为空,密码为空,登录失败"""

        self.login.loginFunc(self.login.unpwData[6][0], self.login.unpwData[6][1])

        failText = self.login.handleAlert() # 获取alert的提示信息

        self.assertEqual('请填写用户名', failText, '提示信息错误')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login_failed_password_blank(self):

        """用户名正确,密码为空,登录失败"""

        self.login.loginFunc(self.login.unpwData[4][0], self.login.unpwData[4][1])

        failText = self.login.handleAlert() # 获取alert的提示信息

        self.assertEqual('请填写用户密码', failText, '提示信息错误')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login_failed_unpw_incorrect(self):

        """用户名错误,密码错误,登录失败"""

        # try:

        self.login.loginFunc(self.login.unpwData[3][0], self.login.unpwData[4][0])

        failText = self.login.getFailedText()

        self.assertEqual ('输入的用户名或密码错误,请重新输入!', failText, 'failed')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

    def test_login(self):

        """循环测试登录功能"""

        for listitem in self.login.unpwData:

            self.login.inputValue(self.login.userNameEle,listitem[0])

            time.sleep(2)

            self.login.inputValue(self.login.passWordEle,listitem[1])

            time.sleep(2)

            self.login.clickLoginBtn()

            time.sleep(2)

            if listitem[0] =='rmln' and listitem[1] == 'qwert1234!@#':

                currUrl = self.driver.current_url

                self.assertIn ('main' , currUrl)

                self.login.quit()

            elif listitem[0] == 'rmln' and listitem[1] != 'qwert1234!@#':

                if listitem[1] == '':

                    failText = self.login.handleAlert()  # 获取alert的提示信息

                    self.assertEqual('请填写用户密码', failText, '提示信息错误')

                else:

                    failText = self.login.getFailedText()

                    self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')

            elif listitem[0] != 'rmln' and listitem[1] == 'qwert1234!@#':

                if listitem[0]=='':

                    failText = self.login.handleAlert()  # 获取alert的提示信息

                    self.assertEqual('请填写用户名', failText, '提示信息错误')

                else:

                    failText = self.login.getFailedText()

                    self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')

            elif listitem[0] == listitem[1] == '':

                failText = self.login.handleAlert()  # 获取alert的提示信息

                self.assertEqual('请填写用户名', failText, '提示信息错误')

            else:

                failText = self.login.getFailedText()

                self.assertEqual('输入的用户名或密码错误,请重新输入!', failText, '提示信息错误')

        log.logger.info('%s->run completed! please check the test report' % (sys._getframe().f_code.co_name))

if __name__ == '__main__':

    unittest.main()

8.modifypw_page.py(修改密码页面)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

'''

 Code description:modify password page

 Create time:

 Developer:

 '''

  

 import logging

 import time

 from selenium.webdriver.common.by import By

 from selenium.webdriver.common.action_chains import ActionChains

 from retail.test_case.page_obj.base_page import BasePage, eleData, modifyPwData

 from retail.test_case.models.log import Logger

  

 log = Logger(__name__, CmdLevel=logging.INFO, FileLevel=logging.INFO)

 class PrimaryMenu(BasePage):

  

     """密码数据"""

     pwdList = \

         [[modifyPwData.readExcel(1, 0), modifyPwData.readExcel(1, 1), modifyPwData.readExcel(1, 2)],

          [modifyPwData.readExcel(2, 0), modifyPwData.readExcel(2, 1), modifyPwData.readExcel(2, 2)],

          [modifyPwData.readExcel(3, 0), modifyPwData.readExcel(3, 1), modifyPwData.readExcel(3, 2)],

          [modifyPwData.readExcel(4, 0), modifyPwData.readExcel(4, 1), modifyPwData.readExcel(4, 2)],

          [modifyPwData.readExcel(5, 0), modifyPwData.readExcel(5, 1), modifyPwData.readExcel(5, 2)]]

  

     """权限管理下拉菜单"""

     menuPersonal = (By.LINK_TEXT, eleData.readExcel(15, 3))

     menuModifyPwd = (By.LINK_TEXT, eleData.readExcel(16, 3))

  

     """密码修改"""

     oldPwd = (By.ID, eleData.readExcel(17, 3))

     newPwd = (By.ID, eleData.readExcel(18, 3))

     commitPwd = (By.ID, eleData.readExcel(19, 3))

  

     """错误提示框及确定"""

     errMessage = (By.XPATH, eleData.readExcel(20, 3))

     closeBtn = (By.CSS_SELECTOR, eleData.readExcel(21, 3))

  

     """密码说明"""

     readMe = (By.ID, eleData.readExcel(22, 3))

  

     """保存"""

     saveBtn = (By.XPATH, eleData.readExcel(23, 3))

  

     #   主菜单

     def findMenu(self,*menuList):

         """

  

         :param menu_list:

         :return:

         """

         return self.findElement(*menuList)

  

     #   旧密码输入框

     def inputOldPw(self, oldPwd=''):

         """"""

         try:

             self.findElement(*self.oldPwd).clear()

             self.findElement(*self.oldPwd).send_keys(oldPwd)

         except Exception:

             log.logger.exception('input Pw [%s] for oldPw [%s] fail' %(oldPwd, self.oldPwd))

             raise

         else:

             log.logger.info('inputing Pw [%s] for oldPw [%s] ' % (oldPwd, self.oldPwd))

     #   新密码输入框

     def inputNewPw(self, newPwd=''):

         """

  

         :param newPwd:

         :return:

         """

         try:

             self.findElement(*self.newPwd).clear()

             self.findElement(*self.newPwd).send_keys(newPwd)

         except Exception:

             log.logger.exception('input Pw [%s] for newPw [%s] fail' % (newPwd, self.newPwd))

             raise

         else:

             log.logger.info('inputing Pw [%s] for newPw [%s] ' % (newPwd, self.newPwd))

     #   确认密码输入框

     def inputConfirmPw(self, confirmPwd=''):

         """

  

         :param confirmPwd:

         :return:

         """

         try:

             self.findElement(*self.commitPwd).clear()

             self.findElement(*self.commitPwd).send_keys(confirmPwd)

         except Exception:

             log.logger.exception('input Pw [%s] for commitPw [%s] fail' %(confirmPwd, self.commitPwd))

             raise

         else:

             log.logger.info('inputing Pw [%s] for commitPw [%s] ' %(confirmPwd, self.commitPwd))

     #   保存

     def saveButton(self):

         """

  

         :return:

         """

         try:

             self.driver.implicitly_wait(5)

             clickbutton = self.findElement(*self.saveBtn)

             time.sleep(1)

             clickbutton.click()

         except Exception:

             log.logger.exception('click save button fail')

             raise

         else:

             log.logger.info('clciking the button')

  

     #   修改密码功能菜单

     def modifyPwMenu(self):

         """

  

         :return:

         """

         try:

             self.findElement(*self.menuList[0]).click()

             self.findElement(*self.menuPersonal).click()

             self.findElement(*self.menuModifyPwd).click()

         except Exception:

             log.logger.exception('not found menu [%s]-[%s]-[%s]' %(self.menuList[0], self.menuPersonal, self.menuModifyPwd))

             raise

         else:

             log.logger.info('finding menu [%s]-[%s]-[%s]' %(self.menuList[0], self.menuPersonal, self.menuModifyPwd))

             self.driver.implicitly_wait(2)

  

     #   修改密码

     def modifyPw(self, list):

         """

  

         :param list:

         :return:

         """

         try:

             self.inputOldPw(list[0])

             self.inputNewPw(list[1])

             self.inputConfirmPw(list[2])

             self.saveButton()

         except Exception:

             log.logger.exception('input oldpw/newpw/commitpw [%s]/[%s]/[%s] fail' %(list[0], list[1], list[2]))

             raise

         else:

             log.logger.info('modifing pw [%s]/[%s]/[%s]' %(list[0], list[1], list[2]))

  

     #   错误提示框

     def errorDialog(self, commit_btn = (By.ID,'unieap_form_Button_1_unieap_input')):

         """

         :type commit_btn: 元祖

         """

  

         try:

             messages_frame = self.findElement(*self.errMessage)

             text = messages_frame.text

             element = self.findElement(*commit_btn)

             time.sleep(2)

             action = ActionChains(self.driver)

             action.move_to_element(element).perform()

             time.sleep(2)

             element.click()

             action.reset_actions() # 释放鼠标

         except Exception:

             log.logger.exception('close errMsgFram [%s] or get text [%s]fail' %(self.errMessage))

             raise

         else:

             log.logger.info('close errMsgFram [%s] and get text [%s] success' %(self.errMessage, text))

             return text

  

     # 关闭提示框

     def closeErrMsg(self, element):

         try:

             ele = self.findElement(*element)

             action = ActionChains(self.driver)

             action.move_to_element(ele).perform()

             time.sleep(2)

             ele.click()

             action.reset_actions()

         except Exception:

             log.logger.exception('close the err msg ifram fail', exc_info=True)

             raise

         else:

             log.logger.info('closing the err msg ifram success!')

  

 if __name__ == '__main__':

     pass

9.ModifyPw.py(修改密码测试用例)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

'''

 Code description:权限管理/个人设置/密码修改 testcase

 Create time:

 Developer:

 '''

  

 import time

 from retail.test_case.models.myunit import MyunitTest

 from retail.test_case.page_obj.modifypw_page import PrimaryMenu

 from retail.test_case.models.strhandle import strhandle

  

 class ModifyPw_TC(MyunitTest):

  

     """权限管理/个人设置/密码修改模块测试用例"""

  

     def test_menu_is_display(self):

         """主菜单校验"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         time.sleep(4)

         num = 0

         for menu_item in menu.menuList: # 循环遍历并断言菜单是否正确

             self.assertEqual(menu.menuList[num][1],(menu.findMenu(*menu_item).text),'菜单不存在')

             num=num+1

  

     def test_modify_password_len(self):

         """旧密码非空,新密码长度小于4位,确认密码非空,修改密码失败,弹窗提示"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         menu.modifyPw(menu.pwdList[0]) # 修改密码

         text = menu.errorDialog(menu.closeBtn)

         self.assertIn('密码长度至少 4 位!', text, '提示信息错误') # 密码长度不满足时断言提示信息

  

     def test_modify_password_strebgth(self):

         """旧密码非空,新密码长度大于4且强度不够,确认密码非空,修改密码失败,弹窗提示"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         menu.modifyPw(menu.pwdList[1]) # 修改密码

         text = menu.errorDialog(menu.closeBtn)

         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!') # 密码强度不满足时断言提示信息

  

     def test_modify_password_incorrect(self):

         """旧密码不正确非空,新密码等于确认密码且满足条件,修改密码失败,弹窗提示"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         menu.modifyPw(menu.pwdList[2]) # 修改密码

         text = menu.errorDialog(menu.closeBtn)

         self.assertIn('旧密码输入错误!', text, '旧密码输入错误!') # 新密码和确认码不同时断言提示信息

  

     def test_modify_password_difference(self):

         """旧密码非空,新密码不等于确认密码且新密码满足条件,修改密码失败,弹窗提示"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         menu.modifyPw(menu.pwdList[3]) # 修改密码

         text = menu.errorDialog(menu.closeBtn)

         self.assertIn('两次输入的新密码不同!', text, '两次输入的新密码不同!') # 新密码和确认码不同时断言提示信息

  

     def test_modify_password_all_blank(self):

         """旧密码,新密码,确认密码任意为空,修改密码失败,弹窗提示"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         menu.modifyPw(menu.pwdList[4]) # 修改密码

         text = menu.errorDialog(menu.closeBtn)

         self.assertIn('该输入项的值不能为空!', text, ' 该输入项的值不能为空!') # 所有密码均为空时断言提示信息

  

     def test_modify_password(self):

         """循环校验提示信息"""

         self.login.loginFunc()

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu() # 查找修改密码页面

         error_list = []

         for list in range(len(menu.pwdList)):

             menu.modifyPw(menu.pwdList[list])

             if menu.isElementExist(menu.errMessage):

                 text = menu.errorDialog(menu.closeBtn) # 这里只判断是否有提示框弹出,如有说明修改失败,没有或者其他提示框默认为修改成功

                 error_list.append(text)

             else:

                 self.assertTrue(menu.isElementExist(*menu.errMessage), 'error fram not exist, please open bug')

         self.assertEqual('密码长度至少 4 位!',error_list[0],'log infomation error!')

         self.assertEqual('密码强度不够,请重新输入密码!', error_list[1], 'log infomation error!')

         self.assertEqual('旧密码输入错误!', error_list[2], 'log infomation error!')

         self.assertEqual('两次输入的新密码不同!', error_list[3], 'log infomation error!')

         self.assertEqual('该输入项的值不能为空!', error_list[4], 'log infomation error!')

  

     def test_modifypw(self):

         """循环测试修改密码功能"""

         self.login.loginFunc()# 登录

         menu = PrimaryMenu(self.driver)

         menu.modifyPwMenu()  # 查找修改密码页面

         for item in menu.pwdList:

             menu.modifyPw(item)

             if menu.isElementExist(menu.errMessage):  # 如果存在提示框 再断言提示信息是否正确

                 if item[0] != '' and len(item[1]) < 4  and item[2] !='': # 新密码长度校验

                     text = menu.errorDialog(menu.closeBtn)

                     try:

                         self.assertEqual('密码长度至少 4 位!',text,'the message incorrect!')

                     except Exception:

                         menu.saveScreenShot('fail_密码长度.png')

                         raise

                 elif item[0] != '' and len(item[1]) >= 4 and item[2] !='': # 新密码强度校验 ['a', 'qwert', 'qwert'],

                     lowercase, uppercase, number, other=strhandle(item[1])

                     if lowercase > 0 and uppercase > 0 and number == 0 and other == 0: # 小写 大写

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif uppercase > 0 and other > 0 and number == 0 and lowercase == 0: # 大写 特殊字符

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase >0 and other > 0 and number == 0 and uppercase == 0: # 小写 特殊字符

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase == 0 and other == 0 and number > 0 and uppercase > 0# 大写 数字

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase > 0 and other == 0 and number > 0 and uppercase == 0# 小写 数字

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase > 0 and other == 0 and number == 0 and uppercase == 0:

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase == 0 and other > 0 and number == 0 and uppercase == 0:

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase == 0 and other == 0 and number > 0 and uppercase == 0:

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif lowercase == 0 and other == 0 and number == 0 and uppercase > 0:

                         text = menu.errorDialog(menu.closeBtn)

                         self.assertIn('密码强度不够,请重新输入密码!', text, ' 密码强度不够,请重新输入密码!')

                     elif item[0] != 'qwert1234!@#' and item[1] == item[2]:# >= 4

                         lowercase, uppercase, number, other = strhandle(item[1])

                         if (lowercase > 0 and uppercase > 0 and number > 0) or (

                                     lowercase > 0 and uppercase > 0 and other > 0) or (

                                     number > 0 and other > 0 and lowercase > 0) or (

                                     number > 0 and other > 0 and uppercase > 0):

                             text = menu.errorDialog(menu.closeBtn)

                             self.assertIn('旧密码输入错误!', text, '旧密码输入错误!'# 新密码和确认码不同时断言提示信息

                     elif item[0] == 'qwert1234!@#$' and item[1] != item[2]:# and item[1] >= 4:

                         lowercase, uppercase, number, other = strhandle(item[1])

                         if (lowercase > 0 and uppercase > 0 and number > 0) or (

                                             lowercase > 0 and uppercase > 0 and other > 0) or (

                                             number > 0 and other > 0 and lowercase > 0) or (

                                             number > 0 and other > 0 and uppercase > 0):

                             text = menu.errorDialog(menu.closeBtn)

                             self.assertIn('两次输入的新密码不同!', text, ' 两次输入的新密码不同!')

                     else:

                         print('test value incorrect! please check it')

                 elif item[0] == '' or item[1] =='' or item[2] =='': # 输入项为空校验

                     text = menu.errorDialog(menu.closeBtn)

                     self.assertIn('该输入项的值不能为空!', text, ' 该输入项的值不能为空!'# 所有密码均为空时断言提示信息

             else:

                 self.assertTrue(menu.isElementExist(menu.errMessage), 'error fram not exist, please check the test value or file bug')

  

 if __name__=='__main__':

     pass

10.RunTc.py(执行测试用例)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#! user/bin/python

'''

Code description:auto run test case

Create time:

Developer:

'''

import unittest

import time

from BeautifulReport import BeautifulReport

from retail.config.conf import *

from retail.test_case.models.testreport import testreport

# TODO : will be use jenkins continuous intergration teachnology manage the auto project

if __name__ == '__main__':

    # currTime = time.strftime('%Y-%m-%d %H_%M_%S')

    # filename = currTime + '.html'

    # # 第一种测试报告

    # test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='*Tc.py')

    # result = BeautifulReport(test_suite)

    # result.report(filename= filename, description='test report', log_path=reportPath)

    # # 第二种测试报告

    runner, fp, fileName = testreport()

    test_suite = unittest.defaultTestLoader.discover(tcPath, pattern='LoginTc.py')

    runner.run(test_suite)

    fp.close()

11.备注

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

12.输出结果展示

1.创建规则失败时截图

 

2.登录成功截图

 

3.用例执行日志

 

4.测试报告

​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/231274.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Azure Machine Learning - 使用 Azure OpenAI 服务生成文本

使用 Azure OpenAI 服务生成文本 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&#xff0c;项目管理专业人士&…

快解析结合智邦国际使用教程

北京智邦国际软件技术有限公司&#xff0c;是经中华人民共和国工业和信息化部以及北京经济和信息化委员会评定和审核的双软企业&#xff0c;国家重点支持的高新技术企业。 十几年来致力于企业信息化&#xff0c;主要从事ERP、CRM、项目管理、人资管理、移动应用等企业管理软件的…

探索 SNMPv3 魔法:armbian系统安装snmp服务并通过SNMPV3进行连接控制

文章目录 说明SNMP服务的安装本机连接SNMPV3操作MIB Browser连接SNMPV3问题总结密码过短权限配置错误&#xff0c;导致OID不存在 说明 工具 建议尝试专业版ireasoning MIB brower&#xff0c;因为只有专业版支持SNMP v3的连接。当然&#xff0c;也可以尝试其他SNMP客户端工具 …

C++系列第七篇 数据类型下篇 - 复合类型(结构体、共用体及枚举)

系列文章 C 系列 前篇 为什么学习C 及学习计划-CSDN博客 C 系列 第一篇 开发环境搭建&#xff08;WSL 方向&#xff09;-CSDN博客 C 系列 第二篇 你真的了解C吗&#xff1f;本篇带你走进C的世界-CSDN博客 C 系列 第三篇 C程序的基本结构-CSDN博客 C 系列 第四篇 C 数据类型…

【MATLAB】辛几何模态分解分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 辛几何模态分解&#xff08;CEEMDAN&#xff09;是一种处理非线性和非平稳信号的适应性信号分解方法。通过在信号中加入白噪声&#xff0c;并多次进行经验模态分解&#xff08;EMD&#…

2024年度AI投资策略报告:乘AI之风,破明日之浪

今天分享的AI系列深度研究报告&#xff1a;《2024年度AI投资策略报告&#xff1a;乘AI之风&#xff0c;破明日之浪》。 &#xff08;报告出品方&#xff1a;万联证券&#xff09; 报告共计&#xff1a;25页 1 需求复苏&#xff0c;政策指引热点驱动AI 赋能助推行业发展 1.1 …

uniapp实战 —— 骨架屏

1. 自动生成骨架屏代码 在微信开发者工具中&#xff0c;预览界面点击生成骨架屏 确定后&#xff0c;会自动打开骨架屏代码文件 pages\index\index.skeleton.wxml 2. 将骨架屏代码转换为vue文件 在项目中新建文件 src\pages\index\components\skeleton.vue 将pages\index\index…

湖南大学-电路与电子学-2021期末A卷★(不含解析)

【写在前面】 电路与电子学好像是从2020级开设的课程&#xff0c;故实际上目前只有2020与2021两个年级考过期末考试。 本份卷子的参考性很高&#xff0c;这是2020级的期末考卷。题目都是很典型的&#xff0c;每一道题都值得仔细研究透。 特别注意&#xff1a;看得懂答案跟写得…

代码随想录算法训练营 ---第六十天

今天是最后一天&#xff0c;也是最后一题了&#xff0c;单调栈的应用&#xff0c;是昨天单调栈的变形题。 第一题&#xff1a; 简介&#xff1a; 本题和昨天的接雨水题可以说是很相似的一题。我们知道做单调栈问题&#xff0c;我们要先明确我们的单调栈是递增还是递减。由题意…

Android studio生成二维码

1.遇到的问题 需要生成一个二维码&#xff0c;可以使用zxing第三方组件&#xff0c;增加依赖。 //生成二维码 implementation com.google.zxing:core:3.4.1 2.代码 展示页面 <ImageViewandroid:id"id/qrCodeImageView"android:layout_width"150dp"an…

Kafka集成springboot

安装kafka&#xff0c;直接到官网下载bin文件&#xff0c;本文使用windows进行使用kafka。 下载之后&#xff0c;第一步&#xff0c;启动zookeeper&#xff1a; zookeeper-server-start.bat ..\..\config\zookeeper.properties 第二步&#xff0c;启动kafka&#xff1a; kafka…

玩转系统|利用HestiaCP自建NS解析及邮局并利用MailGun进行发信

前述 HestiaCP是一个VestaCP分叉来的产物&#xff0c;而同样作为VestaCP分叉来的myVesta也具有类似的功能。VestaCP本身作为一个社区的产区&#xff0c;其仅仅有一个商业插件需要每月付费5USD进行使用&#xff0c;因此为了达到完全开放使用的目的&#xff0c;这里选择使用Hest…

yolov8添加cbam注意力机制

(如果添加的是CBAM&#xff0c;已存在&#xff0c;忽略步骤 1 2 3) 步骤1.创建注意力机制-类 ultralytics/nn/modules/conv.py 步骤2.添加到conv.py文件的头文件里 ultralytics/nn/modules/conv.py 步骤3.添加到 init.py文件的头文件里 ultralytics/nn/modules/init.py…

SD之lora训练

目录 为什么要训练自己的模型 SD模型微调方法 准备素材 1 确定要训练的LoRA类型 2 图片收集 3 图片预处理 4 图片标注 安装Koyha_ss 训练lora 1.准备参数和环境 2.启动训练 使用模型 1 拷贝训练过的lora模型 2 启动SD WebUI进行图像生成 为什么要训练自己的模型 …

redis集群(cluster)笔记

1. 定义&#xff1a; 由于数据量过大&#xff0c;单个Master复制集难以承担&#xff0c;因此需要对多个复制集进行集群&#xff0c;形成水平扩展每个复制集只负责存储整个数据集的一部分&#xff0c;这就是Redis的集群&#xff0c;其作用是提供在多个Redis节点间共享数据的程序…

基于Swin_Transformer的图像超分辨率系统

1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 研究背景与意义 随着科技的不断发展&#xff0c;图像超分辨率技术在计算机视觉领域中变得越来越重要。图像超分辨率是指通过使用计算机算法将低分辨率图像转换为高分辨率图像的过…

111.am40刷机折腾记4-firefly镜像-dp正常显示

1. 平台&#xff1a; rk3399 am40 4g32g 2. 内核&#xff1a;firefly的内核&#xff08;整体镜像&#xff09; 版本&#xff1a; linux4.4.194 3. 交叉编译工具 &#xff1a;暂时不编译 4. 宿主机&#xff1a;ubuntu18.04 5. 需要的素材和资料&#xff1a;boot-am40-202…

Uos打包工具最新

我司中标的桌面端项目&#xff08;electron开发的应用&#xff09;需兼容统信UOS&#xff0c;关键是要发布到应用商店&#xff0c;首先使用了debreateForUos工具进行打包&#xff0c;打包之后也通过了审核上架到了商店&#xff0c;本以为一切都是如此丝滑顺利&#xff0c;但后续…

10个电子工程师常用的测量仪器详解

之前我们聊了电子工程师常用的模电及数电&#xff0c;得到了很多粉丝朋友的追捧&#xff0c;所以今天主要讲讲电子工程师常用的测量仪器&#xff0c;希望对小伙伴们有所帮助&#xff0c;一起来看看吧&#xff01; 1、万用表 万用表是最基本的测量仪器之一&#xff0c;用于测量…