内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

自动化测试框架工具pytest教程2:测试函数

2018-09-11 22:11 出处:清屏网 人气: 评论(0

第2章 测试函数

测试Tasks程序

被测程序Tasks的结构如下

tasks_proj/
├── CHANGELOG.rst
├── LICENSE
├── MANIFEST.in
├── README.rst
├── setup.py
├── src
│ └── tasks
│ ├── __init__.py
│ ├── api.py
│ ├── cli.py
│ ├── config.py
│ ├── tasksdb_pymongo.py
│ └── tasksdb_tinydb.py
└── tests
├── conftest.py
├── pytest.ini
├── func
│ ├── __init__.py
│ ├── test_add.py
│ └── ...
└── unit
├── __init__.py
├── test_task.py
└── ...

安装:

# python3 setup.py install 
running install
Checking .pth file support in /usr/local/lib/python3.5/dist-packages/
/usr/bin/python3 -E -c pass
TEST PASSED: /usr/local/lib/python3.5/dist-packages/ appears to support .pth files
running bdist_egg
running egg_info
creating src/tasks.egg-info
writing src/tasks.egg-info/PKG-INFO
writing dependency_links to src/tasks.egg-info/dependency_links.txt
writing top-level names to src/tasks.egg-info/top_level.txt
writing requirements to src/tasks.egg-info/requires.txt
writing entry points to src/tasks.egg-info/entry_points.txt
writing manifest file 'src/tasks.egg-info/SOURCES.txt'
reading manifest file 'src/tasks.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'src/tasks.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib
creating build/lib/tasks
copying src/tasks/api.py -> build/lib/tasks
copying src/tasks/tasksdb_pymongo.py -> build/lib/tasks
copying src/tasks/tasksdb_tinydb.py -> build/lib/tasks
copying src/tasks/config.py -> build/lib/tasks
copying src/tasks/__init__.py -> build/lib/tasks
copying src/tasks/cli.py -> build/lib/tasks
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
creating build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/api.py -> build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/tasksdb_pymongo.py -> build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/tasksdb_tinydb.py -> build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/config.py -> build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/__init__.py -> build/bdist.linux-x86_64/egg/tasks
copying build/lib/tasks/cli.py -> build/bdist.linux-x86_64/egg/tasks
byte-compiling build/bdist.linux-x86_64/egg/tasks/api.py to api.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/tasks/tasksdb_pymongo.py to tasksdb_pymongo.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/tasks/tasksdb_tinydb.py to tasksdb_tinydb.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/tasks/config.py to config.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/tasks/__init__.py to __init__.cpython-35.pyc
byte-compiling build/bdist.linux-x86_64/egg/tasks/cli.py to cli.cpython-35.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/entry_points.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/requires.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying src/tasks.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating dist
creating 'dist/tasks-0.1.0-py3.5.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing tasks-0.1.0-py3.5.egg
Copying tasks-0.1.0-py3.5.egg to /usr/local/lib/python3.5/dist-packages
Adding tasks 0.1.0 to easy-install.pth file
Installing tasks script to /usr/local/bin

Installed /usr/local/lib/python3.5/dist-packages/tasks-0.1.0-py3.5.egg
Processing dependencies for tasks==0.1.0
Searching for tinydb
Reading https://pypi.python.org/simple/tinydb/
Best match: tinydb 3.9.0.post1
Downloading https://files.pythonhosted.org/packages/82/f2/c26a5c4b8486349dacc8abba33c495b77a0b67052b5c79c5d5c90da49b95/tinydb-3.9.0.post1.tar.gz#sha256=88793016ba94267e3606372e1564d4e797eae855acd5a48352011bfdcf8ee7ad
Processing tinydb-3.9.0.post1.tar.gz
Writing /tmp/easy_install-_cvtvm1f/tinydb-3.9.0.post1/setup.cfg
Running tinydb-3.9.0.post1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-_cvtvm1f/tinydb-3.9.0.post1/egg-dist-tmp-xpn6fitk
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'python_requires'
  warnings.warn(msg)
zip_safe flag not set; analyzing archive contents...

Installed /tmp/easy_install-_cvtvm1f/tinydb-3.9.0.post1/.eggs/pytest_runner-4.2-py3.5.egg
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'project_urls'
  warnings.warn(msg)
Moving tinydb-3.9.0.post1-py3.5.egg to /usr/local/lib/python3.5/dist-packages
Adding tinydb 3.9.0.post1 to easy-install.pth file

Installed /usr/local/lib/python3.5/dist-packages/tinydb-3.9.0.post1-py3.5.egg
Searching for six==1.10.0
Best match: six 1.10.0
Adding six 1.10.0 to easy-install.pth file

Using /usr/lib/python3/dist-packages
Searching for click==6.7
Best match: click 6.7
Adding click 6.7 to easy-install.pth file

Using /usr/local/lib/python3.5/dist-packages
Finished processing dependencies for tasks==0.1.0

其他安装方式: 在tasks_proj执行:“pip install . ” 或者 “pip install -e .”, 或者在上级目录执行“pip install -e tasks_proj”。 -e 为editor,可以编辑源码。

被测程序演示:

$ tasks add "reading pytest!" --owner Andrew
$ tasks add "do something else"
$ tasks list
  ID      owner  done summary
  --      -----  ---- -------
   1     Andrew False reading pytest!
   2            False do something else
$ tasks update 2 --owner Brian
$ tasks list
  ID      owner  done summary
  --      -----  ---- -------
   1     Andrew False reading pytest!
   2      Brian False do something else
$ tasks update 1 --done True
$ tasks list
  ID      owner  done summary
  --      -----  ---- -------
   1     Andrew  True reading pytest!
   2      Brian False do something else
$ tasks delete 1
$ tasks list
  ID      owner  done summary
  --      -----  ---- -------
   2      Brian False do something else

把前面的单元测试进行汇总:

/ch2/tasks_proj/tests/unit/test_task.py

"""Test the Task data type."""
from tasks import Task


def test_asdict():
    """_asdict() should return a dictionary."""
    t_task = Task('do something', 'okken', True, 21)
    t_dict = t_task._asdict()
    expected = {'summary': 'do something',
                'owner': 'okken',
                'done': True,
                'id': 21}
    assert t_dict == expected


def test_replace():
    """replace() should change passed in fields."""
    t_before = Task('finish book', 'brian', False)
    t_after = t_before._replace(id=10, done=True)
    t_expected = Task('finish book', 'brian', True, 10)
    assert t_after == t_expected


def test_defaults():
    """Using no parameters should invoke defaults."""
    t1 = Task()
    t2 = Task(None, None, False, None)
    assert t1 == t2


def test_member_access():
    """Check .field functionality of namedtuple."""
    t = Task('buy milk', 'brian')
    assert t.summary == 'buy milk'
    assert t.owner == 'brian'
    assert (t.done, t.id) == (False, None)

执行

andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/unit$ pytest test_task.py 
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 4 items                                                                                         

test_task.py ....                                                                                   [100%]

======================================== 4 passed in 0.02 seconds =========================================

断言

test_task_fail.py

from tasks import Task


def test_task_equality():
    """Different tasks should not be equal."""
    t1 = Task('sit there', 'brian')
    t2 = Task('do something', 'okken')
    assert t1 == t2


def test_dict_equality():
    """Different tasks compared as dicts should not be equal."""
    t1_dict = Task('make sandwich', 'okken')._asdict()
    t2_dict = Task('make sandwich', 'okkem')._asdict()
    assert t1_dict == t2_dict

执行:

~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/unit$ pytest test_task_fail.py 
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 2 items                                                                                         

test_task_fail.py FF                                                                                [100%]

================================================ FAILURES =================================================
___________________________________________ test_task_equality ____________________________________________

    def test_task_equality():
        """Different tasks should not be equal."""
        t1 = Task('sit there', 'brian')
        t2 = Task('do something', 'okken')
>       assert t1 == t2
E       AssertionError: assert Task(summary=...alse, id=None) == Task(summary='...alse, id=None)
E         At index 0 diff: 'sit there' != 'do something'
E         Use -v to get the full diff

test_task_fail.py:9: AssertionError
___________________________________________ test_dict_equality ____________________________________________

    def test_dict_equality():
        """Different tasks compared as dicts should not be equal."""
        t1_dict = Task('make sandwich', 'okken')._asdict()
        t2_dict = Task('make sandwich', 'okkem')._asdict()
>       assert t1_dict == t2_dict
E       AssertionError: assert OrderedDict([...('id', None)]) == OrderedDict([(...('id', None)])
E         Omitting 3 identical items, use -vv to show
E         Differing items:
E         {'owner': 'okken'} != {'owner': 'okkem'}
E         Use -v to get the full diff

test_task_fail.py:16: AssertionError
======================================== 2 failed in 0.04 seconds =========================================

更多断言实例

预期异常

tasks/api.py的函数如下:

def add(task): # type: (Task) -> int
def get(task_id): # type: (int) -> Task
def list_tasks(owner=None): # type: (str|None) -> list of Task
def count(): # type: (None) -> int
def update(task_id, task): # type: (int, Task) -> None
def delete(task_id): # type: (int) -> None
def delete_all(): # type: () -> None
def unique_id(): # type: () -> int
def start_tasks_db(db_path, db_type): # type: (str, str) -> None
def stop_tasks_db(): # type: () -> None

test_api_exceptions.py

"""Test for expected exceptions from using the API wrong."""

import pytest
import tasks


def test_add_raises():
    """add() should raise an exception with wrong type param."""
    with pytest.raises(TypeError):
        tasks.add(task='not a Task object')


@pytest.mark.smoke
def test_list_raises():
    """list() should raise an exception with wrong type param."""
    with pytest.raises(TypeError):
        tasks.list_tasks(owner=123)


@pytest.mark.get
@pytest.mark.smoke
def test_get_raises():
    """get() should raise an exception with wrong type param."""
    with pytest.raises(TypeError):
        tasks.get(task_id='123')


class TestUpdate():
    """Test expected exceptions with tasks.update()."""

    def test_bad_id(self):
        """A non-int id should raise an excption."""
        with pytest.raises(TypeError):
            tasks.update(task_id={'dict instead': 1},
                         task=tasks.Task())

    def test_bad_task(self):
        """A non-Task task should raise an excption."""
        with pytest.raises(TypeError):
            tasks.update(task_id=1, task='not a task')


def test_delete_raises():
    """delete() should raise an exception with wrong type param."""
    with pytest.raises(TypeError):
        tasks.delete(task_id=(1, 2, 3))


def test_start_tasks_db_raises():
    """Make sure unsupported db raises an exception."""
    with pytest.raises(ValueError) as excinfo:
        tasks.start_tasks_db('some/great/path', 'mysql')
    exception_msg = excinfo.value.args[0]
    assert exception_msg == "db_type must be a 'tiny' or 'mongo'"

标记测试函数

基于标签实现,参见上面代码。

andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$  pytest test_api_exceptions.py 
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 7 items                                                                                         

test_api_exceptions.py .......                                                                      [100%]

======================================== 7 passed in 0.03 seconds =========================================
andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_api_exceptions.py  -v -m "smoke"
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python3
cachedir: ../.pytest_cache
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 7 items / 5 deselected                                                                          

test_api_exceptions.py::test_list_raises PASSED                                                     [ 50%]
test_api_exceptions.py::test_get_raises PASSED                                                      [100%]

================================= 2 passed, 5 deselected in 0.02 seconds ==================================
andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_api_exceptions.py  -v -m "smoke and get"
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python3
cachedir: ../.pytest_cache
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 7 items / 6 deselected                                                                          

test_api_exceptions.py::test_get_raises PASSED                                                      [100%]

================================= 1 passed, 6 deselected in 0.01 seconds ==================================
andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_api_exceptions.py  -v -m "smoke and not get"
=========================================== test session starts ===========================================
platform linux -- Python 3.5.2, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/bin/python3
cachedir: ../.pytest_cache
rootdir: /home/andrew/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
collected 7 items / 6 deselected                                                                          

test_api_exceptions.py::test_list_raises PASSED                                                     [100%]

================================= 1 passed, 6 deselected in 0.01 seconds ==================================
andrew@andrew-PowerEdge-T630:~/code/china-testing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ 

$ pytest -v -m smoke
======================================================== test session starts =========================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: ../.pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 50 items / 47 deselected                                                                                                   

test_add.py::test_added_task_has_id_set PASSED                                                                                 [ 33%]
test_api_exceptions.py::test_list_raises PASSED                                                                                [ 66%]
test_api_exceptions.py::test_get_raises PASSED                                                                                 [100%]

============================================== 3 passed, 47 deselected in 0.07 seconds ===============================================

忽略测试

test_unique_id_1.py

# 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入) 
# qq群:144081101 591302926  567351477
"""Test tasks.unique_id()."""

import pytest
import tasks


def test_unique_id():
    """Calling unique_id() twice should return different numbers."""
    id_1 = tasks.unique_id()
    id_2 = tasks.unique_id()
    assert id_1 != id_2


@pytest.fixture(autouse=True)
def initialized_tasks_db(tmpdir):
    """Connect to db before testing, disconnect after."""
    tasks.start_tasks_db(str(tmpdir), 'tiny')
    yield
    tasks.stop_tasks_db()

执行:

andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_unique_id_1.py 
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 1 item                                                                                                                             

test_unique_id_1.py F                                                                                                                  [100%]

================================================================== FAILURES ==================================================================
_______________________________________________________________ test_unique_id _______________________________________________________________

    def test_unique_id():
        """Calling unique_id() twice should return different numbers."""
        id_1 = tasks.unique_id()
        id_2 = tasks.unique_id()
>       assert id_1 != id_2
E       assert 1 != 1

test_unique_id_1.py:11: AssertionError
========================================================== 1 failed in 0.08 seconds ==========================================================

上述用例没有通过,我们现在想暂时不执行。

test_unique_id_2.py

# 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入) 
# qq群:144081101 591302926  567351477
"""Test tasks.unique_id()."""

import pytest
import tasks
from tasks import Task


@pytest.mark.skip(reason='misunderstood the API')
def test_unique_id_1():
    """Calling unique_id() twice should return different numbers."""
    id_1 = tasks.unique_id()
    id_2 = tasks.unique_id()
    assert id_1 != id_2


def test_unique_id_2():
    """unique_id() should return an unused id."""
    ids = []
    ids.append(tasks.add(Task('one')))
    ids.append(tasks.add(Task('two')))
    ids.append(tasks.add(Task('three')))
    # grab a unique id
    uid = tasks.unique_id()
    # make sure it isn't in the list of existing ids
    assert uid not in ids


@pytest.fixture(autouse=True)
def initialized_tasks_db(tmpdir):
    """Connect to db before testing, disconnect after."""
    tasks.start_tasks_db(str(tmpdir), 'tiny')
    yield
    tasks.stop_tasks_db()

执行:

$ pytest test_unique_id_2.py 
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 2 items                                                                                                                            

test_unique_id_2.py s.                                                                                                                 [100%]

==================================================== 1 passed, 1 skipped in 0.03 seconds =====================================================

skipif可以基于条件,比如基于版本号忽略用例。

test_unique_id_3.py

# 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入) 
# qq群:144081101 591302926  567351477
"""Test tasks.unique_id()."""

import pytest
import tasks
from tasks import Task


@pytest.mark.skipif(tasks.__version__ < '0.2.0',
                    reason='not supported until version 0.2.0')
def test_unique_id_1():
    """Calling unique_id() twice should return different numbers."""
    id_1 = tasks.unique_id()
    id_2 = tasks.unique_id()
    assert id_1 != id_2


def test_unique_id_2():
    """unique_id() should return an unused id."""
    ids = []
    ids.append(tasks.add(Task('one')))
    ids.append(tasks.add(Task('two')))
    ids.append(tasks.add(Task('three')))
    # grab a unique id
    uid = tasks.unique_id()
    # make sure it isn't in the list of existing ids
    assert uid not in ids


@pytest.fixture(autouse=True)
def initialized_tasks_db(tmpdir):
    """Connect to db before testing, disconnect after."""
    tasks.start_tasks_db(str(tmpdir), 'tiny')
    yield
    tasks.stop_tasks_db()

执行:

andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_unique_id_3.py -v
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: ../.pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 2 items                                                                                                                            

test_unique_id_3.py::test_unique_id_1 SKIPPED                                                                                          [ 50%]
test_unique_id_3.py::test_unique_id_2 PASSED                                                                                           [100%]

==================================================== 1 passed, 1 skipped in 0.03 seconds =====================================================
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_unique_id_3.py -rs
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 2 items                                                                                                                            

test_unique_id_3.py s.                                                                                                                 [100%]
========================================================== short test summary info ===========================================================
SKIP [1] func/test_unique_id_3.py:8: not supported until version 0.2.0

==================================================== 1 passed, 1 skipped in 0.03 seconds =====================================================

$ ​​pytest​​ ​​--help​
​...​
-r chars
show extra test summary info as specified by chars
(f)ailed, (E)error, (s)skipped, (x)failed, (X)passed,
(p)passed, (P)passed with output, (a)all except pP.
​...​

预期失败

上例中xfail可以标识在0.2.0失败,以上成功。

test_unique_id_4.py

# 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入) 
# qq群:144081101 591302926  567351477
"""Test tasks.unique_id()."""

import pytest
import tasks
from tasks import Task


@pytest.mark.xfail(tasks.__version__ < '0.2.0',
                   reason='not supported until version 0.2.0')
def test_unique_id_1():
    """Calling unique_id() twice should return different numbers."""
    id_1 = tasks.unique_id()
    id_2 = tasks.unique_id()
    assert id_1 != id_2


@pytest.mark.xfail()
def test_unique_id_is_a_duck():
    """Demonstrate xfail."""
    uid = tasks.unique_id()
    assert uid == 'a duck'


@pytest.mark.xfail()
def test_unique_id_not_a_duck():
    """Demonstrate xpass."""
    uid = tasks.unique_id()
    assert uid != 'a duck'


def test_unique_id_2():
    """unique_id() should return an unused id."""
    ids = []
    ids.append(tasks.add(Task('one')))
    ids.append(tasks.add(Task('two')))
    ids.append(tasks.add(Task('three')))
    # grab a unique id
    uid = tasks.unique_id()
    # make sure it isn't in the list of existing ids
    assert uid not in ids


@pytest.fixture(autouse=True)
def initialized_tasks_db(tmpdir):
    """Connect to db before testing, disconnect after."""
    tasks.start_tasks_db(str(tmpdir), 'tiny')
    yield
    tasks.stop_tasks_db()

执行:

c$ pytest test_unique_id_4.py
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 4 items                                                                                                                            

test_unique_id_4.py xxX.                                                                                                               [100%]

=============================================== 1 passed, 2 xfailed, 1 xpassed in 0.10 seconds ===============================================
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests/func$ pytest test_unique_id_4.py -v
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: ../.pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 4 items                                                                                                                            

test_unique_id_4.py::test_unique_id_1 xfail                                                                                            [ 25%]
test_unique_id_4.py::test_unique_id_is_a_duck xfail                                                                                    [ 50%]
test_unique_id_4.py::test_unique_id_not_a_duck XPASS                                                                                   [ 75%]
test_unique_id_4.py::test_unique_id_2 PASSED                                                                                           [100%]

=============================================== 1 passed, 2 xfailed, 1 xpassed in 0.11 seconds ===============================================

在pytest.ini设置

[pytest]
xfail_strict=true

xfail会置为FAIL。

批量执行

  • 单个目录
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj$ pytest  tests/func --tb=no
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 50 items                                                                                                                           

tests/func/test_add.py ..                                                                                                              [  4%]
tests/func/test_add_variety.py ................................                                                                        [ 68%]
tests/func/test_api_exceptions.py .......                                                                                              [ 82%]
tests/func/test_unique_id_1.py F                                                                                                       [ 84%]
tests/func/test_unique_id_2.py s.                                                                                                      [ 88%]
tests/func/test_unique_id_3.py s.                                                                                                      [ 92%]
tests/func/test_unique_id_4.py xxX.                                                                                                    [100%]

==================================== 1 failed, 44 passed, 2 skipped, 2 xfailed, 1 xpassed in 0.31 seconds ====================================
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj$ pytest  tests/func --tb=no -v
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: tests/.pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 50 items                                                                                                                           

tests/func/test_add.py::test_add_returns_valid_id PASSED                                                                               [  2%]
tests/func/test_add.py::test_added_task_has_id_set PASSED                                                                              [  4%]
tests/func/test_add_variety.py::test_add_1 PASSED                                                                                      [  6%]
tests/func/test_add_variety.py::test_add_2[task0] PASSED                                                                               [  8%]
tests/func/test_add_variety.py::test_add_2[task1] PASSED                                                                               [ 10%]
tests/func/test_add_variety.py::test_add_2[task2] PASSED                                                                               [ 12%]
tests/func/test_add_variety.py::test_add_2[task3] PASSED                                                                               [ 14%]
tests/func/test_add_variety.py::test_add_3[sleep-None-False] PASSED                                                                    [ 16%]
tests/func/test_add_variety.py::test_add_3[wake-brian-False] PASSED                                                                    [ 18%]
tests/func/test_add_variety.py::test_add_3[breathe-BRIAN-True] PASSED                                                                  [ 20%]
tests/func/test_add_variety.py::test_add_3[eat eggs-BrIaN-False] PASSED                                                                [ 22%]
tests/func/test_add_variety.py::test_add_4[task0] PASSED                                                                               [ 24%]
tests/func/test_add_variety.py::test_add_4[task1] PASSED                                                                               [ 26%]
tests/func/test_add_variety.py::test_add_4[task2] PASSED                                                                               [ 28%]
tests/func/test_add_variety.py::test_add_4[task3] PASSED                                                                               [ 30%]
tests/func/test_add_variety.py::test_add_4[task4] PASSED                                                                               [ 32%]
tests/func/test_add_variety.py::test_add_5[Task(sleep,None,True)] PASSED                                                               [ 34%]
tests/func/test_add_variety.py::test_add_5[Task(wake,brian,False)0] PASSED                                                             [ 36%]
tests/func/test_add_variety.py::test_add_5[Task(wake,brian,False)1] PASSED                                                             [ 38%]
tests/func/test_add_variety.py::test_add_5[Task(breathe,BRIAN,True)] PASSED                                                            [ 40%]
tests/func/test_add_variety.py::test_add_5[Task(exercise,BrIaN,False)] PASSED                                                          [ 42%]
tests/func/test_add_variety.py::test_add_6[just summary] PASSED                                                                        [ 44%]
tests/func/test_add_variety.py::test_add_6[summary/owner] PASSED                                                                       [ 46%]
tests/func/test_add_variety.py::test_add_6[summary/owner/done] PASSED                                                                  [ 48%]
tests/func/test_add_variety.py::TestAdd::test_equivalent[Task(sleep,None,True)] PASSED                                                 [ 50%]
tests/func/test_add_variety.py::TestAdd::test_equivalent[Task(wake,brian,False)0] PASSED                                               [ 52%]
tests/func/test_add_variety.py::TestAdd::test_equivalent[Task(wake,brian,False)1] PASSED                                               [ 54%]
tests/func/test_add_variety.py::TestAdd::test_equivalent[Task(breathe,BRIAN,True)] PASSED                                              [ 56%]
tests/func/test_add_variety.py::TestAdd::test_equivalent[Task(exercise,BrIaN,False)] PASSED                                            [ 58%]
tests/func/test_add_variety.py::TestAdd::test_valid_id[Task(sleep,None,True)] PASSED                                                   [ 60%]
tests/func/test_add_variety.py::TestAdd::test_valid_id[Task(wake,brian,False)0] PASSED                                                 [ 62%]
tests/func/test_add_variety.py::TestAdd::test_valid_id[Task(wake,brian,False)1] PASSED                                                 [ 64%]
tests/func/test_add_variety.py::TestAdd::test_valid_id[Task(breathe,BRIAN,True)] PASSED                                                [ 66%]
tests/func/test_add_variety.py::TestAdd::test_valid_id[Task(exercise,BrIaN,False)] PASSED                                              [ 68%]
tests/func/test_api_exceptions.py::test_add_raises PASSED                                                                              [ 70%]
tests/func/test_api_exceptions.py::test_list_raises PASSED                                                                             [ 72%]
tests/func/test_api_exceptions.py::test_get_raises PASSED                                                                              [ 74%]
tests/func/test_api_exceptions.py::TestUpdate::test_bad_id PASSED                                                                      [ 76%]
tests/func/test_api_exceptions.py::TestUpdate::test_bad_task PASSED                                                                    [ 78%]
tests/func/test_api_exceptions.py::test_delete_raises PASSED                                                                           [ 80%]
tests/func/test_api_exceptions.py::test_start_tasks_db_raises PASSED                                                                   [ 82%]
tests/func/test_unique_id_1.py::test_unique_id FAILED                                                                                  [ 84%]
tests/func/test_unique_id_2.py::test_unique_id_1 SKIPPED                                                                               [ 86%]
tests/func/test_unique_id_2.py::test_unique_id_2 PASSED                                                                                [ 88%]
tests/func/test_unique_id_3.py::test_unique_id_1 SKIPPED                                                                               [ 90%]
tests/func/test_unique_id_3.py::test_unique_id_2 PASSED                                                                                [ 92%]
tests/func/test_unique_id_4.py::test_unique_id_1 xfail                                                                                 [ 94%]
tests/func/test_unique_id_4.py::test_unique_id_is_a_duck xfail                                                                         [ 96%]
tests/func/test_unique_id_4.py::test_unique_id_not_a_duck XPASS                                                                        [ 98%]
tests/func/test_unique_id_4.py::test_unique_id_2 PASSED                                                                                [100%]

==================================== 1 failed, 44 passed, 2 skipped, 2 xfailed, 1 xpassed in 0.34 seconds ====================================
  • 单个文件/模块
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj$ pytest tests/func/test_add.py 
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 2 items                                                                                                                            

tests/func/test_add.py ..                                                                                                              [100%]
  • 单个函数
$ pytest tests/func/test_add.py::test_add_returns_valid_id -v
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: tests/.pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 1 item                                                                                                                             

tests/func/test_add.py::test_add_returns_valid_id PASSED                                                                               [100%]

========================================================== 1 passed in 0.03 seconds ==========================================================
                                                                                                            [100%]
  • 单个类
$ pytest tests/func/test_api_exceptions.py::TestUpdate
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 2 items                                                                                                                            

tests/func/test_api_exceptions.py ..                                                                                                   [100%]

========================================================== 2 passed in 0.01 seconds ==========================================================
  • 单个类的测试方法
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj$ pytest tests/func/test_api_exceptions.py::TestUpdate::test_bad_id
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj/tests, inifile: pytest.ini
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 1 item                                                                                                                             

tests/func/test_api_exceptions.py .                                                                                                    [100%]

========================================================== 1 passed in 0.01 seconds ==========================================================
  • 基于测试名
$ pytest -v -k _raises
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: .pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj, inifile:
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 56 items / 51 deselected                                                                                                           

tests/func/test_api_exceptions.py::test_add_raises PASSED                                                                              [ 20%]
tests/func/test_api_exceptions.py::test_list_raises PASSED                                                                             [ 40%]
tests/func/test_api_exceptions.py::test_get_raises PASSED                                                                              [ 60%]
tests/func/test_api_exceptions.py::test_delete_raises PASSED                                                                           [ 80%]
tests/func/test_api_exceptions.py::test_start_tasks_db_raises PASSED                                                                   [100%]

================================================== 5 passed, 51 deselected in 0.12 seconds ===================================================
andrew@andrew-PowerEdge-T630:~/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj$ pytest -v -k "_raises and not delete"
============================================================ test session starts =============================================================
platform linux -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 -- /usr/local/anaconda3/bin/python
cachedir: .pytest_cache
metadata: {'Python': '3.6.5', 'Platform': 'Linux-4.4.0-130-generic-x86_64-with-debian-stretch-sid', 'Packages': {'pytest': '3.5.1', 'py': '1.5.3', 'pluggy': '0.6.0'}, 'Plugins': {'remotedata': '0.2.1', 'openfiles': '0.3.0', 'metadata': '1.7.0', 'html': '1.19.0', 'doctestplus': '0.1.3', 'arraydiff': '0.2'}, 'JAVA_HOME': '/usr/lib/jvm/java-8-oracle/jre/bin'}
rootdir: /home/andrew/code/python-api-tesing/python3_libraries/pytest_testing/ch2/tasks_proj, inifile:
plugins: remotedata-0.2.1, openfiles-0.3.0, metadata-1.7.0, html-1.19.0, doctestplus-0.1.3, arraydiff-0.2
collected 56 items / 52 deselected                                                                                                           

tests/func/test_api_exceptions.py::test_add_raises PASSED                                                                              [ 25%]
tests/func/test_api_exceptions.py::test_list_raises PASSED                                                                             [ 50%]
tests/func/test_api_exceptions.py::test_get_raises PASSED                                                                              [ 75%]
tests/func/test_api_exceptions.py::test_start_tasks_db_raises PASSED                                                                   [100%]

================================================== 4 passed, 52 deselected in 0.06 seconds ===================================================
分享给小伙伴们:
本文标签: pytest自动化测试

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号