0% found this document useful (0 votes)
117 views51 pages

Pytest Pres

This document provides an overview of the pytest testing framework. It discusses basic usage including writing tests, running tests, assertions, and fixtures. Fixtures provide a way to reuse test setup and teardown code by defining reusable preconditions. The document covers built-in fixtures, parametrizing fixtures, fixture scopes, and defining custom fixtures.

Uploaded by

Sandeep Aggarwal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
117 views51 pages

Pytest Pres

This document provides an overview of the pytest testing framework. It discusses basic usage including writing tests, running tests, assertions, and fixtures. Fixtures provide a way to reuse test setup and teardown code by defining reusable preconditions. The document covers built-in fixtures, parametrizing fixtures, fixture scopes, and defining custom fixtures.

Uploaded by

Sandeep Aggarwal
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

py.

test

git clone https://github.com/soasme/pytest_tutorial


• Basic: example / usage

• Fixture: mechanism / builtin

• Plugin: conftest / plugin / hook / 3-party

• Scale
Basic
Getting start!
#  content  of  test_sample.py  
def  func(x):  
       return  x  +  1  
!

def  test_answer():  
       assert  func(3)  ==  5  
#  content  of  test_sysexit.py  
import  pytest  
def  f():  
       raise  SystemExit(1)  
!

def  test_mytest():  
       with  pytest.raises(SystemExit):  
               f()  
class  TestClass:  
       def  test_one(self):  
               x  =  "this"  
               assert  'h'  in  x  
!

       def  test_two(self):  
               x  =  "hello"  
               assert  hasattr(x,  'check')  
How to run cases?

• py.test tests/test_mod.py

• py.test tests/

• py.test -k match # def test_match():
How to run cases?
• py.test --showlocals # trace context

• py.test -x # stop on first failure case

• py.test --maxfail=2 # on the second

• py.test -s # enable `print` output

• py.test --durations=10 # list top10 slowest
cases
How to run cases?

• py.test --tb=long # default traceback



• py.test --tb=line # oneline

• py.test --tb=short

• py.test --tb=native # Python default traceback
/tmp % py.test test_a.py --tb=line --pdb

>>>> traceback >>>>

E assert 1 != 1

>>>>> entering PDB >>>>

> /private/tmp/test_a.py(10)test_one()

-> assert num != 1

(Pdb) num

1

(Pdb) exit
How to run cases?

import  pytest  
def  test_function():  
       ...  
       pytest.set_trace()  
py.test -h
What to test?

• folder, file.

• recursive

• test_xxx.py, xxx_test.py

• TestClass (without __init__ method)

• all the function or method with prefix `test_`
What to test?
#  setup.cfg  /  tox.ini  /  pytest.ini  
[pytest]  
python_files=check_*.py  
python_classes=Check  
python_functions=check  
What to test?
#  content  of  check_myapp.py  
class  CheckMyApp:  
       def  check_simple(self):  
               pass  
       def  check_complex(self):  
               pass  
Basic configuration
INI-style

• pytest.ini

• tox.ini

• setup.cfg
Basic configuration
Path

• Current dir

• Parent dir

• ...
Basic configuration
#  content  of  pytest.ini  
#  (or  tox.ini  or  setup.cfg)  
[pytest]  
addopts  =  -­‐-­‐tb=short  -­‐x

py.test test_module.py -k test_func


Assertions

• assert expr

• assert a == b

• self.assertEqual(a, b)

• assert expr, “Expected message”

• pytest.raises
Assertions

• Why `assert`?

• simple

• nice output

• http://pytest.org/latest/example/
reportingdemo.html
Assertions
Define Own Comparison

#  content  of  conftest.py  


def  pytest_assertrepr_compare(op,  left,  right):  
       if  (isinstance(left,  Foo)  
and  isinstance(right,  Foo)  
and  op  ==  "=="):  
         return  ['Comparing  Foo  instances:',  
 'vals:  {0.val}  !=  {1.val}'.format(left,  right)]  

Lesson 4
Assertions
Define Own Comparison

def  test_compare():  
       assert  Foo(1)  ==  Foo(2)

>              assert  f1  ==  f2  


E              assert  Comparing  Foo  instances:  
E                        vals:  1  !=  2  
Assertions

• Py.test refined `assert` statement



• Note: `assert expr, msg` won't output
traceback
Fixtures
• Better than setUp / tearDown:

• Explicit name

• Call only when needed

• Scope: module, class, session, function

• Cascade, fixture A => fixture B => ...

• Scalability
Fixtures as func args
import  pytest  
!

@pytest.fixture  
def  bookmark(app):  
       return  Bookmark.create(  
user_id=1,  
works_id=1)
Fixtures as func args
def  test_get_by_relation(bookmark):  
       bookmarks  =  Bookmark.get(  
user_id=1,  
works_id=1  
)  
       assert  bookmarks  
       assert  bookmarks[0].id  ==  
bookmark.id
Lesson 01
Fixtures as func args

• Testcase only care about fixture, no import,


no setup, no teardown.

• IoC
Fixtures - scope

@pytest.fixture(scope="module")  
def  smtp():  
       return  smtplib.SMTP("dou.bz")
Fixtures - finalization
@pytest.fixture(scope="session")  
def  database(request):  
       db_name  =  "{}.db".format(time())  
       deferred_db.init(db_name)  
       def  finalizer():  
               if  os.path.exists(db_name):  
                       os.remove(db_name)  
       request.addfinalizer(finalizer)  
       return  deferred_db  

Lesson 2
Fixtures - parametrizing
@pytest.fixture(params=[  
       '/',  
       '/reader/',  
])  
def  signed_page(request):  
       return  requests.get(request.param)  
!
def  test_fetch_pages_success_in_signed(signed_page):  
       assert  signed_page.status_code  <  300

Lesson 3.1
Fixtures - modular
class  App(object):  
!
       def  __init__(self,  request):  
               self.request  =  request  
!
@pytest.fixture  
def  app(request,  
               mc_logger,  
               db_logger  
               ):  
       return  App(request)  
Fixtures - autouse
class  TestClass:  
       @pytest.fixture(autouse=True)  
       def  table(self,  database):  
               Table.create_table()  
!
       def  test_select(self):  
               assert  not  Table.get(id=1)
Fixtures - autouse
@pytest.fixture  
def  table(request,  database):  
       Table.create_table()  
       request.addfinilizer(  
Table.drop_table)  
!
@pytest.mark.usefixtures('table')  
class  TestClass:  
       def  test_select(self):  
               assert  not  Table.get(id=1)
Fixtures - parametrizing
@pytest.mark.parametrize(  
       "input,expected",  [  
       ("3+5",  8),  
       ("2+4",  6),  
       ("6*9",  42),  
       pytest.mark.xfail(("6*9",  42))  
])  
def  test_eval(input,  expected):  
       assert  eval(input)  ==  expected

Lesson 3.2
Fixtures - parametrizing
#  conftest.py  
import  pytest  
!
def  pytest_generate_tests(metafunc):  
       if  'payload'  in  metafunc.fixturenames:  
               metafunc.parametrize('payload',  
                      ['/tmp/test.json',  ])  
!
#  test  file  
def  test_meta(payload):  
       assert  payload  ==  '/tmp/test.json'  
       ...
Fixtures - xUnit
def  setup_function(function):  
       print  'setup'  
def  teardown_function(function):  
       print  'teardown'  
def  test_func():  
       print  'func'  
!
#  ==>  
"""  
setup  
func  
teardown  
"""
Fixtures - xUnit
class  TestBookmark:    
     def  setup_method(self,  method):  
               print  'setup'  
       def  teardown_method(self,  method):  
               print  'teardown'  
       def  test_method(self):  
               print  'method'  
!
#  ==>  
"""  
setup  
method  
teardown  
"""
Fixtures - xUnit

• setup_module / teardown_module

• setup_class / teardown_class

• setup_method / teardown_method

• setup_function / teardown_function
Fixtures - builtin
import  datetime  
import  pytest  
!
FAKE_TIME  =  datetime.datetime(2020,  12,  25,  17,  05,  55)  
!
@pytest.fixture  
def  patch_datetime_now(monkeypatch):  
!
       class  mydatetime:  
               @classmethod  
               def  now(cls):  
                       return  FAKE_TIME  
!
       monkeypatch.setattr(datetime,  'datetime',  mydatetime)  
!
!
def  test_patch_datetime(patch_datetime_now):  
       assert  datetime.datetime.now()  ==  FAKE_TIME
Fixtures - builtin

• monkeypatch

• tmpdir

• capsys / capfd

• `py.test --fixture`
Maker
• pytest.marker

• py.test --marker

• marker is like tag.

• @pytest.mark.skipif(getenv('qaci'))

• @pytest.mark.xfail('oooops')

• @pytest.mark.skipif("config.getvalue('pass')")

• @pytest.mark.ask_sunyi

!
unittest.TestCase

• Compatible

• But be careful. There is no funcargs
mechanism for unittest cases.
Plugin
• py.test supply many hooks.

• collection / configuration / run / output

• Basic types:

• builtin

• 3-party plugins

• conftest.py plugins
Plugin - find conftest.py

• recursive

• `import conftest` X
Plugin - 3-party

• pip install pytest-xxxxx



• pytest-random, pytest-cov

• https://pypi.python.org/pypi?
%3Aaction=search&term=pytest&submit=s
earch
Plugin - load plugin
• py.test -p plugin_name

• py.test -p no:plugin_name

• pytest.ini

• conftest.py `pytest_plugins`

• pytest_plugins = "name1", "name2",

• pytest_plugins = "suites.isolated_cases"
Plugin - hooks

• http://pytest.org/latest/plugins.html#hook-
specification-and-validation

• see source.
Plugin - example
#  content  of  suites.isolated_cases  
def  pytest_addoption(parser):  
       group  =  parser.getgroup("isolated_cases",  "")  
       group._addoption(  
               '-­‐-­‐with-­‐data-­‐service',  
               action="store_true",  
               default=False,  
               dest='with_data_service',  
               help=(  
                       "with  MySQL/beansdb/memcached  up  at  the  
beginning  of  session"  
                       "and  down  at  the  end  of  session."  
               )  
       )
Plugin - example
#  content  of  isolated_cases  
def  pytest_configure(config):  
       if  config.option.with_data_service:  
               build_tables()  
               stop_kvstore()  
               sleep(1)  
               start_kvstore()

$ py.test --with-data-service tests/


Plugin - example

#  content  of  tests/conftest.py  


pytest_plugins  =  "suites.isolated_cases"

$ py.test --with-data-service tests/


EOF

You might also like