pytest_01_安装和入门

Posted mrwuzs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()方法会执行,无论用例的运行状态是怎么样的,都会执行

以上是关于pytest_01_安装和入门的主要内容,如果未能解决你的问题,请参考以下文章

pytest那些事01_执行结果内容改造

pytest接口自动化零基础入门到精通(01)入门基础篇

将 pytest 与 src 层一起使用

pytest 安装和入门

python学习-pytest-pytest常用方法

pytest 一.安装和使用入门