Page Object设计模式实践

  Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,通过对界面元素的封装减少冗余代码,同时在后期维护中,若元素定位发生变化,只需要调整页面元素封装的代码,提高测试用例的可维护性。

  本项目以163邮箱登录为例,163登录脚本(非PO模式)请查看博客中的随笔信息。

1、项目目录结构及相关介绍

test_programe 测试项目

  • driver:用于存放驱动
  • mail:用于存放163登录项目的测试用例、测试报告以及测试数据等
  • run_all_test.py:用于运行项目自动化用例

mail目录

  • data:存放测试数据
  • report:存放HTML测试不报告,其中该目录下的image目录用于存放测试过程中的截图
  • test_case:用于存放测试用例

test_case目录

  • model:存放配置函数及公共类
  • page_object:用于存放页面对象
  • login_case.py:测试对象用例

2、编写公共模块:

编写驱动文件... est_programemail est_casemodeldriver.py

 1 from selenium.webdriver import Remote
 2 from selenium import webdriver
 3 #启动浏览器驱动
 4 def browser():
 5     driver = webdriver.Chrome()
 6     '''
 7     #可以启动到远程主机中,运行自动化测试
 8     host = '127.0.0.1:4444' #运行主机:端口号(本机默认:127.0.0.1:4444)
 9     dc = {'browserName': 'chrome'}  #指定浏览器
10     driver = Remote(command_execute='http://' + host + '/wd/hub',
11                     desired_capabilities=dc)
12     '''
13     return driver
14 '''
15 #用于测试该脚本是否有效
16 if __name__ == '__main__':
17     dr = browser()
18 '''

编写测试公共类... est_programemail est_casemodelmyunit.py

from time import sleep
from .function import insert_img
import unittest
from .driver import browser


class MyTest(unittest.TestCase):


    def setUp(self):
        self.driver = browser()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()


    def tearDown(self):
        self.driver.quit()
myunit.py

 定义截图函数... est_programemail est_casemodelfunction.py

 1 from selenium import webdriver
 2 import os
 3 #截图函数
 4 def insert_img(driver, file_name):
 5     base_dir = os.path.dirname(os.path.dirname(__file__))
 6     #print(base_dir)
 7     base_dir = str(base_dir)
 8     #print(base_dir)
 9     base_dir = base_dir.replace('\','/')
10     #print(base_dir)
11     base = base_dir.split('/mail')[0]
12     #print(base)
13     file_path = base + '/mail/report/image/' + file_name
14     driver.get_screenshot_as_file(file_path)
15 
16 '''
17 #用于验证该脚本是否有效
18 if __name__ == '__main__':
19     driver = webdriver.Chrome()
20     driver.get('http://www.baidu.com')
21     insert_img(driver, 'baidu.jpg')
22     driver.quit()
23 '''
function.py

3、编写Page Object

创建基础类... est_programemail est_casepage_objectase.py

 1 from selenium import webdriver
 2 from selenium.webdriver.common.by import By
 3 from time import sleep
 4 import unittest
 5 #基本层
 6 class Base(object):
 7 
 8     
 9     def __init__(self, driver, base_url = 'http://mail.163.com'):
10         self.driver = driver
11         self.base_url = base_url
12         self.timeout = 30
13 
14     def _open(self, url):
15         url_ = self.base_url + url
16         #print(url_)
17         self.driver.maximize_window()
18         self.driver.get(url_)
19         sleep(2)
20         assert self.driver.current_url == url_, 'Did ont land on %s' % url_
21 
22     def open(self):
23         self._open(self.url)
24 
25     #*参数个数不是固定的(By.ID, 'kw')
26     def find_element(self, *loc):
27         return self.driver.find_element(*loc)
28 
29     def iframe(self, iframeid):
30         return self.driver.switch_to.frame(iframeid)
31 
32     def iframe_out(self):
33         return self.driver.switch_to.default_content()
34 
35     
View Code

创建163邮箱登录对象类... est_programemail est_casepage_objectlogin_page.py

 1 from selenium.webdriver.common.action_chains import ActionChains
 2 from selenium.webdriver.common.by import By
 3 from time import sleep
 4 from .base import Base
 5 
 6 #页面对象(PO)登录页面
 7 class LoginPage(Base):
 8     url = '/'
 9     login_iframe_loc = 'x-URS-iframe'
10     login_username_text_loc = (By.NAME, 'email')
11     login_password_text_loc = (By.NAME, 'password')
12     login_button_loc = (By.ID, 'dologin')
13     login_erro_hint_loc = (By.CLASS_NAME, 'ferrorhead')
14 
15     #把每一个元素封装成一个方法
16     def login_iframe(self):
17         self.iframe(self.login_iframe_loc)
18 
19     def login_iframe_out(self):
20         self.iframe_out()
21 
22     def login_username(self, text):
23         self.find_element(*self.login_username_text_loc).send_keys(text)
24 
25     def login_password(self, text):
26         self.find_element(*self.login_password_text_loc).send_keys(text)
27 
28     def login_button(self):
29         self.find_element(*self.login_button_loc).click()
30 
31     def login_error_hint(self):
32         self.login_iframe()
33         return self.find_element(*self.login_erro_hint_loc).text
34         self.login_iframe_out()
35 
36     def login_action(self, username, password):
37         self.login_iframe()
38         self.login_username(username)
39         self.login_password(password)
40         self.login_button()
41         self.login_iframe_out()
login_page.py

创建163邮箱登录成功后对象类... est_programemail est_casepage_objectmail_page.py

 1 from selenium.webdriver.common.action_chains import ActionChains
 2 from selenium.webdriver.common.by import By
 3 from time import sleep
 4 from .base import Base
 5 
 6 class MailPage(Base):
 7     url = '/'
 8     login_success_user_loc = (By.ID, 'spnUid')
 9 
10     def login_success_user(self):
11         return self.find_element(*self.login_success_user_loc).text
mail_page.py

4、编写测试用例

创建mail登录类... est_programemail est_caselogin_case.py

 1 from time import sleep
 2 import unittest, random, sys
 3 from model import myunit, function
 4 from page_object.login_page import LoginPage
 5 from page_object.mail_page import MailPage
 6 sys.path.append('./model')
 7 sys.path.append('./page_obj')
 8 
 9 class LoginTest(myunit.MyTest):
10 
11     def test_login_user_pwd_null(self):
12         '''用户名、密码为空登录'''
13         po = LoginPage(self.driver)
14         po.open()
15         po.login_action('','')
16         sleep(2)
17         self.assertEqual(po.login_error_hint(),'请输入帐号')
18         function.insert_img(self.driver, 'user_pwd_null.jpg')
19 
20     def test_login_pwd_null(self):
21         '''密码为空登录'''
22         po = LoginPage(self.driver)
23         po.open()
24         po.login_action('abc','')
25         sleep(2)
26         self.assertEqual(po.login_error_hint(),'请输入密码')
27         function.insert_img(self.driver, 'pwd_null.jpg')
28 
29     def test_login_user_pwd_error(self):
30         '''用户名或密码错误'''
31         po = LoginPage(self.driver)
32         po.open()
33         character = random.choice('zyxwvutsrqponmlkjihgfedcba')
34         username = "test" + character
35         po.login_action(username,"$#%#")
36         sleep(2)
37         #print(po.login_error_hint())
38         self.assertEqual(po.login_error_hint(),'帐号或密码错误')
39         function.insert_img(self.driver, "user_pwd_error.jpg")
40 
41     def test_login_success(self):
42         '''用户名、密码正确,登录成功'''
43         po = LoginPage(self.driver)
44         po.open()
45         user = "ldq791918813"
46         po.login_action(user,"xiuxiu060801zhu")
47         sleep(2)
48         po2 = MailPage(self.driver)
49         #print(po2.login_success_user())
50         self.assertEqual(po2.login_success_user(),user+"@163.com")
51         function.insert_img(self.driver, "success.jpg")
login_case.py

5、执行测试用例

创建用例执行代码... est_programe

 1 import unittest, time
 2 from HTMLTestRunner import HTMLTestRunner
 3 from email.mime.text import MIMEText
 4 from email.header import Header
 5 import smtplib, os
 6 
 7 #发送测试报告,需要配置你的邮箱账号
 8 def send_mail(file_new):
 9     f = open(file_new, 'rb')
10     mail_body = f.read()
11     f.close()
12     msg = MIMEText(mail_body, 'html', 'utf-8')
13     msg['Subject'] = Header("自动化测试报告", 'utf-8')
14     msg['From']= 'ldq791918813@163.com'
15     msg['To']= '791918813@qq.com'
16     smtp = smtplib.SMTP()
17     smtp.connect("smtp.163.com")
18     smtp.login("ldq791918813@163.com", "密码")
19     smtp.sendmail("ldq791918813@163.com","791918813@qq.com",msg.as_string())
20     smtp.quit()
21     print('email has send out!')
22 
23 #查找测试报告目录,找到最新生成的测试报告文件
24 def new_report(testreport):
25     lists = os.listdir(testreport)
26     lists.sort(key=lambda fn: os.path.getmtime(testreport + '\' + fn))
27     file_new = os.path.join(testreport, lists[-1])
28     print(file_new)
29     return file_new
30 
31 #指定测试用例为当前文件夹下的test_case目录
32 test_dir = './mail/test_case'
33 test_report = 'D:\sublimePython\test_programe\mail\report'
34 discover = unittest.defaultTestLoader.discover(test_dir, pattern = '*_case.py')
35 
36 if __name__ == "__main__":
37     
38     now = time.strftime("%Y-%m-%d %H_%M_%S")
39     filename = test_report + '/' + now + 'result.html'
40     fp = open(filename, 'wb')
41     #runner = unittest.TextTestRunner()
42     runner = HTMLTestRunner(stream=fp,
43                             title='测试报告',
44                             description="运行环境:windows 7, Chrome")
45     runner.run(discover)
46     fp.close()
47     
48     new_report = new_report(test_report)
49     send_mail(new_report)
run_all_test.py

6、HTML测试报告:

7、截图信息:

原文地址:https://www.cnblogs.com/diaosicai/p/6370321.html