Implementing 3000 + Concurrent Pressure Measurement of Cloud Server with Jmeter
A simple understanding of Unittest and Page Object design patterns:
Unitest is a unit testing framework that comes with Python. It can be used as a case organization execution framework for automated testing frameworks.
- Advantages: Provide us with use case organization and execution methods, comparative methods, rich logs and clear reports, etc.
The general flow of Unitest operation:
- TestCase is the test case that we often call it.
- Then the TestCase is loaded by TestLoader to TestSuite (that is, a collection of test cases)
- Finally, TextTest Runner runs TestSuite and saves the results to TextTest Result
- When executed from the command line or unittest.main(), the main() calls the run() method in TextTestRunner to execute, or the test case can be executed directly through TextTestRunner. When Runner executes, the result of execution will be output to the console by default. In order to view the output easily, we can use logging log to manage the output, and can output the result directly to the specified file.
Page Object is one of the best design patterns in Selenium's automated test development practice. It reduces code redundancy by encapsulating interface elements. At the same time, in the later maintenance, once the location of elements changes, we only need to adjust the encapsulated code of page elements, which can improve the dimensionality of test cases. Protective sex.
The Page Object design pattern is used to reconstruct the written code for the login test case of pea pod written earlier. The idea of reconstructing is as follows:
- Extract common content (such as canceling updates, skipping element locations, etc.)
- Separation of element location methods and element attribute values from business code
- Independently encapsulate the login function into a module
- Finally, unittest is used for overall planning.
Code implementation:
1. Separate encapsulation of startup information for Pea Pod App
xgCaps.py
from appium import webdriver import yaml, logging, logging.config log_file = '../log.conf' logging.config.fileConfig(log_file) logging = logging.getLogger() def appium_caps(): file = open('../appium_two/wdj_capability.yaml', 'r') data = yaml.load(file, Loader=yaml.FullLoader) xg_caps = {} xg_caps['platformName'] = data['platformName'] xg_caps['platformVersion'] = data['platformVersion'] xg_caps['deviceName'] = data['deviceName'] xg_caps['appPackage'] = data['appPackage'] xg_caps['appActivity'] = data['appActivity'] xg_caps['noReset'] = data['noReset'] xg_caps['unicodeKeyboard'] = data['unicodeKeyboard'] xg_caps['resetKeyboard'] = data['resetKeyboard'] logging.info('start app ......') driver = webdriver.Remote('http://'+str(data['ip'])+':'+str(data['port'])+'/wd/hub', xg_caps) driver.implicitly_wait(6) return driver if __name__ == '__main__': appium_caps()
2. Encapsulating a baseView.py Class
In this base class, we mainly encapsulate the initialization of driver and the positioning of elements.
class BaseView(object): def __init__(self, driver): self.driver = driver def find_element(self, *location): return self.driver.find_element(*location)
3. Encapsulating a common class general_class.py
In this public class, we mainly prepare for the later implementation of multi-account switching login, because there may be updates and skipped images when multi-account login.
from page_unit.baseView import BaseView from selenium.common.exceptions import NoSuchElementException from page_unit.xgCaps import appium_caps from selenium.webdriver.common.by import By import logging class general_view(BaseView): cancelBtn = (By.ID, 'com.wandoujia.phoenix2:id/s5') jumpBtn = (By.ID, 'com.wandoujia.phoenix2:id/v8') def click_cancelBtn(self): logging.info('*' * 10 + 'cancelBtn' + '*' * 10) try: cancel_element = self.driver.find_element(*self.cancelBtn) except NoSuchElementException: logging.info('cancelBtn is not found !') else: logging.info('click cancelBtn') cancel_element.click() def click_jumpBtn(self): logging.info('-' * 10 + 'jumpBtn' + '-' * 10) try: jump_element = self.driver.find_element(*self.jumpBtn) except NoSuchElementException: logging.info('jumpBtn is not fond !') else: logging.info('click jumpBtn') jump_element.click() if __name__ == '__main__': driver = appium_caps() general = general_view(driver) general.click_cancelBtn() general.click_jumpBtn()
4. Encapsulating login operations
In this step of operation, you will use a By module, which is relatively simple and easy to understand, oh, just need to specify which positioning method to use, and then follow the positioning method of this element corresponding to the content.
by.py Content
class By(object): """ Set of supported locator strategies. """ ID = "id" XPATH = "xpath" LINK_TEXT = "link text" PARTIAL_LINK_TEXT = "partial link text" NAME = "name" TAG_NAME = "tag name" CLASS_NAME = "class name" CSS_SELECTOR = "css selector"
As for the specific use of the class By, you can see the following login_view.py
from page_unit.general_class import general_view from page_unit.xgCaps import appium_caps from selenium.webdriver.common.by import By import logging class login_view(general_view): # Main Navigation Menu navigation_element = (By.ID, 'com.wandoujia.phoenix2:id/w4') # Setting menu setting_element = (By.ID, 'com.wandoujia.phoenix2:id/pp_item_setting') # Sign in login_element = (By.ID, 'com.wandoujia.phoenix2:id/ow') # User name, password username_element = (By.ID, 'com.wandoujia.phoenix2:id/l_') password_element = (By.ID, 'com.wandoujia.phoenix2:id/la') # check box checkBox_element = (By.ID, 'com.wandoujia.phoenix2:id/mw') # Logon button loginBtn_element = (By.ID, 'com.wandoujia.phoenix2:id/mf') def login_action(self, username, password): self.click_jumpBtn() self.click_cancelBtn() logging.info('=' * 10 + 'login_action' + '=' * 10) self.driver.find_element(*self.navigation_element).click() self.driver.find_element(*self.setting_element).click() self.driver.find_element(*self.login_element).click() logging.info('username is: %s' % username) self.driver.find_element(*self.username_element).send_keys(username) logging.info('password is: *************') self.driver.find_element(*self.password_element).send_keys(password) logging.info('check the box') self.driver.find_element(*self.checkBox_element).click() logging.info('click loginBtn') self.driver.find_element(*self.loginBtn_element).click() if __name__ == '__main__': driver = appium_caps() login = login_view(driver) login.login_action('User name', 'Password')
5. Using unittest Use Case Encapsulation
5.1 Encapsulation of configuration at start and end of use cases
xgunit.py
from page_unit.xgCaps import appium_caps import unittest, logging from time import sleep class startAndEnd(unittest.TestCase): def setUp(self): logging.info('-' * 10 + 'setUp' + '-' * 10) self.driver = appium_caps() def tearDown(self): logging.info('=' * 10 + 'tearDown' + '=' * 10) sleep(5) self.driver.close_app()
5.2 Encapsulation of logins for multiple accounts
xg_login.py
from page_unit.login_view import login_view from page_unit.xgUnit import startAndEnd import logging, unittest class TestLogin(startAndEnd): def test_login_first(self): logging.info('-' * 10 + 'first' + '-' * 10) first = login_view(self.driver) first.login_action('User name', 'Password') def test_login_second(self): logging.info('=' * 10 + 'second' + '=' * 10) second = login_view(self.driver) second.login_action('User name', 'Password') def test_login_third(self): logging.info('*' * 10 + 'third' + '*' * 10) third = login_view(self.driver) third.login_action('User name', 'Password') if __name__ == '__main__': unittest.main()
6. Implementation process and results
Log and console printing of execution: