美文网首页
pytest使用

pytest使用

作者: E术家 | 来源:发表于2023-07-23 13:45 被阅读0次

前置安装

pip install -U requests -i https://mirrors.aliyun.com/pypi/simple/

requests模块安装

pip install -U pytest -i https://mirrors.aliyun.com/pypi/simple/

pytest模块安装

requests创建接口请求
def request(method, url, **kwargs):
    """Constructs and sends a :class:`Request <Request>`.

    :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
    :param url: URL for the new :class:`Request` object.
    :param params: (optional) Dictionary, list of tuples or bytes to send
        in the query string for the :class:`Request`.
    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
        object to send in the body of the :class:`Request`.
    :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
    :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
    :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
    :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
        ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
        or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
        defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
        to add for the file.
    :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
    :param timeout: (optional) How many seconds to wait for the server to send data
        before giving up, as a float, or a :ref:`(connect timeout, read
        timeout) <timeouts>` tuple.
    :type timeout: float or tuple
    :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
    :type allow_redirects: bool
    :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
    :param verify: (optional) Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use. Defaults to ``True``.
    :param stream: (optional) if ``False``, the response content will be immediately downloaded.
    :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
    :return: :class:`Response <Response>` object
    :rtype: requests.Response

    Usage::

      >>> import requests
      >>> req = requests.request('GET', 'https://httpbin.org/get')
      >>> req
      <Response [200]>
    """

常用封装好的POST、GET、PUT等请求

requests.post(url="http://www.xxxx", params={"key": "value"}, data={"key": "value"})
requests.get(url="http://www.xxxx", params={"key": "value"}, data={"key": "value"})
pytest文件/文件夹命名要求

1.模块名称必须格式test_*.py*_test.py
2.测试类必须以Test开头,且没有构造方法
3.函数方法必须以test_开头

案例

import requests

class ECMobile():
    baseUrl = "http://localhost/ECMobile/?url="
    loginUrl = f"{baseUrl}/user/signin"
    addToCartUrl = f"{baseUrl}/cart/create"
    orderUrl = f"{baseUrl}/flow/done"

    sid = ""
    uid = ""
    isLogin = False
    status = None

    def login(self, username = None, password = None):
        content = {}
        if username != None:
            content["name"] = username
        if password != None:
            content["password"] = password
        content = str(content)
        content = content.replace("\'", "\"")
        data = {
            "json": content
        }
        print("request_body: ")
        print(data) 
        req = requests.post(url=self.loginUrl, data=data)
        requests.post(url="http://www.xxxx", params={"key": "value"}, data={"key": "value"})
        jsondata = req.json()
        print("login json start " + "=" * 80)
        print(jsondata)
        print("login json end " + "=" * 80)
        self.status = req.status_code
        if jsondata["status"]["succeed"] == 1:
            self.isLogin = True
            self.sid = jsondata["data"]["session"]["sid"]
            self.uid = jsondata["data"]["session"]["uid"]
            print("login_success")
        else:
            self.isLogin = False
            self.sid = ""
            self.uid = ""
            print("login_fail")

    def addToCart(self, goods_id = None, spec = None, num = None):
        content = {}
        if self.isLogin:
            userinfo = {}
            userinfo["sid"] = self.sid
            userinfo["uid"] = self.uid
            content["session"] = userinfo
        if goods_id != None:
            content["goods_id"] = str(goods_id)
        if spec != None:
            content["spec"] = [spec]
        if num != None:
            content["number"] = str(num)
        content = str(content)
        content = content.replace("\'", "\"")
        data = {
            "json": content
        }
        print("request_body: ")
        print(data)
        req = requests.post(url=self.addToCartUrl, data=data)
        jsondata = req.json()
        print("addToCart json start " + "=" * 80)
        print(jsondata)
        print("addToCart json end " + "=" * 80)
        self.status = jsondata["status"]["succeed"]
        if jsondata["status"]["succeed"] == 1:
            print("addToCart_success")
        else:
            print("addToCart_fail")

    def order(self, pay_id = None, shipping_id = None, bonus = None, integral = None, inv_type = None, inv_content = None, inv_payee = None):
        content = {}
        if self.isLogin:
            userinfo = {}
            userinfo["sid"] = self.sid
            userinfo["uid"] = self.uid
            content["session"] = userinfo
        if pay_id != None:
            content["pay_id"] = pay_id
        if shipping_id != None:
            content["shipping_id"] = shipping_id
        if bonus != None:
            content["bonus"] = bonus
        if integral != None:
            content["integral"] = integral
        if inv_type != None:
            content["inv_type"] = inv_type
        if inv_content != None:
            content["inv_content"] = inv_content
        if inv_payee != None:
            content["inv_payee"] = inv_payee
        content = str(content)
        content = content.replace("\'", "\"")
        data = {
            "json": content
        }
        print("request_body: ")
        print(data)
        req = requests.post(url=self.orderUrl, data=data)
        jsondata = req.json()
        print("addToCart json start " + "=" * 80)
        print(jsondata)
        print("addToCart json end " + "=" * 80)
        self.status = jsondata["status"]["succeed"]
        if jsondata["status"]["succeed"] == 1:
            print("order_success")
        else:
            print("order_fail")

创建pytest类

class Test_ECMobile_Interface:

创建测试用函数并实现断言

    def test_login_success(self):
        self.ec.login("ecshop", "ecshop")
        assert self.ec.isLogin

main函数调用

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

完整代码

import pytest
from ecshop_request_FN.data.ecmobile import *

class Test_ECMobile_Interface:
    ec = None

    def setup_method(self):
        print("setup_method")
        self.ec = ECMobile()

    @pytest.mark.smoking
    def test_login_success(self):
        self.ec.login("ecshop", "ecshop")
        assert self.ec.isLogin

    def test_login_username_error(self):
        self.ec.login("errorname", "abc123")
        assert not self.ec.isLogin

    def test_login_without_password(self):
        self.ec.login("ecshop")
        assert not self.ec.isLogin

    @pytest.mark.smoking
    def test_add_cart_success(self):
        self.ec.login("ecshop", "ecshop")
        self.ec.addToCart(goods_id=9, spec=227, num=1)
        assert self.ec.status == 1

    def test_add_cart_without_login(self):
        self.ec.addToCart(goods_id=9, spec=227, num=1)
        assert self.ec.status != 1

    def test_add_cart_unsale_goods(self):
        self.ec.login("ecshop", "ecshop")
        self.ec.addToCart(goods_id=31, num=1)
        assert self.ec.status != 1

    @pytest.mark.smoking
    def test_order_goods(self):
        self.ec.login("ecshop", "ecshop")
        self.ec.addToCart(goods_id=9, spec=227, num=1)
        self.ec.order(pay_id=3, shipping_id=3)
        assert self.ec.status == 1

    def test_order_without_payid(self):
        self.ec.login("ecshop", "ecshop")
        self.ec.addToCart(goods_id=9, spec=227, num=1)
        self.ec.order(shipping_id=3)
        assert self.ec.status != 1

    def test_order_without_login(self):
        self.ec.addToCart(goods_id=9, spec=227, num=1)
        self.ec.order(pay_id=3, shipping_id=3)
        assert self.ec.status != 1

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

pytest修饰器

    @pytest.mark.smoking
    def test_login_success(self):
        self.ec.login("ecshop", "ecshop")
        assert self.ec.isLogin

为函数添加名为smoking的标签
可以通过pytest -m smoking调用所有带smoking标签的函数

# 参数化
# @pytest.mark.parametrize("变量名逗号隔开",列表[(每个变量的值), ()])
# 测试方法需要带参数
@pytest.mark.parametrize("datas, expect", [
    ((1, 2, 3), 6),  # passed
    ((1, 2, 3, 4), 0),  # fail
    ((5, 0, -5), 0)  # passed
])
def test_int_02(datas, expect):
    x = plus(*datas)  # plus(1, 2, 3)
    assert x == expect

通过@pytest.mark.parametrize实现参数化

命令行执行
pytest [选项] [文件或目录]

常用选项

选项 说明
-s 表示输出调试信息,包括 print打印的信息
-v 显示更详细的信息, -vs:这两个参数通常一起用
-n num 支持多线程或者分布式运行测试用例
--html=path 表示生成html测试报告
--reruns=count 表示失败重跑
-p no:warnings 取消警告
--ff 先执行上次失败的用例
--lf 只执行上次失败的用例
-x 遇到测试用例fail,就结束测试
--maxfail=num 遇到num条测试用例fail, 就结束测试
-k 根据测试用例的部分字符串指定测试用例
-m markname 将运行用@pytest.mark.标签名 装饰的所有测试

相关文章

网友评论

      本文标题:pytest使用

      本文链接:https://www.haomeiwen.com/subject/qlstpdtx.html