
рдирдорд╕реНрдХрд╛рд░ред рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдореИрдВ рдЕрдЬрдЧрд░ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ django рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВред рд╣рдо рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг (рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг), рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдФрд░ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдХреБрдЫ рдиреБрдХрд╕рд╛рди рджреЗрдЦреЗрдВрдЧреЗред
рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд╛рднреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рднрд╛рдЧ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ - рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХреЛрдб рдирд░рдо рдФрд░ рд░реЗрд╢рдореА рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдЖрд▓рд╕реА рд▓реЛрдЧреЛрдВ рдиреЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрднреА рддрдХ рдкрдврд╝рд╛ / рд▓рд┐рдЦрд╛ рдирд╣реАрдВ рд╣реИред
unittest
рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рдореЙрдбреНрдпреВрд▓ (unittest, рдкрд╣рд▓реЗ рдкреНрдпреВрдирд┐рдЯ) рдкрд╛рдпрдерди рд╕рдВрд╕реНрдХрд░рдг 2.1 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рдФрд░ рдЬрд╛рд╡рд╛ рдХреЗ рд╕рд╛рде рдПрдХ JUnit рдкреЛрд░реНрдЯ рдерд╛ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреИрдорд▓рдХреЗрд╕ рдиреЗ рдирд╛рдордХрд░рдг рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛, рдЬреЛ
pep8 рдХреЗ рд╡рд┐рдкрд░реАрдд рдерд╛)ред рдЕрдЬрдЧрд░ 2.7 (3.2) рдореЗрдВ, рдпреВрдиреАрдЯреЗрд╕реНрдЯ рдиреЗ рдХрдИ рдирдИ рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬреЗрдВ
@skip
: рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдВрдЪ (
assert*
), рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг (
@skip
,
@skipIf
) рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдпрд╛ рдЯреВрдЯреЗ рд╣реБрдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ (
@expectedFailure
) рддрд░реАрдХреЗ рд╕реЗ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рд╕реЗ рд▓реЙрдиреНрдЪред рдЕрдЬрдЧрд░ 2.4 рдФрд░ рдЙрдЪреНрдЪрддрд░ рдХреЗ рд▓рд┐рдП рдЗрди рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрджрд░рдЧрд╛рд╣ рднреА рд╣реИ, рдЬрд┐рд╕реЗ
рдпреВрдирд┐рдЯреЗрд╕реНрдЯ 2 рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрд╣ рдмрд╛рдд рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИ рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЕрдорд╛рдирд╡реАрдп рд░реВрдк рд╕реЗ рдЬрдЯрд┐рд▓ рдореЙрдбреНрдпреВрд▓ рд╣реИ, run_once.py:
def run_once(f): """ . . """ def _f(*args, **kwargs): if not hasattr(_f, "_retval"): _f._retval = f(*args, **kwargs) return _f._retval return _f
(рдпрд╣ рдПрдХ рдбреЗрдХреЛрд░реЗрдЯрд░ рд╣реИ рдЬреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд╣рд▓реЗ рдХреЙрд▓ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрд╢рд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред)рд╣рдорд╛рд░реЗ рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
import unittest class Test(unittest.TestCase): def test_run_once(self): @run_once def inc(n): return n + 1
рдЕрдВрддрд┐рдо рджреЛ рд▓рд╛рдЗрдиреЗрдВ рдПрдХ рд▓реЙрдиреНрдЪрд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИрдВ рдЬреЛ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЦреЛрдЬреЗрдЧрд╛ рдФрд░ рдЪрд▓рд╛рдПрдЧрд╛ред рдЕрдм рдХрдВрд╕реЛрд▓ рдореЗрдВ рд╣рдо рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
$ python run_once.py
рдФрд░ рдкрд░реАрдХреНрд╖рд╛ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВ:
. --- Ran 1 test in 0.000s OK
doctest
рдЪреВрдВрдХрд┐ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдЗрди рджрд┐рдиреЛрдВ рдХрд┐рд╕реА рдХреЛ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЖрдкрдХреЛ рдЕрдЬрдЧрд░ - рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреАрдЬ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред рдпрд╣ рд╕рдордЭрд╛рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рджрд┐рдЦрд╛рдирд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ:
def run_once(f): """ >>> @run_once ... def foo(n): return n + 1 >>> foo(7) 8 >>> foo(0) 8 """ def _f(*args, **kwargs): if not hasattr(_f, "_retval"): _f._retval = f(*args, **kwargs) return _f._retval return _f if __name__ == "__main__": import doctest doctest.testmod()
рдкреНрд░рд╛рд░рдВрдн рдХреБрдВрдЬреА:
$ python run_once2.py -v Trying: @run_once def foo(n): return n + 1 Expecting nothing ok Trying: foo(7) Expecting: 8 ok Trying: foo(0) Expecting: 8 ok 1 items had no tests: __main__ 1 items passed all tests: 3 tests in __main__.run_once 3 tests in 2 items. 3 passed and 0 failed. Test passed.
рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдбреЙрдХрд╕реНрдЯреНрд░рд┐рдВрдЧ рдПрдХ рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдбреЗрд╡рд▓рдкрд░ рдФрд░ рджреБрднрд╛рд╖рд┐рдпрд╛ рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп рд╣реИ (рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ)ред
рдХреНрд▓рд╛рд╕рд┐рдХ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ, рдбреЙрдХреНрд╕ рдореЗрдВ рджреЛрдиреЛрдВ рдкреНрд▓рд╕рд╕ рд╣реЛрддреЗ рд╣реИрдВ (рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдЖрд╕рд╛рдиреА, рдЖрдк рд╕реАрдзреЗ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдкрд╛рд░реНрдердерди рд╕рддреНрд░ рд╕реЗ рдХреЙрдкреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ; рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рд╣рдореЗрд╢рд╛ рдХреЛрдб рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ) рдФрд░ рдорд┐рдиреАрд╕ (рдЬрдЯрд┐рд▓ рдХреЛрдб рдЬрд▓реНрджреА рд╕реЗ рдЕрдкрдардиреАрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ; рдПрдХ рдкрд╛рда рд╕рдВрдкрд╛рджрдХ рдРрд╕реЗ рдХреЛрдб рдХреЛ рдЙрдЬрд╛рдЧрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реНрдереИрддрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдЗрд╕рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреЗ)ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХреБрдЫ рднреА рдЫреЛрдЯреА рдЪреАрдЬрд╝реЛрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░), рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЙрдХрд╕реНрдЯреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд╣рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИред
py.test
рдЕрдЬрдЧрд░ рдХреЗ рдорд╛рдирдХ рдкреИрдХреЗрдЬ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде, рд╡реИрдХрд▓реНрдкрд┐рдХ рдЙрдкрдХрд░рдг рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
py.test ред рд╕реНрдерд╛рдкрдирд╛ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рд╣реИ
easy_install -U pytest
рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реЗрдВред рд╕рдВрд╢реЛрдзрд┐рдд рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:
def test_run_once(): @run_once def inc(n): return n + 1
рдЖрдЗрдП рдЬрд╛рдиреЗ:
$ py.test run_once3.py === test session starts === platform darwin
Py.test (рдЕрдЪреНрдЫрд╛) рдХреА рдореБрдЦреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ: рдХреЛрдИ рдПрдкреАрдЖрдИ (рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛ рдореЗрдВ: рдЕрд╕рд╛рдзрд╛рд░рдг рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдПрдкреАрдЖрдИ рдХреА рдЕрднреА рднреА рдЬрд░реВрд░рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ); рдкрд░рдЦ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЧрдгрдирд╛ рдХреЗ рдмрд┐рдирд╛ рдЙрддреНрдкрд╛рджрди рд╕рд░реНрд╡рд░ рдкрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, py.test рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рднреА рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЯреЗрд╕реНрдЯ рдХреЛ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (
test_*
рд╢реИрд▓реА рдореЗрдВ), рдпрд╛ рдХреЗрд╡рд▓ рдлреЙрд░реНрдо
test_*
ред
рдПрдХ рдПрдкреАрдЖрдИ рдХреА рдХрдореА, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рдкрд╣рд▓реВ рд╣реИ: рдПрдХ рдирдпрд╛ рдбреЗрд╡рд▓рдкрд░, рдЬреЛ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдмрд╕ рдпрд╣ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдвреЗрд░ рдХреЛ рдХреИрд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдбреЗрд╡рд▓рдкрд░ рдмрд╣реБрдд рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдирдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдФрд░ рдиреБрдХрд╕рд╛рди рд╕реЗ рджреВрд░, рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬреАрдХрд░рдг рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред
рдирд╛рдХ
рдирд╛рдХ unittest рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рд╣реИ (рдФрд░ doctest,
--with-doctest
the
--with-doctest
)ред рдЗрд╕рдХрд╛ рдЕрдкрдирд╛ API рднреА рд╣реИ, рдЬреЛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИред рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ:
$ nosetests * -v --with-doctest test_run_once (run_once.Test) ... ok Doctest: run_once2.run_once ... ok run_once3.test_run_once ... ok --- Ran 3 tests in 0.008s OK
рдЬреИрд╕рд╛ рдХрд┐
Yur4eg рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИ (рдзрдиреНрдпрд╡рд╛рдж!), рдирд╛рдХ рд╕реНрд╡рддрдГ рдлреЙрд░реНрдо
test_*
рдХреА рдлрд╛рдЗрд▓реЛрдВ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдПрдХрддреНрд░ рдХрд░рддрд╛ рд╣реИ, рдпрджрд┐ рд╡рд╣ рдПрдХ рд╣реИ рддреЛ рдкрд░реАрдХреНрд╖рдг рдлрд╝реЛрд▓реНрдбрд░ рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╕реНрдорд╛рд░реНрдЯ рд╣реИ, рдпрд╣
--with-coverage
(
--with-coverage
) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдХрд╡рд░реЗрдЬ рдХреЛ рдорд╛рдк рд╕рдХрддрд╛ рд╣реИ ред рдЖрдк рдХреЗрд╡рд▓ рдЙрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рднреА рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЕрдВрддрд┐рдо рд░рди (- рдмрдВрдж) рдореЗрдВ рдЧрд┐рд░ рдЧрдП рдереЗред
рдореИрдВ рд╕рд┐рдо рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЫреБрдЯреНрдЯреА рд▓реЗ рд░рд╣рд╛ рд╣реВрдВред рдпрд╣ рдХреЗрд╡рд▓
рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ
рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рд╕рдВрд▓рдЧреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ, рддреАрди рдЯреБрдХрдбрд╝реЗред рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдбреЛрдореЗрдиред
рдЕрдЧрд▓реЗ рдЕрдВрдХ рдореЗрдВ : рдирд┐рдпрдорд┐рдд django рдЯреЗрд╕реНрдЯрд┐рдВрдЧ рдЯреВрд▓ рдФрд░ рдЙрдирд╕реЗ рдХреИрд╕реЗ рдирд┐рдкрдЯреЗрдВред