[py-dev] new resource API documentation comments
holger krekel
holger at merlinux.eu
Sun Aug 26 16:57:00 CEST 2012
On Fri, Aug 17, 2012 at 17:32 +1000, Brianna Laugher wrote:
> Also,
>
> Would this be a roughly equivalent old-style to the smtp examples in
> http://pytest.org/dev/funcargs.html ?
>
> def pytest_funcarg__smtpMerLinux(request):
> smtp = smtplib.SMTP("merlinux.eu")
> def teardown(smtp):
> print ("finalizing %s" % smtp)
> smtp.close()
> return request.cached_setup(setup=lambda: smtp, teardown=teardown,
> scope='session')
>
>
> def pytest_funcarg__smtpMailPython(request):
> smtp = smtplib.SMTP("mail.python.org")
> def teardown(smtp):
> print ("finalizing %s" % smtp)
> smtp.close()
> return request.cached_setup(setup=lambda: smtp, teardown=teardown,
> scope='session')
>
> # test file
> def pytest_generate_tests(metafunc):
> merlinux = request.getfuncargvalue('smtpMerLinux')
> mailpython = request.getfuncargvalue('smtpMailPython')
>
> if'smtp' in metafunc.funcargnames:
> metafunc.addcall(id='merlinux.eu', param=merlinux) # ? would
> this work? seems magic
> metafunc.addcall(id='mail.python.org', param=mailpython)
>
> I feel like this makes it clear how much more powerful parametrizing
> funcargs themselves is.
The old-style code would even be a bit more involved. I guess it could
be added to http://pytest.org/dev/funcarg_compare.html
I wouldn't put it to the entry-level main docs because for newcomers
it's not immediately neccessary to know the old ways :)
best,
holger
> cheers
> Brianna
>
>
>
>
> On 16 August 2012 18:58, Brianna Laugher <brianna.laugher at gmail.com> wrote:
> > Hi,
> >
> > I just spent some time reading the dev docs so these comments are just
> > based on the docs and not actually using the new API. In general it
> > looks pretty sensible.
> >
> > - being able to have funcargs like funcargs directly is really nice, a
> > lot more obvious than calling request.getfuncargvalue('foo')
> > - why addfinalizer and not teardown?
> > -although I don't really know what cached_setup did, the trinity of
> > defining the scope, setup and teardown methods made sense to me. Now
> > the scope is in a decorator, the setup is implicitly the entire thing
> > that is happening and the teardown seems somewhat awkwardly tacked on.
> > - none of the "addfinalizer" examples take an argument, how would you
> > convert an old-style teardown method to that? e.g. we have a lot of
> > funcargs which do things like
> > return request.cached_setup(setup=setup,
> > teardown=lambda obj: obj.close(),
> > scope='function')
> > - Sometimes things are referred to as "funcargs", sometimes they are
> > referred to as "injected resources". Is there any difference here? The
> > funcarg is the actual function and the injected resource is the
> > instance in a specific test function? I suggest to use the term
> > "funcarg" as much as possible as it is specific and a necessary
> > concept for using pytest with any depth.
> >
> > Some of the following comments are fairly picky so feel free to ignore them.
> >
> > funcargs.txt
> > line 118 - I think in this first incarnation of the smtp funcarg
> > (factory? what to call it now?), it doesn't actually need to take a
> > testcontext, right?
> >
> > line 527 "Parametrizing test functions" - may be worth having a simple
> > example showing a combination using both (test data) parametrization
> > and funcarg parametrization, to emphasise how they are differently
> > useful. Using a database as an example of funcarg parametrization is
> > good, maybe better than values like 1/2. I feel like parametrizing
> > tests (test data) is probably the more common use case and it is a
> > little buried amongst the heavy duty parametrized funcargs.
> >
> > line 598 "Basic ``pytest_generate_tests`` example" - I think this is
> > not a very basic example! I think it is copied from parametrize.txt
> > page, where it might make more sense. Here is what I would consider a
> > basic example.
> >
> > # code
> > def isSquare(n):
> > n = n ** 0.5
> > return int(n) == n
> >
> > # test file
> > def pytest_generate_tests(metafunc):
> > squares = [1, 4, 9, 16, 25, 36, 49]
> > for n in range(1, 50):
> > expected = n in squares
> > if metafunc.function.__name__ == 'test_isSquare':
> > metafunc.addcall(id=n, funcargs=dict(n=n, expected=expected))
> >
> >
> > def test_isSquare(n, expected):
> > assert isSquare(n) == expected
> >
> > Well, this is so trivial you might bundle it all into a single test,
> > but it can be useful to have each case genuinely be a separate test.
> > You could also shoe-horn this data into a parametrize decorator I
> > suppose but it is nicer to have more space if your test data is more
> > complicated, to explain it.
> >
> > I am starting to have a feeling that the way my project has been using
> > generate_tests is not the way everyone else uses it. In our
> > conftest.py one of the enterprising developers on the project (who got
> > us all onto py.test initially) put this:
> >
> > def pytest_generate_tests(__multicall__, metafunc):
> > """Supports parametrised tests using generate_ fns.
> > Use multicall to call any other pytest_generate_tests hooks first.
> > If the test_ fn has a generate_ fn then call it with the metafunc
> > to let it parametrise the test.
> > """
> > __multicall__.execute()
> > name = metafunc.function.__name__.replace('test_', 'generate_')
> > fn = getattr(metafunc.module, name, None)
> > if fn:
> > fn(metafunc)
> >
> > this means I can simplify my example above to:
> >
> > def generate_isSquare(metafunc):
> > squares = [1, 4, 9, 16, 25, 36, 49]
> > for n in range(1, 50):
> > expected = n in squares
> > metafunc.addcall(id=n, funcargs=dict(n=n, expected=expected))
> >
> > maybe this is a useful pattern for others? or maybe we're doing it
> > wrong, I dunno :)
> >
> > in funcarg_compare.txt
> > line 53 - (in old-style) "4. there is no way how you can make use of
> > funcarg factories in xUnit setup methods."
> >
> > Is there an example of this? I would like to see it! This sounds like
> > a way for people with existing xUnit style test suites to more easily
> > convert to funcarg style.
> >
> > Maybe with all the parametrized test examples it is a good idea to
> > show the verbose output, just to be more explicit about what is being
> > generated.
> >
> > As an aside, there is a comment in example/markers.txt line 144 that
> > "You can use the ``-k`` command line option to only run tests with
> > names matching
> > the given argument". Whether it is an oversight in the functionality
> > or the docs, I have always found that -k also matches against markers
> > (py.test.mark decorators). (Currently using pytest 2.2.3)
> >
> > in setup.txt
> > line 65 'old = tmpdir.chdir()'
> > - it's not really relevant to the example but I don't know what this
> > does, and I couldn't find out, so it's just a bit distracting.
> >
> > thanks as always for providing this great library :)
> >
> > cheers
> > Brianna
> >
> > --
> > They've just been waiting in a mountain for the right moment:
> > http://modernthings.org/
>
>
>
> --
> They've just been waiting in a mountain for the right moment:
> http://modernthings.org/
> _______________________________________________
> py-dev mailing list
> py-dev at codespeak.net
> http://codespeak.net/mailman/listinfo/py-dev
>
More information about the Pytest-dev
mailing list