wangwt123

UI自动化测试-页面对象设计(PO)

一、为什么使用页面对象设计

在之前的UI自动化测试的学习中,我们认为我们的有些代码模块,还是可以进一步有优化的,因而页面对象设计应运而生。

使用页面对象设计的优势在于:

  • 可以创建跨多个测试用例共享的代码
  • 减少一些重复代码的书写
  • 如果用户界面发生了一些变化,我们只需要维护一个地方,这样不仅对于修改以及维护的成本会降低,而且也会提高我们测试人员的工作效率。

二、目录结构设计

之所以建成这样,是因为:

  • base的包下主要编写基础的代码,可以理解为基础层
  • page包下主要存放对象层的代码,可以理解为对象层
  • test报下主要存放编写的测试模块的代码,可以理解为测试层
  • utils下存放的主要是工具类的代码,比如针对JSON文件,YAML文件的处理
  • common下主要存放的是公共类的代码,比如文件目录的处理
  • data主要存放测试过程中使用到的数据
  • report主要存储的是测试报告这部分

三、页面对象设计模式(PO:Page Object)

3-1:基础层(base)

首先在基础层里新建一个名为:“base.py”的文件,内容如下:

 1 from selenium import webdriver
 2 from selenium.webdriver.support.expected_conditions import NoSuchElementException
 3 from selenium.webdriver.common.by import By
 4 import time as t
 5 
 6 
 7 
 8 class WebDriver(object):
 9     def __init__(self,driver):
10         # self.driver=webdriver.Chrome()
11         # self.driver是driver实例化后的对象
12         self.driver=driver
13 
14 
15     def findElement(self,*loc):
16         '''单个元素定位的方式'''
17         try:
18             # loc即表示括号里面是动态参数,*也表示括号中的元素是元组类型
19             return self.driver.find_element(*loc)
20         except NoSuchElementException as e:
21             return e.args[0]
22 
23 
24     def findElements(self,*loc):
25         '''多个元素定位的方式'''
26         try:
27             return self.driver.find_elements(*loc)
28         except NoSuchElementException as e:
29             return e.args[0]

3-2:对象层(page)

其次在对象层里新建两个名为:“login_sina.py”和“register_sina.py”的文件,我们以新浪邮箱的“登陆”和“注册”为例,内容如下:

“login_sina.py”代码如下:

 1 from selenium import webdriver
 2 from selenium.webdriver.support.expected_conditions import NoSuchElementException
 3 from selenium.webdriver.common.by import By
 4 import time as t
 5 from base.base import WebDriver
 6 
 7 class Login(WebDriver):
 8     username=(By.ID,'freename')
 9     password=(By.ID,'freepassword')
10     loginButton=(By.LINK_TEXT,'登录')
11     usernameDev=(By.CSS_SELECTOR,'body > div.mailLoginBox > div > div.mainBox.bg1 > div > div > div:nth-child(6) > div.loginBox > div.freeMailbox > div.freeError > span.loginError.tip11')
12     passwordDev=(By.CSS_SELECTOR,'body > div.mailLoginBox > div > div.mainBox.bg1 > div > div > div:nth-child(6) > div.loginBox > div.freeMailbox > div.freeError > span.loginError.tip13')
13     emailsuccess=(By.ID,'right_nav_1')
14     autologin=(By.ID,'store1')
15 
16 
17     def inputusername(self,username):
18         '''输入框:输入邮箱名/手机号'''
19         t.sleep(3)
20         self.findElement(*self.username).send_keys(username)
21 
22     def inputpassword(self,password):
23         '''输入框:输入密码'''
24         t.sleep(3)
25         self.findElement(*self.password).send_keys(password)
26 
27     def clicklogin(self):
28         '''点击登录'''
29         t.sleep(3)
30         self.findElement(*self.loginButton).click()
31 
32     def getusernameDev(self):
33         '''获取错误的用户名'''
34         t.sleep(3)
35         return self.findElement(*self.usernameDev).text
36 
37     def getpasswordDev(self):
38         '''获取错误的密码'''
39         t.sleep(3)
40         return self.findElement(*self.passwordDev).text
41 
42     def getemailsucces(self):
43         '''获取登陆成功的[首页]文字'''
44         t.sleep(3)
45         return self.findElement(*self.emailsuccess).text
46 
47     def autologinyes(self):
48         '''自动勾选[自动登录]'''
49         t.sleep(3)
50         return self.findElement(*self.autologin).is_selected()
51 
52     def autologinno(self):
53         '''取消自动勾选[自动登录]'''
54         t.sleep(3)
55         return self.findElement(*self.autologin).click()

“register_sina.py”代码如下:

 1 from selenium.webdriver.common.by import By
 2 import time as t
 3 from base.base import WebDriver
 4 
 5 
 6 class Register(WebDriver):
 7     register=(By.LINK_TEXT,'注册')
 8     agree=(By.ID,'agreement1')
 9     lijiregister=(By.CSS_SELECTOR,'body > div.main > div > div > div > div > form:nth-child(2) > div:nth-child(8) > ul > li > div > div > a')
10     emailnull=(By.CSS_SELECTOR,'body > div.main > div > div > div > div > form:nth-child(2) > div:nth-child(7) > ul > li.fiSel.zIndexNew > div.tipText > p > abbr')
11     passwordnull=(By.CSS_SELECTOR,'body > div.main > div > div > div > div > form:nth-child(2) > div:nth-child(7) > ul > li:nth-child(2) > div.tipText > p > abbr')
12 
13 
14 
15     def click_register(self):
16         '''点击新浪邮箱的注册'''
17         t.sleep(3)
18         self.findElement(*self.register).click()
19 
20 
21 
22     def click_agree(self):
23         '''点击勾选协议'''
24         t.sleep(3)
25         self.findElement(*self.agree).click
26 
27 
28 
29     def click_lijiregister(self):
30         '''点击立即注册'''
31         t.sleep(3)
32         self.findElement(*self.lijiregister).click()
33 
34 
35 
36 
37     def clickReg(self): #封装
38         self.click_agree()
39         self.click_lijiregister()
40 
41 
42 
43     def getEmail(self):
44         '''获取邮箱一栏的提示信息'''
45         t.sleep(3)
46         return self.findElement(*self.emailnull).text
47 
48 
49 
50     def getpassword(self):
51         '''获取密码一栏的提示信息'''
52         t.sleep(3)
53         return self.findElement(*self.passwordnull).text

3-3: 测试层(test)

再者,在测试层,也就是test包下创建两个“test_sina_login.py”和“test_sina_register.py”

的文件,内容为:

“test_sina_login.py”文件的内容如下:

 1 from selenium import  webdriver
 2 from page.login_sina import Login
 3 import unittest
 4 from utils.operationJson import readJson
 5 
 6 class TestLogin(unittest.TestCase,Login):
 7     def setUp(self) -> None:
 8         self.driver=webdriver.Chrome()
 9         self.driver.maximize_window()
10         self.driver.get("https://mail.sina.com.cn/#")
11         self.driver.implicitly_wait(30)
12 
13     def tearDown(self) -> None:
14         self.driver.quit()
15 
16     def test_username_null(self):
17         '''登录验证:账户为空错误提示信息验证'''
18         self.login(username='',password='12334')
19         # self.assertEqual(self.getuserDev(),"请输入邮箱名")
20         self.assertEqual(self.getusernameDev(), readJson()["nullEmail"])
21 
22     def test_email_format_error(self):
23         '''登录验证:验证邮箱格式错误'''
24         self.login(username='gfs',password='hhhhf')
25         # self.assertEqual(self.getuserDev(),"您输入的邮箱名格式不正确")
26         self.assertEqual(self.getusernameDev(),readJson()["formatEmail"])
27 
28     def test_username_password_error(self):
29         '''登录验证:验证登录账户错误'''
30         self.login(username='gfhhgh@sina.com',password='xgfj')
31         # self.assertEqual(self.getuserDev(),"登录名或密码错误")
32         self.assertEqual(self.getusernameDev(),readJson()["loginError"])
33 
34     def test_password_null(self):
35         '''登录验证:验证密码为空错误提示信息'''
36         self.login(username='gfhhgh@sina.com',password='')
37         # self.assertEqual(self.getpssswdDev(),"请输入密码")
38         self.assertEqual(self.getpasswordDev(), readJson()["nullPasswd"])
39 
40 
41     def test_login_success(self):
42         '''登录验证:验证登录成功的账户'''
43         self.login(username='wuya1303@sina.com',password='admin123')
44         self.assertEqual(self.getemailsucces(),"wuya1303@sina.com")
45 
46     def test_auto_login(self):
47         '''自动登陆勾选'''
48         self.assertTrue(self.autologinyes())
49 
50 
51     def test_auto_login_cancel(self):
52         '''取消自动登陆勾选'''
53         self.autologinno()
54         self.assertFalse(self.autologinyes())
55 
56 if __name__ == '__main__':
57     unittest.main()

“test_sina_register.py”文件的内容如下:

 1 from selenium import webdriver
 2 from page.register_sina import Register
 3 import unittest
 4 from utils.operationJson import readJson
 5 import time as t
 6 
 7 class TestLogin(unittest.TestCase,Register):
 8     def setUp(self) -> None:
 9         self.driver=webdriver.Chrome()
10         self.driver.maximize_window()
11         self.driver.get("https://mail.sina.com.cn/#")
12         self.driver.implicitly_wait(30)
13 
14     def tearDown(self) -> None:
15         self.driver.quit()
16 
17     def test_email_null(self):
18         '''注册之后:邮箱名为空错误提示信息验证'''
19         nowpage=self.driver.current_window_handle
20         self.click_register()
21         allpages=self.driver.window_handles
22         t.sleep(3)
23         for hander in allpages:
24             if nowpage!=hander:
25                 self.driver.switch_to.window(hander)
26                 self.clickReg()
27                 self.assertEqual(self.getEmailDev(),'请输入邮箱名')
28 
29 if __name__ == '__main__':
30     unittest.main()

3-4:公共类(common)

然后,在common包下创建一个“public.py”的文件,里面主要编写针对文件路径的处理,具体内容如下:

 1 import os
 2 
 3 def base_dir():
 4     return os.path.dirname(os.path.dirname(__file__))
 5 
 6 def filePath(directory,filename):
 7     '''
 8     获取文件的详细路径
 9     :param directory:
10     :param filename:
11     :return:
12     '''
13     return os.path.join(base_dir(),directory,filename)

3-5:数据驱动(data)

下来在data的文件夹下创建一个“login.json”的文件,把使用到的数据分离到login.json的文件里面,内容为:

{
  "nullEmail": "请输入邮箱名",
  "formatEmail": "您输入的邮箱名格式不正确",
  "loginError": "登录名或密码错误",
  "nullPasswd": "请输入密码"
}

这样,我们就可以将“test_sina_login.py”文件测试代码改为这样:

这样,我们就可以将“test_sina_register.py”文件测试代码改为这样:

3-6:工具类(utils)

在具体的工具类中编写针对JSON文件的处理,创建的模块名称为:operationJson.py,具体源码为:

1 import json
2 from common.public import filePath
3 
4 def readJson():
5     return json.load(open(filePath(
6         directory="data",
7         filename="login.json"),encoding="utf-8"))
8 print(readJson())

3-7:测试固件分离

在page包下新建一个“init.py”文件,来具体分离我们的测试固件,内容为:

 1 from selenium import webdriver
 2 import unittest
 3 
 4 class Init(unittest.TestCase):
 5     def setUp(self) -> None:
 6         self.driver=webdriver.Chrome()
 7         self.driver.maximize_window()
 8         self.driver.implicitly_wait(30)
 9         self.driver.get("https://mail.sina.com.cn/#")
10 
11     def tearDown(self) -> None:
12         self.driver.quit()

3-8:完善后的测试层

“test_sina_login.py”文件测试代码完善为这样:

 1 from selenium import  webdriver
 2 from page.login_sina import Login
 3 import unittest
 4 from utils.operationJson import readJson
 5 from page.init import Init
 6 
 7 class TestLogin(Init,Login):
 8 
 9 
10     def test_username_null(self):
11         '''登录验证:账户为空错误提示信息验证'''
12         self.login(username='',password='12334')
13         # self.assertEqual(self.getuserDev(),"请输入邮箱名")
14         self.assertEqual(self.getusernameDev(),readJson()["nullEmail"])
15 
16     def test_email_format_error(self):
17         '''登录验证:验证邮箱格式错误'''
18         self.login(username='gfs',password='hhhhf')
19         # self.assertEqual(self.getuserDev(),"您输入的邮箱名格式不正确")
20         self.assertEqual(self.getusernameDev(),readJson()["formatEmail"])
21 
22     def test_username_password_error(self):
23         '''登录验证:验证登录账户错误'''
24         self.login(username='gfhhgh@sina.com',password='xgfj')
25         # self.assertEqual(self.getuserDev(),"登录名或密码错误")
26         self.assertEqual(self.getusernameDev(),readJson()["loginError"])
27 
28     def test_password_null(self):
29         '''登录验证:验证密码为空错误提示信息'''
30         self.login(username='gfhhgh@sina.com',password='')
31         # self.assertEqual(self.getpssswdDev(),"请输入密码")
32         self.assertEqual(self.getpasswordDev(),readJson()["nullPasswd"])
33 
34 
35     def test_login_success(self):
36         '''登录验证:验证登录成功的账户'''
37         self.login(username='wuya1303@sina.com',password='admin123')
38         self.assertEqual(self.getemailsucces(),"首页")
39 
40     def test_auto_login(self):
41         '''自动登陆勾选'''
42         self.assertTrue(self.autologinyes())
43 
44 
45     def test_auto_login_cancel(self):
46         '''取消自动登陆勾选'''
47         self.autologinno()
48         self.assertFalse(self.autologinyes())
49 
50 if __name__ == '__main__':
51     unittest.main()

“test_sina_register.py”文件测试代码完善为这样:

 1 from selenium import webdriver
 2 from page.register_sina import Register
 3 import unittest
 4 from utils.operationJson import readJson
 5 import time as t
 6 from page.init import Init
 7 
 8 class TestLogin(Init,Register):
 9 
10 
11     def test_email_null(self):
12         '''注册之后:邮箱名为空错误提示信息验证'''
13         nowpage=self.driver.current_window_handle
14         self.click_register()
15         allpages=self.driver.window_handles
16         t.sleep(3)
17         for hander in allpages:
18             if nowpage!=hander:
19                 self.driver.switch_to.window(hander)
20                 self.clickReg()
21                 # self.assertEqual(self.getEmailDev(),'请输入邮箱名')
22                 self.assertEqual(self.getEmailDev(),readJson()["nullEmail"])

3-9:报告(report)

在运行测试层的代码之前,先在PageObject工程下新建一个”main.py"文件,在该文件里写如下内容:

 1 import unittest
 2 import HTMLTestRunner   #在上一节里,已经在电脑里下载了这个第三方库
 3 import time
 4 from common.public import *
 5 
 6 '''
 7 import os
 8 因为在“common”包下“public"里存放的路径为:
 9 print(os.path.dirname(os.path.dirname(__file__)))   运行结果:D:\test\code\PageObject
10 所以:要拼接路径
11 '''
12 def allTests():
13     '''获取要执行的模块'''
14     suite=unittest.TestLoader().discover(
15         start_dir=os.path.join(base_dir(), 'test'),
16         pattern='test_*.py')
17     return suite
18 
19 def getNowTime():
20     return time.strftime("%y-%m-%d %H_%M_%S",time.localtime(time.time()))
21 
22 
23 def run():
24     filename=filePath(directory='report',filename=getNowTime()+'.html')
25     fp=open(file=filename,mode='wb')
26     runner=HTMLTestRunner.HTMLTestRunner(
27         stream=fp,
28         title='新浪邮箱自动化测试',
29         description='自动化测试内容'
30     )
31     runner.run(allTests())
32 
33 if __name__ == '__main__':
34     run()

然后运行测试文件,会在report文件夹下,生成具体的测试报告,用浏览器打开便可看到:

posted on 2022-07-03 18:43  DOUBLE快乐  阅读(154)  评论(0编辑  收藏  举报

导航