python Realizes Automatic Script Writing

  • 2021-11-10 10:27:50
  • OfStack

Directory 1. Open the browser, Visit p. to2. Log in 3. Modify the administrator password 4. Unit test data 5. Check the validity of the input data 6. Get the page prompt after entering the wrong data 7. Write test cases 8. Write unit test classes 8.1 General operations in unit tests 8.2 test classes 9. Carry out unit tests and generate test reports 10. Close the browser 11. Exception handling 11.1 Click function 11.2 to fill out the form 11.3 yuan Element loading 12. Complete test code

This paper takes the modification of user name and password unit as an example, and writes a test script. Complete the unit test of modifying username and password module.

(ps. The login password in this demo is "admin")

1. Open a browser and access p. to


# 1.  Open a browser and access p.to
driver = webdriver.Chrome()
def openDriver():
    driver.get("http://p.to")
    driver.maximize_window()

Step 2: Log in

The parameter passed in by login action is only 1 "User Password"

There are two actions to perform: 1. Enter the password into the input box 2. Click OK

It should be noted that when logging in, our program may start filling out the form before the page is loaded.

To prevent exceptions, functions waitandSendkeys and waitandClick are written to handle exceptions. (Exception handlers are described later.)


class loginClass(object):
    """docstring for login"""
    def __init__(self, arg):
        self.login_pwd = arg
    def login(self):
        waitandSendkeys('//*[@id="Pwd"]', self.login_pwd)
        waitandClick('//*[@id="Save"]')

3. Change the administrator password

There are two parameters that need to be passed in: 1. Old password 2. New password

It should be noted that there is a pop-up window for modifying the administrator password, so it is necessary to judge and wait for the pop-up window to pop up before operating


class changePwdClass(object):
    """docstring for changePwdClass"""
    def __init__(self, pwdNew, pwdOld):
        self.pwdNew = pwdNew        
        self.pwdOld = pwdOld

    def changeUserPwd(self):
        waitandClick('//*[@id="Con"]/div[1]/ul[2]/li[1]')
        waitandClick('//*[@id="Con"]/div[1]/ul[2]/li[1]/ul/li[3]')
        waitforDisplay('//*[@id="_Widget"]')
        waitandSendkeys('//*[@id="PwdOld"]', self.pwdOld)
        waitandSendkeys('//*[@id="PwdNew"]', self.pwdNew)
        waitandSendkeys('//*[@id="PwdCfm"]', self.pwdNew)
        waitandClick('//*[@id="SavePwd"]')

Here, we can complete the action of modifying the user name and password. Unit testing will be performed later.

4. Unit test data

The anti-foolish rules for modifying the user name and password function are as follows:

输入项 允许输入 可为空 格式规范 合法性 依赖项
原管理员密码 字符串 长度限制:5-63; 字符集:英文字符集; 需要与管理员密码相同
新管理员密码 字符串 长度限制:5-63; 字符集:英文字符集;
确认管理员密码 字符串 需要与新管理员密码相同

According to the anti-foolish rules, you can list: 1. Possible errors 2. Prompts that the page should have when errors occur


# Possible errors 
errcode = ['oldPwdErr', 'lenErr', 'charErr', 'matchErr', 'pwdSameErr',\
    'oldPwdBlankErr', 'newPwdBlankErr']

# Prompt that the page should have when an error occurs 
errTips = {
    'oldPwdErr' :' Original password error ',
    'lenErr' : ' The length of the new password should be 5~63 Bit ',
    'charErr' : " The new password contains illegal characters ",
    'matchErr' : ' Enter the password twice. No 1 To ',
    'pwdSameErr' : ' The new password is the same as the original password, please re-enter it ',
    'oldPwdBlankErr' : ' Please enter the original password ',
    'newPwdBlankErr' : ' Please enter a new password '
}

5. Check the validity of the data entered

The data to be entered are the data to be checked and the login password


def checkData(data, loginPwd):# Check in the same order as the page order 
    pwd = loginPwd
    #'oldPwdBlankErr'
    if data['pwdOld'] == "":
        return errcode[5]
    #newPwdBlankErr
    if data['pwdNew'] == "":
        return errcode[6]
    #charErr
    strTmp = data['pwdNew']
    for x in xrange(0,len(data['pwdNew'])):
        if ord(strTmp[x]) < 33 or ord(strTmp[x]) > 127:#ASCII Representation range :32-127
            return errcode[2]
    #lenErr
    if len(data['pwdNew']) > 63 or len(data['pwdNew']) < 5:
        return errcode[1]
    #oldPwdErr
    if pwd != loginData.login_data['login_pwd']:
        return errcode[0]
    #pwdSameErr
    if data['pwdNew'] == pwd:
        return errcode[4]
    #no error
    return None

6. Get the page prompt after entering the wrong data


def checkResponse(error):
    if error == None:
        return

    webText = getText('//*[@id="PwdTip"]')
    if webText == False:# No hint 
        print('###Error: no tips on web!')
    else:
        webText = webText.decode('UTF-8')
    waitandClick('//*[@id="ModifyPwd"]/i')
    time.sleep(1)
    return webText

7. Write test cases


    data = [
        {"pwdNew" : "12345678","pwdOld" : '8dadla'},#"oldPwdErr"
        {"pwdNew" : "admi","pwdOld" : 'admin'},#lenErr
        {'pwdNew' : '1  2  3','pwdOld' : 'admin'},#charErr
        {'pwdNew' : 'admin','pwdOld' : 'admin'},#pwdSameErr
        {'pwdNew' : "",'pwdOld' : ""},#oldPwdBlank
        {'pwdNew' : "",'pwdOld' : "admin"}#newPwdBlank
    ]

8. Write unit test classes

8.1 Common Actions in Unit Testing

In a unit test, the different parts should be data, so you can define a common operation.

Among them, self. assertEqual (checkResponse (error) and errTips [error]) are the conditions for judging whether the test passes: whether the page prompt is correct.


def commonAction(self, arg):
        error = checkData(arg)
        changeUserPwd.main(arg)
        self.assertEqual(checkResponse(error), errTips[error])

8.2 Test classes

The test class mainly includes 6 test cases and corresponding test functions beginning with "test".

This inherits unittest from python.

For the syntax of unittest, please refer to://www.ofstack.com/article/65856. htm


class TestCase(unittest.TestCase):
    data = [
        {"pwdNew" : "12345678","pwdOld" : '8dadla'},#"oldPwdErr"
        {"pwdNew" : "admi","pwdOld" : '*'},#lenErr
        {'pwdNew' : '1  2  3','pwdOld' : '*'},#charErr
        {'pwdNew' : 'admin','pwdOld' : '*'},#pwdSameErr
        {'pwdNew' : "",'pwdOld' : ""},#oldPwdBlank
        {'pwdNew' : "",'pwdOld' : "*"}#newPwdBlank
    ]

    def commonAction(self, arg):
        error = checkData(arg)
        changeUserPwd.main(arg)
        self.assertEqual(checkResponse(error), errTips[error])

    def test_oldPwdErr(self):
        self.commonAction(self.data[0])
    def test_lenErr(self):
        self.commonAction(self.data[1])
    def test_charErr(self):
        self.commonAction(self.data[2])
    def test_pwdSameErr(self):
        self.commonAction(self.data[3])
    def test_oldPwdBlank(self):
        self.commonAction(self.data[4])
    def test_newPwdBlank(self):
        self.commonAction(self.data[5])

9. Unit Test and Generate Test Reports

Here, HTMLTestRunner is used to generate test reports.

For the syntax of HTMLTestRunner, see: https://testerhome.com/topics/7576

The resulting test report will be stored in the reports/test_report folder, named by time. The title of the test report is called "Modifying Administrator Password Trial Report"


unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='test_report',report_title=' Trial report on modifying administrator password '))

10. Close the browser


class loginClass(object):
    """docstring for login"""
    def __init__(self, arg):
        self.login_pwd = arg
    def login(self):
        waitandSendkeys('//*[@id="Pwd"]', self.login_pwd)
        waitandClick('//*[@id="Save"]')
0

At this point, we can complete the unit test of modifying the username and password module. In order to increase the robustness of the code, the following introduces exception handling.

11. Exception handling

11.1 Click function

An anomaly that may occur when clicking a button is that the clicking action may occur before the page element is loaded. This throws an element not found exception.

The solution is to check whether the page element is loaded once every 10ms by displaying wait, and click after completion, otherwise, wait until the timeout to end the action.


class loginClass(object):
    """docstring for login"""
    def __init__(self, arg):
        self.login_pwd = arg
    def login(self):
        waitandSendkeys('//*[@id="Pwd"]', self.login_pwd)
        waitandClick('//*[@id="Save"]')
1

11.2 Fill out the form

When filling out the form, in addition to the exception that the page element has not been loaded, it is also possible that there is text in the original form, and our input is filled in append mode. This will lead to inaccurate text.


class loginClass(object):
    """docstring for login"""
    def __init__(self, arg):
        self.login_pwd = arg
    def login(self):
        waitandSendkeys('//*[@id="Pwd"]', self.login_pwd)
        waitandClick('//*[@id="Save"]')
2

11.3 Element Loading

Possible occurrences in element loading: 1. Element not loaded within timeout 2. Query element does not exist at all

Exception handling for these two situations:


def waitforDisplay(xpath):
    try:
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath)))
    except TimeoutException as e:
        print('Error:waitforDisplay, TimeoutException, xpath = %s\n' % xpath)
    else:
        try:
            process = driver.find_element_by_xpath(xpath)
            WebDriverWait(driver, 10).until(lambda driver: process.is_displayed())
        except NoSuchElementException as e:
            print('Error:waitforDisplay, NoSuchElementException, xpath = %s\n' % xpath)

12. Complete test code


class loginClass(object):
    """docstring for login"""
    def __init__(self, arg):
        self.login_pwd = arg
    def login(self):
        waitandSendkeys('//*[@id="Pwd"]', self.login_pwd)
        waitandClick('//*[@id="Save"]')
4

For the complete demo, please refer to: https://github.com/niununu/k2p_web_test


Related articles: