ãŸããã
æŽå²çãªè·æ¥ã«ãããšãç§ã¯SQL-schikã§ãã ããããéåœã¯ç§ãBigDataã«é£ããŠè¡ãããã®åŸãèŠåŽããŸãã-JavaãPythonãããã³é¢æ°åããã°ã©ãã³ã°ãç¿åŸããŸããïŒScalaã®åŠç¿ããªã¹ãã«èŒã£ãŠããŸãïŒã å®éããããžã§ã¯ãã®äžéšã§ãPythonã³ãŒãããã¹ãããå¿ èŠãçããŸããã QAã®ã¹ã¿ããã¯ãããã®ç®çã®ããã«PyTestã«å©èšããŸãããããã®ç£ããªãè¯ãã®ããæ確ã«çããããšã¯é£ãããšæããŸããã æ®å¿µãªããããã·ã¢èªã®ã»ã°ã¡ã³ãã§ã¯ããã®åé¡ã«é¢ããæ å ±ã¯ããã»ã©å€ããããŸãããYandexã§ã©ã®ããã«äœ¿çšãããŠããã ããã¹ãŠãè¯ãæ¹æ³ã§ãã åæã«ããã®èšäºã§èª¬æãããŠãããã®ã¯ããã®éã«æ²¿ã£ãŠæ ãå§ãã人ã«ãšã£ãŠã¯ããªãè€éã«èŠããŸãã å ¬åŒã®ããã¥ã¡ã³ãã¯èšããŸã§ããããŸããããã¢ãžã¥ãŒã«èªäœãä»ã®ãœãŒã¹ããèŠã€ããåŸã«åããŠæå³ããããŸããã ç§ã¯ãèå³æ·±ãããšã¯ããã«æžãããŠãããšã¯èšããŸããããæ®å¿µãªãããæåã¯ãŸã£ããããã§ã¯ãããŸããã
PythonãŠããããã¹ã
ãããäœã§ããããªãç§ãäŒããã¹ããã€ã³ããèŠããªãã®ã-ãŠã£ãããã£ã¢ã¯ãŸã ãã£ãšç¥ã£ãŠããŸãã Pythonã®æ¢åã®ã¢ãžã¥ãŒã«ã«é¢ããŠã¯ã Habréã§è©³ãã説æãããŠããŸã ã
å¿ èŠãªç¥èã®çŽ¹ä»
説æããæç¹ã§ãPythonã®ç§ã®ç¥èã¯éåžžã«è¡šé¢çã§ãã-ããã€ãã®ç°¡åãªã¢ãžã¥ãŒã«ãäœæããæšæºçãªãã®ãç¥ã£ãŠããŸããã ããããPyTestãšã®è¡çªã§ã ãããšãã ããããŠyieldæ§é äœã§ç¥èããŒã¹ããã³ã¬ãŒã¿ãŒã§è£å ããå¿ èŠããããŸããã
PyTestã®é·æãšçæ
1ïŒAPIããã®ç¬ç«ïŒå®åãªãïŒã åãunittestã§ã³ãŒããã©ã®ããã«èŠãããïŒ
ã³ãŒã
import unittest class TestUtilDate(unittest.TestCase): def setUp(self): #init_something() pass def tearDown(self): #teardown_something() pass def test_upper(self): self.assertEqual('foo'.upper(), 'FOO') def test_isupper(self): self.assertTrue('FOO'.isupper()) def test_failed_upper(self): self.assertEqual('foo'.upper(), 'FOo') if __name__ == '__main__': suite = unittest.TestLoader().loadTestsFromTestCase(TestUtilDate) unittest.TextTestRunner(verbosity=2).run(suite)
PyTestã§ãåãããšïŒ
ã³ãŒã
import pytest def setup_module(module): #init_something() pass def teardown_module(module): #teardown_something() pass def test_upper(): assert 'foo'.upper() == 'FOO' def test_isupper(): assert 'FOO'.isupper() def test_failed_upper(): assert 'foo'.upper() == 'FOo'
2ïŒè©³çŽ°ã¬ããŒãã JUnitXMLãžã®ã¢ããããŒããå«ãïŒJenkinsãšã®çµ±åçšïŒã ã¬ããŒãèªäœã®ã¿ã€ãã¯ãè¿œå ã®ã¢ãžã¥ãŒã«ã«ãã£ãŠå€æŽã§ããŸãïŒè²ãå«ãïŒïŒãããã«ã€ããŠã¯åŸã§å¥é説æããŸãïŒã ãŸããäžè¬çã«ã¯ãã³ã³ãœãŒã«ã®ã«ã©ãŒã¬ããŒãã®æ¹ã䟿å©ã§ããèµ€ã®FAILEDã¯ããã«è¡šç€ºãããŸãã

3ïŒäŸ¿å©ãªã¢ãµãŒãïŒPythonã®æšæºïŒã ç°ãªãassert'ovã®æå šäœãèŠããŠããå¿ èŠã¯ãããŸããã
4ïŒãã¹ãŠã®ã¬ãã«ã®åçãªãã£ã¯ã¹ãã£ãããã¯ãèªåçã«ç¹å®ã®ãã¹ãã®ããã«åŒã³åºãããšãã§ããŸãã
5ïŒãã£ã¯ã¹ãã£ã®è¿œå æ©èœïŒæ»ãå€ããã¡ã€ãã©ã€ã¶ãã¹ã³ãŒãããªã¯ãšã¹ããªããžã§ã¯ããèªå䜿çšããã¹ãããããã£ã¯ã¹ãã£ïŒ
6ïŒãã¹ãã®ãã©ã¡ãŒã¿ãŒåãã€ãŸããç°ãªããã©ã¡ãŒã¿ãŒã»ããã䜿çšããåããã¹ãã®èµ·åã äžè¬çã«ãããã¯ãã©ã°ã©ã5ãè¿œå æ©èœãã£ã¯ã¹ãã£ããæããŸãããå¥ã®ãã©ã°ã©ãã«å€ããã»ã©æ©äŒãå€ãã®ã§ãã
7ïŒããŒã¯ããã¹ããã¹ããããããããã¹ãã倱æãšããŠããŒã¯ãããïŒããã¯éçºäžã«äŸ¿å©ãªäºæ³ãããåäœã§ãïŒããã¹ãã¹ã€ãŒãã«ååãä»ããŠååã§ã®ã¿å®è¡ã§ããããã«ããŸãã
8ïŒãã©ã°ã€ã³ã ãã®ã¢ãžã¥ãŒã«ã«ã¯ãåå¥ã«ã€ã³ã¹ããŒã«ã§ããè¿œå ã¢ãžã¥ãŒã«ã®ããªã倧ããªãªã¹ãããããŸãã
9ïŒunittestããã³noseã§èšè¿°ããããã¹ããå®è¡ããæ©èœãã€ãŸããããããšã®å®å šãªäžäœäºææ§ã
æ¬ ç¹ã«ã€ããŠã¯ãå€ãã¯ãããŸãããã次ã®ããã«èšããŸãã
1ïŒè¿œå ã¬ãã«ã®ãã¹ãã®æ¬ åŠïŒãã¹ãã®ã¢ãžã¥ãŒã«ãã¯ã©ã¹ãã¡ãœãããé¢æ°ã«ã¯ãé©åãªã¬ãã«ããããŸãã ãã ããåãé¢æ°ãè€æ°ã®ãã¹ãã±ãŒã¹ãæã€ããšãã§ããå ŽåïŒããšãã°ãæ»ãå€ãšãšã©ãŒã®ãã§ãã¯ïŒãããžãã¯ã«ã¯è¿œå ã¬ãã«ã®ãã¹ãã±ãŒã¹ãå¿ èŠã§ãã ããã¯ãè¿œå ã®ã¢ãžã¥ãŒã«ïŒãã©ã°ã€ã³ïŒpytest-describeã«ãã£ãŠéšåçã«è£ãããŸãããé©åãªã¬ãã«ã®ãã£ã¯ã¹ãã£ãŒããªããšããåé¡ãçºçããŸãïŒscope =â describeâïŒã ãã¡ãããããã§çããããšã¯ã§ããŸãããç¶æ³ã«ãã£ãŠã¯ãPyTestã®äž»ãªååãåçŽããšäŸ¿å©ãã®ããã®ãã¹ãŠãã«éåããå¯èœæ§ããããŸãã
2ïŒçç£ãå«ããã¢ãžã¥ãŒã«ã®åå¥ã®ã€ã³ã¹ããŒã«ã®å¿ èŠæ§ã ããã§ããunittestãšdoctestã¯åºæ¬çãªPythonããŒã«ãããã®äžéšã§ãããè¿œå ã®ãžã§ã¹ãã£ãŒã¯å¿ èŠãããŸããã
3ïŒPyTestã䜿çšããã«ã¯ãåããŠããããã¹ããããPythonã®ç¥èãå°ãå¿ èŠã§ãïŒãå¿ èŠãªç¥èã®æŠèŠããåç §ïŒã
ã«ããã®äžã®ã¢ãžã¥ãŒã«ãšãã®æ©èœã®è©³çŽ°ãªèª¬æã
ãã¹ããå®è¡ãã
unittestã®å Žåãã¡ã€ã³é¢æ°åŒã³åºãã䜿çšãããŸãã ãããã£ãŠãèµ·åã¯ãpython unittest_example.pyããšãã圢åŒã«ãªããŸãã åæã«ããã¹ãã¹ã€ãŒããå®è¡ããã«ã¯ãTestSuitã§ããããåå¥ã«çµã¿åãããŠå®è¡ããå¿ èŠããããŸãã PyTestã¯ããã©ã«ãå ã®ãã¹ãŠã®ãã¡ã€ã«ïŒååž°çã«ãµããã©ã«ãããã©ããŒã¹ããïŒãŸãã¯æå®ããããã¡ã€ã«ã«ã€ããŠãç¬èªã®ååtest_ *ïŒã¯ã©ã¹åã®Test_ *ïŒã§ãã¹ãŠã®ãã¹ããåéããŸãã ã€ãŸããåŒã³åºãäŸã¯ãpy.test -v pytest_example.pyãã®ããã«ãªããŸã
åºæ¬çãªåå
ãã®å Žåããã£ã¯ã¹ãã£ã¯ããã¹ãã«é©åãªç°å¢ãäœæããããã«èµ·åãããé¢æ°ãšã¡ãœãããåŒã³åºããŸãã unittestãšåæ§ã«ãPyTestã«ã¯ãã¹ãŠã®ã¬ãã«ã®ãã£ã¯ã¹ãã£ã®ååããããŸãã
import pytest def setup(): print ("basic setup into module") def teardown(): print ("basic teardown into module") def setup_module(module): print ("module setup") def teardown_module(module): print ("module teardown") def setup_function(function): print ("function setup") def teardown_function(function): print ("function teardown") def test_numbers_3_4(): print "test 3*4" assert 3*4 == 12 def test_strings_a_3(): print "test a*3" assert 'a'*3 == 'aaa' class TestUM: def setup(self): print ("basic setup into class") def teardown(self): print ("basic teardown into class") def setup_class(cls): print ("class setup") def teardown_class(cls): print ("class teardown") def setup_method(self, method): print ("method setup") def teardown_method(self, method): print ("method teardown") def test_numbers_5_6(self): print "test 5*6" assert 5*6 == 30 def test_strings_b_2(self): print "test b*2" assert 'b'*2 == 'bb'
printã³ãã³ãã«ãã£ãŠçæããããã¹ãŠã®åºåã衚瀺ããã«ã¯ã-sãã©ã°ãæå®ããŠãã¹ããå®è¡ããå¿ èŠããããŸãã
tmp>py.test -s basic_fixtures.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 rootdir: tmp/, inifile: collected 4 items basic_fixtures.py module setup function setup basic setup into module test 3*4 .basic teardown into module function teardown function setup basic setup into module test a*3 .basic teardown into module function teardown class setup method setup basic setup into class test 5*6 .basic teardown into class method teardown method setup basic setup into class test b*2 .basic teardown into class method teardown class teardown module teardown ========================== 4 passed in 0.03 seconds
ãã®äŸã¯ãåãã£ã¯ã¹ãã£ã¬ãã«ã®éå±€ãšåçŸæ§ãå®å šã«ç€ºããŠããŸãïŒããšãã°ãsetup_functionã¯åé¢æ°åŒã³åºãã®åã«åŒã³åºãããsetup_moduleã¯ã¢ãžã¥ãŒã«å šäœã«å¯ŸããŠ1åã ãåŒã³åºãããŸãïŒã ããã©ã«ãã®ãã£ã¯ã¹ãã£ã¬ãã«ãé¢æ°/ã¡ãœããïŒãã£ã¯ã¹ãã£ã®ã»ããã¢ãããšå解ïŒã§ããããšãããããŸãã
æ¡åŒµãã£ã¯ã¹ãã£
åé¡ã¯ãäžéšã®ãã¹ãã§ç¹å®ã®ç°å¢ãå¿ èŠã§ããããä»ã®ãã¹ãã§ã¯å¿ èŠãªãå Žåã¯ã©ãããã°ããããšããããšã§ãã ç°ãªãã¢ãžã¥ãŒã«ãŸãã¯ã¯ã©ã¹ã«åºãããŸããïŒ ããã¯éåžžã«å¿«é©ã§çŸããèŠããŸããã æ¡åŒµPyTestãã£ã¯ã¹ãã£ã圹ç«ã¡ãŸãã
ãããã£ãŠãPyTestã§æ¡åŒµãã£ã¯ã¹ãã£ãäœæããã«ã¯ã次ã®ãã®ãå¿ èŠã§ãã
1ïŒpytestã¢ãžã¥ãŒã«ãã€ã³ããŒããã
2ïŒ@ pytest.fixtureïŒïŒãã³ã¬ãŒã¿ã䜿çšããŠããã®é¢æ°ããã£ã¯ã¹ãã£ã§ããããšã瀺ããŸã
3ïŒãã£ã¯ã¹ãã£ïŒã¹ã³ãŒãïŒã®ã¬ãã«ãèšå®ããŸãã å¯èœãªå€ã¯ããé¢æ°ãããclsãããã¢ãžã¥ãŒã«ãããã»ãã·ã§ã³ãã§ãã ããã©ã«ãå€=ãé¢æ°ãã
4ïŒãã®ãã£ã¯ã¹ãã£ã®ãã£ã¢ããŠã³ãåŒã³åºãå¿ èŠãããå Žåããã¡ã€ãã©ã€ã¶ãè¿œå ããå¿ èŠããããŸãïŒãã£ã¯ã¹ãã£ã«æž¡ããããªã¯ãšã¹ããªããžã§ã¯ãã®addfinalizerã¡ãœãããŸãã¯yieldæ§æäœã䜿çšããŠïŒ
5ïŒãã®ãã£ã¯ã¹ãã£ã®ååãé¢æ°ãã©ã¡ãŒã¿ãŒã®ãªã¹ãã«è¿œå ããŸã
import pytest @pytest.fixture() def resource_setup(request): print("resource_setup") def resource_teardown(): print("resource_teardown") request.addfinalizer(resource_teardown) def test_1_that_needs_resource(resource_setup): print("test_1_that_needs_resource") def test_2_that_does_not(): print("test_2_that_does_not") def test_3_that_does_again(resource_setup): print("test_3_that_does_again")
以äžãéå§ããŸãã
tmp>py.test -s extended_fixture.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 rootdir: tmp/, inifile: collected 3 items extended_fixture.py resource_setup test_1_that_needs_resource .resource_teardown test_2_that_does_not .resource_setup test_3_that_does_again .resource_teardown ========================== 3 passed in 0.01 seconds
é«åºŠãªãã£ã¯ã¹ãã£ãåŒã³åºã
é«åºŠãªãã£ã¯ã¹ãã£ã¯ãããã«2ã€ã®æ¹æ³ã§åŒã³åºãããšãã§ããããšã«æ³šæããŠãã ããã
1ïŒãã³ã¬ãŒã¿@ pytest.mark.usefixturesïŒïŒã§ãã¹ããè£ é£Ÿãã
2ïŒãã£ã¯ã¹ãã£ã«èªå䜿çšãã©ã°ã䜿çšããŸãã ãã ããäºæããªããã¹ãåäœãçºçããå¯èœæ§ãããããããã®æ©èœã¯æ³šæããŠäœ¿çšããå¿ èŠããããŸãã
3ïŒãã¹ããã©ã¡ãŒã¿ãä»ããäžèšã®æ¹æ³
åã®äŸã次ã«ç€ºããŸãã
import pytest @pytest.fixture() def resource_setup(request): print("resource_setup") def resource_teardown(): print("resource_teardown") request.addfinalizer(resource_teardown) @pytest.fixture(scope="function", autouse=True) def another_resource_setup_with_autouse(request): print("another_resource_setup_with_autouse") def resource_teardown(): print("another_resource_teardown_with_autouse") request.addfinalizer(resource_teardown) def test_1_that_needs_resource(resource_setup): print("test_1_that_needs_resource") def test_2_that_does_not(): print("test_2_that_does_not") @pytest.mark.usefixtures("resource_setup") def test_3_that_does_again(): print("test_3_that_does_again")
以äžãéå§ããŸãã
tmp>py.test -s call_extended_fixtures.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 rootdir: tmp/, inifile: collected 3 items call_extended_fixtures.py another_resource_setup_with_autouse resource_setup test_1_that_needs_resource .resource_teardown another_resource_teardown_with_autouse another_resource_setup_with_autouse test_2_that_does_not .another_resource_teardown_with_autouse another_resource_setup_with_autouse resource_setup test_3_that_does_again .resource_teardown another_resource_teardown_with_autouse ========================== 3 passed in 0.01 seconds
å解æ¡åŒµåšå ·
äžèšã®ããã«ãç¹å®ã®æ¡åŒµãã£ã¯ã¹ãã£ã«å¯ŸããŠãã£ã¢ããŠã³ãåŒã³åºãå¿ èŠãããå Žåã2ã€ã®æ¹æ³ã§å®è£ ã§ããŸãã
1ïŒãã¡ã€ãã©ã€ã¶ããã£ã¯ã¹ãã£ã«è¿œå ããŸãïŒãã£ã¯ã¹ãã£ã«æž¡ããããªã¯ãšã¹ããªããžã§ã¯ãã®addfinalizerã¡ãœãããä»ããŠïŒ
2ïŒyieldã³ã³ã¹ãã©ã¯ãã䜿çšããŠïŒPyTestããŒãžã§ã³2.4以éïŒ
æ¡åŒµãã£ã¯ã¹ãã£ãäœæããäŸã§æ€èšããæåã®æ¹æ³ã 次ã«ãyieldã䜿çšããŠåãæ©èœãå®èšŒããŸãã é¢æ°ããã£ã¯ã¹ãã£ãšããŠè£ 食ãããšãã«yieldã䜿çšããã«ã¯ã@ pytest.fixtureïŒïŒã§ã¯ãªã@ pytest.yield_fixtureïŒïŒãã³ã¬ãŒã¿ã䜿çšããå¿ èŠãããããšã«æ³šæããŠãã ããã
import pytest @pytest.yield_fixture() def resource_setup(): print("resource_setup") yield print("resource_teardown") def test_1_that_needs_resource(resource_setup): print("test_1_that_needs_resource") def test_2_that_does_not(): print("test_2_that_does_not") def test_3_that_does_again(resource_setup): print("test_3_that_does_again")
ãã¡ã€ãã©ã€ã¶ãªãã·ã§ã³ãšäžèŽãããããããã¹ãã«çµè«ãè¿œå ããŸããã
ãã£ã¯ã¹ãã£ã®æ»ãå€
ãªãã·ã§ã³ãšããŠãPyTestã®ãã£ã¯ã¹ãã£ã¯returnãä»ããŠãã¹ãã«äœããè¿ãããšãã§ããŸãã äœããã®ç¶æ å€ãŸãã¯ãªããžã§ã¯ãïŒãã¡ã€ã«ãªã©ïŒã«ãªããŸãã
import pytest @pytest.fixture(scope="module") def resource_setup(request): print("\nconnect to db") db = {"Red":1,"Blue":2,"Green":3} def resource_teardown(): print("\ndisconnect") request.addfinalizer(resource_teardown) return db def test_db(resource_setup): for k in resource_setup.keys(): print "color {0} has id {1}".format(k, resource_setup[k]) def test_red(resource_setup): assert resource_setup["Red"] == 1 def test_blue(resource_setup): assert resource_setup["Blue"] != 1
以äžãéå§ããŸãã
tmp>py.test -v -s return_value.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 3 items return_value.py::test_db connect to db color Blue has id 2 color Green has id 3 color Red has id 1 PASSED return_value.py::test_red PASSED return_value.py::test_blue PASSED disconnect ========================== 3 passed in 0.02 seconds
ãã£ã¯ã¹ãã£ã¬ãã«ïŒã¹ã³ãŒãïŒ
ãã£ã¯ã¹ãã£ã¬ãã«ã¯ããé¢æ°ãããclsãããã¢ãžã¥ãŒã«ãããã»ãã·ã§ã³ãã®å€ãåããŸãã ããã©ã«ãå€=ãé¢æ°ã\
æ©èœ-åãã¹ãã®ãã£ã¯ã¹ãã£å®è¡
cls-åã¯ã©ã¹ã®ãã£ã¯ã¹ãã£å®è¡
ã¢ãžã¥ãŒã«-åã¢ãžã¥ãŒã«ã«å¯ŸããŠãã£ã¯ã¹ãã£ãèµ·åãããŸã
ã»ãã·ã§ã³-ãã£ã¯ã¹ãã£ã¯ã»ãã·ã§ã³ããšã«èµ·åãããŸãïŒã€ãŸããå®éã«ã¯1åïŒ
ããšãã°ãåã®äŸã§ã¯ãã¹ã³ãŒããæ©èœã«å€æŽãããã¹ãããšã«ããŒã¿ããŒã¹æ¥ç¶ãåŒã³åºããŠåæã§ããŸãã
import pytest @pytest.fixture(scope="function") def resource_setup(request): print("\nconnect to db") db = {"Red":1,"Blue":2,"Green":3} def resource_teardown(): print("\ndisconnect") request.addfinalizer(resource_teardown) return db def test_db(resource_setup): for k in resource_setup.keys(): print "color {0} has id {1}".format(k, resource_setup[k]) def test_red(resource_setup): assert resource_setup["Red"] == 1 def test_blue(resource_setup): assert resource_setup["Blue"] != 1
tmp>py.test -v -s scope.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 3 items scope.py::test_db connect to db color Blue has id 2 color Green has id 3 color Red has id 1 PASSED disconnect scope.py::test_red connect to db PASSED disconnect scope.py::test_blue connect to db PASSED disconnect ========================== 3 passed in 0.02 seconds
ãã£ã¯ã¹ãã£ã¯ãPyTestã«ãã£ãŠèªåçã«ã€ã³ããŒããããconftest.pyãã¡ã€ã«ã§ã説æã§ããŸãã ãã®å Žåããã£ã¯ã¹ãã£ã«ã¯ä»»æã®ã¬ãã«ãèšå®ã§ããŸãïŒãã®ãã¡ã€ã«ã®èª¬æãä»ããŠã®ã¿ããã»ãã·ã§ã³ãã¬ãã«ã®ãã£ã¯ã¹ãã£ãäœæã§ããŸãïŒã
ããšãã°ãconftest.pyãã¡ã€ã«ãš2ã€ã®ãã¹ããã¡ã€ã«ã§åå¥ã®ã»ãã·ã§ã³ã¹ã³ãŒããã©ã«ããŒãäœæããŸãïŒPyTestãã¢ãžã¥ãŒã«ãèªåçã«ã€ã³ããŒãããã«ã¯ãã¢ãžã¥ãŒã«ã®ååãtest_ã§å§ãŸãå¿ èŠããããŸãããã®åäœã¯å€æŽã§ããŸããïŒã
conftest.pyïŒ
import pytest @pytest.fixture(scope="session", autouse=True) def auto_session_resource(request): """ Auto session resource fixture """ print("auto_session_resource_setup") def auto_session_resource_teardown(): print("auto_session_resource_teardown") request.addfinalizer(auto_session_resource_teardown) @pytest.fixture(scope="session") def manually_session_resource(request): """ Manual set session resource fixture """ print("manually_session_resource_setup") def manually_session_resource_teardown(): print("manually_session_resource_teardown") request.addfinalizer(manually_session_resource_teardown) @pytest.fixture(scope="function") def function_resource(request): """ Function resource fixture """ print("function_resource_setup") def function_resource_teardown(): print("function_resource_teardown") request.addfinalizer(function_resource_teardown)
test_session_scope1.py
import pytest def test_1_that_does_not_need_session_resource(): print("test_1_that_does_not_need_session_resource") def test_2_that_does(manually_session_resource): print("test_2_that_does")
test_session_scope2.py
import pytest def test_3_that_uses_all_fixtures(manually_session_resource, function_resource): print("test_2_that_does_not")
以äžãéå§ããŸãã
tmp\session scope>py.test -s -v ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\pro ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp\session scope, inifile: collected 3 items test_session_scope1.py::test_1_that_does_not_need_session_resource auto_session resource_setup test_1_that_does_not_need_session_resource PASSED test_session_scope1.py::test_2_that_does manually_session_resource_setup test_2_that_does PASSED test_session_scope2.py::test_3_that_uses_all_fixtures function_resource_setup test_2_that_does_not PASSEDfunction_resource_teardown manually_session_resource_teardown auto_session_resource_teardown ========================== 3 passed in 0.02 seconds
ãŸããPyTestã--fixtureså ¥åãã©ã¡ãŒã¿ãŒããµããŒãããåŒã³åºãããå Žåãconftest.pyïŒdocstringããã£ãïŒã§èª¬æãããŠãããã®ãå«ãã䜿çšå¯èœãªãã¹ãŠã®ãã£ã¯ã¹ãã£ãŒãè¿ããŸãã
tmp\session scope>py.test --fixtures ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 rootdir: tmp\session scope, inifile: collected 3 items cache Return a cache object that can persist state between testing sessions. âŠ..... path object. ----------------------- fixtures defined from conftest ------------------------ manually_session_resource Manual set session resource fixture function_resource Function resource fixture auto_session_resource Auto session resource fixture ============================== in 0.07 seconds
ãªã¯ãšã¹ããªããžã§ã¯ã
æ¡åŒµãã£ã¯ã¹ãã£ãäœæããäŸã§ã¯ããªã¯ãšã¹ããã©ã¡ãŒã¿ãæž¡ããŸããã ããã¯ãaddfinalizerã¡ãœãããéããŠãã¡ã€ãã©ã€ã¶ãŒãè¿œå ããããã«è¡ãããŸããã ãã ãããã®ãªããžã§ã¯ãã«ã¯å€ãã®å±æ§ãšä»ã®ã¡ãœããïŒ å ¬åŒAPIã®å®å šãªãªã¹ãïŒããããŸãã
import pytest @pytest.fixture(scope="function") def resource_setup(request): print request.fixturename print request.scope print request.function.__name__ print request.cls print request.module.__name__ print request.fspath def test_1(resource_setup): assert True class TestClass(): def test_2(self, resource_setup): assert True
以äžãéå§ããŸãã
tmp>py.test -v -s request_object.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 2 items request_object.py::test_1 resource_setup function test_1 None 08 tmp\request_object.py PASSED request_object.py::TestClass::test_2 resource_setup function test_2 08.TestClass 08 tmp\request_object.py PASSED ========================== 2 passed in 0.04 seconds
ãã©ã¡ãŒã¿å
ãã©ã¡ãŒã¿åã¯ãç°ãªãäžé£ã®å ¥åãã©ã¡ãŒã¿ã䜿çšããŠåããã¹ããå®è¡ããæ¹æ³ã§ãã ããšãã°ãæååã5æåããé·ãå Žåã¯çå笊ãã5æåããçãå Žåã¯æå笊ããæååã«æ£ç¢ºã«5æåãããå Žåã¯ããããè¿œå ããé¢æ°ããããŸãã ãããã£ãŠã3ã€ã®ãã¹ããäœæãã代ããã«ã1ã€ã®ãã¹ããäœæã§ããŸãããç°ãªããã©ã¡ãŒã¿ãŒã§åŒã³åºããŸãã
ãã¹ãã®ãã©ã¡ãŒã¿ãŒãèšå®ããã«ã¯ã2ã€ã®æ¹æ³ããããŸãã
1ïŒå€ã®é åãæž¡ããã£ã¯ã¹ãã£ã®paramsãã©ã¡ãŒã¿ãŒã®å€ãä»ããŠã
ã€ãŸãããã®å Žåã®ãã£ã¯ã¹ãã£ã¯ããã©ã¡ãŒã¿ãŒãæž¡ãã©ãããŒã§ãã ãããŠããããã¯äžèšã®ãªã¯ãšã¹ããªããžã§ã¯ãã®paramå±æ§ãä»ããŠãã¹ãèªäœã«æž¡ãããŸãã
2ïŒãã³ã¬ãŒã¿ïŒã©ãã«ïŒ@ pytest.mark.parametrizeãä»ããŠãå€æ°åã®ãªã¹ããšãã®å€ã®é åãæž¡ãããŸãã
ã ããæåã®æ¹æ³ã
import pytest def strange_string_func(str): if len(str) > 5: return str + "?" elif len(str) < 5: return str + "!" else: return str + "." @pytest.fixture(scope="function", params=[ ("abcdefg", "abcdefg?"), ("abc", "abc!"), ("abcde", "abcde.") ]) def param_test(request): return request.param def test_strange_string_func(param_test): (input, expected_output) = param_test result = strange_string_func(input) print "input: {0}, output: {1}, expected: {2}".format(input, result, expected_output) assert result == expected_output
以äžãéå§ããŸãã
tmp>py.test -s -v parametrizing_base.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 3 items parametrizing_base.py::test_strange_string_func[param_test0] input: abcdefg, output: abcdefg?, e xpected: abcdefg? PASSED parametrizing_base.py::test_strange_string_func[param_test1] input: abc, output: abc!, expected: abc! PASSED parametrizing_base.py::test_strange_string_func[param_test2] input: abcde, output: abcde., expec ted: abcde. PASSED ========================== 3 passed in 0.03 seconds
1ã€ã®äžå¿«ãªè©³çŽ°ãé€ãããã¹ãŠãæ£åžžã«æ©èœããŸãããã¹ãã®ååã«ãã£ãŠãã©ã®çš®é¡ã®ãã©ã¡ãŒã¿ãŒããã¹ãã«æž¡ãããããç解ããããšã¯äžå¯èœã§ãã ãããŠããã®å Žåããã£ã¯ã¹ãã£ãã©ã¡ãŒã¿IDã圹ç«ã¡ãŸãã ãã¹ãåã®ãªã¹ãïŒé·ãã¯ãã¹ãã®æ°ãšäžèŽããå¿ èŠããããŸãïŒããŸãã¯æçµåãçæããé¢æ°ã®ãããããåãå ¥ããŸãã
import pytest def strange_string_func(str): if len(str) > 5: return str + "?" elif len(str) < 5: return str + "!" else: return str + "." @pytest.fixture(scope="function", params=[ ("abcdefg", "abcdefg?"), ("abc", "abc!"), ("abcde", "abcde.")], ids=["len>5","len<5","len==5"] ) def param_test(request): return request.param def test_strange_string_func(param_test): (input, expected_output) = param_test result = strange_string_func(input) print "input: {0}, output: {1}, expected: {2}".format(input, result, expected_output) assert result == expected_output def idfn(val): return "params: {0}".format(str(val)) @pytest.fixture(scope="function", params=[ ("abcdefg", "abcdefg?"), ("abc", "abc!"), ("abcde", "abcde.")], ids=idfn ) def param_test_idfn(request): return request.param def test_strange_string_func_with_ifdn(param_test_idfn): (input, expected_output) = param_test result = strange_string_func(input) print "input: {0}, output: {1}, expected: {2}".format(input, result, expected_output) assert result == expected_output
以äžãéå§ããŸãã
tmp>py.test -s -v parametrizing_named.py --collect-only ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 6 items <Module 'parametrizing_named.py'> <Function 'test_strange_string_func[len>5]'> <Function 'test_strange_string_func[len<5]'> <Function 'test_strange_string_func[len==5]'> <Function "test_strange_string_func_with_ifdn[params: ('abcdefg', 'abcdefg?')] "> <Function "test_strange_string_func_with_ifdn[params: ('abc', 'abc!')]"> <Function "test_strange_string_func_with_ifdn[params: ('abcde', 'abcde.')]"> ============================== in 0.03 seconds
ãã®å Žåãè¿œå ãã©ã¡ãŒã¿ãŒâcollect-onlyãæå®ããŠPyTestãèµ·åããŸãããããã«ããããã©ã¡ãŒã¿ãŒåã«ãã£ãŠçæããããã¹ãŠã®ãã¹ããå®è¡ããã«åéã§ããŸãã
2çªç®ã®æ¹æ³ã«ã¯1ã€ã®å©ç¹ããããŸãïŒç°ãªããã©ã¡ãŒã¿ãŒã§è€æ°ã®ã©ãã«ãæå®ãããšããã¹ãŠã®å¯èœãªãã©ã¡ãŒã¿ãŒã»ããïŒã€ãŸãããã©ã¡ãŒã¿ãŒã®ãã«ã«ãç©ïŒã§ãã¹ããéå§ãããŸãã
import pytest @pytest.mark.parametrize("x", [1,2]) @pytest.mark.parametrize("y", [10,11]) def test_cross_params(x, y): print "x: {0}, y: {1}".format(x, y) assert True
以äžãéå§ããŸãã
tmp>py.test -s -v parametrizing_combinations.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 4 items parametrizing_combinations.py::test_cross_params[10-1] x: 1, y: 10 PASSED parametrizing_combinations.py::test_cross_params[10-2] x: 2, y: 10 PASSED parametrizing_combinations.py::test_cross_params[11-1] x: 1, y: 11 PASSED parametrizing_combinations.py::test_cross_params[11-2] x: 2, y: 11 PASSED ========================== 4 passed in 0.02 seconds
ãã©ã¡ãŒã¿ãŒåã©ãã«ã§ã¯ããã©ã¡ãŒã¿ãŒãèšå®ããæåã®æ¹æ³ãšåæ§ã«ãåºåã«ãã©ã¡ãŒã¿ãŒã衚瀺ããidsãã©ã¡ãŒã¿ãŒãæž¡ãããšãã§ããŸãã
import pytest def idfn_x(val): return "x=({0})".format(str(val)) def idfn_y(val): return "y=({0})".format(str(val)) @pytest.mark.parametrize("x", [-1,2], ids=idfn_x) @pytest.mark.parametrize("y", [-10,11], ids=idfn_y) def test_cross_params(x, y): print "x: {0}, y: {1}".format(x, y) assert True @pytest.mark.parametrize("x", [-1,2], ids=["negative x","positive y"]) @pytest.mark.parametrize("y", [-10,11], ids=["negative y","positive y"]) def test_cross_params_2(x, y): print "x: {0}, y: {1}".format(x, y) assert True
以äžãéå§ããŸãã
tmp>py.test -s -v parametrizing_combinations_named.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp/, inifile: collected 8 items parametrizing_combinations_named.py::test_cross_params[y=(-10)-x=(-1)] x: -1, y: -10 PASSED parametrizing_combinations_named.py::test_cross_params[y=(-10)-x=(2)] x: 2, y: -10 PASSED parametrizing_combinations_named.py::test_cross_params[y=(11)-x=(-1)] x: -1, y: 11 PASSED parametrizing_combinations_named.py::test_cross_params[y=(11)-x=(2)] x: 2, y: 11 PASSED parametrizing_combinations_named.py::test_cross_params_2[negative y-negative x] x: -1, y: -10 PASSED parametrizing_combinations_named.py::test_cross_params_2[negative y-positive y] x: 2, y: -10 PASSED parametrizing_combinations_named.py::test_cross_params_2[positive y-negative x] x: -1, y: 11 PASSED parametrizing_combinations_named.py::test_cross_params_2[positive y-positive y] x: 2, y: 11 PASSED ========================== 8 passed in 0.04 seconds
è€æ°ã®ãã£ã¯ã¹ãã£ãšãã£ã¯ã¹ãã£ã䜿çšããŠãã£ã¯ã¹ãã£ãåŒã³åºããŸã
PyTestã¯ããã¹ãã®ããã«åŒã³åºããããã£ã¯ã¹ãã£ã®ãªã¹ããå¶éããŸããã
import pytest @pytest.fixture() def fixture1(request): print("fixture1") @pytest.fixture() def fixture2(request): print("fixture2") @pytest.fixture() def fixture3(request): print("fixture3") def test_1(fixture1, fixture2): print("test_1") def test_2(fixture1, fixture2, fixture3): print("test_2")
tmp>py.test -s -v multiply_fixtures.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: collected 2 items multiply_fixtures.py::test_1 fixture1 fixture2 test_1 PASSED multiply_fixtures.py::test_2 fixture1 fixture2 fixture3 test_2 PASSED ========================== 2 passed in 0.01 seconds
ãŸããã©ã®ãã£ã¯ã¹ãã£ãŒããããèªäœã«å¯ŸããŠä»»æã®æ°ã®ãã£ã¯ã¹ãã£ãŒã®å®è¡ãåŒã³åºãããšãã§ããŸãã
import pytest @pytest.fixture() def fixture1(request, fixture2): print("fixture1") @pytest.fixture() def fixture2(request, fixture3): print("fixture2") @pytest.fixture() def fixture3(request): print("fixture3") def test_1(fixture1): print("test_1") def test_2(fixture2): print("test_2")
tmp>py.test -s -v fixtures_use_fixtures.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: collected 2 items fixtures_use_fixtures.py::test_1 fixture3 fixture2 fixture1 test_1 PASSED fixtures_use_fixtures.py::test_2 fixture3 fixture2 test_2 PASSED ========================== 2 passed in 0.01 seconds
ã¿ã°
PyTestã¯ããããŒã¯ããšåŒã°ãã@ pytest.markãã³ã¬ãŒã¿ã®ã¯ã©ã¹ããµããŒãããŠããŸããåºæ¬ãªã¹ãã«ã¯ã次ã®ã©ãã«ãå«ãŸ
ããŸãã1ïŒ@ pytest.mark.parametrize-ãã¹ãã®ãã©ã¡ãŒã¿ãŒåïŒäžèšïŒ
2ïŒ@ pytest.mark.xfail-ãã¹ãã«åæ ŒããªãããšãããŒã¯ããPyTestã¯ãããæåŸ ãããåäœãšããŠèªèããŸãïŒéçºãããæ©èœã®ãã¹ãã®ã¿ã€ã ã¹ã¿ã³ããšããŠæçšã§ãïŒããŸãããã®ã©ãã«ã¯ããã¹ãããã®ã©ãã«ã§ããŒã¯ãããæ¡ä»¶ãåãå ¥ããå ŽåããããŸãã
3ïŒ@ pytest.mark.skipif-ãã¹ããã¹ããããããšãã®æ¡ä»¶ãèšå®ã§ããŸã;
4ïŒ@ pytest.mark.usefixtures-ãã¹ãã®ããã«åŒã³åºããããã¹ãŠã®ãã£ã¯ã¹ãã£ããªã¹ãã§ããŸãã
äžè¬çã«ããªã¹ãã¯åºããã³ãã³ããpy.test-ããŒã«ãŒãã
import pytest import sys @pytest.mark.xfail() def test_failed(): assert False @pytest.mark.xfail(sys.platform != "win64", reason="requires windows 64bit") def test_failed_for_not_win32_systems(): assert False @pytest.mark.skipif(sys.platform != "win64", reason="requires windows 64bit") def test_skipped_for_not_win64_systems(): assert False
以äžãéå§ããŸãã
tmp>py.test -s -v basic_marks.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: collected 3 items basic_marks.py::test_failed xfail basic_marks.py::test_failed_for_not_win32_systems xfail basic_marks.py::test_skipped_for_not_win64_systems SKIPPED ==================== 1 skipped, 2 xfailed in 0.02 seconds
éèŠãªè¿œå æ©èœã¯ããŠãŒã¶ãŒãã©ãã«ãä»»æã«èšå®ã§ããããšã§ããããã«ãããã©ãã«åã§åå¥ã«å®è¡ãããã¹ãã¹ã€ãŒããéžæãã-mã¹ã€ããã§æž¡ãããšãã§ããŸãã
import pytest def test_1(): print "test_1" @pytest.mark.critital_tests def test_2(): print "test_2" def test_3(): print "test_3"
tmp>py.test -s -v -m "critital_tests" custom_marks.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: collected 3 items custom_marks.py::test_2 test_2 PASSED ================= 2 tests deselected by "-m 'critital_tests'" ================= =================== 1 passed, 2 deselected in 0.01 seconds ====================
ã©ãã«ã¯ãpytest.iniã¢ãžã¥ãŒã«ã®èª¬æã䜿çšããŠèª¬æãããã¹ãŠã®ã¢ãžã¥ãŒã«ã§äœ¿çšå¯èœã«ããããšãã§ããŸããåæã«ããpy.test --markersãã§ååŸããå©çšå¯èœãªã¿ã°ã®ãªã¹ãã«è¡šç€ºãããŸãã
pytest.ini
# content of pytest.ini [pytest] markers = critical_test: mark test as critical. These tests must to be checked first.
tmp>py.test --markers @pytest.mark.critical_test: mark test as critical. These tests must to be checked first. âŠ......
ãŸãããã¹ãã ãã§ãªããã¯ã©ã¹ãã¢ãžã¥ãŒã«ïŒã€ã³ããŒããããã¢ãžã¥ãŒã«ã®å±æ§ãå€æŽããŠèšå®ïŒããŸãã¯ãã©ã¡ãŒã¿ãŒåã«ãã£ãŠååŸããããã®èµ·åã«ãã©ãã«ãä»ããããšãã§ããŸãïŒæ¬¡ã®äŸãåç §ïŒã
import pytest pytestmark = pytest.mark.level1 def test_1(): print "test_1" @pytest.mark.level2 class TestClass: def test_2(self): print "test_2" @pytest.mark.level3 def test_3(self): print "test_3"
tmp>py.test -s -v -m "level3" custom_marks_others.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 3 items custom_marks_others.py::TestClass::test_3 test_3 PASSED ===================== 2 tests deselected by "-m 'level3'" ===================== =================== 1 passed, 2 deselected in 0.07 seconds ====================
tmp>py.test -s -v -m "level2" custom_marks_others.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 3 items custom_marks_others.py::TestClass::test_2 test_2 PASSED custom_marks_others.py::TestClass::test_3 test_3 PASSED ===================== 1 tests deselected by "-m 'level2'" ===================== =================== 2 passed, 1 deselected in 0.03 seconds ====================
tmp>py.test -s -v -m "level1" custom_marks_others.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 3 items custom_marks_others.py::test_1 test_1 PASSED custom_marks_others.py::TestClass::test_2 test_2 PASSED custom_marks_others.py::TestClass::test_3 test_3 PASSED ========================== 3 passed in 0.02 seconds ===========================
import pytest @pytest.mark.parametrize(("x","expected"), [ (1,2), pytest.mark.critical((2,3)), (3,4) ]) def test_inc(x,expected): print x, "+ 1 = ", expected assert x + 1 == expected
tmp>py.test -s -v -m "critical" custom_marks_params.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 3 items custom_marks_params.py::test_inc[2-3] 2 + 1 = 3 PASSED ==================== 2 tests deselected by "-m 'critical'" ==================== =================== 1 passed, 2 deselected in 0.02 seconds ====================
äŸå€åŠç
ãã¡ããããã¹ãçšã®æ¬æ Œçãªã¢ãžã¥ãŒã«ãšããŠãPyTestã§ã¯ãwith pytest.raisesïŒïŒãã䜿çšããŠãè¿ãããäŸå€ã®æ£ç¢ºãã確èªããããšãã§ããŸãã
import pytest def f(): print 1/0 def test_exception(): with pytest.raises(ZeroDivisionError): f()
tmp>py.test -s -v check_exception.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 1 items check_exception.py::test_exception PASSED ========================== 1 passed in 0.01 seconds
ååãŸãã¯IDã«ãããã¹ãã®å®è¡
module.py::class::method orã®åœ¢åŒã§ã¢ãžã¥ãŒã«ãžã®ãã«ãã¹ããªã¹ãããããšã«ãããã¢ãžã¥ãŒã«ããåã ã®ãã¹ããå®è¡ã§ããŸããmodule.py::functionããŸããååã®äžéšã-kãã©ã°ã§æž¡ããŸãã
import pytest def test_one(): print "test_one" def test_one_negative(): print "test_one_negative" def test_two(): print "test_one_negative"
tmp>py.test -s -v call_by_name_and_id.py::test_two ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 4 items call_by_name_and_id.py::test_two test_one_negative PASSED ========================== 1 passed in 0.04 seconds
tmp>py.test -s -v -k "one" call_by_name_and_id.py ============================= test session starts ============================= platform win32 -- Python 2.7.8, pytest-2.8.2, py-1.4.30, pluggy-0.3.1 -- c:\prog ram files (x86)\python27\python.exe cachedir: .cache rootdir: tmp, inifile: pytest.ini collected 3 items call_by_name_and_id.py::test_one test_one PASSED call_by_name_and_id.py::test_one_negative test_one_negative PASSED ======================== 1 tests deselected by '-kone' ======================== =================== 2 passed, 1 deselected in 0.01 seconds ====================
Eclipseã§ã®PyDevãšã®çµ±å
PyTestã¯ãEclipseã®PyDevã¢ãžã¥ãŒã«ã®PyUnitã³ã³ããŒãã³ãã«çµ±åãããŠããããšã«èšåããããšæããŸããèšå®ã§ã䜿çšããå¿ èŠãããããšãæå®ããå¿ èŠããããŸãã

è¿œå ã¢ãžã¥ãŒã«
PyTestã«ã¯å€æ°ã®ã¢ããªã³ã¢ãžã¥ãŒã«ããããŸãã
èå³ã®ããã¢ãžã¥ãŒã«ãšãã®çç±ã®ã¿ã«èšåããããšãã§ããŸãïŒã¢ãžã¥ãŒã«ã®è©³çŽ°ã«ã€ããŠã¯ãäžèšã®ãªã³ã¯ãåç §ããŠãã ããïŒïŒ
pytest-describe-å¥ã®ã¬ãã«ã®æœè±¡åãè¿œå ããŸãïŒåçã®module-function-testcaseãšããŠmodule-description-functionïŒã
pytest-instafail-ã¢ãžã¥ãŒã«ã®åºæ¬çãªåäœãå€æŽããŠãã»ãã·ã§ã³å šäœã®çµããã§ã¯ãªããå®è¡äžã«ãã¹ãŠã®ãšã©ãŒãšã¯ã©ãã·ã¥ã衚瀺ãããããã«ããŸãã
pytest-marks-ãã¹ãã«è€æ°ã®ã©ãã«ãåæã«èšå®ã§ããŸãïŒ
@pytest.mark.red @pytest.mark.green @pytest.mark.blue def some_test_method(self): .....
pytest-ordering -Runã©ãã«ã§ãã¹ããå®è¡ããé åºãæåã§èšå®ã§ããŸãã
import pytest @pytest.mark.run(order=2) def test_foo(): assert True @pytest.mark.run(order=1) def test_bar(): assert True
pytest-pep8 -pep-8èŠçŽã«æºæ ããŠãããã©ãããã¹ãã³ãŒãã確èªã§ããŸãã
pytest-smartcov-å®å šãŸãã¯éšåçãªãã¹ãã®ã³ãŒãã®ã«ãã¬ããžã確èªã§ããŸãã
pytest-timeout-ã³ãã³ãã©ã€ã³ãã©ã¡ãŒã¿ãŒãŸãã¯ç¹å¥ãªã©ãã«ã䜿çšããŠãã¿ã€ã ã¢ãŠãã§ãã¹ããå®äºã§ããŸãã
pytest-sugar -PyTestã®åºåã®å€èŠ³ãå€æŽããé²è¡ç¶æ³ããŒãšå®äºçãè¿œå ã§ããŸããããã¯å Žæã«ããããããçŸããèŠããããŸãæçã§ã¯ãããŸããã
ããšãã
PyTestã®åºæ¬çãªããã¥ã¡ã³ãã«ã¯ããã®æ¡åŒµããã䜿çšã«é¢ããå€ãã®èå³æ·±ãäŸãèšèŒãããŠããŸãããããã次åã¯ãããã«ã€ããŠã話ããããšæããŸãïŒåºæ¬çãªPyTestã®åäœã®ç®¡çïŒãã¹ãã®åéã«äœ¿çšããããã³ãã¬ãŒããã³ãã³ãã©ã€ã³ã®é«åºŠãªãªãã·ã§ã³ã®è¿œå ïŒããã©ã¡ãŒã¿ãŒåäžã®ãã¹ãã®åéããã»ã¹ã®å¶åŸ¡ïŒmetafuncãªããžã§ã¯ãïŒãªã©ã