System specifications

System version: MacOS 10.15.7 Python: 3.8.0 Selenium: 3.141.0Copy the code

How to use

  1. Project address: PySeTest
  2. Download the project file. Modify the following global variables in testindex.py
home_url = 'http://www.mi.com/'
login_name = 'Enter login name'
login_pass = 'Enter login password'
test_product = "Mi 10 Pro"
Copy the code
  1. If automatic login is required, modify the auto_login method. If not, comment out the auto_login method and change the script in the testMain method to your own test process.

Functional specifications

To realize the automation of web page scaffolding project PySeTest. At present, it is done according to the automated testing process of Xiaomi Mall. Other websites can be modified according to the actual situation. The following functions are realized through this project

  • Automatically log on to the web page and keep the Cookie
  • Automatically fill in the preset text as required
  • Locate the list based on Xpath and select or click an item
  • Click the pop-up confirmation button
  • The display waits, after positioning through Xpath and text content, and clicks
  • Display wait, locate by tag ID
  • Test results Automatically output Html test reports

Implementation steps

Testing path

According to my analysis of the mi Mall web page, through the following path can go through the complete process from login to order.

  1. Open the home page
  2. The system automatically logs in to the login page. After the login succeeds, the system returns to the home page
  3. Enter a search keyword test
  4. Click on the search
  5. Open search results for the first product
  6. Click the Add to Cart button
  7. Click the Go shopping cart checkout button
  8. Fill in quantity of goods
  9. Click the “Go to Settlement” button to start the order confirmation page
  10. Select the first address
  11. Click to order now
  12. Judge whether the order is successful

Test script code implementation

logger('Start automated testing, home page testing... ')
driver.get(home_url)
webWaitById(driver, 'J_siteUserInfo'.10."Automated test failed: Home page opening timeout")
logger('Start login... ')
auto_login(driver, login_name, login_pass)
webWaitById(driver, 'J_siteUserInfo'.10."Automated test failed: Return to home page timeout")
logger('Enter a search keyword test')
driver.find_element_by_id('search').send_keys(test_product)
logger('Click to search')
driver.find_element_by_xpath('//*[@id="J_submitBtn"]/input').click()
webWaitById(driver, 'J_navCategory'.10."Automated test failed: Opening search list timed out")
findListAndOpen(driver,"//div[@class='goods-item']/div/a".0)
waitByTextAndClick(driver, "//a[@class='btn btn-primary']".'Add to cart'.10."Automated test failed: opening product failed".1.True)
waitByTextAndClick(driver, "//a[@class='btn btn-primary']".'Go to the shopping cart'.10."Automated test failed: Adding to cart failed".1.True)
waitByTextAndClick(driver, "//a[@class='btn btn-a btn-primary']".'To settle'.10."Automated test failed: Shopping cart checkout failed".1)
logger('Input quantity')
auto_fill(driver, '//input[@class="goods-num"]'.1)
driver.find_element_by_xpath("//a[@class='btn btn-a btn-primary']").click()
waitByTextAndClick(driver, "//a[@class='btn btn-primary']".'To settle'.10."Automated test failure: Debilling failure".1)
logger('Select 1st shipping address')
driver.find_elements_by_xpath("//div[@class='address-item']") [0].click()
waitByTextAndClick(driver, "//a[@class='btn btn-primary']".'Order now'.10."Automated test failed: Address selected failed".1.True)
waitByTextAndClick(driver, "//*[@class='fl']".'Order submitted successfully! Go pay ~ '.10."Automated test failed: order failed".1)
logger('Automated test successful')
Copy the code

After using some of the methods we used to encapsulate the scaffolding, the whole code is actually quite simple. You just need to find the Xpath to locate the tag.

Common method encapsulation

  1. Automatic login code
def auto_login(driver, username, password) :
	# Locate the home page login button
    el = driver.find_element_by_xpath('//*[@id="J_siteUserInfo"]/a[1]')
    The value of the data-href attribute contains the jump location of the login path
    url=el.get_attribute("data-href")
    Go to the login page
    driver.get("https://"+url)
    # Verify the correct jump to the login interface
    webWaitById(driver, 'main-content'.5."Automated test failed: Login page open timeout")
    auto_fill(driver, '//input[@class="item_account" and @name="user"]', username)
    auto_fill(driver, '//input[@class="item_account" and @name="password"]', password)
    Locate the login button and click the login button
    driver.find_element_by_xpath('//input[@id="login-button" and @class="btnadpt"]').click()
    webWaitById(driver, 'J_siteUserInfo'.5."Automated test failed: login timed out")
    cookie_items = driver.get_cookies()  # Get cookie value
    # incoming cookies
    for cookie in cookie_items:
        driver.add_cookie(cookie)
Copy the code

In fact, many websites have the same login interface. Just modify the code accordingly. There is no graphical verification code required to log in.

  1. The display waits, after positioning through Xpath and text content, and clicks
# Display wait, after positioning through Xpath and text content and click
# param _driver: driver
# param xpath: xpath
# param text: The search text
# param timeout: Wait a few seconds
# param err_msg: error message
# param finally_sleep: Sometimes the waiting result shows that the element has been found. But in fact, when using the error. So, force a delay of a few seconds
# param is_click: Whether to click on the found text
def waitByTextAndClick(_driver, xpath, text, timeout, err_msg, finally_sleep=0, is_click = False) :
    try:
    	Display wait, positioning by Xpath and text content
        WebDriverWait(_driver, timeout).until( EC.text_to_be_present_in_element((By.XPATH, xpath), text))
    except TimeoutException:
    	Error message printed after waiting timeout
        sys.exit(err_msg)
    finally:
        time.sleep(finally_sleep)

    if is_click:
        logger("Click:"+text)
        _driver.find_element_by_xpath(xpath).click()
Copy the code

Display wait, implicit wait, forced wait. Is an important concept for Selenium. We’ll get to that. Once you understand what display wait is, you can understand the encapsulation above. Other methods will not be introduced. Look at the code for yourself

Basic Usage of Selenium

Selenium Chinese Documents

First-hand information: Official Documentation for Selenium

Selenium3 location method

  • Selenium provides eight locations.

id name class name tag name link text partial link text xpath css selector

  • The eight positioning methods in Python selenium correspond to:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
# Locate a list or one with multiple results using the following method
find_elements_by_id()
find_elements_by_name()
find_elements_by_class_name()
find_elements_by_tag_name()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_xpath()
find_elements_by_css_selector()
Copy the code
  • You can also use find_element(by.id, “ID “) in Selenium3. Here are the eight method mappings
find_element(By.ID, "id")
find_element(By.NAME, "name")
find_element(By.CLASS_NAME, "class name")
find_element(By.TAG_NAME, "tag name")
find_element(By.LINK_TEXT, "link text")
find_element(By.PARTIAL_LINK_TEXT, "partial link text")
find_element(By.XPATH, "xpath")
find_element(By.CSS_SELECTOR, "css selector")
# Locate a list or one with multiple results using the following method
find_elements(By.ID, "id")
find_elements(By.NAME, "name")
find_elements(By.CLASS_NAME, "class name")
find_elements(By.TAG_NAME, "tag name")
find_elements(By.LINK_TEXT, "link text")
find_elements(By.PARTIAL_LINK_TEXT, "partial link text")
find_elements(By.XPATH, "xpath")
find_elements(By.CSS_SELECTOR, "css selector")
Copy the code
  • How to quickly find an element’s xpath value through Chrome.
  1. Open chrome developer Tools. Select the element you want to position

2. Right-click the section and select Copy -> Copy XPath3. Verify that the XPath value can locate the corresponding element. You can use the shortcut key CMD +F to call up the search function. Then paste the XPath value you just copied. Prove that XPath works as expected if you can select what you want to locateIf you want to write your own xPaths, it’s best to verify the xPaths with Chrome before running scripts. It saves time

The Selenium wait

Waiting is very critical, many times can not locate is due to the waiting time is not enough. Because the code is fast, Selenium needs to wait for the browser element to load before locating it. If we don’t delay the execution of the code, there is a chance that the code will run out of the interface and throw an exception before it is loaded. Therefore, let’s talk about the use of waiting in detail here. For authoritative content, please check the official document carefully. My summary may have some deviations

  1. Mandatory waiting

Forced wait means that as long as there is no crash or script crash, you have to wait out time before you can move on. The code is as follows:

# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep

driver = webdriver.Chrome()
driver.get('https://github.com/sugood')
sleep(3)  Force wait 3 seconds before performing the next step
print driver.current_url
driver.quit()
Copy the code
  1. An implicit wait

Implicit wait is to set a maximum time. If the page loads within the specified time (that is, the little circle in the browser TAB bar does not rotate), then go to the next step. Otherwise, wait until the time is up and then go to the next step.

# -*- coding: utf-8 -*-
from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)  # Hidden wait, maximum 10 seconds
driver.get('https://github.com/sugood')

print driver.current_url
driver.quit()
Copy the code
  1. Explicit waiting

WebDriverWait, combined with the until() and until_not() methods of this class, provides flexibility for waiting depending on the criteria. It basically means that the program looks at it every xx seconds, if the condition is true, it goes to the next step, otherwise it waits until the maximum time is exceeded, and then it throws a TimeoutException.

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(10)  Implicit wait and explicit wait can be used at the same time, but note: the longest wait time should be the largest of the two
driver.get('https://github.com/sugood')
locator = (By.LINK_TEXT, 'github')
try:
    WebDriverWait(driver, 20,).until(EC.presence_of_element_located(locator))
    print driver.find_element_by_link_text('github').get_attribute('href')
finally:
    driver.close()
Copy the code

Automatically generate Html test reports

HTMLTestRunner compatible Python3

This project has integrated HTMLTestRunner, the specific code can be viewed by the HTMLTestrunner. py file, has been compatible with Python3

How to use

Running report.py automatically finds all test*.py in the current folder and executes them one by one. At the same time after executing all test scripts, automatically generate test results (Html file) in the current directory. The test results are as follows:

conclusion

A few tricks.

  • If the location is not possible, it is likely that there is a problem with the delay. You can use a forced wait to test that there is no problem and then switch to an explicit wait.
  • Not all operations can be performed after the wait is successful. Indicating success only indicates that the element is loaded, but when you want to click or jump to the page. It may not be successful yet. These operations may involve other resources as well. Wait until all relevant resources are loaded. A silly way to do this is to impose a slightly enforced wait and then wait. The waitByTextAndClick method in our project contains this control.
  • Max retries exceeded with URL 错 误 Max retries exceeded with URL 错 误 Max retries exceeded with URL 错 误

series

Python3 + Selenium3 + Chrome environment installation # Good for good

Configure the Python tutorial with PyCharm and execute a simple script # do the right thing

#Python3 + Selenium3+ HTMLTestRunner# Python3 + Selenium3+ htmltestrunner