012 python接口 参数化与封装

Posted 汁虫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了012 python接口 参数化与封装相关的知识,希望对你有一定的参考价值。

 

 

\'\'\'
时间:2018/11/04
目录: 
  一: 禅道登录
1 工程结构 2 unittest文件 3 实现功能文件
4 执行结果   二: 禅道登录 - 报告
1 工程结构 2 Common 3 TestCase 4 TestFunction 5 TestReport 6 run_all.py
     7 执行结果 三: 拉勾网登录
1 工程结构
     2 unittest文件
3 实现功能文件
4 执行结果
\'\'\'

 

一: 禅道登录

  1 工程结构

1 :  主要两个文件,unittest文件和操作文件。

2 :  unittest文件的功能:输入数据、预期结果、断言判断。

2 :  操作文件的功能:步骤执行、返回实际结果 。


  2 unittest文件

# coding:utf-8
import unittest
from chandao_login.chandao_login_api_v2 import *

class TestLogin(unittest.TestCase):
    #session = requests.session()
    def setUp(self):
        self.session = requests.session()

    def tearDown(self):
        self.session.cookies.clear()    # 清除缓存 - cookies
        self.session.close()            # 去除警告 - 关闭进程

    def test_001(self):
        \'\'\' 登录成功: 正确账号 + 正确密码 \'\'\'
        strUser = "admin"
        strPass = "123456"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertTrue(bResult)

    def test_002(self):
        \'\'\' 登录失败: 正确账号 + 错误密码 \'\'\'
        strUser = "admin"
        strPass = "123456789"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertFalse(bResult)

    def test_003(self):
        \'\'\' 登录失败: 错误账号 + 错误密码 \'\'\'
        strUser = "admin123"
        strPass = "123456789"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertFalse(bResult)

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

 


  3 实现功能文件

# coding:utf-8
import requests


url = "http://127.0.0.1/zentao/user-login.htm"  # url经常变 : 做全局变量 - 做配置文件

def Login(session, strUser, strPass):
    \'\'\'
    登录禅道
    :param session:     session
    :param strUser:     用户名
    :param strPass:     密码
    :return:            请求结果 - 服务端
    \'\'\'

    body = {
        "account": strUser,
        "password": strPass,
        "keepLogin[]": "on",
        "referer": "/zentao/my.html"
    }
    r = session.post(url, data = body)
    strResult = r.content.decode("utf-8")
    return strResult

def DecideResult(strResult):
    \'\'\'
    判断结果 - 登录禅道
    :param strResult:  请求结果 - 服务端
    :return:
    \'\'\'
    if "登录失败" in strResult:
        print("登录失败")
        return False
    elif "parent.location" in strResult:
        print("登录成功")
        return True
    else:
        print("登录失败 - 其他情况")
        return False

if __name__ == \'__main__\':
    s = requests.session()
    result = Login(s, "admin", "123456")
    DecideResult(result)

 

  4 执行结果

1 :  测试用例全部运行pass。

 

1 :  测试用例有failed。


二: 禅道登录 - 报告

  1 工程结构

1 :  由5个部分组成:4个文件夹 + 1个运行文件。

2 :  Common文件夹: 存放公共的文件

3 :  TestCase文件夹: 存放unittest文件

4 :  TestFunction文件夹: 存放功能操作文件

5 :  TestReport文件夹: 存放测试报告文件

6 :  run_all.py: 执行测试、生成报告。


  2 Common

1 : 使用第三方 HTMLTestRunner_cn.py,方便查看测试结果。


  3 TestCase

# coding:utf-8
import unittest
from TestFunction.chandao_login_api import *

class TestLogin(unittest.TestCase):
    #session = requests.session()
    def setUp(self):
        self.session = requests.session()

    def tearDown(self):
        self.session.cookies.clear()    # 清除缓存 - cookies
        self.session.close()            # 去除警告 - 关闭进程

    def test_001(self):
        \'\'\' 登录成功: 正确账号 + 正确密码 \'\'\'
        strUser = "admin"
        strPass = "123456"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertTrue(bResult)

    def test_002(self):
        \'\'\' 登录失败: 正确账号 + 错误密码 \'\'\'
        strUser = "admin"
        strPass = "123456789"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertFalse(bResult)

    def test_003(self):
        \'\'\' 登录失败: 错误账号 + 错误密码 \'\'\'
        strUser = "admin123"
        strPass = "123456789"
        strResult = Login(self.session, strUser, strPass)
        bResult = DecideResult(strResult)
        self.assertFalse(bResult)

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

 

  4 TestFunction

# coding:utf-8
import requests


url = "http://127.0.0.1/zentao/user-login.htm"  # url经常变 : 做全局变量 - 做配置文件

def Login(session, strUser, strPass):
    \'\'\'
    登录禅道
    :param session:     session
    :param strUser:     用户名
    :param strPass:     密码
    :return:            请求结果 - 服务端
    \'\'\'

    body = {
        "account": strUser,
        "password": strPass,
        "keepLogin[]": "on",
        "referer": "/zentao/my.html"
    }
    r = session.post(url, data = body)
    strResult = r.content.decode("utf-8")
    return strResult


def DecideResult(strResult):
    \'\'\'
    判断结果 - 登录禅道
    :param strResult:  请求结果 - 服务端
    :return:
    \'\'\'
    if "登录失败" in strResult:
        print("登录失败")
        return False
    elif "parent.location" in strResult:
        print("登录成功")
        return True
    else:
        print("登录失败 - 其他情况")
        return False


if __name__ == \'__main__\':
    s = requests.session()
    result = Login(s, "admin", "123456")
    DecideResult(result)

 

  5 TestReport

1 :  运行完程序,生成一个report.html文件。

 

1 :  测试用例全部运行pass。

 

1 :  测试用例有failed。


  6 run_all.py

# coding:utf-8
import unittest
import os
from Common import HTMLTestRunner_cn


# 路径兼容 - windows/mac
cur_path = os.path.dirname(os.path.realpath(__file__))  # 获取路径 - 当前脚本
cur_path = os.path.join(cur_path, "TestCase")           # 拼接路径

# 显示结果 - unnitest
pattern = "test*.py"    # 匹配文件
discover = unittest.defaultTestLoader.discover(start_dir = cur_path, pattern = pattern)
print(discover)


# 路径兼容 - windows/mac
cur_path = os.path.dirname(os.path.realpath(__file__))  # 获取路径 - 当前脚本
report_path = os.path.join(cur_path, "TestReport", "report.html")
fp = open(report_path, "wb")
runner = HTMLTestRunner_cn.HTMLTestRunner(stream = fp,                      # 报告路径
                                          title = "接口测试用例报告",       # 报告标题
                                          description = "测试用例详情报告", # 报告描述
                                          retry = 1,                        # 错误重写执行
                                          verbosity = 2)                    # 注释显示
runner.run(discover)

 

三: 拉勾网登录

  1 工程结构

1 :  主要两个文件,unittest文件和操作文件。

2 :  unittest文件的功能:输入数据、预期结果、断言判断。

2 :  操作文件的功能:步骤执行、返回实际结果 。


  2 unittest文件

# coding:utf-8
import unittest
from TestLagou.Lagou_login_api import *


class TestLogin(unittest.TestCase):
    def setUp(self):
        self.session = requests.session()
        self.lgw = LoginLgw(self.session)

    def tearDown(self):
        self.session.cookies.clear()    # 清除缓存 - cookies
        self.session.close()            # 去除警告 - 关闭进程

    def test_001(self):
        \'\'\' 登录成功: 正确账号 + 正确密码 \'\'\'
        ServerResult = self.lgw.login("13581906014", "1358190lago*")
        bResult = self.lgw.CheckResult(ServerResult)
        self.assertTrue(bResult)

    def test_002(self):
        \'\'\' 登录失败: 正确账号 + 错误密码 \'\'\'
        ServerResult = self.lgw.login("13581906014", "1234567895*")
        bResult = self.lgw.CheckResult(ServerResult)
        self.assertFalse(bResult)

    def test_003(self):
        \'\'\' 登录失败: 错误账号 + 错误密码 \'\'\'
        ServerResult = self.lgw.login("123456", "1234567895*")
        bResult = self.lgw.CheckResult(ServerResult)
        self.assertFalse(bResult)

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

 

  3 实现功能文件

# coding:utf-8
import requests
import re
from bs4 import BeautifulSoup
import urllib3
import hashlib
urllib3.disable_warnings()
import sys

class LoginLgw():
    def __init__(self, s):
        self.s = s

    def getToeknCode(self):
        \'\'\'
        获取拉勾网 - token和code
        :return:    {"X_Anti_Forge_Token":"xxx", "X_Anti_Forge_Code":"xxx"}
        \'\'\'
        # 更新数据 - 头部信息
        url = "https://passport.lagou.com/login/login.html"
        head = {
             "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
            }
        self.s.headers.update(head)

        # 获取数据 - token和code
        data = self.s.get(url, verify = False)
        soup = BeautifulSoup(data.content, "html.parser", from_encoding="utf-8")
        tokenCode = {}
        try:
            t = soup.find_all("script")[1].get_text()
            tokenCode[\'X_Anti_Forge_Token\'] = re.findall(r"Token = \'(.+?)\'", t)[0]
            tokenCode[\'X_Anti_Forge_Code\'] = re.findall(r"Code = \'(.+?)\'", t)[0]
            return tokenCode
        except:
            print("Get Faild")
            tokenCode[\'X_Anti_Forge_Token\'] = ""
            tokenCode[\'X_Anti_Forge_Code\'] = ""
            return tokenCode

    def encryptPwd(self, passwd):
        \'\'\'
        密码加密
        :param passwd: 原始密码
        :return:       加密密码
        \'\'\'
        passwd = hashlib.md5(passwd.encode("utf-8")).hexdigest()    # md5加密
        passwd = "veenike" + passwd + "veenike"                     # veennike : js文件 - 写死的值
        passwd = hashlib.md5(passwd.encode("utf-8")).hexdigest()    # md5加密
        return passwd

    def login(self, user, password):
        \'\'\'
        登录拉勾网
        :param user:        用户名
        :param password:    密码
        :return:       登录成功 - 服务信息
        \'\'\'
        # 获取数据 - token和code
        tokenCode = self.getToeknCode()
        #print(tokenCode)

        # 密码加密
        password = self.encryptPwd(password)
        #print(password)

        # 更新数据 - 头部信息
        url = "https://passport.lagou.com/login/login.json"
        head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "X-Requested-With": "XMLHttpRequest",
        "X-Anit-Forge-Token": tokenCode[\'X_Anti_Forge_Token\'],
        "X-Anit-Forge-Code": tokenCode[\'X_Anti_Forge_Code\'],
        "Referer": "https://passport.lagou.com/login/login.html",
        }
        self.s.headers.update(head)

        # 登录网站
        body = {
                "isValidate":\'true\',
                "username": user,
                "password": password,
                "request_form_verifyCode": "",
                "submit": ""
        }
        r = self.s.post(url, data=body, verify=False)
        return r

    def CheckResult(self, strServerResult):
        \'\'\'
        判断结果 - 登录拉钩
        :param strServerResult: 返回数据 - 服务器
        :return:
        \'\'\'
        deictResult = strServerResult.json()

        if "操作成功" in deictResult["message"]:
            print("登录成功")
            return True
        else:
            print("登录失败: %s" %strServerResult.text)
            return False

if __name__ == "__main__":
    s = requests.session()
    lgw = LoginLgw(s)
    r = lgw.login("13581906014", "1358190lago1*")
    bReslut = lgw.CheckResult(r)
    print("%r %s" %(bReslut, type(bReslut)))

 

  4 执行结果

 

以上是关于012 python接口 参数化与封装的主要内容,如果未能解决你的问题,请参考以下文章

jmeter(四十六)参数化与断言实战

selenium+python自动化78-autoit参数化与批量上传

selenium+python自动化78-autoit参数化与批量上传转载

QuantLib 金融计算——自己动手封装 Python 接口

Python 封装

012 python接口 数据驱动ddt