From holger at merlinux.eu Sun May 5 15:05:35 2013 From: holger at merlinux.eu (holger krekel) Date: Sun, 5 May 2013 13:05:35 +0000 Subject: [pytest-dev] fixtures as context managers Message-ID: <20130505130535.GO30215@merlinux.eu> Hi all, after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, i finally tried to allow fixture functions to be context managers like this: @pytest.fixture def myfixture(): print "setup" yield val print "teardown" With this, you don't need to use "request.addfinalizer" - pytest does this by detecting your yield. I checked this into trunk to allow experimentation - it seems to work fine with scopes and parametrization. For pytest, it's really just a slightly different "fixture function calling" protocol, contained in this commit: https://bitbucket.org/hpk42/pytest/commits/b93ac0cdae02effaa3c136a681cc45bba757fe46 Note that i don't plan to extend this yield mechanism to parametrization as that would meanparametrization at test execution time, rather than at collection time. It would be both conceptually and implementation wise hard to do i think. The change is committed to trunk, and you can also do: pip install -i http://pypi.testrun.org -U pytest to get pytest-2.3.6.dev2 at least. feedback welcome, actually without people actively wanting it, it might be thrown out again ;) holger From nicoddemus at gmail.com Sun May 5 15:40:29 2013 From: nicoddemus at gmail.com (Bruno Oliveira) Date: Sun, 5 May 2013 10:40:29 -0300 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130505130535.GO30215@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> Message-ID: Very nice! I always thought the "request.addfinalizer" mechanism somewhat cumbersome. :) On Sun, May 5, 2013 at 10:05 AM, holger krekel wrote: > Hi all, > > after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, > i finally tried to allow fixture functions to be context managers like > this: > > @pytest.fixture > def myfixture(): > print "setup" > yield val > print "teardown" > > With this, you don't need to use "request.addfinalizer" - pytest does > this by detecting your yield. I checked this into trunk to allow > experimentation - it seems to work fine with scopes and parametrization. > For pytest, it's really just a slightly different "fixture function > calling" > protocol, contained in this commit: > > > https://bitbucket.org/hpk42/pytest/commits/b93ac0cdae02effaa3c136a681cc45bba757fe46 > > Note that i don't plan to extend this yield mechanism to parametrization > as that would meanparametrization at test execution time, rather than at > collection time. It would be both conceptually and implementation wise > hard to do i think. > > The change is committed to trunk, and you can also do: > > pip install -i http://pypi.testrun.org -U pytest > > to get pytest-2.3.6.dev2 at least. > > feedback welcome, actually without people actively > wanting it, it might be thrown out again ;) > > holger > > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas at pelme.se Mon May 6 08:50:56 2013 From: andreas at pelme.se (Andreas Pelme) Date: Mon, 6 May 2013 08:50:56 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130505130535.GO30215@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> Message-ID: <767403660C7F426CB8C7D13934E3442C@pelme.se> On Sunday 5 May 2013 at 15:05, holger krekel wrote: > after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, > i finally tried to allow fixture functions to be context managers like this: > @pytest.fixture > def myfixture(): > print "setup" > yield val > print "teardown" I just want to note that this makes it very easy to reuse/combine existing context managers as fixtures: @pytest.fixture def myfixture(): with context_manager_a(): with context_manager_b() as foo: yield foo This is my main use case for this, those kinds of setups would be cumbersome to write with addfinalizer(). > feedback welcome, actually without people actively > wanting it, it might be thrown out again ;) I just replaced my pytest-contextfixture's with this, and everything just works (that uses the above pattern)! I also changed some of my fixtures which previously used request.addfinalizer(), and it just worked too. It really makes fixture definitions very nice to read and write IMHO! Thanks a lot for looking into this Holger! I really hope it is not getting throwed out! :) Andreas From holger at merlinux.eu Thu May 9 15:56:08 2013 From: holger at merlinux.eu (holger krekel) Date: Thu, 9 May 2013 13:56:08 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: References: <20130505130535.GO30215@merlinux.eu> Message-ID: <20130509135607.GY30215@merlinux.eu> Hi Bruno, Andreas, all, yesterday in my in-house course i demonstrated the change. Somebody pointed out rightly that with 2.3.5 you are allowed to do: @pytest.fixture def genfix(): yield 1 yield 2 Which means that when you write a test you can use the fixture as a generator: def test_gen(genfix): for x in genfix: # ... This is probably used by very few people but to be on the safe side, we probably should introduce a flag like this: @pytest.fixture(ctx=True) # signal this is a context manager style fixture def fix(): yield 1 What do you think? Any other suggestions for the flag name? I'd rather not introduce something like @pytest.contextfixture because it would be a duplication of the API (scope, params). But i am open to be convinced otherwise. cheers, holger On Sun, May 05, 2013 at 10:40 -0300, Bruno Oliveira wrote: > Very nice! I always thought the "request.addfinalizer" mechanism somewhat > cumbersome. :) > > > On Sun, May 5, 2013 at 10:05 AM, holger krekel wrote: > > > Hi all, > > > > after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, > > i finally tried to allow fixture functions to be context managers like > > this: > > > > @pytest.fixture > > def myfixture(): > > print "setup" > > yield val > > print "teardown" > > > > With this, you don't need to use "request.addfinalizer" - pytest does > > this by detecting your yield. I checked this into trunk to allow > > experimentation - it seems to work fine with scopes and parametrization. > > For pytest, it's really just a slightly different "fixture function > > calling" > > protocol, contained in this commit: > > > > > > https://bitbucket.org/hpk42/pytest/commits/b93ac0cdae02effaa3c136a681cc45bba757fe46 > > > > Note that i don't plan to extend this yield mechanism to parametrization > > as that would meanparametrization at test execution time, rather than at > > collection time. It would be both conceptually and implementation wise > > hard to do i think. > > > > The change is committed to trunk, and you can also do: > > > > pip install -i http://pypi.testrun.org -U pytest > > > > to get pytest-2.3.6.dev2 at least. > > > > feedback welcome, actually without people actively > > wanting it, it might be thrown out again ;) > > > > holger > > > > > > _______________________________________________ > > Pytest-dev mailing list > > Pytest-dev at python.org > > http://mail.python.org/mailman/listinfo/pytest-dev > > From Ronny.Pfannschmidt at gmx.de Thu May 9 16:39:06 2013 From: Ronny.Pfannschmidt at gmx.de (Ronny Pfannschmidt) Date: Thu, 09 May 2013 16:39:06 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130509135607.GY30215@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> Message-ID: <518BB50A.7000301@gmx.de> Hi all, how about using proper context managers in all cases if a class that implements the context manager protocol is marked as fixture, it can be used instead so we would use @pytest.fixture @contextlib.contextmanager def foo(...): ... however the contextlib stuff might be a bit messy to deal with so a pytest.contextmanager might be necessary im -1 on the flag -- Ronny On 05/09/2013 03:56 PM, holger krekel wrote: > Hi Bruno, Andreas, all, > > yesterday in my in-house course i demonstrated the change. Somebody > pointed out rightly that with 2.3.5 you are allowed to do: > > @pytest.fixture > def genfix(): > yield 1 > yield 2 > > Which means that when you write a test you can use the fixture as a generator: > > def test_gen(genfix): > for x in genfix: > # ... > > This is probably used by very few people but to be on the safe side, > we probably should introduce a flag like this: > > @pytest.fixture(ctx=True) # signal this is a context manager style fixture > def fix(): > yield 1 > > What do you think? Any other suggestions for the flag name? > > I'd rather not introduce something like @pytest.contextfixture > because it would be a duplication of the API (scope, params). > But i am open to be convinced otherwise. > > cheers, > holger > > > > On Sun, May 05, 2013 at 10:40 -0300, Bruno Oliveira wrote: >> Very nice! I always thought the "request.addfinalizer" mechanism somewhat >> cumbersome. :) >> >> >> On Sun, May 5, 2013 at 10:05 AM, holger krekel wrote: >> >>> Hi all, >>> >>> after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, >>> i finally tried to allow fixture functions to be context managers like >>> this: >>> >>> @pytest.fixture >>> def myfixture(): >>> print "setup" >>> yield val >>> print "teardown" >>> >>> With this, you don't need to use "request.addfinalizer" - pytest does >>> this by detecting your yield. I checked this into trunk to allow >>> experimentation - it seems to work fine with scopes and parametrization. >>> For pytest, it's really just a slightly different "fixture function >>> calling" >>> protocol, contained in this commit: >>> >>> >>> https://bitbucket.org/hpk42/pytest/commits/b93ac0cdae02effaa3c136a681cc45bba757fe46 >>> >>> Note that i don't plan to extend this yield mechanism to parametrization >>> as that would meanparametrization at test execution time, rather than at >>> collection time. It would be both conceptually and implementation wise >>> hard to do i think. >>> >>> The change is committed to trunk, and you can also do: >>> >>> pip install -i http://pypi.testrun.org -U pytest >>> >>> to get pytest-2.3.6.dev2 at least. >>> >>> feedback welcome, actually without people actively >>> wanting it, it might be thrown out again ;) >>> >>> holger >>> >>> >>> _______________________________________________ >>> Pytest-dev mailing list >>> Pytest-dev at python.org >>> http://mail.python.org/mailman/listinfo/pytest-dev >>> > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev From holger at merlinux.eu Thu May 9 16:49:08 2013 From: holger at merlinux.eu (holger krekel) Date: Thu, 9 May 2013 14:49:08 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <518BB50A.7000301@gmx.de> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <518BB50A.7000301@gmx.de> Message-ID: <20130509144908.GB30215@merlinux.eu> On Thu, May 09, 2013 at 16:39 +0200, Ronny Pfannschmidt wrote: > Hi all, > > how about using proper context managers in all cases > > if a class that implements the context manager protocol is marked as > fixture, it can be used instead Today, marking a class like this: @pytest.fixture class X: will raise an error. In the future, it could look at the __init__ and regard it as the fixture. I don't think we should look at __enter__ or __exit__ there. After all the intention might be to use it like this: def test_some(X): ... with X: ... > so we would use > > @pytest.fixture > @contextlib.contextmanager > def foo(...): > ... > > however the contextlib stuff might be a bit messy to deal with > so a pytest.contextmanager might be necessary it might indeed be messy becaue contextlib returns another function. Needs to be checked. > im -1 on the flag Why? And wh is introducing a new "@fixturemanager" decorator which duplicates the API better, in your oppinion? cheers, holger > -- Ronny > > On 05/09/2013 03:56 PM, holger krekel wrote: > >Hi Bruno, Andreas, all, > > > >yesterday in my in-house course i demonstrated the change. Somebody > >pointed out rightly that with 2.3.5 you are allowed to do: > > > > @pytest.fixture > > def genfix(): > > yield 1 > > yield 2 > > > >Which means that when you write a test you can use the fixture as a generator: > > > > def test_gen(genfix): > > for x in genfix: > > # ... > > > >This is probably used by very few people but to be on the safe side, > >we probably should introduce a flag like this: > > > > @pytest.fixture(ctx=True) # signal this is a context manager style fixture > > def fix(): > > yield 1 > > > >What do you think? Any other suggestions for the flag name? > > > >I'd rather not introduce something like @pytest.contextfixture > >because it would be a duplication of the API (scope, params). > >But i am open to be convinced otherwise. > > > >cheers, > >holger > > > > > > > >On Sun, May 05, 2013 at 10:40 -0300, Bruno Oliveira wrote: > >>Very nice! I always thought the "request.addfinalizer" mechanism somewhat > >>cumbersome. :) > >> > >> > >>On Sun, May 5, 2013 at 10:05 AM, holger krekel wrote: > >> > >>>Hi all, > >>> > >>>after having been asked by Andreas Pelme and Vladimir Keleshev, repeatedly, > >>>i finally tried to allow fixture functions to be context managers like > >>>this: > >>> > >>> @pytest.fixture > >>> def myfixture(): > >>> print "setup" > >>> yield val > >>> print "teardown" > >>> > >>>With this, you don't need to use "request.addfinalizer" - pytest does > >>>this by detecting your yield. I checked this into trunk to allow > >>>experimentation - it seems to work fine with scopes and parametrization. > >>>For pytest, it's really just a slightly different "fixture function > >>>calling" > >>>protocol, contained in this commit: > >>> > >>> > >>>https://bitbucket.org/hpk42/pytest/commits/b93ac0cdae02effaa3c136a681cc45bba757fe46 > >>> > >>>Note that i don't plan to extend this yield mechanism to parametrization > >>>as that would meanparametrization at test execution time, rather than at > >>>collection time. It would be both conceptually and implementation wise > >>>hard to do i think. > >>> > >>>The change is committed to trunk, and you can also do: > >>> > >>> pip install -i http://pypi.testrun.org -U pytest > >>> > >>>to get pytest-2.3.6.dev2 at least. > >>> > >>>feedback welcome, actually without people actively > >>>wanting it, it might be thrown out again ;) > >>> > >>>holger > >>> > >>> > >>>_______________________________________________ > >>>Pytest-dev mailing list > >>>Pytest-dev at python.org > >>>http://mail.python.org/mailman/listinfo/pytest-dev > >>> > >_______________________________________________ > >Pytest-dev mailing list > >Pytest-dev at python.org > >http://mail.python.org/mailman/listinfo/pytest-dev > From holger at merlinux.eu Fri May 10 08:30:36 2013 From: holger at merlinux.eu (holger krekel) Date: Fri, 10 May 2013 06:30:36 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <518BBDF7.3070209@gmx.de> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <518BB50A.7000301@gmx.de> <20130509144908.GB30215@merlinux.eu> <518BBDF7.3070209@gmx.de> Message-ID: <20130510063036.GC30215@merlinux.eu> On Thu, May 09, 2013 at 17:17 +0200, Ronny Pfannschmidt wrote: > >>im -1 on the flag > > > >Why? And wh is introducing a new "@fixturemanager" decorator which > >duplicates the API better, in your oppinion? > > while the same api, they have different behaviours, > im really not a fan of creating boolean flags to trigger behaviours, > i'd rather see a new api that allows more kinds of fixture > setups/teardowns/parametrizations to be implemented and implementing > the ones for function/contextmanager fixtures on top of that, > so that we get a more flexible base and clear separation of behaviour Not sure what you are referring to here. API implementation layers or exposed APIs? Let's also see what Andreas and Bruno have to say on this api design topic. cheers, holger > -- Ronny > From Ronny.Pfannschmidt at gmx.de Fri May 10 09:06:21 2013 From: Ronny.Pfannschmidt at gmx.de (Ronny Pfannschmidt) Date: Fri, 10 May 2013 09:06:21 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130510063036.GC30215@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <518BB50A.7000301@gmx.de> <20130509144908.GB30215@merlinux.eu> <518BBDF7.3070209@gmx.de> <20130510063036.GC30215@merlinux.eu> Message-ID: <518C9C6D.50809@gmx.de> On 05/10/2013 08:30 AM, holger krekel wrote: > On Thu, May 09, 2013 at 17:17 +0200, Ronny Pfannschmidt wrote: >>>> im -1 on the flag >>> >>> Why? And wh is introducing a new "@fixturemanager" decorator which >>> duplicates the API better, in your oppinion? >> >> while the same api, they have different behaviours, >> im really not a fan of creating boolean flags to trigger behaviours, >> i'd rather see a new api that allows more kinds of fixture >> setups/teardowns/parametrizations to be implemented and implementing >> the ones for function/contextmanager fixtures on top of that, >> so that we get a more flexible base and clear separation of behaviour > > Not sure what you are referring to here. API implementation layers > or exposed APIs? Both actually, i think we should have an api to implement fixture parametrization, setup and teardown in a very flexible way (including parameter generators) and the simple contextmanager/function convenience on top of that however i think we should use a different api to register contextmanager based fixtures and function result based fixtures since for one the contract is -> returns the set up object and for the other the contract is -> returns a context manager that uppon entering will create set up object -- Ronny > > Let's also see what Andreas and Bruno have to say on this api design topic. > > cheers, > holger > > > >> -- Ronny >> From nicoddemus at gmail.com Fri May 10 12:55:19 2013 From: nicoddemus at gmail.com (Bruno Oliveira) Date: Fri, 10 May 2013 07:55:19 -0300 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <518C9C6D.50809@gmx.de> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <518BB50A.7000301@gmx.de> <20130509144908.GB30215@merlinux.eu> <518BBDF7.3070209@gmx.de> <20130510063036.GC30215@merlinux.eu> <518C9C6D.50809@gmx.de> Message-ID: Can you provide some examples of what you mean? Just for illustration purposes, not actual an api proposal. On Fri, May 10, 2013 at 4:06 AM, Ronny Pfannschmidt < Ronny.Pfannschmidt at gmx.de> wrote: > > > On 05/10/2013 08:30 AM, holger krekel wrote: > >> On Thu, May 09, 2013 at 17:17 +0200, Ronny Pfannschmidt wrote: >> >>> im -1 on the flag >>>>> >>>> >>>> Why? And wh is introducing a new "@fixturemanager" decorator which >>>> duplicates the API better, in your oppinion? >>>> >>> >>> while the same api, they have different behaviours, >>> im really not a fan of creating boolean flags to trigger behaviours, >>> i'd rather see a new api that allows more kinds of fixture >>> setups/teardowns/**parametrizations to be implemented and implementing >>> the ones for function/contextmanager fixtures on top of that, >>> so that we get a more flexible base and clear separation of behaviour >>> >> >> Not sure what you are referring to here. API implementation layers >> or exposed APIs? >> > > Both actually, > > i think we should have an api to implement fixture parametrization, setup > and teardown in a very flexible way (including parameter generators) > and the simple contextmanager/function convenience on top of that > > however i think we should use a different api to register contextmanager > based fixtures and function result based fixtures > > since for one the contract is > > -> returns the set up object > > and for the other the contract is > > -> returns a context manager that uppon entering will create set up object > > -- Ronny > > > > >> Let's also see what Andreas and Bruno have to say on this api design >> topic. >> >> cheers, >> holger >> >> >> >> -- Ronny >>> >>> > ______________________________**_________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/**mailman/listinfo/pytest-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From yusuf.mahdi at gmail.com Tue May 21 17:52:41 2013 From: yusuf.mahdi at gmail.com (Mahdi Yusuf) Date: Tue, 21 May 2013 11:52:41 -0400 Subject: [pytest-dev] pytest-django Message-ID: Hi: I am having issues running pytest-django without inhertiting form Django Testcase, I am also pretty sure this is what is causing the issue to do deal with the database being recreated every time. I would like to reuse my database between test suite runs at least while in development. Thoughts? I am new to using pytest, so any ignorance here in inadvertent. -- Mahdi Yusuf -------------- next part -------------- An HTML attachment was scrubbed... URL: From flub at devork.be Wed May 22 10:11:08 2013 From: flub at devork.be (Floris Bruynooghe) Date: Wed, 22 May 2013 09:11:08 +0100 Subject: [pytest-dev] pytest-django In-Reply-To: References: Message-ID: On 21 May 2013 16:52, Mahdi Yusuf wrote: > I am having issues running pytest-django without inhertiting form Django > Testcase You'll have to be a little more specific about what your issue is... > I am also pretty sure this is what is causing the issue to do deal > with the database being recreated every time. I would like to reuse my > database between test suite runs at least while in development. Are you using --reuse-db? Check out the docs on reusing the database, they might help: http://pytest-django.readthedocs.org/en/latest/database.html -- Debian GNU/Linux -- The Power of Freedom www.debian.org | www.gnu.org | www.kernel.org From Shujie.Liao at safenet-inc.com Wed May 22 19:29:06 2013 From: Shujie.Liao at safenet-inc.com (Liao, Shujie) Date: Wed, 22 May 2013 13:29:06 -0400 Subject: [pytest-dev] Question: How to inject an external id to each pytest test case? Message-ID: Hi, We want to update the test result automatically from pytest to a web application, we run pytest from Jenkins currently , and our plan is to run a script as post step to make this happen. We have thousands of test cases in an excel file, and now they were all imported to the web tool(the tool generated a unique id for each test), the problem is, the test name in web tool and from pytest are not exactly the same, and so far we don't have plan as well as hands to make them the same.... Our thoughts is to pass the test id to each pytest test case, so that from output result, the id becomes part of test name, then we have the map from pytest test cases to the web tool. We are looking for a feature from pytest, which can help achieve following requirements: 1. Can easily inject an external id to each test case, both non-parameterized and parameterized test. 2. The injected id will be part of test name in output 3. Without impacting existing parameterized mechanism (or need minor modification is fine) For parameterized test, I tried to use @pytest.mark.parametrize(('name'),create_data,ids=['DEMO-1','DEMO-2']), of them, "DEMO-1" and "DEMO-2" are ids from the test cases in web tool, I got this as output: platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items However, for non-parameterized test, seems this solution is less decent, although we can pass the parameter without using it, still seems ugly... Is there a better way we can do this? The information contained in this electronic mail transmission may be privileged and confidential, and therefore, protected from disclosure. If you have received this communication in error, please notify us immediately by replying to this message and deleting it from your computer without copying or disclosing it. -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at merlinux.eu Wed May 22 20:01:08 2013 From: holger at merlinux.eu (holger krekel) Date: Wed, 22 May 2013 18:01:08 +0000 Subject: [pytest-dev] Question: How to inject an external id to each pytest test case? In-Reply-To: References: Message-ID: <20130522180108.GK7789@merlinux.eu> Hi Shujie, On Wed, May 22, 2013 at 13:29 -0400, Liao, Shujie wrote: > Hi, > > We want to update the test result automatically from pytest to a web application, we run pytest from Jenkins currently , and our plan is to run a script as post step to make this happen. > > We have thousands of test cases in an excel file, and now they were all imported to the web tool(the tool generated a unique id for each test), the problem is, the test name in web tool and from pytest are not exactly the same, and so far we don't have plan as well as hands to make them the same.... > > Our thoughts is to pass the test id to each pytest test case, so that from output result, the id becomes part of test name, then we have the map from pytest test cases to the web tool. > > We are looking for a feature from pytest, which can help achieve following requirements: > > 1. Can easily inject an external id to each test case, both non-parameterized and parameterized test. > > 2. The injected id will be part of test name in output > > 3. Without impacting existing parameterized mechanism (or need minor modification is fine) > > For parameterized test, I tried to use @pytest.mark.parametrize(('name'),create_data,ids=['DEMO-1','DEMO-2']), of them, "DEMO-1" and "DEMO-2" are ids from the test cases in web tool, I got this as output: > > > platform linux2 -- Python 2.7.3 -- pytest-2.3.4 > collected 2 items > > > > > > > However, for non-parameterized test, seems this solution is less decent, although we can pass the parameter without using it, still seems ugly... > > > > Is there a better way we can do this? It all depends a bit but you might look into marking your tests like this:: # content of test_file.py import pytest @pytest.mark.id("demo1") def test_hello(): pass @pytest.mark.id("demo2") def test_world(): pass and then implementing a hook which transfers the marks as part of the test id: # content of conftest.py def pytest_collection_modifyitems(items): for item in items: id = item.keywords.get("id", None) if id is not None and getattr(id, "args", None): item.name += "[%s]" % id.args[0] which when run gives this: $ py.test -v test_file.py test_file.py:4: test_hello[demo1] PASSED test_file.py:8: test_world[demo2] PASSED Of course, you could also have a different way to configure the names in the conftest hook, e.g. by reading a file which maps test ids to names or so. HTH, holger > > > The information contained in this electronic mail transmission > may be privileged and confidential, and therefore, protected > from disclosure. If you have received this communication in > error, please notify us immediately by replying to this > message and deleting it from your computer without copying > or disclosing it. > > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev From lpbrac at dolby.com Wed May 22 21:05:02 2013 From: lpbrac at dolby.com (Brack, Laurent P.) Date: Wed, 22 May 2013 19:05:02 +0000 Subject: [pytest-dev] Question: How to inject an external id to each pytest test case? In-Reply-To: <20130522180108.GK7789@merlinux.eu> Message-ID: Hi Shujie, Is the web application "Testlink" by any chance (the ID sure do look like TL id's)? If so, we have a pytest plugin we have been using internally for a couple of year already and I should be able to get (internal) permission to release it (it is thoroughly documented). Otherwise, what Holger is suggesting is the approach we have taken for our implementation (we have a pytest.testlink marker for that purpose). Best /Laurent On 5/22/13 11:01 AM, "holger krekel" wrote: >Hi Shujie, > >On Wed, May 22, 2013 at 13:29 -0400, Liao, Shujie wrote: >> Hi, >> >> We want to update the test result automatically from pytest to a web >>application, we run pytest from Jenkins currently , and our plan is to >>run a script as post step to make this happen. >> >> We have thousands of test cases in an excel file, and now they were all >>imported to the web tool(the tool generated a unique id for each test), >>the problem is, the test name in web tool and from pytest are not >>exactly the same, and so far we don't have plan as well as hands to make >>them the same.... >> >> Our thoughts is to pass the test id to each pytest test case, so that >>from output result, the id becomes part of test name, then we have the >>map from pytest test cases to the web tool. >> >> We are looking for a feature from pytest, which can help achieve >>following requirements: >> >> 1. Can easily inject an external id to each test case, both >>non-parameterized and parameterized test. >> >> 2. The injected id will be part of test name in output >> >> 3. Without impacting existing parameterized mechanism (or need >>minor modification is fine) >> >> For parameterized test, I tried to use >>@pytest.mark.parametrize(('name'),create_data,ids=['DEMO-1','DEMO-2']), >>of them, "DEMO-1" and "DEMO-2" are ids from the test cases in web tool, >>I got this as output: >> >> >> platform linux2 -- Python 2.7.3 -- pytest-2.3.4 >> collected 2 items >> >> >> >> >> >> >> However, for non-parameterized test, seems this solution is less >>decent, although we can pass the parameter without using it, still seems >>ugly... >> >> >> >> Is there a better way we can do this? > >It all depends a bit but you might look into marking your tests like >this:: > > # content of test_file.py > > import pytest > > @pytest.mark.id("demo1") > def test_hello(): > pass > > @pytest.mark.id("demo2") > def test_world(): > pass > > >and then implementing a hook which transfers the marks as part of the >test id: > > # content of conftest.py > > def pytest_collection_modifyitems(items): > for item in items: > id = item.keywords.get("id", None) > if id is not None and getattr(id, "args", None): > item.name += "[%s]" % id.args[0] > >which when run gives this: > > $ py.test -v test_file.py > > test_file.py:4: test_hello[demo1] PASSED > test_file.py:8: test_world[demo2] PASSED > >Of course, you could also have a different way to configure >the names in the conftest hook, e.g. by reading a file which >maps test ids to names or so. > >HTH, >holger > > > >> >> >> The information contained in this electronic mail transmission >> may be privileged and confidential, and therefore, protected >> from disclosure. If you have received this communication in >> error, please notify us immediately by replying to this >> message and deleting it from your computer without copying >> or disclosing it. >> >> > >> _______________________________________________ >> Pytest-dev mailing list >> Pytest-dev at python.org >> http://mail.python.org/mailman/listinfo/pytest-dev > >_______________________________________________ >Pytest-dev mailing list >Pytest-dev at python.org >http://mail.python.org/mailman/listinfo/pytest-dev From Shujie.Liao at safenet-inc.com Wed May 22 21:09:52 2013 From: Shujie.Liao at safenet-inc.com (Liao, Shujie) Date: Wed, 22 May 2013 15:09:52 -0400 Subject: [pytest-dev] Question: How to inject an external id to each pytest test case? In-Reply-To: References: <20130522180108.GK7789@merlinux.eu> Message-ID: @holger: the way to implement a hook seems fine, I'll try it, thanks! @Laurent P: it's a jira plugin - synapseRT, we used testlink before, now switch to Jira. -----Original Message----- From: Brack, Laurent P. [mailto:lpbrac at dolby.com] Sent: May-22-13 3:05 PM To: Liao, Shujie Cc: pytest-dev at python.org Subject: Re: [pytest-dev] Question: How to inject an external id to each pytest test case? Hi Shujie, Is the web application "Testlink" by any chance (the ID sure do look like TL id's)? If so, we have a pytest plugin we have been using internally for a couple of year already and I should be able to get (internal) permission to release it (it is thoroughly documented). Otherwise, what Holger is suggesting is the approach we have taken for our implementation (we have a pytest.testlink marker for that purpose). Best /Laurent On 5/22/13 11:01 AM, "holger krekel" wrote: >Hi Shujie, > >On Wed, May 22, 2013 at 13:29 -0400, Liao, Shujie wrote: >> Hi, >> >> We want to update the test result automatically from pytest to a web >>application, we run pytest from Jenkins currently , and our plan is to >>run a script as post step to make this happen. >> >> We have thousands of test cases in an excel file, and now they were >>all imported to the web tool(the tool generated a unique id for each >>test), the problem is, the test name in web tool and from pytest are >>not exactly the same, and so far we don't have plan as well as hands >>to make them the same.... >> >> Our thoughts is to pass the test id to each pytest test case, so that >>from output result, the id becomes part of test name, then we have the >>map from pytest test cases to the web tool. >> >> We are looking for a feature from pytest, which can help achieve >>following requirements: >> >> 1. Can easily inject an external id to each test case, both >>non-parameterized and parameterized test. >> >> 2. The injected id will be part of test name in output >> >> 3. Without impacting existing parameterized mechanism (or need >>minor modification is fine) >> >> For parameterized test, I tried to use >>@pytest.mark.parametrize(('name'),create_data,ids=['DEMO-1','DEMO-2']) >>, of them, "DEMO-1" and "DEMO-2" are ids from the test cases in web >>tool, I got this as output: >> >> >> platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items >> >> >> >> >> >> >> However, for non-parameterized test, seems this solution is less >>decent, although we can pass the parameter without using it, still >>seems ugly... >> >> >> >> Is there a better way we can do this? > >It all depends a bit but you might look into marking your tests like >this:: > > # content of test_file.py > > import pytest > > @pytest.mark.id("demo1") > def test_hello(): > pass > > @pytest.mark.id("demo2") > def test_world(): > pass > > >and then implementing a hook which transfers the marks as part of the >test id: > > # content of conftest.py > > def pytest_collection_modifyitems(items): > for item in items: > id = item.keywords.get("id", None) > if id is not None and getattr(id, "args", None): > item.name += "[%s]" % id.args[0] > >which when run gives this: > > $ py.test -v test_file.py > > test_file.py:4: test_hello[demo1] PASSED > test_file.py:8: test_world[demo2] PASSED > >Of course, you could also have a different way to configure the names >in the conftest hook, e.g. by reading a file which maps test ids to >names or so. > >HTH, >holger > > > >> >> >> The information contained in this electronic mail transmission may be >> privileged and confidential, and therefore, protected from >> disclosure. If you have received this communication in error, please >> notify us immediately by replying to this message and deleting it >> from your computer without copying or disclosing it. >> >> > >> _______________________________________________ >> Pytest-dev mailing list >> Pytest-dev at python.org >> http://mail.python.org/mailman/listinfo/pytest-dev > >_______________________________________________ >Pytest-dev mailing list >Pytest-dev at python.org >http://mail.python.org/mailman/listinfo/pytest-dev The information contained in this electronic mail transmission may be privileged and confidential, and therefore, protected from disclosure. If you have received this communication in error, please notify us immediately by replying to this message and deleting it from your computer without copying or disclosing it. From andreas at pelme.se Fri May 24 16:36:27 2013 From: andreas at pelme.se (Andreas Pelme) Date: Fri, 24 May 2013 16:36:27 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130509135607.GY30215@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> Message-ID: On Thursday 9 May 2013 at 15:56, holger krekel wrote: > This is probably used by very few people but to be on the safe side, > we probably should introduce a flag like this: > > @pytest.fixture(ctx=True) # signal this is a context manager style fixture > def fix(): > yield 1 > > What do you think? Any other suggestions for the flag name? > > I'd rather not introduce something like @pytest.contextfixture > because it would be a duplication of the API (scope, params). > But i am open to be convinced otherwise. I agree that another API like contextfixture should be avoided. We had a short discussion on IRC about this, Holger had the idea of doing the opposite if ctx=True - a new default argument "yielding=False" which would make it possible to restore the old behavior by putting yielding=True on fixtures that would be affected by this. A fixture that is a generator that currently looks like this @pytest.fixture def fix(): yield 1 yield 2 Would then have to be changed to @pytest.fixture(yielding=True) def fix(): yield 1 yield 2 This is backward incompatible, but given that it seems questionable if "generator fixtures" useful/is used, with a note in the release notes and documentation I think this could be a good compromise. I will be happy to give this a try if it is decided this could be a good approach! Cheers Andreas From harro.vanderklauw at paylogic.eu Fri May 24 16:50:12 2013 From: harro.vanderklauw at paylogic.eu (Harro van der Klauw) Date: Fri, 24 May 2013 16:50:12 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> Message-ID: As long as it throws an error hinting that you might need yielding=True it should be obvious on how to fix the backwards incompatibility issue as soon as you run your tests. I don't see a big problem with this, updating of a requirement is something that you should never do automatically. Cheers, Harro On 24 May 2013 16:36, Andreas Pelme wrote: > On Thursday 9 May 2013 at 15:56, holger krekel wrote: > > This is probably used by very few people but to be on the safe side, > > we probably should introduce a flag like this: > > > > @pytest.fixture(ctx=True) # signal this is a context manager style > fixture > > def fix(): > > yield 1 > > > > What do you think? Any other suggestions for the flag name? > > > > I'd rather not introduce something like @pytest.contextfixture > > because it would be a duplication of the API (scope, params). > > But i am open to be convinced otherwise. > > I agree that another API like contextfixture should be avoided. > > We had a short discussion on IRC about this, Holger had the idea of doing > the opposite if ctx=True - a new default argument "yielding=False" which > would make it possible to restore the old behavior by putting yielding=True > on fixtures that would be affected by this. > > A fixture that is a generator that currently looks like this > > @pytest.fixture > def fix(): > yield 1 > yield 2 > > Would then have to be changed to > > @pytest.fixture(yielding=True) > def fix(): > yield 1 > yield 2 > > This is backward incompatible, but given that it seems questionable if > "generator fixtures" useful/is used, with a note in the release notes and > documentation I think this could be a good compromise. > > I will be happy to give this a try if it is decided this could be a good > approach! > > Cheers > Andreas > > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas at pelme.se Fri May 24 17:02:10 2013 From: andreas at pelme.se (Andreas Pelme) Date: Fri, 24 May 2013 17:02:10 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> Message-ID: <7034D89ED8094C098FE011BCB2091B7F@pelme.se> On Friday 24 May 2013 at 16:50, Harro van der Klauw wrote: > As long as it throws an error hinting that you might need yielding=True it should be obvious on how to fix > the backwards incompatibility issue as soon as you run your tests. > > I don't see a big problem with this, updating of a requirement is something that you should never do automatically. Good point, the error that is thrown when more than one value is yielded should include a note about yielding=True. Fixtures that only yield one value cannot really be detected and raise an explicit error. Such tests would very likely fail since the fixture value will be a yielded value rather than the generator itself. I think it will be hard to put a helpful error message there since it will just look like an uncaught exception/assertion failure, but at least the problem will not pass without notice. Cheers Andreas From holger at merlinux.eu Fri May 24 17:07:08 2013 From: holger at merlinux.eu (holger krekel) Date: Fri, 24 May 2013 15:07:08 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> Message-ID: <20130524150708.GS7789@merlinux.eu> On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > As long as it throws an error hinting that you might need yielding=True it > should be obvious on how to fix > the backwards incompatibility issue as soon as you run your tests. We cannot easily throw an error with a hint. Consider this example: import pytest @pytest.fixture def fix(): yield 1 yield 2 def test_fix(fix): for x in fix: assert x < 3 This runs fine on pytest-2.3.5. On trunk it gives this error: ... fix = 1 def test_fix(fix): > for x in fix: assert x < 3 E TypeError: 'int' object is not iterable I've never written or seen somebody writing such a generator fixture, though. And what you would need to do is rewrite the fixture: @pytest.fixture def fix(): def gen(): yield 1 yield 2 return gen() Then again, when i first saw the contextlib.contextmanager decorator i found it not very intuitive. Did anyone? It looks like a hack. >From that angle i'd rather go for requiring "contextyield=True" or @pytest.contextfixture because that can be looked up in documentation and thus is easier to read for people not familiar with yields/contextlib. best, holger > I don't see a big problem with this, updating of a requirement is something > that you should never do automatically. > > Cheers, > Harro > > > > On 24 May 2013 16:36, Andreas Pelme wrote: > > > On Thursday 9 May 2013 at 15:56, holger krekel wrote: > > > This is probably used by very few people but to be on the safe side, > > > we probably should introduce a flag like this: > > > > > > @pytest.fixture(ctx=True) # signal this is a context manager style > > fixture > > > def fix(): > > > yield 1 > > > > > > What do you think? Any other suggestions for the flag name? > > > > > > I'd rather not introduce something like @pytest.contextfixture > > > because it would be a duplication of the API (scope, params). > > > But i am open to be convinced otherwise. > > > > I agree that another API like contextfixture should be avoided. > > > > We had a short discussion on IRC about this, Holger had the idea of doing > > the opposite if ctx=True - a new default argument "yielding=False" which > > would make it possible to restore the old behavior by putting yielding=True > > on fixtures that would be affected by this. > > > > A fixture that is a generator that currently looks like this > > > > @pytest.fixture > > def fix(): > > yield 1 > > yield 2 > > > > Would then have to be changed to > > > > @pytest.fixture(yielding=True) > > def fix(): > > yield 1 > > yield 2 > > > > This is backward incompatible, but given that it seems questionable if > > "generator fixtures" useful/is used, with a note in the release notes and > > documentation I think this could be a good compromise. > > > > I will be happy to give this a try if it is decided this could be a good > > approach! > > > > Cheers > > Andreas > > > > > > _______________________________________________ > > Pytest-dev mailing list > > Pytest-dev at python.org > > http://mail.python.org/mailman/listinfo/pytest-dev > > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev From nicoddemus at gmail.com Fri May 24 23:13:18 2013 From: nicoddemus at gmail.com (Bruno Oliveira) Date: Fri, 24 May 2013 18:13:18 -0300 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130524150708.GS7789@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> Message-ID: In light of the examples, IMHO, I agree that fixtures being explicit about using yield as context-managers is preferable. I like @pytest.contextfixture, it is easy to look-up and understand since it mimics what we already have in contextlib. On Fri, May 24, 2013 at 12:07 PM, holger krekel wrote: > On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > > As long as it throws an error hinting that you might need yielding=True > it > > should be obvious on how to fix > > the backwards incompatibility issue as soon as you run your tests. > > We cannot easily throw an error with a hint. Consider this example: > > import pytest > > @pytest.fixture > def fix(): > yield 1 > yield 2 > > def test_fix(fix): > for x in fix: > assert x < 3 > > This runs fine on pytest-2.3.5. On trunk it gives this error: > > ... > > fix = 1 > > def test_fix(fix): > > for x in fix: > assert x < 3 > E TypeError: 'int' object is not iterable > > I've never written or seen somebody writing such a generator fixture, > though. > And what you would need to do is rewrite the fixture: > > @pytest.fixture > def fix(): > def gen(): > yield 1 > yield 2 > return gen() > > Then again, when i first saw the contextlib.contextmanager decorator > i found it not very intuitive. Did anyone? It looks like a hack. > From that angle i'd rather go for requiring "contextyield=True" or > @pytest.contextfixture because that can be looked up in documentation > and thus is easier to read for people not familiar with yields/contextlib. > > best, > holger > > > I don't see a big problem with this, updating of a requirement is > something > > that you should never do automatically. > > > > Cheers, > > Harro > > > > > > > > On 24 May 2013 16:36, Andreas Pelme wrote: > > > > > On Thursday 9 May 2013 at 15:56, holger krekel wrote: > > > > This is probably used by very few people but to be on the safe side, > > > > we probably should introduce a flag like this: > > > > > > > > @pytest.fixture(ctx=True) # signal this is a context manager style > > > fixture > > > > def fix(): > > > > yield 1 > > > > > > > > What do you think? Any other suggestions for the flag name? > > > > > > > > I'd rather not introduce something like @pytest.contextfixture > > > > because it would be a duplication of the API (scope, params). > > > > But i am open to be convinced otherwise. > > > > > > I agree that another API like contextfixture should be avoided. > > > > > > We had a short discussion on IRC about this, Holger had the idea of > doing > > > the opposite if ctx=True - a new default argument "yielding=False" > which > > > would make it possible to restore the old behavior by putting > yielding=True > > > on fixtures that would be affected by this. > > > > > > A fixture that is a generator that currently looks like this > > > > > > @pytest.fixture > > > def fix(): > > > yield 1 > > > yield 2 > > > > > > Would then have to be changed to > > > > > > @pytest.fixture(yielding=True) > > > def fix(): > > > yield 1 > > > yield 2 > > > > > > This is backward incompatible, but given that it seems questionable if > > > "generator fixtures" useful/is used, with a note in the release notes > and > > > documentation I think this could be a good compromise. > > > > > > I will be happy to give this a try if it is decided this could be a > good > > > approach! > > > > > > Cheers > > > Andreas > > > > > > > > > _______________________________________________ > > > Pytest-dev mailing list > > > Pytest-dev at python.org > > > http://mail.python.org/mailman/listinfo/pytest-dev > > > > > > _______________________________________________ > > Pytest-dev mailing list > > Pytest-dev at python.org > > http://mail.python.org/mailman/listinfo/pytest-dev > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jaraco at jaraco.com Sat May 25 16:40:30 2013 From: jaraco at jaraco.com (Jason R. Coombs) Date: Sat, 25 May 2013 14:40:30 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> Message-ID: <2c906a6cd8cb4e73be047d9dbedbf10e@BLUPR06MB003.namprd06.prod.outlook.com> May I suggest an alternate idea: @pytest.fixture.context(.) def func(): . Or @pytest.fixture.yielding(.) def func(): . Depending on which mode is not supported by fixture directly. Then, the decorator can take the same signature as the natural usage (@pytest.fixture), but alter the handling of a generator appropriately. It can be thought of as an alternate constructor for the same fixture factory. It provides a nice, namespaced name and doesn't threaten to pollute the pytest namespace with a proliferation of fixture variants. From: Pytest-dev [mailto:pytest-dev-bounces+jaraco=jaraco.com at python.org] On Behalf Of Bruno Oliveira Sent: Friday, 24 May, 2013 17:13 To: holger krekel; Harro van der Klauw; Andreas Pelme; pytest-dev at python.org Subject: Re: [pytest-dev] fixtures as context managers In light of the examples, IMHO, I agree that fixtures being explicit about using yield as context-managers is preferable. I like @pytest.contextfixture, it is easy to look-up and understand since it mimics what we already have in contextlib. On Fri, May 24, 2013 at 12:07 PM, holger krekel > wrote: On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > As long as it throws an error hinting that you might need yielding=True it > should be obvious on how to fix > the backwards incompatibility issue as soon as you run your tests. We cannot easily throw an error with a hint. Consider this example: import pytest @pytest.fixture def fix(): yield 1 yield 2 def test_fix(fix): for x in fix: assert x < 3 This runs fine on pytest-2.3.5. On trunk it gives this error: ... fix = 1 def test_fix(fix): > for x in fix: assert x < 3 E TypeError: 'int' object is not iterable I've never written or seen somebody writing such a generator fixture, though. And what you would need to do is rewrite the fixture: @pytest.fixture def fix(): def gen(): yield 1 yield 2 return gen() Then again, when i first saw the contextlib.contextmanager decorator i found it not very intuitive. Did anyone? It looks like a hack. >From that angle i'd rather go for requiring "contextyield=True" or @pytest.contextfixture because that can be looked up in documentation and thus is easier to read for people not familiar with yields/contextlib. best, holger > I don't see a big problem with this, updating of a requirement is something > that you should never do automatically. > > Cheers, > Harro > > > > On 24 May 2013 16:36, Andreas Pelme > wrote: > > > On Thursday 9 May 2013 at 15:56, holger krekel wrote: > > > This is probably used by very few people but to be on the safe side, > > > we probably should introduce a flag like this: > > > > > > @pytest.fixture(ctx=True) # signal this is a context manager style > > fixture > > > def fix(): > > > yield 1 > > > > > > What do you think? Any other suggestions for the flag name? > > > > > > I'd rather not introduce something like @pytest.contextfixture > > > because it would be a duplication of the API (scope, params). > > > But i am open to be convinced otherwise. > > > > I agree that another API like contextfixture should be avoided. > > > > We had a short discussion on IRC about this, Holger had the idea of doing > > the opposite if ctx=True - a new default argument "yielding=False" which > > would make it possible to restore the old behavior by putting yielding=True > > on fixtures that would be affected by this. > > > > A fixture that is a generator that currently looks like this > > > > @pytest.fixture > > def fix(): > > yield 1 > > yield 2 > > > > Would then have to be changed to > > > > @pytest.fixture(yielding=True) > > def fix(): > > yield 1 > > yield 2 > > > > This is backward incompatible, but given that it seems questionable if > > "generator fixtures" useful/is used, with a note in the release notes and > > documentation I think this could be a good compromise. > > > > I will be happy to give this a try if it is decided this could be a good > > approach! > > > > Cheers > > Andreas > > > > > > _______________________________________________ > > Pytest-dev mailing list > > Pytest-dev at python.org > > http://mail.python.org/mailman/listinfo/pytest-dev > > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev _______________________________________________ Pytest-dev mailing list Pytest-dev at python.org http://mail.python.org/mailman/listinfo/pytest-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 6572 bytes Desc: not available URL: From holger at merlinux.eu Sun May 26 13:50:24 2013 From: holger at merlinux.eu (holger krekel) Date: Sun, 26 May 2013 11:50:24 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <2c906a6cd8cb4e73be047d9dbedbf10e@BLUPR06MB003.namprd06.prod.outlook.com> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> <2c906a6cd8cb4e73be047d9dbedbf10e@BLUPR06MB003.namprd06.prod.outlook.com> Message-ID: <20130526115024.GV7789@merlinux.eu> Hi Jason, (your post contains a bit many blank lines, btw, deleting them :) On Sat, May 25, 2013 at 14:40 +0000, Jason R. Coombs wrote: > May I suggest an alternate idea: > > @pytest.fixture.context(.) > > def func(): > . > > Or > > @pytest.fixture.yielding(.) > > def func(): > . > > Depending on which mode is not supported by fixture directly. > > Then, the decorator can take the same signature as the natural usage > (@pytest.fixture), but alter the handling of a generator appropriately. It > can be thought of as an alternate constructor for the same fixture factory. > It provides a nice, namespaced name and doesn't threaten to pollute the > pytest namespace with a proliferation of fixture variants. Not cramming the pytest.* is a goal i share but i am not sure about this suggestion. The "idiomatic" way to introduce a decorator variant in Python is adding a keyword argument or a new name. Your suggested syntax reminds of what one does for classes, i.e. providing classmethods for alternate constructors. But i haven't seen it anywhere for decorators, did you? best, holger > > From: Pytest-dev [mailto:pytest-dev-bounces+jaraco=jaraco.com at python.org] On > Behalf Of Bruno Oliveira > Sent: Friday, 24 May, 2013 17:13 > To: holger krekel; Harro van der Klauw; Andreas Pelme; pytest-dev at python.org > Subject: Re: [pytest-dev] fixtures as context managers > > > > In light of the examples, IMHO, I agree that fixtures being explicit about > using yield as context-managers is preferable. > > > > I like @pytest.contextfixture, it is easy to look-up and understand since it > mimics what we already have in contextlib. > > > > > > > > On Fri, May 24, 2013 at 12:07 PM, holger krekel > wrote: > > On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > > As long as it throws an error hinting that you might need yielding=True it > > should be obvious on how to fix > > the backwards incompatibility issue as soon as you run your tests. > > We cannot easily throw an error with a hint. Consider this example: > > import pytest > > > @pytest.fixture > def fix(): > yield 1 > yield 2 > > def test_fix(fix): > for x in fix: > assert x < 3 > > This runs fine on pytest-2.3.5. On trunk it gives this error: > > ... > > fix = 1 > > def test_fix(fix): > > for x in fix: > assert x < 3 > E TypeError: 'int' object is not iterable > > I've never written or seen somebody writing such a generator fixture, > though. > And what you would need to do is rewrite the fixture: > > @pytest.fixture > def fix(): > def gen(): > yield 1 > yield 2 > return gen() > > Then again, when i first saw the contextlib.contextmanager decorator > i found it not very intuitive. Did anyone? It looks like a hack. > >From that angle i'd rather go for requiring "contextyield=True" or > @pytest.contextfixture because that can be looked up in documentation > and thus is easier to read for people not familiar with yields/contextlib. > > best, > holger > > > > I don't see a big problem with this, updating of a requirement is > something > > that you should never do automatically. > > > > Cheers, > > Harro > > > > > > > > On 24 May 2013 16:36, Andreas Pelme > wrote: > > > > > On Thursday 9 May 2013 at 15:56, holger krekel wrote: > > > > This is probably used by very few people but to be on the safe side, > > > > we probably should introduce a flag like this: > > > > > > > > @pytest.fixture(ctx=True) # signal this is a context manager style > > > fixture > > > > def fix(): > > > > yield 1 > > > > > > > > What do you think? Any other suggestions for the flag name? > > > > > > > > I'd rather not introduce something like @pytest.contextfixture > > > > because it would be a duplication of the API (scope, params). > > > > But i am open to be convinced otherwise. > > > > > > I agree that another API like contextfixture should be avoided. > > > > > > We had a short discussion on IRC about this, Holger had the idea of > doing > > > the opposite if ctx=True - a new default argument "yielding=False" which > > > would make it possible to restore the old behavior by putting > yielding=True > > > on fixtures that would be affected by this. > > > > > > A fixture that is a generator that currently looks like this > > > > > > @pytest.fixture > > > def fix(): > > > yield 1 > > > yield 2 > > > > > > Would then have to be changed to > > > > > > @pytest.fixture(yielding=True) > > > def fix(): > > > yield 1 > > > yield 2 > > > > > > This is backward incompatible, but given that it seems questionable if > > > "generator fixtures" useful/is used, with a note in the release notes > and > > > documentation I think this could be a good compromise. > > > > > > I will be happy to give this a try if it is decided this could be a good > > > approach! > > > > > > Cheers > > > Andreas > > > > > > > > > _______________________________________________ > > > Pytest-dev mailing list > > > Pytest-dev at python.org > > > http://mail.python.org/mailman/listinfo/pytest-dev > > > > > > _______________________________________________ > > Pytest-dev mailing list > > Pytest-dev at python.org > > http://mail.python.org/mailman/listinfo/pytest-dev > > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev > > > From jaraco at jaraco.com Sun May 26 17:37:32 2013 From: jaraco at jaraco.com (Jason R. Coombs) Date: Sun, 26 May 2013 15:37:32 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130526115024.GV7789@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> <2c906a6cd8cb4e73be047d9dbedbf10e@BLUPR06MB003.namprd06.prod.outlook.com> <20130526115024.GV7789@merlinux.eu> Message-ID: <2D1A8525-9F51-4564-BD80-C5A39EC11224@jaraco.com> No. I haven't seen that syntax much if at all. I suggest it because it appeals to my aesthetic. I'm not sure the distinction between class and decorator is so clear. After all, a decorator is just a callable with a particular signature. I haven't considered the implementation, but I imagine pytest.fixture could in fact be a class if you wanted it to be. Even if fixture is only a factory function, it's conceivable that the alternate function could be appended as an attribute: def fixture(...): # primary behavior def _yielding_fixture(*args, **kwargs): # wrap or alter behavior of fixture(*args, **kwargs) fixture.yielding = _yielding_fixture I agree the implementation is a little clumsy, but I would be inclined to accept a little bit of implementation cruft for a nicer exposed API. That said, I'm not trying to convince, but only to share. If you don't love the idea, I won't be offended if you don't incorporate it. Sent from Earth On May 26, 2013, at 7:52, "holger krekel" wrote: > Hi Jason, > > (your post contains a bit many blank lines, btw, deleting them :) > > On Sat, May 25, 2013 at 14:40 +0000, Jason R. Coombs wrote: >> May I suggest an alternate idea: >> >> @pytest.fixture.context(.) >> >> def func(): >> . >> >> Or >> >> @pytest.fixture.yielding(.) >> >> def func(): >> . >> >> Depending on which mode is not supported by fixture directly. >> >> Then, the decorator can take the same signature as the natural usage >> (@pytest.fixture), but alter the handling of a generator appropriately. It >> can be thought of as an alternate constructor for the same fixture factory. >> It provides a nice, namespaced name and doesn't threaten to pollute the >> pytest namespace with a proliferation of fixture variants. > > Not cramming the pytest.* is a goal i share but i am not sure about > this suggestion. The "idiomatic" way to introduce a decorator variant > in Python is adding a keyword argument or a new name. > > Your suggested syntax reminds of what one does for classes, i.e. providing > classmethods for alternate constructors. But i haven't seen it anywhere > for decorators, did you? > > best, > holger > >> >> From: Pytest-dev [mailto:pytest-dev-bounces+jaraco=jaraco.com at python.org] On >> Behalf Of Bruno Oliveira >> Sent: Friday, 24 May, 2013 17:13 >> To: holger krekel; Harro van der Klauw; Andreas Pelme; pytest-dev at python.org >> Subject: Re: [pytest-dev] fixtures as context managers >> >> >> >> In light of the examples, IMHO, I agree that fixtures being explicit about >> using yield as context-managers is preferable. >> >> >> >> I like @pytest.contextfixture, it is easy to look-up and understand since it >> mimics what we already have in contextlib. >> >> >> >> >> >> >> >> On Fri, May 24, 2013 at 12:07 PM, holger krekel > > wrote: >> >> On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: >>> As long as it throws an error hinting that you might need yielding=True it >>> should be obvious on how to fix >>> the backwards incompatibility issue as soon as you run your tests. >> >> We cannot easily throw an error with a hint. Consider this example: >> >> import pytest >> >> >> @pytest.fixture >> def fix(): >> yield 1 >> yield 2 >> >> def test_fix(fix): >> for x in fix: >> assert x < 3 >> >> This runs fine on pytest-2.3.5. On trunk it gives this error: >> >> ... >> >> fix = 1 >> >> def test_fix(fix): >>> for x in fix: >> assert x < 3 >> E TypeError: 'int' object is not iterable >> >> I've never written or seen somebody writing such a generator fixture, >> though. >> And what you would need to do is rewrite the fixture: >> >> @pytest.fixture >> def fix(): >> def gen(): >> yield 1 >> yield 2 >> return gen() >> >> Then again, when i first saw the contextlib.contextmanager decorator >> i found it not very intuitive. Did anyone? It looks like a hack. >>> From that angle i'd rather go for requiring "contextyield=True" or >> @pytest.contextfixture because that can be looked up in documentation >> and thus is easier to read for people not familiar with yields/contextlib. >> >> best, >> holger >> >> >>> I don't see a big problem with this, updating of a requirement is >> something >>> that you should never do automatically. >>> >>> Cheers, >>> Harro >>> >>> >>> >>> On 24 May 2013 16:36, Andreas Pelme > > wrote: >>> >>>> On Thursday 9 May 2013 at 15:56, holger krekel wrote: >>>>> This is probably used by very few people but to be on the safe side, >>>>> we probably should introduce a flag like this: >>>>> >>>>> @pytest.fixture(ctx=True) # signal this is a context manager style >>>> fixture >>>>> def fix(): >>>>> yield 1 >>>>> >>>>> What do you think? Any other suggestions for the flag name? >>>>> >>>>> I'd rather not introduce something like @pytest.contextfixture >>>>> because it would be a duplication of the API (scope, params). >>>>> But i am open to be convinced otherwise. >>>> >>>> I agree that another API like contextfixture should be avoided. >>>> >>>> We had a short discussion on IRC about this, Holger had the idea of >> doing >>>> the opposite if ctx=True - a new default argument "yielding=False" which >>>> would make it possible to restore the old behavior by putting >> yielding=True >>>> on fixtures that would be affected by this. >>>> >>>> A fixture that is a generator that currently looks like this >>>> >>>> @pytest.fixture >>>> def fix(): >>>> yield 1 >>>> yield 2 >>>> >>>> Would then have to be changed to >>>> >>>> @pytest.fixture(yielding=True) >>>> def fix(): >>>> yield 1 >>>> yield 2 >>>> >>>> This is backward incompatible, but given that it seems questionable if >>>> "generator fixtures" useful/is used, with a note in the release notes >> and >>>> documentation I think this could be a good compromise. >>>> >>>> I will be happy to give this a try if it is decided this could be a good >>>> approach! >>>> >>>> Cheers >>>> Andreas >>>> >>>> >>>> _______________________________________________ >>>> Pytest-dev mailing list >>>> Pytest-dev at python.org >>>> http://mail.python.org/mailman/listinfo/pytest-dev >> >>> _______________________________________________ >>> Pytest-dev mailing list >>> Pytest-dev at python.org >>> http://mail.python.org/mailman/listinfo/pytest-dev >> >> _______________________________________________ >> Pytest-dev mailing list >> Pytest-dev at python.org >> http://mail.python.org/mailman/listinfo/pytest-dev > > > -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2899 bytes Desc: not available URL: From holger at merlinux.eu Mon May 27 09:36:04 2013 From: holger at merlinux.eu (holger krekel) Date: Mon, 27 May 2013 07:36:04 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <2D1A8525-9F51-4564-BD80-C5A39EC11224@jaraco.com> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> <2c906a6cd8cb4e73be047d9dbedbf10e@BLUPR06MB003.namprd06.prod.outlook.com> <20130526115024.GV7789@merlinux.eu> <2D1A8525-9F51-4564-BD80-C5A39EC11224@jaraco.com> Message-ID: <20130527073604.GY7789@merlinux.eu> On Sun, May 26, 2013 at 15:37 +0000, Jason R. Coombs wrote: > No. I haven't seen that syntax much if at all. I suggest it because it appeals to my aesthetic. that's fine :) > I'm not sure the distinction between class and decorator is so clear. After all, a decorator is just a callable with a particular signature. I haven't considered the implementation, but I imagine pytest.fixture could in fact be a class if you wanted it to be. it could but decorators are typically functions. > Even if fixture is only a factory function, it's conceivable that the alternate function could be appended as an attribute: > > def fixture(...): > # primary behavior > > def _yielding_fixture(*args, **kwargs): > # wrap or alter behavior of fixture(*args, **kwargs) > > fixture.yielding = _yielding_fixture sure, that's possible. > I agree the implementation is a little clumsy, but I would be inclined to accept a little bit of implementation cruft for a nicer exposed API. I claim it would be a bit of an unexpected API. Maybe someone else than us two can comment on it :) > That said, I'm not trying to convince, but only to share. If you don't love the idea, I won't be offended if you don't incorporate it. thanks for the relaxedness. > Sent from Earth :) holger > > On May 26, 2013, at 7:52, "holger krekel" wrote: > > > Hi Jason, > > > > (your post contains a bit many blank lines, btw, deleting them :) > > > > On Sat, May 25, 2013 at 14:40 +0000, Jason R. Coombs wrote: > >> May I suggest an alternate idea: > >> > >> @pytest.fixture.context(.) > >> > >> def func(): > >> . > >> > >> Or > >> > >> @pytest.fixture.yielding(.) > >> > >> def func(): > >> . > >> > >> Depending on which mode is not supported by fixture directly. > >> > >> Then, the decorator can take the same signature as the natural usage > >> (@pytest.fixture), but alter the handling of a generator appropriately. It > >> can be thought of as an alternate constructor for the same fixture factory. > >> It provides a nice, namespaced name and doesn't threaten to pollute the > >> pytest namespace with a proliferation of fixture variants. > > > > Not cramming the pytest.* is a goal i share but i am not sure about > > this suggestion. The "idiomatic" way to introduce a decorator variant > > in Python is adding a keyword argument or a new name. > > > > Your suggested syntax reminds of what one does for classes, i.e. providing > > classmethods for alternate constructors. But i haven't seen it anywhere > > for decorators, did you? > > > > best, > > holger > > > >> > >> From: Pytest-dev [mailto:pytest-dev-bounces+jaraco=jaraco.com at python.org] On > >> Behalf Of Bruno Oliveira > >> Sent: Friday, 24 May, 2013 17:13 > >> To: holger krekel; Harro van der Klauw; Andreas Pelme; pytest-dev at python.org > >> Subject: Re: [pytest-dev] fixtures as context managers > >> > >> > >> > >> In light of the examples, IMHO, I agree that fixtures being explicit about > >> using yield as context-managers is preferable. > >> > >> > >> > >> I like @pytest.contextfixture, it is easy to look-up and understand since it > >> mimics what we already have in contextlib. > >> > >> > >> > >> > >> > >> > >> > >> On Fri, May 24, 2013 at 12:07 PM, holger krekel >> > wrote: > >> > >> On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > >>> As long as it throws an error hinting that you might need yielding=True it > >>> should be obvious on how to fix > >>> the backwards incompatibility issue as soon as you run your tests. > >> > >> We cannot easily throw an error with a hint. Consider this example: > >> > >> import pytest > >> > >> > >> @pytest.fixture > >> def fix(): > >> yield 1 > >> yield 2 > >> > >> def test_fix(fix): > >> for x in fix: > >> assert x < 3 > >> > >> This runs fine on pytest-2.3.5. On trunk it gives this error: > >> > >> ... > >> > >> fix = 1 > >> > >> def test_fix(fix): > >>> for x in fix: > >> assert x < 3 > >> E TypeError: 'int' object is not iterable > >> > >> I've never written or seen somebody writing such a generator fixture, > >> though. > >> And what you would need to do is rewrite the fixture: > >> > >> @pytest.fixture > >> def fix(): > >> def gen(): > >> yield 1 > >> yield 2 > >> return gen() > >> > >> Then again, when i first saw the contextlib.contextmanager decorator > >> i found it not very intuitive. Did anyone? It looks like a hack. > >>> From that angle i'd rather go for requiring "contextyield=True" or > >> @pytest.contextfixture because that can be looked up in documentation > >> and thus is easier to read for people not familiar with yields/contextlib. > >> > >> best, > >> holger > >> > >> > >>> I don't see a big problem with this, updating of a requirement is > >> something > >>> that you should never do automatically. > >>> > >>> Cheers, > >>> Harro > >>> > >>> > >>> > >>> On 24 May 2013 16:36, Andreas Pelme >> > wrote: > >>> > >>>> On Thursday 9 May 2013 at 15:56, holger krekel wrote: > >>>>> This is probably used by very few people but to be on the safe side, > >>>>> we probably should introduce a flag like this: > >>>>> > >>>>> @pytest.fixture(ctx=True) # signal this is a context manager style > >>>> fixture > >>>>> def fix(): > >>>>> yield 1 > >>>>> > >>>>> What do you think? Any other suggestions for the flag name? > >>>>> > >>>>> I'd rather not introduce something like @pytest.contextfixture > >>>>> because it would be a duplication of the API (scope, params). > >>>>> But i am open to be convinced otherwise. > >>>> > >>>> I agree that another API like contextfixture should be avoided. > >>>> > >>>> We had a short discussion on IRC about this, Holger had the idea of > >> doing > >>>> the opposite if ctx=True - a new default argument "yielding=False" which > >>>> would make it possible to restore the old behavior by putting > >> yielding=True > >>>> on fixtures that would be affected by this. > >>>> > >>>> A fixture that is a generator that currently looks like this > >>>> > >>>> @pytest.fixture > >>>> def fix(): > >>>> yield 1 > >>>> yield 2 > >>>> > >>>> Would then have to be changed to > >>>> > >>>> @pytest.fixture(yielding=True) > >>>> def fix(): > >>>> yield 1 > >>>> yield 2 > >>>> > >>>> This is backward incompatible, but given that it seems questionable if > >>>> "generator fixtures" useful/is used, with a note in the release notes > >> and > >>>> documentation I think this could be a good compromise. > >>>> > >>>> I will be happy to give this a try if it is decided this could be a good > >>>> approach! > >>>> > >>>> Cheers > >>>> Andreas > >>>> > >>>> > >>>> _______________________________________________ > >>>> Pytest-dev mailing list > >>>> Pytest-dev at python.org > >>>> http://mail.python.org/mailman/listinfo/pytest-dev > >> > >>> _______________________________________________ > >>> Pytest-dev mailing list > >>> Pytest-dev at python.org > >>> http://mail.python.org/mailman/listinfo/pytest-dev > >> > >> _______________________________________________ > >> Pytest-dev mailing list > >> Pytest-dev at python.org > >> http://mail.python.org/mailman/listinfo/pytest-dev > > > > > > From holger at merlinux.eu Mon May 27 21:00:45 2013 From: holger at merlinux.eu (holger krekel) Date: Mon, 27 May 2013 19:00:45 +0000 Subject: [pytest-dev] anybody could give pytest/tox training in SF? Message-ID: <20130527190045.GH7789@merlinux.eu> Hi all, I was asked me to give an in-house python testing course in San Francisco. I can probably not make it myself in the next 2-3 months. It's basically the same 3-day course i am giving in Leipzig later in June, see here: http://www.python-academy.com/courses/specialtopics/python_course_testing.html I am looking for someone to subcontract who could use/modify my existing materials and give the course. If you are interested please contact me privately. thanks, holger From andreas at pelme.se Tue May 28 16:30:21 2013 From: andreas at pelme.se (Andreas Pelme) Date: Tue, 28 May 2013 16:30:21 +0200 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <20130524150708.GS7789@merlinux.eu> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> Message-ID: <8EA3090A0B314A17977C18A98971CBF2@pelme.se> On Friday 24 May 2013 at 17:07, holger krekel wrote: > On Fri, May 24, 2013 at 16:50 +0200, Harro van der Klauw wrote: > > As long as it throws an error hinting that you might need yielding=True it > > should be obvious on how to fix > > the backwards incompatibility issue as soon as you run your tests. > > > > > > We cannot easily throw an error with a hint. Consider this example: > > import pytest > > @pytest.fixture > def fix(): > yield 1 > yield 2 > > def test_fix(fix): > for x in fix: > assert x < 3 > > This runs fine on pytest-2.3.5. On trunk it gives this error: > > ... > > fix = 1 > > def test_fix(fix): > > for x in fix: > > assert x < 3 > E TypeError: 'int' object is not iterable > > I've never written or seen somebody writing such a generator fixture, though. > And what you would need to do is rewrite the fixture: > > @pytest.fixture > def fix(): > def gen(): > yield 1 > yield 2 > return gen() > > Then again, when i first saw the contextlib.contextmanager decorator > i found it not very intuitive. Did anyone? It looks like a hack. > From that angle i'd rather go for requiring "contextyield=True" or > @pytest.contextfixture because that can be looked up in documentation > and thus is easier to read for people not familiar with yields/contextlib. > I cannot say that the contextmanager was obvious the first time I first saw it. But neither was generators and the yield statement. :-) I do think that using yield contextmanager-style that is a very good fit for fixtures. People that are not familiar/happy with the idea contextmanager, generators and with statements might just want to continue use request.addfinalizer, which is totally fine. About the API/naming: I like and prefer the current trunk behavior (just one API: pytest.fixture). If you find pytest.contextfixture more explicit and clear - go for it. I will be very happy with "context fixtures" whatever they are called. :-) Cheers Andreas From vladimir at keleshev.com Tue May 28 16:49:25 2013 From: vladimir at keleshev.com (Vladimir Keleshev) Date: Tue, 28 May 2013 16:49:25 +0200 Subject: [pytest-dev] fixtures as context managers Message-ID: <167651369752565@web2h.yandex.ru> An HTML attachment was scrubbed... URL: From nicoddemus at gmail.com Tue May 28 17:19:21 2013 From: nicoddemus at gmail.com (Bruno Oliveira) Date: Tue, 28 May 2013 12:19:21 -0300 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <167651369752565@web2h.yandex.ru> References: <167651369752565@web2h.yandex.ru> Message-ID: On Tue, May 28, 2013 at 11:49 AM, Vladimir Keleshev wrote: > > I would even advertize this as the default way to make fixtures in py.test > documentation. > +1 on that, specially if we have the same API. Cheers, Bruno. -------------- next part -------------- An HTML attachment was scrubbed... URL: From brianna.laugher at gmail.com Wed May 29 04:16:55 2013 From: brianna.laugher at gmail.com (Brianna Laugher) Date: Wed, 29 May 2013 12:16:55 +1000 Subject: [pytest-dev] parametrize and ids Message-ID: Hi, I was wondering if anyone has ideas about 'nicer' ways to specify IDs for tests when using the parametrize mark. Example: my parametrize might look like this: @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ (['ra2', 'ra2', 'ra4', 'ra4'], 'Isol', None), (['sh2', 'sh2', 'sh4', 'sh4'], 'Isol', 'increasing'), (['ts2', 'ts2', 'ts4', 'ts4'], 'Isol', None), (['ra2', 'ra2', 'ra2', None], 'Isol', None), (['sh2', 'sh2', 'sh2', None], 'Isol', 'clearing'), (['ts2', 'ts2', 'ts2', None], 'Isol', None), ([None, None, 'ra2', 'ra2'], 'Isol', None), ([None, None, 'sh2', 'sh2'], 'Isol', 'developing'), ([None, None, 'ts2', 'ts2'], 'Isol', None), ]) which results in IDs like this: I can add IDs (I just learned last week! :)) like this: @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ (['ra2', 'ra2', 'ra4', 'ra4'], 'Isol', None), (['sh2', 'sh2', 'sh4', 'sh4'], 'Isol', 'increasing'), (['ts2', 'ts2', 'ts4', 'ts4'], 'Isol', None), (['ra2', 'ra2', 'ra2', None], 'Isol', None), (['sh2', 'sh2', 'sh2', None], 'Isol', 'clearing'), (['ts2', 'ts2', 'ts2', None], 'Isol', None), ([None, None, 'ra2', 'ra2'], 'Isol', None), ([None, None, 'sh2', 'sh2'], 'Isol', 'developing'), ([None, None, 'ts2', 'ts2'], 'Isol', None), ], ids=['IsolRA increasing', 'IsolSH increasing', 'IsolTS increasing', 'IsolRA clearing', 'IsolSH clearing', 'IsolTS clearing', 'IsolRA developing', 'IsolSH developing', 'IsolTS developing', ]) but there are a couple of things I don't like about this: * takes a lot of lines * ID is separate from the test data, bad for maintenance, if the test data gets changed the test name could easily be overlooked when it should be updated too What I would really like is if a string in the tuples could represent the name. Maybe there could be a "magic" fieldname (id, testid, _pytestid ?) that could be stripped out from the data and used as the id. e.g. @py.test.mark.parametrize(('id', 'wx', 'expectedCoverage', 'expectedTrend'), [ ('ChcRA increasing', ['ra1', 'ra1', 'ra4', 'ra4'], 'Wide', None), ('ChcSH increasing', ['sh1', 'sh1', 'sh4', 'sh4'], 'Wide', None), ('ChcTS increasing', ['ts1', 'ts1', 'ts4', 'ts4'], 'Wide', None), ]) def test_noTrendsStartingWithChc(wx, expectedCoverage, expectedTrend): # blah This would be really nice. Another alternative could be if you could specify a function that would take the test data and form a string for the test id from it. An example here might be @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ (['ra1', 'ra1', 'ra4', 'ra4'], 'Wide', None), (['sh1', 'sh1', 'sh4', 'sh4'], 'Wide', None), (['ts1', 'ts1', 'ts4', 'ts4'], 'Wide', None), ], idFn=lambda (wx, cov, trend): '{!s}{} {!s}'.format(wx[0], cov, trend)) However this is quite a bit more messy, and not as flexible as specifying your own string. I would be interested to hear what people think about this, as well as if there are other ways of specifying ids that I have overlooked. (I know I could lay out the data the way I want and use pytest_generate_tests to slice it up for metafunc.parametrize, but I actually prefer explicitly writing out each test case as it tends to be a lot simpler for other developers and future-me to grok.) thanks, Brianna -- They've just been waiting in a mountain for the right moment: http://modernthings.org/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From brianna.laugher at gmail.com Wed May 29 05:17:20 2013 From: brianna.laugher at gmail.com (Brianna Laugher) Date: Wed, 29 May 2013 13:17:20 +1000 Subject: [pytest-dev] parametrize and ids In-Reply-To: References: Message-ID: Another alternative - I would often prefer just doing what metafunc.addcall does if you don't specify an id, which is just make an integer, like so: Maybe it is wrong and should be updated to use idmaker :P But basically, if the id can't be simple and meaningful to me (and with parametrize it is often not), an integer would be less "visual noise" and in the case of the mark parametrize, easy to map back to the specific test data in the case of a failure. Brianna -- They've just been waiting in a mountain for the right moment: http://modernthings.org/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From holger at merlinux.eu Wed May 29 09:48:33 2013 From: holger at merlinux.eu (holger krekel) Date: Wed, 29 May 2013 07:48:33 +0000 Subject: [pytest-dev] parametrize and ids In-Reply-To: References: Message-ID: <20130529074833.GF7789@merlinux.eu> Hi Brianna, I am not using mark.parametrize as much as you do and usually in simpler scenarios. Here are some comments nevertheless. On Wed, May 29, 2013 at 12:16 +1000, Brianna Laugher wrote: > Hi, > > I was wondering if anyone has ideas about 'nicer' ways to specify IDs for > tests when using the parametrize mark. > > Example: > > my parametrize might look like this: > > @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ > (['ra2', 'ra2', 'ra4', 'ra4'], 'Isol', None), > (['sh2', 'sh2', 'sh4', 'sh4'], 'Isol', 'increasing'), > (['ts2', 'ts2', 'ts4', 'ts4'], 'Isol', None), > (['ra2', 'ra2', 'ra2', None], 'Isol', None), > (['sh2', 'sh2', 'sh2', None], 'Isol', 'clearing'), > (['ts2', 'ts2', 'ts2', None], 'Isol', None), > ([None, None, 'ra2', 'ra2'], 'Isol', None), > ([None, None, 'sh2', 'sh2'], 'Isol', 'developing'), > ([None, None, 'ts2', 'ts2'], 'Isol', None), > ]) > > which results in IDs like this: > > > > > > > > > > > I can add IDs (I just learned last week! :)) like this: > > @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ > (['ra2', 'ra2', 'ra4', 'ra4'], 'Isol', None), > (['sh2', 'sh2', 'sh4', 'sh4'], 'Isol', 'increasing'), > (['ts2', 'ts2', 'ts4', 'ts4'], 'Isol', None), > (['ra2', 'ra2', 'ra2', None], 'Isol', None), > (['sh2', 'sh2', 'sh2', None], 'Isol', 'clearing'), > (['ts2', 'ts2', 'ts2', None], 'Isol', None), > ([None, None, 'ra2', 'ra2'], 'Isol', None), > ([None, None, 'sh2', 'sh2'], 'Isol', 'developing'), > ([None, None, 'ts2', 'ts2'], 'Isol', None), > ], ids=['IsolRA increasing', > 'IsolSH increasing', > 'IsolTS increasing', > 'IsolRA clearing', > 'IsolSH clearing', > 'IsolTS clearing', > 'IsolRA developing', > 'IsolSH developing', > 'IsolTS developing', > ]) > > but there are a couple of things I don't like about this: > * takes a lot of lines > * ID is separate from the test data, bad for maintenance, if the test data > gets changed the test name could easily be overlooked when it should be > updated too agreed. One a sidenote, yesterday i introduced a briefer way to specify argument names. Your example would start like this: @pytest.mark.parametrize("wx,expectedCoverage,expectedTrend", ...) and you can also have spaces after the commas if you prefer. > What I would really like is if a string in the tuples could represent the > name. Maybe there could be a "magic" fieldname (id, testid, _pytestid ?) > that could be stripped out from the data and used as the id. > > e.g. > > @py.test.mark.parametrize(('id', 'wx', 'expectedCoverage', > 'expectedTrend'), [ > ('ChcRA increasing', ['ra1', 'ra1', 'ra4', 'ra4'], 'Wide', None), > ('ChcSH increasing', ['sh1', 'sh1', 'sh4', 'sh4'], 'Wide', None), > ('ChcTS increasing', ['ts1', 'ts1', 'ts4', 'ts4'], 'Wide', None), > ]) > def test_noTrendsStartingWithChc(wx, expectedCoverage, expectedTrend): > # blah > > This would be really nice. Looks better, maybe the special id name should then be spelled "__id" or so to make it more obvious it's not just an argument name. > Another alternative could be if you could specify a function that would > take the test data and form a string for the test id from it. An example > here might be > > > @py.test.mark.parametrize(('wx', 'expectedCoverage', 'expectedTrend'), [ > (['ra1', 'ra1', 'ra4', 'ra4'], 'Wide', None), > (['sh1', 'sh1', 'sh4', 'sh4'], 'Wide', None), > (['ts1', 'ts1', 'ts4', 'ts4'], 'Wide', None), > ], idFn=lambda (wx, cov, trend): '{!s}{} {!s}'.format(wx[0], cov, trend)) > > However this is quite a bit more messy, and not as flexible as specifying > your own string. Messyness depends, i'd say. If you have multiple test functions you could aim to re-use the same id-generating function and could then be sure that the IDs are always correctly denoting the parametrizted data. > I would be interested to hear what people think about this, as well as if > there are other ways of specifying ids that I have overlooked. (I know I > could lay out the data the way I want and use pytest_generate_tests to > slice it up for metafunc.parametrize, but I actually prefer explicitly > writing out each test case as it tends to be a lot simpler for other > developers and future-me to grok.) I'd recommend to write a wrapper "@myparametrize" which generates a pytest.mark.parametrize() instance in the end. This way you could use and consolidate your API ideas in real life with today's pytest in real life before aiming for pytest inclusion. best, holger > > thanks, > Brianna > > > -- > They've just been waiting in a mountain for the right moment: > http://modernthings.org/ > _______________________________________________ > Pytest-dev mailing list > Pytest-dev at python.org > http://mail.python.org/mailman/listinfo/pytest-dev From holger at merlinux.eu Thu May 30 20:41:18 2013 From: holger at merlinux.eu (holger krekel) Date: Thu, 30 May 2013 18:41:18 +0000 Subject: [pytest-dev] fixtures as context managers In-Reply-To: <8EA3090A0B314A17977C18A98971CBF2@pelme.se> References: <20130505130535.GO30215@merlinux.eu> <20130509135607.GY30215@merlinux.eu> <20130524150708.GS7789@merlinux.eu> <8EA3090A0B314A17977C18A98971CBF2@pelme.se> Message-ID: <20130530184118.GU7789@merlinux.eu> On Tue, May 28, 2013 at 16:30 +0200, Andreas Pelme wrote: > On Friday 24 May 2013 at 17:07, holger krekel wrote: > > Then again, when i first saw the contextlib.contextmanager decorator > > i found it not very intuitive. Did anyone? It looks like a hack. > > From that angle i'd rather go for requiring "contextyield=True" or > > @pytest.contextfixture because that can be looked up in documentation > > and thus is easier to read for people not familiar with yields/contextlib. > > I cannot say that the contextmanager was obvious the first time I > first saw it. But neither was generators and the yield statement. :-) > I do think that using yield contextmanager-style that is a very good > fit for fixtures. I recently gave a testing course where i didn't have the impression "yield"-contextmanager would be very obvious to people who are not very familiar with Python (and i think there are a lot these days). I know because i needed to explain "yield" to begin with, and the context manager usage is a hack on top :) OTOH some had problems with ``request.addfinalizer(fin)`` because they hadn't passed functions around yet in their python code :) I'd like to have preferably one main way explained in the docs and i am not sure yet which, to be honest. > People that are not familiar/happy with the idea contextmanager, > generators and with statements might just want to continue use > request.addfinalizer, which is totally fine. > > About the API/naming: I like and prefer the current trunk behavior > (just one API: pytest.fixture). If you find pytest.contextfixture more > explicit and clear - go for it. I will be very happy with "context > fixtures" whatever they are called. :-) Right, we are going to have context fixtures one way or another in 2.4 :) Ideally, we could ask some not-so-proficient-in-python people and present them the addfinalizer() and the yield-context method and observe their reactions. If any of you can do that with some colleagues, that'd be most appreciated. cheers, holger > Cheers > Andreas > >