рдкрд╛рдпрдерди рдХреЗ рд╕рд╛рде рдкрд╛рдпрдерди рдкрд░реАрдХреНрд╖рдгред рдЕрдзреНрдпрд╛рдп 3 рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдлрд┐рдХреНрд╕реНрдЪрд░

рдкреАрдЫреЗ рдЕрдЧрд▓рд╛


рдпрд╣ рдкреБрд╕реНрддрдХ рдЧрд╛рдпрдм рдЕрдзреНрдпрд╛рдп рд╣реИ рдЬреЛ рд╣рд░ рд╡реНрдпрд╛рдкрдХ рдкрд╛рдпрдерди рдкреБрд╕реНрддрдХ рд╕реЗ рдЧрд╛рдпрдм рд╣реИред


рдлреНрд░реИрдВрдХ рдмрд░реНрдмрд╛рдж
рдкреНрд░рд┐рдВрд╕рд┐рдкрд▓ рд╕рд╛рдЗрдЯ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдЗрдВрдЬреАрдирд┐рдпрд░, рдмреЙрдХреНрд╕, рдЗрдВрдХред



рдЗрд╕ рдкреБрд╕реНрддрдХ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг Python 3.6 рдФрд░ pytest 3.2 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ 3.2 рдкрд╛рдпрдерди 2.6, 2.7 рдФрд░ рдкрд╛рдпрдерди 3.3+ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ


рдЯрд╛рд╕реНрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЗрд╕ рдкреБрд╕реНрддрдХ рдореЗрдВ рджрд┐рдЦрд╛рдП рдЧрдП рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдкреБрд╕реНрддрдХ рдХреЗ рд╡реЗрдм рдкреЗрдЬ pragprog.com рдкрд░ рд▓рд┐рдВрдХ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд╕реНрд░реЛрдд рдХреЛрдб рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ; рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╛ рдЕрдкрдиреА рдЦреБрдж рдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░реЗрдВ (рдЖрдкрдХреЗ рд╣рд╛рде рдЕрдирдЯреВрдЯ рд╣реЛ рдЧрдП рд╣реИрдВ!), рдЖрдкрдХреЛ рдкреБрд╕реНрддрдХ рдХреЗ рд╡реЗрдм рдкреЗрдЬ рдкрд░ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдХрд╛рдо рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╡рд╣рд╛рдБ, рдкреБрд╕реНрддрдХ рдХреЗ рд╡реЗрдм рдкреЗрдЬ рдкрд░, рдЗрд░реЗрдЯрд╛ рд╕рдВрджреЗрд╢реЛрдВ рдФрд░ рдПрдХ рдЪрд░реНрдЪрд╛ рдордВрдЪ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд╣реИред

рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рддрд╣рдд рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд▓реЗрдЦреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред



рдЕрдм рдЬрдм рдЖрдкрдиреЗ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рджреЗрдЦреА рд╣реИрдВ, рддреЛ рд╣рдо рдЕрдкрдирд╛ рдзреНрдпрд╛рди рдЙрди рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреА рдУрд░ рдореЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬреЛ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рдЧреИрд░-рддреБрдЪреНрдЫ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИрдВред рдлрд┐рдХреНрд╕реНрдЪрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ (рдФрд░ рдХрднреА-рдХрднреА рдХреЗ рдмрд╛рдж) рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдп рд╣реИрдВред рдлрд╝рд┐рдХреНрдЪрд░ рдХреЛрдб рдЖрдкрдХреЛ рдЬреЛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рд╕реЗрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рд╕реА рдЬреНрдЮрд╛рдд рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХрдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рд╕реНрдерд┐рд░рддрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдЬреЛ рдПрдХ рдирдВрдмрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:


ch3 / test_fixtures.py

 import pytest @pytest.fixture() def some_data(): """Return answer to ultimate question.""" return 42 def test_some_data(some_data): """Use fixture return value in a test.""" assert some_data == 42 

@pytest.fixture() рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ pytest рдХреЛ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдлрд┐рдХреНрд╕реЗрдЯрд░ рд╣реИред рдЬрдм рдЖрдк рдкрд░реАрдХреНрд╖рдг рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА рдореЗрдВ рд╕реНрдерд┐рд░рддрд╛ рдирд╛рдо рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕реЗ рдХреИрд╕реЗ рдЪрд▓рд╛рдирд╛ рд╣реИред рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рд╡реЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рдбреЗрдЯрд╛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


test_some_data() рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ some_data рдирд╛рдо some_data ред рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдЧрд╛ рдФрд░ рдЙрд╕ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рдЬреБрдбрд╝рд╛рд╡ рдЦреЛрдЬреЗрдЧрд╛ред рдкрд╛рдЗрд╕реНрдЯ рдореЗрдВ рдирд╛рдо рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред Pytest рдкрд░реАрдХреНрд╖рдг рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЙрд╕ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдерд┐рд░рддрд╛ рдХреА рддрд▓рд╛рд╢ рдХрд░реЗрдЧрд╛ред рдЕрдЧрд░ рд╡рд╣ рдЗрд╕рдореЗрдВ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИ рддреЛ рд╡рд╣ рднреА conftest.py рдореЗрдВ рдЦреЛрдЬ рдХрд░реЗрдЧрд╛ред


рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЬреБрдбрд╝рдирд╛рд░ (рдФрд░ conftest.py рдлрд╝рд╛рдЗрд▓) рдкрд░ рдЕрдкрдирд╛ рд╢реЛрдз рд╢реБрд░реВ рдХрд░реЗрдВ, рдореБрдЭреЗ рдЗрд╕ рддрдереНрдп рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╢рдмреНрдж рдирд┐рд░реНрдзрд╛рд░рдг рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдФрд░ рдкрд░реАрдХреНрд╖рдг рд╕рдореБрджрд╛рдп рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдкрд╛рдпрдерди рд╕рдореБрджрд╛рдп рдореЗрдВ рдХрдИ рдЕрд░реНрде рд╣реИрдВред рдореИрдВ рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рд╡рд░реНрдгрд┐рдд @pytest.fixture() рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП fixture , fixture function , рдФрд░ fixture method рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рд╕реНрдерд┐рд░рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рд╕рдВрд╕рд╛рдзрди рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рд╕реНрдерд┐рд░рддрд╛ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдлрд┐рдХреНрд╕реНрдЪрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдЕрдХреНрд╕рд░ рдХреБрдЫ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдпрд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХрднреА-рдХрднреА рдпрд╣ рдбреЗрдЯрд╛ рд╕реНрдерд┐рд░рддрд╛ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Django рд╕рдореБрджрд╛рдп рдЕрдХреНрд╕рд░ рдХреБрдЫ рдХрдЪреНрдЪреЗ рдбреЗрдЯрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд▓реЛрдб рд╣реЛрддрд╛ рд╣реИред


рдЕрдиреНрдп рдЕрд░реНрдереЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, pytest рдореЗрдВ рдФрд░ рдЗрд╕ рдкреБрд╕реНрддрдХ рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг рдлрд┐рдХреНрд╕реНрдЪрд░ рдЙрд╕ рддрдВрддреНрд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ pytest рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рд╕реЗ "рдХреЛрдб рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░" рдФрд░ "рд╕рдлрд╛рдИ рдХреЗ рдмрд╛рдж" рдХреЛрдб рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред


pytest рдЬреБрдбрд╝рдирд╛рд░ рдЕрджреНрд╡рд┐рддреАрдп рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬреЛ рдЕрдиреНрдп рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдгреЛрдВ рдкрд░ pytest рдмрдврд╝рд╛рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕реЗ рд╕рдореНрдорд╛рдирд┐рдд рд▓реЛрдЧ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╣реИрдВ ... рдФрд░ pytest рдХреЗ рд╕рд╛рде рд░рд╣рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдореЗрдВ рдЬреБрдбрд╝рдирд╛рд░, Django рдореЗрдВ рдЬреБрдбрд╝рдирд╛рд░ рд╕реЗ рдЕрд▓рдЧ рд╣реИрдВ рдФрд░ рдПрдХрддрд░рдлрд╛ рдФрд░ рдирд╛рдХ рдореЗрдВ рдкрд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реЗрдЯрдЕрдк рдФрд░ рдлрд╛рдбрд╝ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рд╕реЗ рдЕрд▓рдЧ рд╣реИрдВред рдЬреБрдбрд╝рдирд╛рд░ рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рдХрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рдФрд░ рдмрд╛рд░реАрдХрд┐рдпрд╛рдВ рд╣реИрдВред рдПрдХ рдмрд╛рд░ рдЬрдм рдЖрдк рдПрдХ рдЕрдЪреНрдЫрд╛ рдорд╛рдирд╕рд┐рдХ рдореЙрдбрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдмреЗрд╣рддрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВрдЧреЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЖрдкрдХреЛ рдбреНрд░рд╛рдЗрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдЙрдирдХреЗ рд╕рд╛рде рдЦреЗрд▓рдирд╛ рд╣реЛрдЧрд╛, рддреЛ рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред


Conftest.py рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреБрдбрд╝рдирд╛рд░ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛


рдЖрдк рдЬреБрдбрд╝рдирд╛рд░ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХрдИ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдЬреБрдбрд╝рдирд╛рд░ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЗрдВрджреНрд░реАрдп рд╕реНрдерд╛рди рдкрд░, рдХрд╣реАрдВ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХреЙрдиреНрдЯреЗрд╕реНрдЯрд╕реНрдЯреЗрдо рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред рдХрд┐рд╕реА рдХрд╛рд░реНрдп рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП, рд╕рднреА рдлрд┐рдХреНрд╕реНрдЪрд░ tasks_proj/tests/conftest.py ред


рд╡рд╣рд╛рдВ рд╕реЗ, рдЬреБрдбрд╝рдирд╛рд░ рдХрд┐рд╕реА рднреА рдЖрдЯреЗ рд╕реЗ рд╕рд╛рдЭрд╛ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рдЖрдк рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдЬреБрдбрд╝рдирд╛рд░ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕реА рддрд░рд╣, рдЖрдкрдХреЗ рдкрд╛рд╕ рд╢реАрд░реНрд╖ рдкрд░реАрдХреНрд╖рдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА рдЙрдкрдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдореЗрдВ рдЕрдиреНрдп conftest.py рдлрд╛рдЗрд▓реЗрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдпрджрд┐ рдЖрдк рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп conftest.py рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЬреБрдбрд╝рдирд╛рд░ рдЗрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдФрд░ рдЙрдкрдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛрдВрдЧреЗред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдм рддрдХ рдЯрд╛рд╕реНрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд┐рд╕реА рднреА рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдкрд░реАрдХреНрд╖рдг рдХреЗ рдореВрд▓ рдореЗрдВ conftest.py рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣рдорд╛рд░реЗ рд╕рднреА рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, tasks_proj/tests , рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред


рд╣рд╛рд▓рд╛рдБрдХрд┐ conftest.py рдПрдХ рдкрд╛рдпрдерди рдореЙрдбреНрдпреВрд▓ рд╣реИ, рдЗрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрдпрд╛рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдХрдм рдЖрдпрд╛рдд рдЖрдпрд╛рдд рдордд рдХрд░реЛ! Conftest.py рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рджреНрд╡рд╛рд░рд╛ рдкрдврд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рд╕реНрдерд╛рдиреАрдп рдкреНрд▓рдЧ-рдЗрди рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдЬрдм рд╣рдо рдЕрдзреНрдпрд╛рдп 5 рдореЗрдВ рдкреНрд▓рдЧ-рдЗрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдкреГрд╖реНрда 95 рдкрд░ "рдкреНрд▓рдЧ-рдЗрди"ред рдЕрднреА рдХреЗ рд▓рд┐рдП, tests/conftest.py рдХреЛ рдЙрд╕ рдЬрдЧрд╣ рдХреЗ рд░реВрдк рдореЗрдВ tests/conftest.py рдЬрд╣рд╛рдВ рд╣рдо рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╕рднреА рдкрд░реАрдХреНрд╖рдгред рддреЛ рдЪрд▓реЛ рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рд╕рд╣реА рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП task_proj рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ task_proj рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред


рд╕реЗрдЯрдЕрдк рдФрд░ рдЯрд┐рдпрд░рдбрд╛рдЙрди рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдХрд╛рд░реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдкрд░реАрдХреНрд╖рдг рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд╛рд░реНрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреЙрдиреНрдлрд╝рд┐рдЧрд░, рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рдФрд░ рддреИрдпрд╛рд░ рд╣реИред рдФрд░ рд╣рдореЗрдВ рдЕрдВрдд рдореЗрдВ рдХреБрдЫ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рд╣реЛрдЧрд╛, рдЕрдЧрд░ рд╕рдлрд╛рдИ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдФрд░ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕рдореЗрдВ рд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдХреЛ рдЯрд╛рд╕реНрдХ рдХреЛрдб рдореЗрдВ tasks.start_tasks_db(<directory to store db\>, 'tiny' or 'mongo') tasks.stop_tasks_db() tasks.start_tasks_db(<directory to store db\>, 'tiny' or 'mongo') tasks.stop_tasks_db() tasks.start_tasks_db(<directory to store db\>, 'tiny' or 'mongo') рдФрд░ tasks.stop_tasks_db() ; рд╣рдореЗрдВ рдмрд╕ рдЙрдиреНрд╣реЗрдВ рд╕рд╣реА рд╕рдордп рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред


рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, pytest рдореЗрдВ рдПрдХ рдЙрддреНрдХреГрд╖реНрдЯ рд╕реНрдерд┐рд░рддрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕реЗ tmpdir рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдлрд╛рдИ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИред рдпрд╣ рдЬрд╛рджреВ рдирд╣реАрдВ рд╣реИ, рд╕рдмрд╕реЗ рдЬрд┐рдЬреНрдЮрд╛рд╕реБ рд▓реЛрдЧреЛрдВ рд╕реЗ рд╕рд┐рд░реНрдл рдЕрдЪреНрдЫрд╛ рдХреЛрдбрд┐рдВрдЧ рдЕрднреНрдпрд╛рд╕ рд╣реИред (рдЪрд┐рдВрддрд╛ рди рдХрд░реЗрдВ; рд╣рдо tmpdir рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ рдФрд░ рдкреГрд╖реНрда "71 рдкрд░ tmpdir рдФрд░ tmpdir_factory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ" рдЕрдиреБрднрд╛рдЧ рдореЗрдВ tmpdir_factory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВрдЧреЗред)


рдЗрди рд╕рднреА рдШрдЯрдХреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдпрд╣ рд╕реНрдерд┐рд░рддрд╛ рдорд╣рд╛рди рдХрд╛рдо рдХрд░рддреА рд╣реИ:


ch3 / a / tasks_proj /tests/conftest.py

 import pytest import tasks from tasks import Task @pytest.fixture() def tasks_db(tmpdir): """    ,  .""" # Setup : start db tasks.start_tasks_db(str(tmpdir), 'tiny') yield #    # Teardown : stop db tasks.stop_tasks_db() 

Tmpdir рдХрд╛ рдорд╛рди рд╕реНрдЯреНрд░рд┐рдВрдЧ рдирд╣реАрдВ рд╣реИ - рдпрд╣ рдПрдХ рдРрд╕реА рд╡рд╕реНрддреБ рд╣реИ рдЬреЛ рдПрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ start_tasks_db() рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ str() рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП start_tasks_db() ред рдЕрднреА рдХреЗ рд▓рд┐рдП, рд╣рдо рдЕрднреА рднреА TinyDB рдХреЗ рд▓рд┐рдП рдЫреЛрдЯреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред


рдлрд╝рд┐рдХреНрдЪрд░ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрджрд┐ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЙрдкрдЬ рд╣реИ , рддреЛ рдпрд╣ рд╡рд╣реАрдВ рд░реБрдХ рдЬрд╛рдПрдЧрд╛, рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдВрддреНрд░рдг рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЙрдкрдЬ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЕрдЧрд▓реА рдкрдВрдХреНрддрд┐ред рдЗрд╕рд▓рд┐рдП, рдЙрдкрдЬ рдХреЗ рдКрдкрд░ рдХреЛрдб рдХреЛ "рд╕реЗрдЯрдЕрдк" рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЛрдЪреЗрдВ, рдФрд░ рдХреЛрдб рдХреЗ рдмрд╛рдж рдЙрдкрдЬ рдХреЛ "рдлрд╛рдбрд╝" рдХреЗ рд░реВрдк рдореЗрдВред рдкреИрджрд╛рд╡рд╛рд░ "рдлрд╛рдбрд╝" рдХреЗ рдмрд╛рдж рдХреЛрдб рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рджреМрд░рд╛рди рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛ред рд╣рдо рдЗрд╕ рд╕реНрдерд┐рд░рддрд╛ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛ рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЖрдЗрдП рдЗрд╕ tasks.add() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдХрд┐рд╕реА рдХрд╛рд░реНрдп рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░реЗрдВред


ch3 / a / tasks_proj / рдкрд░реАрдХреНрд╖рдг / func / test_add .py

 import pytest import tasks from tasks import Task def test_add_returns_valid_id(tasks_db): """tasks.add(<valid task>)    .""" # GIVEN    # WHEN    # THEN  task_id  int new_task = Task('do something') task_id = tasks.add(new_task) assert isinstance(task_id, int) 

рдпрд╣рд╛рдВ рдореБрдЦреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрдерд┐рд░рддрд╛ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╣рдордиреЗ рдкрд░реАрдХреНрд╖рдг рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ tasks_db рдЬреЛрдбрд╝рд╛ рд╣реИред рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ GIVEN / WHEN / THEN рдкреНрд░рд╛рд░реВрдк (DANO / WHEN / AFTER) рдореЗрдВ рд╕рдВрд░рдЪрдирд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдпрд╣ рдХреЛрдб рд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реИред рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ GIVEN рдЖрд░рдВрднреАрдХреГрдд db рдХрд╛рд░реНрдп рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ рдХрд┐ tasks_db рдЙрдкрдпреЛрдЧ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ




рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдХрд╛рд░реНрдп рд╕реНрдерд╛рдкрд┐рдд рд╣реИред




рд╣рдо рдЕрднреА рднреА рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдХрд╛рд░реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЬреЛ рдкрд╣рд▓реЗ рдЕрдзреНрдпрд╛рдп 2 рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдпрджрд┐ рдЖрдкрдиреЗ рдЗрд╕ рдЕрдзреНрдпрд╛рдп рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИ, рддреЛ рд╕реАрдбреА рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ; pip install ./tasks_proj/ ред / pip install ./tasks_proj/ ред




-рд╕реЗрдЯрдЕрдк-рд╢реЛ рдХреЗ рд╕рд╛рде рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдлрд┐рдХреНрд╕реЗрд╢рди рдирд┐рд╖реНрдкрд╛рджрди


рдпрджрд┐ рдЖрдк рдЕрдВрддрд┐рдо рдЦрдВрдб рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рдкрд╛рдПрдВрдЧреЗ рдХрд┐ рдХреМрди рд╕реЗ рдЬреБрдбрд╝рдирд╛рд░ рдЪрд▓ рд░рд╣реЗ рд╣реИрдВ:


 $ cd /path/to/code/ $ pip install ./tasks_proj/ #      $ cd /path/to/code/ch3/a/tasks_proj/tests/func $ pytest -v test_add.py -k valid_id ===================== test session starts ====================== collected 3 items test_add.py::test_add_returns_valid_id PASSED ====================== 2 tests deselected ====================== ============ 1 passed, 2 deselected in 0.02 seconds ============ 

рдЬрдм рдореИрдВ рдлрд┐рдХреНрд╕реНрдЪрд░ рдбрд┐рдЬрд╛рдЗрди рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдпрд╣ рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрдмред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдЗрд╕ рддрд░рд╣ рдХреА рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдлреНрд▓реИрдЧ, -- setup-show рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рд╕рд┐рд░реНрдл рдпрд╣реА рдХрд░рддрд╛ рд╣реИ:


 $ pytest --setup-show test_add.py -k valid_id ============================= test session starts ============================= collected 3 items / 2 deselected test_add.py SETUP S tmpdir_factory SETUP F tmpdir (fixtures used: tmpdir_factory) SETUP F tasks_db (fixtures used: tmpdir) func/test_add.py::test_add_returns_valid_id (fixtures used: tasks_db, tmpdir, tmpdir_factory). TEARDOWN F tasks_db TEARDOWN F tmpdir TEARDOWN S tmpdir_factory =================== 1 passed, 2 deselected in 0.18 seconds ==================== 

рд╣рдорд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдордзреНрдп рдореЗрдВ рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрдк рдФрд░ рдЯреАрдПрдЖрд░рдбреАрдПрдЪрдИ рднрд╛рдЧ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред test_add_returns_valid_id рд╢реБрд░реВ рдХрд░рддреЗ test_add_returns_valid_id , рдЖрдк рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ tmpdir рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ред рдФрд░ tmpdir_factory рдкрд╣рд▓реЗ tmpdir_factory ред tmpdir рдЗрд╕реЗ рдПрдХ рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред


рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рдирд╛рдореЛрдВ рдХреЗ рд╕рд╛рдордиреЗ рдПрдл рдФрд░ рдПрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╕реНрдХреЛрдк рдХреЗ рд▓рд┐рдП рдПрдл рдФрд░ рд╕рддреНрд░ рд╕реНрдХреЛрдк рдХреЗ рд▓рд┐рдП рдПрд╕ ред рдореИрдВ рдкреГрд╖реНрда релрем рдкрд░ "рд╕реНрдХреЛрдк рд╕реНрдерд┐рд░рддрд╛ рд╡рд┐рдирд┐рд░реНрджреЗрд╢" рдЦрдВрдб рдореЗрдВ рдЧреБрдВрдЬрд╛рдЗрд╢ рдХреЛ рдХрд╡рд░ рдХрд░реВрдВрдЧрд╛ред


рдЯреЗрд╕реНрдЯ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдлрд┐рдХреНрд╕реНрдЪрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рд╛рдирджрд╛рд░ рдЬрдЧрд╣ рд╣реИред рдЖрдк рдХреБрдЫ рднреА рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдлрд╝рд┐рдХреНрд╕рдЪрд░ рд╣реИ рдЬреЛ рдорд┐рд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЯрдкрд▓ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:


ch3 / test_fixtures.py

 @pytest.fixture() def a_tuple(): """ -  """ return (1, 'foo', None, {'bar': 23}) def test_a_tuple(a_tuple): """Demo the a_tuple fixture.""" assert a_tuple[3]['bar'] == 32 

рдЪреВрдВрдХрд┐ test_a_tuple() рд╡рд┐рдлрд▓ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП (23! = 32) , рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рд╕реНрдерд┐рд░рддрд╛ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:


 $ cd /path/to/code/ch3 $ pytest test_fixtures.py::test_a_tuple ============================= test session starts ============================= collected 1 item test_fixtures.py F [100%] ================================== FAILURES =================================== ________________________________ test_a_tuple _________________________________ a_tuple = (1, 'foo', None, {'bar': 23}) def test_a_tuple(a_tuple): """Demo the a_tuple fixture.""" > assert a_tuple[3]['bar'] == 32 E assert 23 == 32 test_fixtures.py:38: AssertionError ========================== 1 failed in 0.17 seconds =========================== 

рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдЕрдиреБрднрд╛рдЧ рдХреЗ рд╕рд╛рде, рдкрд╛рдЗрд╕реНрдЯреЗрд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдорд╛рди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЕрдкрд╡рд╛рдж рдпрд╛ рдЕрд╕рдлрд▓ рджрд╛рд╡реЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬреБрдбрд╝рдирд╛рд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдиреНрд╣реЗрдВ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЕрднрд┐рдХрд░реНрддрд╛ (рдпрд╛ рдЕрдкрд╡рд╛рдж) рд╕реНрдерд┐рд░рддрд╛ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ рддреЛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ?


 $ pytest -v test_fixtures.py::test_other_data ============================= test session starts ============================= test_fixtures.py::test_other_data ERROR [100%] =================================== ERRORS ==================================== ______________________ ERROR at setup of test_other_data ______________________ @pytest.fixture() def some_other_data(): """Raise an exception from fixture.""" x = 43 > assert x == 42 E assert 43 == 42 test_fixtures.py:21: AssertionError =========================== 1 error in 0.13 seconds =========================== 

рдПрдХ рджреЛ рдмрд╛рддреЗрдВ рд╣реЛрддреА рд╣реИрдВред рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдПрд╕реЗрдЯ рд╕реНрдерд┐рд░рддрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╣реБрдЖред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, test_other_data рдХреЛ FAIL рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ ERROR рдХреЗ рд░реВрдк test_other_data рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдмрдбрд╝рд╛ рдЕрдВрддрд░ рд╣реИред рдпрджрд┐ рдкрд░реАрдХреНрд╖рдг рдЕрдЪрд╛рдирдХ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡рд┐рдлрд▓рддрд╛ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╣реА рд╣реБрдИ рдереА, рдФрд░ рдХреБрдЫ рд╕реНрдерд┐рд░рддрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред


рд▓реЗрдХрд┐рди рдЯрд╛рд╕реНрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдХрд╛рд░реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╢рд╛рдпрдж рдХреБрдЫ рдбреЗрдЯрд╛ рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдВрднрд╡рддрдГ рд╡рд┐рднрд┐рдиреНрди рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХрд╛рд░реНрдп рд╕реВрдЪрд┐рдпрд╛рдВ:


ch3 / a / task_proj / рдкрд░реАрдХреНрд╖рдг / conftest.py

 #    Task constructor # Task(summary=None, owner=None, done=False, id=None) # summary    # owner  done   # id    @pytest.fixture() def tasks_just_a_few(): """    .""" return ( Task('Write some code', 'Brian', True), Task("Code review Brian's code", 'Katie', False), Task('Fix what Brian did', 'Michelle', False)) @pytest.fixture() def tasks_mult_per_owner(): """     .""" return ( Task('Make a cookie', 'Raphael'), Task('Use an emoji', 'Raphael'), Task('Move to Berlin', 'Raphael'), Task('Create', 'Michelle'), Task('Inspire', 'Michelle'), Task('Encourage', 'Michelle'), Task('Do a handstand', 'Daniel'), Task('Write some books', 'Daniel'), Task('Eat ice cream', 'Daniel')) 

рдЖрдк рдЙрдиреНрд╣реЗрдВ рд╕реАрдзреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ, рдпрд╛ рдЕрдиреНрдп рдЬреБрдбрд╝рдирд╛рд░ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рдЙрдирдХреА рдорджрдж рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдЧреИрд░-рд░рд┐рдХреНрдд рдбреЗрдЯрд╛рдмреЗрд╕ рдмрдирд╛рдПрдВред


рдПрдХрд╛рдзрд┐рдХ рдлрд┐рдХреНрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдЖрдк рдкрд╣рд▓реЗ рд╣реА рджреЗрдЦ рдЪреБрдХреЗ рд╣реИрдВ рдХрд┐ tmpdir tmpdir_factory рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдФрд░ рдЖрдкрдиреЗ рд╣рдорд╛рд░реЗ рдЯрд╛рд╕реНрдХ_ рдбреАрдмреА рд╕реНрдерд┐рд░рддрд╛ рдореЗрдВ tmpdir рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдЪрд▓рд┐рдП рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ рдФрд░ рдХрд╛рд░реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдЧреИрд░-рдЦрд╛рд▓реА рдард┐рдХрд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдЬреБрдбрд╝рдирд╛рд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:


ch3 / a / task_proj / рдкрд░реАрдХреНрд╖рдг / conftest.py

 @pytest.fixture() def db_with_3_tasks(tasks_db, tasks_just_a_few): """   3 ,  .""" for t in tasks_just_a_few: tasks.add(t) @pytest.fixture() def db_with_multi_per_owner(tasks_db, tasks_mult_per_owner): """   9 , 3 owners,  3   .""" for t in tasks_mult_per_owner: tasks.add(t) 

рдЗрди рд╕рднреА рдлрд┐рдХреНрд╕реНрдЪрд░ рдореЗрдВ рдЙрдирдХреА рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА рдореЗрдВ рджреЛ рдЬреБрдбрд╝рдирд╛рд░ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ: tasks_db рдФрд░ рдбреЗрдЯрд╛ рд╕реЗрдЯред рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдЧреИрд░-рдЦрд╛рд▓реА рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╢реБрд░реВ рд╣реЛ, рддреЛ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


ch3 / a / functions_proj / рдкрд░реАрдХреНрд╖рдг / func / test_add.py

 def test_add_increases_count(db_with_3_tasks): """Test tasks.add()    tasks.count().""" # GIVEN db  3  # WHEN     tasks.add(Task('throw a party')) # THEN    1 assert tasks.count() == 4 

рдпрд╣ рднреА рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдХрд╛рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рддрд╛ рд╣реИ: рдкрд░реАрдХреНрд╖рдг рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрд╕ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреА рддреИрдпрд╛рд░реА рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рдерд╛ред рдореБрдЭреЗ GIVEN / WHEN / THEN рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИ рдФрд░ рджреЛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ рдЬреБрдбрд╝рдирд╛рд░ рдореЗрдВ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдбреЗрдЯрд╛ (GIVEN) рдкреБрд╢ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЕрдзрд┐рдХ рдкрдардиреАрдп рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП рдЕрдзрд┐рдХ рдмрдирд╛рдП рд░рдЦрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рджреВрд╕рд░реЗ, рдПрдХ рдПрд╕реНрдЯрд░ рдпрд╛ рдЕрдкрд╡рд╛рдж рдПрдХ рддреНрд░реБрдЯрд┐ (ERROR) рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рдкрд░реАрдХреНрд╖рдг рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдПрд╕реНрдЯрд░ рдпрд╛ рдЕрдкрд╡рд╛рдж рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рддреНрд░реБрдЯрд┐ (FAIL) рд╣реЛрддреА рд╣реИред рдореИрдВ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдХрд┐ test_add_increases_count() рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рдЖрд░рдВрдн рдореЗрдВ рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рдкрд░ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПред рдпрд╣ рд╕рд┐рд░реНрдл рднреНрд░рд╛рдордХ рд╣реИред рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ test_add_increases_count() рдХреА рд╡рд┐рдлрд▓рддрд╛ (FAIL) рдХреЗрд╡рд▓ рддрднреА рд╕рдВрднрд╡ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬрдм add () рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдЙрдВрдЯрд░ рдХреЛ рдмрджрд▓ рди рд╕рдХреЗред рдЖрдЗрдП рджреМрдбрд╝реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╕рднреА рдЬреБрдбрд╝рдирд╛рд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ:


 $ cd /path/to/code/ch3/a/tasks_proj/tests/func $ pytest --setup-show test_add.py::test_add_increases_count ============================= test session starts ============================= collected 1 item test_add.py SETUP S tmpdir_factory SETUP F tmpdir (fixtures used: tmpdir_factory) SETUP F tasks_db (fixtures used: tmpdir) SETUP F tasks_just_a_few SETUP F db_with_3_tasks (fixtures used: tasks_db, tasks_just_a_few) func/test_add.py::test_add_increases_count (fixtures used: db_with_3_tasks, tasks_db, tasks_just_a_few, tmpdir, tmpdir_factory). TEARDOWN F db_with_3_tasks TEARDOWN F tasks_just_a_few TEARDOWN F tasks_db TEARDOWN F tmpdir TEARDOWN S tmpdir_factory ========================== 1 passed in 0.20 seconds =========================== 

рд╣рдореЗрдВ рдлрдВрдХреНрд╢рди рдФрд░ рд╕рддреНрд░ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рдПрдлрдПрд╕ рдФрд░ рдПрд╕рдПрд╕ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдорд┐рд▓рд╛ред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИред


рд╕реНрдХреЛрдк рд╕реНрдерд┐рд░рддрд╛ рд╡рд┐рдирд┐рд░реНрджреЗрд╢


рдлрд┐рдХреНрд╕реНрдЪрд░ рдореЗрдВ рдЧреБрдВрдЬрд╛рдЗрд╢ рдирд╛рдордХ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЬреБрдбрд╝рдирд╛рд░ рдХрд┐рддрдиреА рдмрд╛рд░ рд╕реЗрдЯрдЕрдк рдФрд░ рдЯреЙрд░рдбрд╛рдЙрди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред @ pytest.fixture() рд▓рд┐рдП рдЧреБрдВрдЬрд╛рдЗрд╢ рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди, рд╡рд░реНрдЧ, рдореЙрдбреНрдпреВрд▓ рдпрд╛ рд╕рддреНрд░ рдорд╛рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрдХреЛрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИред рдХрд╛рд░реНрдп_db рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдФрд░ рд╕рднреА рдЬреБрдбрд╝рдирд╛рд░ рдЕрднреА рддрдХ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╡реЗ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдЬреБрдбрд╝рдирд╛рд░ рд╣реИрдВред


рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдХреЛрдк рдорд╛рди рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ:


  • рдХрд╛рд░реНрдпрдХреНрд╖реЗрддреНрд░ = 'рдХрд╛рд░реНрдп'


    рдпрд╣ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕реЗрдЯрдЕрдк рднрд╛рдЧ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрдерд┐рд░рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рдж рд╕реНрдерд┐рд░рддрд╛ рдХреЗ рд╕рд╛рде рдЕрд╢реНрд░реБ рднрд╛рдЧ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреНрд╖реЗрддреНрд░ рд╣реИред


  • рджрд╛рдпрд░рд╛ = 'рд╡рд░реНрдЧ'


    рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдПрдХ рдмрд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХрдХреНрд╖рд╛ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ред


  • рдЧреБрдВрдЬрд╛рдЗрд╢ = 'рдореЙрдбреНрдпреВрд▓'


    рдореЙрдбреНрдпреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдХрд┐рддрдиреЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рдпрд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдпрд╛ рдЕрдиреНрдп рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ рдЗрд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


  • рдЧреБрдВрдЬрд╛рдЗрд╢ = 'рд╕рддреНрд░'


    рдпрд╣ рдкреНрд░рддрд┐ рд╕рддреНрд░ рдПрдХ рдмрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╡рд┐рдзрд┐рдпреЛрдВ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рд╕рддреНрд░ рдЧреБрдВрдЬрд╛рдЗрд╢ рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдПрдХ рдПрдХрд▓ рд╕реЗрдЯрдЕрдк рдФрд░ рдлрд╛рдбрд╝ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред



рдХрд╛рд░реНрд░рд╡рд╛рдИ рдореЗрдВ рдЧреБрдВрдЬрд╛рдЗрд╢ рдорд╛рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ:


ch3 / test_scope.py

 """Demo fixture scope.""" import pytest @pytest.fixture(scope='function') def func_scope(): """A function scope fixture.""" @pytest.fixture(scope='module') def mod_scope(): """A module scope fixture.""" @pytest.fixture(scope='session') def sess_scope(): """A session scope fixture.""" @pytest.fixture(scope='class') def class_scope(): """A class scope fixture.""" def test_1(sess_scope, mod_scope, func_scope): """   ,   .""" def test_2(sess_scope, mod_scope, func_scope): """     .""" @pytest.mark.usefixtures('class_scope') class TestSomething(): """Demo class scope fixtures.""" def test_3(self): """Test using a class scope fixture.""" def test_4(self): """Again, multiple tests are more fun.""" 

рдЪрд▓реЛ рдпрд╣ --setup-show рдХреЗ рд▓рд┐рдП --setup-show рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ --setup-show рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝реА рдЧрдИ рд╕реНрдерд┐рд░рддрд╛ рдФрд░ рд╕реЗрдЯрдЕрдк рдХреЙрд▓ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреА рдЬрд╛рддреА рд╣реИ:


 $ cd /path/to/code/ch3/ $ pytest --setup-show test_scope.py ============================= test session starts ============================= collected 4 items test_scope.py SETUP S sess_scope SETUP M mod_scope SETUP F func_scope test_scope.py::test_1 (fixtures used: func_scope, mod_scope, sess_scope). TEARDOWN F func_scope SETUP F func_scope test_scope.py::test_2 (fixtures used: func_scope, mod_scope, sess_scope). TEARDOWN F func_scope SETUP C class_scope test_scope.py::TestSomething::()::test_3 (fixtures used: class_scope). test_scope.py::TestSomething::()::test_4 (fixtures used: class_scope). TEARDOWN C class_scope TEARDOWN M mod_scope TEARDOWN S sess_scope ========================== 4 passed in 0.11 seconds =========================== 

рдЕрдм рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдФрд░ рд╕рддреНрд░ рдХреЗ рд▓рд┐рдП рди рдХреЗрд╡рд▓ рдПрдл рдФрд░ рдПрд╕ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рд╡рд░реНрдЧ рдФрд░ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд▓рд┐рдП рд╕реА рдФрд░ рдПрдо рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред


рдЧреБрдВрдЬрд╛рдЗрд╢ рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ рд╣реИ рдХрд┐ рдЖрдк рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд░рд╛рд╣ рд░рд╣реЗ рд╣реИрдВред рд╕рдордЭ тАЭ)ред рджрд╛рдпрд░рд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдХреЙрд▓ рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдирд╣реАрдВред рдЬреБрдбрд╝рдирд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдХрд┐рддрдиреА рдмрд╛рд░ (SETUP) рдФрд░ рд╕реНрдерд┐рд░рддрд╛ рдЯреВрдЯрдиреЗ (TEARDOWN) рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред


рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреЗрд╡рд▓ рдЙрд╕реА рдпрд╛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рджрд╛рдпрд░реЗ рд╕реЗ рдЕрдиреНрдп рдЬреБрдбрд╝рдирд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдлрдВрдХреНрд╢рди рд╕реНрдХреЛрдк рдлрд┐рдХреНрд╕реЗрд╢рди рдЕрдиреНрдп рдлрдВрдХреНрд╢рди рд╕реНрдХреЛрдк рдлрд╝рд┐рдХреНрдЪрд░ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдФрд░ рдЕрднреА рднреА рдЯрд╛рд╕реНрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рд╕реНрдХреЛрдк рдлрд┐рдХреНрд╕реЗрд╢рди рднреА рдХреНрд▓рд╛рд╕ рдХреНрд╖реЗрддреНрд░, рдореЙрдбреНрдпреВрд▓ рдФрд░ рд╕рддреНрд░ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЬреБрдбрд╝рдирд╛рд░ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрднреА рднреА рд░рд┐рд╡рд░реНрд╕ рдСрд░реНрдбрд░ рдореЗрдВ рдирд╣реАрдВред


рдЯрд╛рд╕реНрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд┐рдХреНрд╕реНрдЪрд░ рдХреЗ рд▓рд┐рдП рд╕реНрдХреЛрдк рдмрджрд▓реЗрдВ


рдЧреБрдВрдЬрд╛рдЗрд╢ рдХреЗ рдЗрд╕ рдЬреНрдЮрд╛рди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдЪрд▓реЛ рдЕрдм рдЯрд╛рд╕реНрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдХреБрдЫ рдЬреБрдбрд╝рдирд╛рд░ рдХреЗ рджрд╛рдпрд░реЗ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВред


рдЕрдм рддрдХ, рд╣рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╕рдордп рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реБрдИ рд╣реИред рд▓реЗрдХрд┐рди, рдЖрдкрдХреЛ рдпрд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдФрд░ рдПрдХ рдирдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдирд╛ рдмреЗрдХрд╛рд░ рд╣реИред рдЬрдм рддрдХ рд╣рдо рдПрдХ рдЦрд╛рд▓реА рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рд╕рддреНрд░ рдХреЗ рдХрд╛рд░реНрдпрдХреНрд╖реЗрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ tasks_db рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ tmpdir_factory рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ tmpdir рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрдХреНрд╖реЗрддреНрд░ рд╣реИ рдФрд░ tmpdir_factory рд╕рддреНрд░ рдХрд╛ рдХрд╛рд░реНрдпрдХреНрд╖реЗрддреНрд░ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдпрд╣ рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди рдХреА рд╕рд┐рд░реНрдл рдПрдХ рдкрдВрдХреНрддрд┐ рд╣реИ (рдареАрдХ рд╣реИ, рджреЛ рдпрджрд┐ рдЖрдк рдкреИрд░рд╛рдореАрдЯрд░ рд╕реВрдЪреА рдореЗрдВ tmpdir->tmpdir_factory рдкрд░ рд╡рд┐рдЪрд╛рд░ tmpdir->tmpdir_factory ):


ch3 / b / task_proj / рдкрд░реАрдХреНрд╖рдг / conftest.py

 """Define some fixtures to use in the project.""" import pytest import tasks from tasks import Task @pytest.fixture(scope='session') def tasks_db_session(tmpdir_factory): """Connect to db before tests, disconnect after.""" temp_dir = tmpdir_factory.mktemp('temp') tasks.start_tasks_db(str(temp_dir), 'tiny') yield tasks.stop_tasks_db() @pytest.fixture() def tasks_db(tasks_db_session): """An empty tasks db.""" tasks.delete_all() 

рдпрд╣рд╛рдВ рд╣рдордиреЗ tasks_db рдЖрдзрд╛рд░ рдкрд░ tasks_db_session рдмрджрд▓ рджрд┐рдпрд╛, рдФрд░ рд╣рдордиреЗ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдХрд┐ рдпрд╣ рдЦрд╛рд▓реА рд╣реИред рдЪреВрдВрдХрд┐ рд╣рдордиреЗ рдЗрд╕рдХрд╛ рдирд╛рдо рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдЬреБрдбрд╝рдирд╛рд░ рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдХреЛ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдбреЗрдЯрд╛ рдЬреБрдбрд╝рдирд╛рд░ рдмрд╕ рдПрдХ рдореВрд▓реНрдп рд╡рд╛рдкрд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдХреЗ рд▓рд┐рдП рд╣рд░ рд╕рдордп рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рд╣реИред рдПрдХ рдмрд╛рд░ рдкреНрд░рддрд┐ рд╕рддреНрд░ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ:


ch3 / b / task_proj / рдкрд░реАрдХреНрд╖рдг / conftest.py

 # Reminder of Task constructor interface # Task(summary=None, owner=None, done=False, id=None) # summary is required # owner and done are optional # id is set by database @pytest.fixture(scope='session') def tasks_just_a_few(): """All summaries and owners are unique.""" return ( Task('Write some code', 'Brian', True), Task("Code review Brian's code", 'Katie', False), Task('Fix what Brian did', 'Michelle', False)) @pytest.fixture(scope='session') def tasks_mult_per_owner(): """Several owners with several tasks each.""" return ( Task('Make a cookie', 'Raphael'), Task('Use an emoji', 'Raphael'), Task('Move to Berlin', 'Raphael'), Task('Create', 'Michelle'), Task('Inspire', 'Michelle'), Task('Encourage', 'Michelle'), Task('Do a handstand', 'Daniel'), Task('Write some books', 'Daniel'), Task('Eat ice cream', 'Daniel')) 

рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдпреЗ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрди рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ:


 $ cd /path/to/code/ch3/b/tasks_proj $ pytest ===================== test session starts ====================== collected 55 items tests/func/test_add.py ... tests/func/test_add_variety.py ............................ tests/func/test_add_variety2.py ............ tests/func/test_api_exceptions.py ....... tests/func/test_unique_id.py . tests/unit/test_task.py .... ================== 55 passed in 0.17 seconds =================== 

рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд▓рдЧрддрд╛ рд╣реИред рдЖрдЗрдП рдПрдХ рдПрдХрд▓ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдЬреБрдбрд╝рдирд╛рд░ рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдорд╛рд░реА рдЙрдореНрдореАрджреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╡рд┐рднрд┐рдиреНрди рдХреНрд╖реЗрддреНрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ:


 $ pytest --setup-show tests/func/test_add.py ============================= test session starts ============================= platform win32 -- Python 3.6.5, pytest-3.9.3, py-1.7.0, pluggy-0.8.0 rootdir: c:\_BOOKS_\pytest_si\bopytest-code\code\ch3\b\tasks_proj\tests, inifile: pytest.ini collected 3 items tests\func\test_add.py SETUP S tmpdir_factory SETUP S tasks_db_session (fixtures used: tmpdir_factory) SETUP F tasks_db (fixtures used: tasks_db_session) func/test_add.py::test_add_returns_valid_id (fixtures used: tasks_db, tasks_db_session, tmpdir_factory). TEARDOWN F tasks_db SETUP F tasks_db (fixtures used: tasks_db_session) func/test_add.py::test_added_task_has_id_set (fixtures used: tasks_db, tasks_db_session, tmpdir_factory). TEARDOWN F tasks_db SETUP S tasks_just_a_few SETUP F tasks_db (fixtures used: tasks_db_session) SETUP F db_with_3_tasks (fixtures used: tasks_db, tasks_just_a_few) func/test_add.py::test_add_increases_count (fixtures used: db_with_3_tasks, tasks_db, tasks_db_session, tasks_just_a_few, tmpdir_factory). TEARDOWN F db_with_3_tasks TEARDOWN F tasks_db TEARDOWN S tasks_db_session TEARDOWN S tmpdir_factory TEARDOWN S tasks_just_a_few ========================== 3 passed in 0.24 seconds =========================== 

рд╣рд╛рдБред . tasks_db_session , task_db .


Specifying Fixtures with usefixtures


, , , . , @pytest.mark.usefixtures('fixture1', 'fixture2') . usefixtures , , . тАФ . :


ch3/test_scope.py

 @pytest.mark.usefixtures('class_scope') class TestSomething(): """Demo class scope fixtures.""" def test_3(self): """Test using a class scope fixture.""" def test_4(self): """Again, multiple tests are more fun.""" 

usefixtures , . , , . , - usefixtures , .


autouse Fixtures That Always Get Used ( )


, , ( usefixtures ). autouse=True , . , , . :


ch3/test_autouse.py

 """ autouse fixtures.""" import pytest import time @pytest.fixture(autouse=True, scope='session') def footer_session_scope(): """    session().""" yield now = time.time() print('--') print('finished : {}'.format(time.strftime('%d %b %X', time.localtime(now)))) print('-----------------') @pytest.fixture(autouse=True) def footer_function_scope(): """     .""" start = time.time() yield stop = time.time() delta = stop - start print('\ntest duration : {:0.3} seconds'.format(delta)) def test_1(): """   .""" time.sleep(1) def test_2(): """    .""" time.sleep(1.23) 

, . :


 $ cd /path/to/code/ch3 $ pytest -v -s test_autouse.py ===================== test session starts ====================== collected 2 items test_autouse.py::test_1 PASSED test duration : 1.0 seconds test_autouse.py::test_2 PASSED test duration : 1.24 seconds -- finished : 25 Jul 16:18:27 ----------------- =================== 2 passed in 2.25 seconds =================== 

autouse . , . , .


, autouse , , tasks_db . Tasks , , , API . . , .


Fixtures


, , , . , pytest name @pytest.fixture() :


ch3/ test_rename_fixture.py

 """ fixture renaming.""" import pytest @pytest.fixture(name='lue') def ultimate_answer_to_life_the_universe_and_everything(): """  .""" return 42 def test_everything(lue): """   .""" assert lue == 42 

lue fixture , fixture_with_a_name_much_longer_than_lue . , --setup-show :


 $ pytest --setup-show test_rename_fixture.py ======================== test session starts ======================== collected 1 items test_rename_fixture.py SETUP F lue test_rename_fixture.py::test_everything (fixtures used: lue). TEARDOWN F lue ===================== 1 passed in 0.01 seconds ====================== 

, lue , pytest --fixtures . , , , :


 $ pytest --fixtures test_rename_fixture.py ======================== test session starts ======================= ... ------------------ fixtures defined from test_rename_fixture ------------------ lue Return ultimate answer. ================= no tests ran in 0.01 seconds ================= 

тАФ . , , , , , . , lue . ┬лTasks┬╗:


 $ cd /path/to/code/ch3/b/tasks_proj $ pytest --fixtures tests/func/test_add.py ======================== test session starts ======================== ... tmpdir_factory Return a TempdirFactory instance for the test session. tmpdir Return a temporary directory path object which is unique to each test function invocation, created as a sub directory of the base temporary directory. The returned object is a `py.path.local`_ path object. ----------------------- fixtures defined from conftest ------------------------ tasks_db An empty tasks db. tasks_just_a_few All summaries and owners are unique. tasks_mult_per_owner Several owners with several tasks each. db_with_3_tasks Connected db with 3 tasks, all unique. db_with_multi_per_owner Connected db with 9 tasks, 3 owners, all with 3 tasks. tasks_db_session Connect to db before tests, disconnect after. =================== no tests ran in 0.01 seconds ==================== 

! conftest.py . tmpdir tmpdir_factory , .



[Parametrized Testing] , . 42, . . - , , :


ch3/b/tasks_proj/tests/func/test_add_variety2.py

"""Test the tasks.add() API function."""

import pytest
import tasks
from tasks import Task

tasks_to_try = (Task('sleep', done=True),
Task('wake', 'brian'),
Task('breathe', 'BRIAN', True),
Task('exercise', 'BrIaN', False))

task_ids = ['Task({},{},{})'.format(t.summary, t.owner, t.done)
for t in tasks_to_try]

def equivalent(t1, t2):
"""Check two tasks for equivalence."""
return ((t1.summary == t2.summary) and
(t1.owner == t2.owner) and
(t1.done == t2.done))

, , a_task :


ch3/b/tasks_proj/tests/func/ test_add_variety2.py

@pytest.fixture(params=tasks_to_try)
def a_task(request):
""" ."""
return request.param

def test_add_a(tasks_db, a_task):
""" a_task ( ids)."""
task_id = tasks.add(a_task)
t_from_db = tasks.get(task_id)
assert equivalent(t_from_db, a_task)

, fixture, , . . param, , params @pytest.fixture(params=tasks_to_try) .


a_task тАФ request.param , . , , :


 $ cd /path/to/code/ch3/b/tasks_proj/tests/func $ pytest -v test_add_variety2.py::test_add_a ===================== test session starts ====================== collected 4 items test_add_variety2.py::test_add_a[a_task0] PASSED test_add_variety2.py::test_add_a[a_task1] PASSED test_add_variety2.py::test_add_a[a_task2] PASSED test_add_variety2.py::test_add_a[a_task3] PASSED =================== 4 passed in 0.03 seconds =================== 

, pytest , () . , :


ch3/b/tasks_proj/tests/func/ test_add_variety2.py

@pytest.fixture(params=tasks_to_try, ids=task_ids)
def b_task(request):
""" ."""
return request.param

def test_add_b(tasks_db, b_task):
""" b_task, ."""
task_id = tasks.add(b_task)
t_from_db = tasks.get(task_id)
assert equivalent(t_from_db, b_task)

:


 $ pytest -v test_add_variety2.py::test_add_b ===================== test session starts ====================== collected 4 items test_add_variety2.py::test_add_b[Task(sleep,None,True)] PASSED test_add_variety2.py::test_add_b[Task(wake,brian,False)] PASSED test_add_variety2.py::test_add_b[Task(breathe,BRIAN,True)] PASSED test_add_variety2.py::test_add_b[Task(exercise,BrIaN,False)] PASSED =================== 4 passed in 0.04 seconds =================== 

ids , , . , :


ch3/b/tasks_proj/tests/func/ test_add_variety2.py

def id_func(fixture_value):
""" ."""
t = fixture_value
return 'Task({},{},{})'.format(t.summary, t.owner, t.done)

@pytest.fixture(params=tasks_to_try, ids=id_func)
def c_task(request):
""" (id_func) ."""
return request.param

def test_add_c(tasks_db, c_task):
""" ."""
task_id = tasks.add(c_task)
t_from_db = tasks.get(task_id)
assert equivalent(t_from_db, c_task)

. Task, id_func() Task , namedtuple Task Task . , , :


 $ pytest -v test_add_variety2.py::test_add_c ===================== test session starts ====================== collected 4 items test_add_variety2.py::test_add_c[Task(sleep,None,True)] PASSED test_add_variety2.py::test_add_c[Task(wake,brian,False)] PASSED test_add_variety2.py::test_add_c[Task(breathe,BRIAN,True)] PASSED test_add_variety2.py::test_add_c[Task(exercise,BrIaN,False)] PASSED =================== 4 passed in 0.04 seconds =================== 

. , , . , !


Fixtures Tasks Project


, Tasks. TinyDB . , . , , , , TinyDB , MongoDB .


( ), , start_tasks_db() tasks_db_session :


ch3/b/tasks_proj/tests/conftest.py

""" ."""

import pytest
import tasks
from tasks import Task

@pytest.fixture(scope='session')
def tasks_db_session(tmpdir_factory):
""" , ."""
temp_dir = tmpdir_factory.mktemp('temp')
tasks.start_tasks_db(str(temp_dir), 'tiny')
yield
tasks.stop_tasks_db()

@pytest.fixture()
def tasks_db(tasks_db_session):
""" tasks."""
tasks.delete_all()

db_type start_tasks_db() . , :


tasks_proj/src/tasks/api.py

  def start_tasks_db(db_path, db_type): # type: (str, str) -None """  API  .""" if not isinstance(db_path, string_types): raise TypeError('db_path must be a string') global _tasksdb if db_type == 'tiny': import tasks.tasksdb_tinydb _tasksdb = tasks.tasksdb_tinydb.start_tasks_db(db_path) elif db_type == 'mongo': import tasks.tasksdb_pymongo _tasksdb = tasks.tasksdb_pymongo.start_tasks_db(db_path) else: raise ValueError("db_type   'tiny'  'mongo'") 

MongoDB, db_type mongo. :


ch3/c/tasks_proj/tests/conftest.py

  import pytest import tasks from tasks import Task # @pytest.fixture(scope='session', params=['tiny',]) @pytest.fixture(scope='session', params=['tiny', 'mongo']) def tasks_db_session(tmpdir_factory, request): """Connect to db before tests, disconnect after.""" temp_dir = tmpdir_factory.mktemp('temp') tasks.start_tasks_db(str(temp_dir), request.param) yield # this is where the testing happens tasks.stop_tasks_db() @pytest.fixture() def tasks_db(tasks_db_session): """An empty tasks db.""" tasks.delete_all() 

params=['tiny',' mongo'] -. request temp_db db_type request.param , "tiny" "mongo".


--verbose -v pytest , pytest . , .




MongoDB рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛




MongoDB, , MongoDB pymongo . MongoDB, https://www.mongodb.com/download-center . pymongo pipтАФ pip install pymongo . MongoDB ; 7 .




:


  $ cd /path/to/code/ch3/c/tasks_proj $ pip install pymongo $ pytest -v --tb=no ===================== test session starts ====================== collected 92 items test_add.py::test_add_returns_valid_id[tiny] PASSED test_add.py::test_added_task_has_id_set[tiny] PASSED test_add.py::test_add_increases_count[tiny] PASSED test_add_variety.py::test_add_1[tiny] PASSED test_add_variety.py::test_add_2[tiny-task0] PASSED test_add_variety.py::test_add_2[tiny-task1] PASSED ... test_add.py::test_add_returns_valid_id[mongo] FAILED test_add.py::test_added_task_has_id_set[mongo] FAILED test_add.py::test_add_increases_count[mongo] PASSED test_add_variety.py::test_add_1[mongo] FAILED test_add_variety.py::test_add_2[mongo-task0] FAILED ... ============= 42 failed, 50 passed in 4.94 seconds ============= 

рд╣рдореНрдоред . , , - Mongo. , pdb: , . 125. TinyDB.


рдЕрднреНрдпрд╛рд╕


  1. test_fixtures.py .
    2. fixturesтАФfunctions @pytest.fixture() , . , , .
  2. , .
  3. , .
  4. pytest --setup-show test_fixtures.py . ?
  5. scope= 'module' 4.
  6. pytest --setup-show test_fixtures.py . рдХреНрдпрд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ?
  7. 6 return <data> yield <data> .
  8. yield .
  9. pytest -s -v test_fixtures.py . ?

рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ


pytest fixture , , building blocks , setup teardown , (, Mongo TinyDB). , , .


pytest, , (builtin) tmpdir tmpdir_factory. (builtin) .


рдкреАрдЫреЗ рдЕрдЧрд▓рд╛

Source: https://habr.com/ru/post/hi448786/


All Articles