[Automated Testing] PO model introduction and cases

Table of contents

concept

PO three-tier model:

1. Build the basic BasePage object layer

2. Build the Page layer (operation layer) of the homepage

3. Build the business layer

Commonly used assertion methods:

4. Build use case sets, execute files, and output automated test reports

 Test report template


concept

PO (Page Object) design pattern is an object-oriented (page object) design pattern that encapsulates test objects and individual test steps in each Page object and manages them in units of pages.

advantage

  1. Enables code reuse
  2. Reduce maintenance costs
  3. Improve program readability and writing efficiency.
  4. You can separate page positioning and business operations, test objects (element objects) and test scripts (use case scripts)
  5. Improve the maintainability of use cases
Non-PO mode PO mode
Process-oriented linear scripting POM separates page element positioning and business operation processes to achieve loose coupling.
Poor reusability Changing UI elements does not require modifying the business logic code. You only need to find the corresponding PO page and modify the positioning. The data code is separated.
Poor maintenance PO can make the code more readable, highly reusable and maintainable

PO three-tier model:

It is mainly divided into three layers:
1. Base layer (object library layer): Some public methods on the page page. Such as: initialization, element positioning, click, input, text acquisition, screenshots, etc.;
2. Page layer (operation layer): encapsulates operations on elements. Encapsulate each involved element operation into an operation method separately, and then assemble the operation steps according to the needs, such as login method = enter account + enter password + click to log in three operations to assemble; 3.scripts layer (business layer): guide
package call page page, use the unit testing framework to encapsulate and test the business logic. For example: to implement login, just call the login method of page assembly directly.
The relationship between the three: The page layer inherits the base layer, and the scripts layer calls the page layer.

Case:

Project structure introduction:

Create a project as shown below

1. Build the basic BasePage object layer

Create driver, browser driver package

# encoding='UTF-8'
# 浏览器启动
from selenium import webdriver
def browser():
    driver=webdriver.Chrome()
    # driver.get("http://www.baidu.com")
    return driver

Create the myuni.py file and initialize the package.

Define a test case class that inherits from unittest.TestCase

Define setUp and tearDown. These two methods are the same as junit. That is, if defined, the setUp method will be executed before each test case is executed, and the tearDown method will be executed after execution.

# encoding='UTF-8'
import unittest
from driver import *
class StartEnd(unittest.TestCase):
    def setUp(self):
        self.driver=browser()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

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

Create function.py file and screenshot function

# encoding='UTF-8'
import os
from selenium import webdriver

# 截图
def insert_img(driver,filename):
    func_path=os.path.dirname(__file__)
    # print(func_path)
    base_dir=os.path.dirname(func_path)
    # print(base_dir)
    # 将路径转化为字符串
    base_dir=str(base_dir)
    # 对路径的字符串进行替换
    base_dir=base_dir.replace("\\","/")
    # print(base_dir)
    # 获取项目文件的要目录路径
    base=base_dir.split('/Website')[0]
    # print(base)
    # 指定截图存放路径(注意路径最后要加/)
    filepath=base+'/Website/test_report/screnshot/'+filename
    driver.get_screenshot_as_file(filepath)

if __name__=='__main__':
    driver=webdriver.Chrome()
    driver.get("http://www.sogou.com")

2. Build the Page layer (operation layer) of the homepage

Create the BasePage.py file to determine whether the opened page is the expected page

# encoding='UTF-8'
from time import sleep

class Page():
    def __init__(self,driver):
        self.driver=driver
        self.base_url="http://localhost"
        self.timeout=10

    def _open(self,url):
        url_=self.base_url+url
        # print("这个页面url是:%s"%url_)
        self.driver.maximize_window()
        self.driver.get(url_)
        # sleep(2)
        assert self.driver.current_url==url_,'这不是我们想要的地址'

    def open(self):
        self._open(self.url)

    def find_element(self,*loc):
        return self.driver.find_element(*loc)

Create the LoginPage.py file and page element positioning encapsulation

# encoding='UTF-8'
from BasePage import *
from selenium.webdriver.common.by import By

class LoginPage(Page):
    url='/news/'

    username_loc=(By.NAME,'username')
    password_loc=(By.NAME,'password')
    submit_loc=(By.NAME,'Submit')

    def type_username(self,username):
        self.find_element(*self.username_loc).send_keys(username)
    def type_password(self,password):
        self.find_element(*self.password_loc).send_keys(password)
    def type_submit(self):
        self.find_element(*self.submit_loc).click()

    def login_action(self,username,password):
        self.open()
        self.type_username(username)
        self.type_password(password)
        self.type_submit()

    loginPass_loc=(By.LINK_TEXT,'我的空间')
    loginErr_loc=(By.LINK_TEXT,'加入收藏')

    def type_loginPass_hint(self):
        return self.find_element(*self.loginPass_loc).text

    def type_loginErr_hit(self):
        return self.find_element(*self.loginErr_loc).text

3. Build the business layer

  1. Create test_login.py file
  2. 导包:function、myunit、LoginPage
  3. Create the LoginTest class, inherit myunit.StartEnd, and initialize the method
  4. Define a test case with a name starting with test. Unittest will automatically put the method starting with test into the test case set.
  5. To implement login, call the login method assembled by LoginPage, enter user name, password, click login, assert, and take screenshots
# encoding='UTF-8'
import unittest
from model import function,myunit
from page_object.LoginPage import *
from time import sleep

class LoginTest(myunit.StartEnd):
    def test_login1_normal(self):
        print("test_login1_normal测试开始")
        po=LoginPage(self.driver)
        po.login_action("yuruyi","12345678")
        sleep(5)
        self.assertEqual(po.type_loginPass_hint(),'我的空间')
        function.insert_img(self.driver,"login_normal.png")
        print("test_login1_normal执行结束")

    def test_login2_PasswdError(self):
        print("test_login2_PasswdError测试开始")
        po=LoginPage(self.driver)
        po.login_action("yuruyi","1234567")
        sleep(5)
        self.assertEqual(po.type_loginErr_hit(),'加入收藏')
        function.insert_img(self.driver,"login_Err.png")
        print("test_login2_PasswdError执行结束")

    def test_login3_empty(self):
        print("test_login3_empty测试开始")
        po = LoginPage(self.driver)
        po.login_action("", "")
        sleep(5)
        self.assertEqual(po.type_loginErr_hit(), '加入收藏')
        function.insert_img(self.driver, "login_empty.png")
        print("test_login3_empty执行结束")

if __name__=='__main__':
    unittest.main()

Commonly used assertion methods:

4. Build use case sets, execute files, and output automated test reports

When there are many test cases and test files, it is very convenient to use a unified main test execution file to execute test cases, which requires combining the discover method and TextTestRunner.

# encoding='UTF-8'
import unittest
# 测试报告模板
from HTMLTestRunnerCN import HTMLTestRunner
import time

report_dir='./test_report'
test_dir='./test_case'

print("start run test case")
discover=unittest.defaultTestLoader.discover(test_dir,pattern="test_login.py")

now=time.strftime("%Y-%m-%d %H_%M_%S")
report_name=report_dir+'/'+now+'result.html'

print("start write report..")
#使用runner运行器运行测试集
with open(report_name,'wb')as f:
    runner=HTMLTestRunner(stream=f,title="Test Report",description="localhost login test")
    runner.run(discover)
    f.close()
print("Test end")

 Test report template

 


The following are relatively good learning tutorial resources that I have collected. Although they are not very valuable, if you happen to need them, you can leave a message in the comment area [777] and just take them away.

 

Friends who want to get information, please like + comment + collect , three times in a row!

After three consecutive rounds , I will send you private messages one by one in the comment area~

Guess you like

Origin blog.csdn.net/m0_70618214/article/details/132763950