• pytest_01_安装和入门


    pytest

    安装与入门

    1.pip install -U pytest

    2.创建一个test01.py的文件

    def func(x):
        return x + 1
    
    def test_answer():
        assert func(3) == 5
    

    3.在该目录下执行pytest(venv)

    D:4_codestudy>pytest
    ============================= test session starts =============================
    platform win32 -- Python 3.6.2, pytest-3.7.1, py-1.5.4, pluggy-0.7.1
    rootdir: D:4_codestudy, inifile:
    collected 1 item

    test01.py . [100%]

    ========================== 1 passed in 0.19 seconds ===========================

    (venv) D:4_codestudy>pytest

    4.执行多个,新建一个py文件 test02.py

    def add(x, y):
        return x + y
    
    def test_add():
        assert add(1, 0) == 1
        assert add(1, 1) == 2
        assert add(1, 99) == 100
    

    执行pytest

    (venv) D:4_codestudy>pytest
    ============================= test session starts =============================
    platform win32 -- Python 3.6.2, pytest-3.7.1, py-1.5.4, pluggy-0.7.1
    rootdir: D:4_codestudy, inifile:
    collected 2 items

    test01.py . [ 50%]
    test02.py . [100%]

    ========================== 2 passed in 0.30 seconds ===========================

    pytest将在当前目录及其子目录中运行test _ * .py或* _test.py形式的所有文件。

    5.在一个类中组合多个测试

    一旦开发了多个测试,您可能希望将它们分组到一个类中。pytest可以很容易地创建一个包含多个测试的类:

    class TestClass(object):
        def test_one(self):
            x = "this"
            assert 'h' in x
    
        def test_two(self):
            x = "hello"
            assert hasattr(x, 'check')
    

    (venv) D:4_codestudy>pytest
    ============================= test session starts =============================
    platform win32 -- Python 3.6.2, pytest-3.7.1, py-1.5.4, pluggy-0.7.1
    rootdir: D:4_codestudy, inifile:
    collected 4 items

    test_calc.py . [ 25%]
    test_class.py .F [ 75%]
    test_quick_start.py . [100%]

    ================================== FAILURES ===================================
    _____________________________ TestClass.test_two ______________________________

    self = <test_class.TestClass object at 0x058A59F0>

    def test_two(self):
        x = "hello"
    
      assert hasattr(x, 'check')
      E       AssertionError: assert False
      E        +  where False = hasattr('hello', 'check')
    

    test_class.py:16: AssertionError
    ===================== 1 failed, 3 passed in 0.37 seconds ======================

    6.指定测试 用例

    (venv) D:4_codestudy>pytest -q test_calc.py
    . [100%]
    1 passed in 0.02 seconds

    7.Assert

    pytest使用的是python自带的assert关键字来进行断言
    assert关键字后面可以接一个表达式,只要表达式的最终结果为True,那么断言通过,用例执行成功,否则用例执行失败

    断言异常抛出

    import pytest
    
    def test_zero_division():
        with pytest.raises(ZeroDivisionError):
            1 / 0
    

    1/0的时候应该抛出ZeroDivisionError,否则用例失败,断言不通过。

    8.Fixture

    如测试数据为

    [
      {"name":"jack","password":"Iloverose"},
      {"name":"rose","password":"Ilovejack"},
      {"name":"tom","password":"password123"}
    ]
    
    
    import pytest
    import json
    
    class TestUserPassword(object):
        @pytest.fixture
        def users(self):
            return json.loads(open('./users.dev.json', 'r').read()) # 读取当前路径下的users.dev.json文件,返回的结果是dict
    
        def test_user_password(self, users):
            # 遍历每条user数据
            for user in users:
                passwd = user['password']
                assert len(passwd) >= 6
                msg = "user %s has a weak password" %(user['name'])
                assert passwd != 'password', msg
                assert passwd != 'password123', msg
    
    (venv) D:4_codestudy>pytest test_user_password.py
    ============================= test session starts =============================
    platform win32 -- Python 3.6.2, pytest-3.7.1, py-1.5.4, pluggy-0.7.1
    rootdir: D:4_codestudy, inifile:
    collected 1 item                                                               
    
    test_user_password.py F                                                  [100%]
    
    ================================== FAILURES ===================================
    _____________________ TestUserPassword.test_user_password _____________________
    
    self = <test_user_password.TestUserPassword object at 0x044783B0>
    users = [{'name': 'jack', 'password': 'Iloverose'}, {'name': 'rose', 'password': 'Ilovejack'}, {'name': 'tom', 'password': 'password123'}]
    
        def test_user_password(self, users):
            # 遍历每条user数据
            for user in users:
                passwd = user['password']
                assert len(passwd) >= 6
                msg = "user %s has a weak password" %(user['name'])
                assert passwd != 'password', msg
    >           assert passwd != 'password123', msg
    E           AssertionError: user tom has a weak password
    E           assert 'password123' != 'password123'
    
    test_user_password.py:16: AssertionError
    ========================== 1 failed in 0.26 seconds ===========================
    
    

    使用@pytest.fixture装饰器可以定义feature
    在用例的参数中传递fixture的名称以便直接调用fixture,拿到fixture的返回值
    3个assert是递进关系,前1个assert断言失败后,后面的assert是不会运行的,因此重要的assert放到前面
    E AssertionError: user tom has a weak password可以很容易的判断出是哪条数据出了问题,所以定制可读性好的错误信息是很必要的
    任何1个断言失败以后,for循环就会退出,所以上面的用例1次只能发现1条错误数据,换句话说任何1个assert失败后,用例就终止运行了

    执行顺序

    pytest找到以test_开头的方法,也就是test_user_password方法,执行该方法时发现传入的参数里有跟fixture users名称相同的参数
    pytest认定users是fixture,执行该fixture,读取json文件解析成dict实例
    test_user_password方法真正被执行,users fixture被传入到该方法

    使用下面的命令来查看用例中可用的fixtures

    pytest --fixtures test_user_password.py

    ------------------ fixtures defined from test_user_password -------------------
    users
        test_user_password.py:6: no docstring available
    
    ======================== no tests ran in 0.07 seconds =========================
    
    
    

    数据清理

    有时候我们需要在用例结束的时候去清理一些测试数据,或清除测试过程中创建的对象,我们可以使用下面的方式

    import smtplib
    import pytest
    
    @pytest.fixture(scope="module")
    def smtp():
        smtp = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
        yield smtp  # provide the fixture value
        print("teardown smtp")
        smtp.close()
    yield 关键字返回了fixture中实例化的对象smtp
    module中的用例执行完成后smtp.close()方法会执行,无论用例的运行状态是怎么样的,都会执行
    
  • 相关阅读:
    佛教:禅宗和净土--佛教的归途
    佛教:从精英到世俗
    佛教:神迹的演变。
    收藏品:MP3播放器
    淘书百胜楼
    Spring注解是如何生效的?
    logstash6.8.3 导入 CSV 文件到 ElasticSearch
    三个线程交替按顺序打印ABC之条件队列的理解
    谈谈多线程
    ElasticSearch如何更新集群的状态
  • 原文地址:https://www.cnblogs.com/mrwuzs/p/9536458.html
Copyright © 2020-2023  润新知