Top Banner
py.test git clone https://github.com/soasme/pytest_tutorial
51

Py.test

Dec 14, 2014

Download

Technology

soasme

A py.test sharing slide.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Py.test

py.test

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

Page 2: Py.test

• Basic: example / usage

• Fixture: mechanism / builtin

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

• Scale

Page 3: Py.test

Basic

Page 4: Py.test

Getting start!

#  content  of  test_sample.py  def  func(x):          return  x  +  1  !

def  test_answer():          assert  func(3)  ==  5  

Page 5: Py.test

#  content  of  test_sysexit.py  import  pytest  def  f():          raise  SystemExit(1)  !

def  test_mytest():          with  pytest.raises(SystemExit):                  f()  

Page 6: Py.test

class  TestClass:          def  test_one(self):                  x  =  "this"                  assert  'h'  in  x  !

       def  test_two(self):                  x  =  "hello"                  assert  hasattr(x,  'check')  

Page 7: Py.test

How to run cases?

• py.test tests/test_mod.py

• py.test tests/

• py.test -k match # def test_match():

Page 8: Py.test

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

Page 9: Py.test

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

Page 10: Py.test

/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

Page 11: Py.test

How to run cases?

import  pytest  def  test_function():          ...          pytest.set_trace()  

Page 12: Py.test

py.test -h

Page 13: Py.test

What to test?

• folder, file.

• recursive

• test_xxx.py, xxx_test.py

• TestClass (without __init__ method)

• all the function or method with prefix `test_`

Page 14: Py.test

What to test?

#  setup.cfg  /  tox.ini  /  pytest.ini  [pytest]  python_files=check_*.py  python_classes=Check  python_functions=check  

Page 15: Py.test

What to test?

#  content  of  check_myapp.py  class  CheckMyApp:          def  check_simple(self):                  pass          def  check_complex(self):                  pass  

Page 16: Py.test

Basic configuration

• pytest.ini

• tox.ini

• setup.cfg

INI-style

Page 17: Py.test

Basic configuration

• Current dir

• Parent dir

• ...

Path

Page 18: Py.test

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

Page 19: Py.test

Assertions

• assert expr

• assert a == b

• self.assertEqual(a, b)

• assert expr, “Expected message”

• pytest.raises

Page 20: Py.test

Assertions

• Why `assert`?

• simple

• nice output

• http://pytest.org/latest/example/reportingdemo.html

Page 21: Py.test

Assertions

#  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)]  

Define Own Comparison

Lesson 4

Page 22: Py.test

Assertions

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

Define Own Comparison

>              assert  f1  ==  f2  E              assert  Comparing  Foo  instances:  E                        vals:  1  !=  2  

Page 23: Py.test

Assertions

• Py.test refined `assert` statement

• Note: `assert expr, msg` won't output traceback

Page 24: Py.test

Fixtures

• Better than setUp / tearDown:

• Explicit name

• Call only when needed

• Scope: module, class, session, function

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

• Scalability

Page 25: Py.test

Fixtures as func args

import  pytest  !

@pytest.fixture  def  bookmark(app):          return  Bookmark.create(  

user_id=1,  works_id=1)

Page 26: Py.test

Fixtures as func argsdef  test_get_by_relation(bookmark):          bookmarks  =  Bookmark.get(  

user_id=1,  works_id=1  )  

       assert  bookmarks          assert  bookmarks[0].id  ==  bookmark.id

Lesson 01

Page 27: Py.test

Fixtures as func args

• Testcase only care about fixture, no import, no setup, no teardown.

• IoC

Page 28: Py.test

Fixtures - scope

@pytest.fixture(scope="module")  def  smtp():          return  smtplib.SMTP("dou.bz")

Page 29: Py.test

Fixtures - [email protected](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

Page 30: Py.test

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

Page 31: Py.test

Fixtures - modularclass  App(object):  !        def  __init__(self,  request):                  self.request  =  request  [email protected]  def  app(request,                  mc_logger,                  db_logger                  ):          return  App(request)  

Page 32: Py.test

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)

Page 33: Py.test

Fixtures - [email protected]  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)

Page 34: Py.test

Fixtures - [email protected](          "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

Page 35: Py.test

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'          ...

Page 36: Py.test

Fixtures - xUnitdef  setup_function(function):          print  'setup'  def  teardown_function(function):          print  'teardown'  def  test_func():          print  'func'  !#  ==>  """  setup  func  teardown  """

Page 37: Py.test

Fixtures - xUnitclass  TestBookmark:          def  setup_method(self,  method):                  print  'setup'          def  teardown_method(self,  method):                  print  'teardown'          def  test_method(self):                  print  'method'  !#  ==>  """  setup  method  teardown  """

Page 38: Py.test

Fixtures - xUnit

• setup_module / teardown_module

• setup_class / teardown_class

• setup_method / teardown_method

• setup_function / teardown_function

Page 39: Py.test

Fixtures - builtinimport  datetime  import  pytest  !FAKE_TIME  =  datetime.datetime(2020,  12,  25,  17,  05,  55)  [email protected]  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

Page 40: Py.test

Fixtures - builtin

• monkeypatch

• tmpdir

• capsys / capfd

• `py.test --fixture`

Page 41: Py.test

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

!

Page 42: Py.test

unittest.TestCase

• Compatible

• But be careful. There is no funcargs mechanism for unittest cases.

Page 43: Py.test

Plugin

• py.test supply many hooks.

• collection / configuration / run / output

• Basic types:

• builtin

• 3-party plugins

• conftest.py plugins

Page 44: Py.test

Plugin - find conftest.py

• recursive

• `import conftest` X

Page 45: Py.test

Plugin - 3-party

• pip install pytest-xxxxx

• pytest-random, pytest-cov

• https://pypi.python.org/pypi?%3Aaction=search&term=pytest&submit=search

Page 46: Py.test

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"

Page 47: Py.test

Plugin - hooks

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

• see source.

Page 48: Py.test

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."                  )          )

Page 49: Py.test

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/

Page 50: Py.test

Plugin - example

#  content  of  tests/conftest.py  pytest_plugins  =  "suites.isolated_cases"

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

Page 51: Py.test

EOF