[TIP] (no subject)

Brianna Laugher brianna.laugher at gmail.com
Sun Mar 29 16:19:18 PDT 2015


Holger actually described on Stack Overflow in 2012 how to define
"step" or "incremental" tests.
http://stackoverflow.com/questions/12411431/pytest-how-to-skip-the-rest-of-tests-in-the-class-if-one-has-failed

Then you wouldn't need to run with -x.
But it wouldn't work with xdist, and to have the state persist from
test to test you'd still want to use a fixture rather than having
things on the test class.

(Also, this question has 5 linked questions, so whether or not it is
the "right" question to be asking, it is something that does come up.)

Brianna


On 29 March 2015 at 21:14, dpb dpb <dpb.mediamath at gmail.com> wrote:
> Yes, that's what I had in mind — a separate non-test class that can be
> passed in as a fixture or instantiated and assigned to a module-level
> variable.
>
> I prefer to try to arrange things so that each test function has a single,
> reportable assertion for any given collection of parameters.
>
> As long as I know the test functions will always be run in the prescribed
> order, I can pass option -x to py.test when I run it, and it will exclude
> all tests after the first failing one.
>
> On Sun, Mar 29, 2015 at 2:09 PM, holger krekel <holger at merlinux.eu> wrote:
>>
>> On Sun, Mar 29, 2015 at 12:38 -0400, dpb dpb wrote:
>> > Thanks to both of you.
>> >
>> > I understand that it's normally the case to want complete isolation
>> > between
>> > tests.
>> >
>> > But on occasion it's useful to run tests on a series of cumulative
>> > changes
>> > to state. That means forfeiting test independence, or anyway building it
>> > into the sequence in which tests are run. The alternatives seem to be
>> > placing many asserts into each test function, or running tests based on
>> > simulated data.
>> >
>> > I see that I can keep track cumulative changes in state pretty simply,
>> > using a non-test class (rather than the test class) to define the
>> > state-bearing object.
>>
>> Yes, more precisely you can do something like this:
>>
>>     import pytest
>>
>>     class IncState:
>>         """ you can store state on attributes and pass them from test to
>> test. """
>>
>>     @pytest.fixture(scope="module")
>>     def incstate():
>>         return IncState()
>>
>>     def test_one(incstate):
>>         incstate.x = 1
>>
>>     def test_two(incstate):
>>         assert incstate.x == 1
>>         incstate.x += 1
>>
>>     def test_three(incstate):
>>         assert incstate.x == 2
>>
>> With pytest it's safe to do it because it guarantees execution in source
>> order.
>> Other test runners depend on dictionary order (of the module globals() or
>> a class dict)
>> and thus are typically less predictable.  Of course this pattern does
>> violate test
>> isolation and i have very rarely used the above incremental pattern when i
>> wanted
>> to avoid having one large test containing all the increments.  Rarely
>> means twice or so in my 15 years of writing thousands of tests.
>>
>> best,
>> holger
>>
>>
>> > - dpb
>> >
>> > On Sun, Mar 29, 2015 at 12:01 PM, Ned Batchelder <ned at nedbatchelder.com>
>> > wrote:
>> >
>> > >  On 3/29/15 4:57 AM, dpb dpb wrote:
>> > >
>> > >  Something I do not see addressed explicitly in the Pytest docs is
>> > > this
>> > > behavior: Unlike normal class writing in Python 3, changing the value
>> > > of a
>> > > class attribute in one function does not leave it changed in test
>> > > functions
>> > > that are called subsequently:
>> > >
>> > >   As Holger mentioned, a new TestExample instance is created for each
>> > > test.  This is how all the test runners work, because you want
>> > > isolation
>> > > between your tests.  One of the principles of the xUnit style of
>> > > testing is
>> > > that each test is independent of all other tests.  You want to be able
>> > > to
>> > > run a single test and not have it depend on the results of previous
>> > > tests.
>> > >
>> > > --Ned.
>> > >
>> > >  # test_pytest_class_attributes.py
>> > >> """Test the setting of class attributes."""
>> > >> class TestExample():
>> > >>     def setup(self):
>> > >>         self.attribute = 1
>> > >
>> > >
>> > >>     def test_changing_attr(self):
>> > >>         """Change attribute on object."""
>> > >>         self.attribute = 2
>> > >>         assert self.attribute == 2
>> > >
>> > >
>> > >>     def test_attr_is_changed(self):
>> > >>         """Assume attribute is changed."""
>> > >>         assert self.attribute == 2
>> > >
>> > >
>> > >>     def test_attr_is_unchanged(self):
>> > >>         """Assume attribute is unchanged."""
>> > >>         assert self.attribute == 1
>> > >
>> > >
>> > >  Output:
>> > >
>> > >  $ py.test test_pytest_class_attributes.py -v
>> > >> ============================= test session starts
>> > >> ==============================
>> > >> platform darwin -- Python 3.4.1 -- py-1.4.25 -- pytest-2.6.3 --
>> > >> /Users/dpb/py34/bin/python3.4
>> > >> collected 3 items
>> > >> test_pytest_class_attributes.py::TestExample::test_changing_attr
>> > >> PASSED
>> > >> test_pytest_class_attributes.py::TestExample::test_attr_is_changed
>> > >> FAILED
>> > >> test_pytest_class_attributes.py::TestExample::test_attr_is_unchanged
>> > >> PASSED
>> > >> =================================== FAILURES
>> > >> ===================================
>> > >> _______________________ TestExample.test_attr_is_changed
>> > >> _______________________
>> > >> self = <test_pytest_class_attributes.TestExample object at
>> > >> 0x10dd98ef0>
>> > >>     def test_attr_is_changed(self):
>> > >>         """Test whether attribute is changed."""
>> > >> >       assert self.attribute == 2
>> > >> E       assert 1 == 2
>> > >> E        +  where 1 = <test_pytest_class_attributes.TestExample
>> > >> object at
>> > >> 0x10dd98ef0>.attribute
>> > >
>> > >
>> > >
>> > > test_pytest_class_attributes.py:14: AssertionError
>> > >> ====================== 1 failed, 2 passed in 0.02 seconds
>> > >> ======================
>> > >> $
>> > >
>> > >
>> > >  Is there special syntax or some special structure to make class
>> > > attributes behave In Pytest as they do in an ordinary Python class?
>> > > Example:
>> > >
>> > >  # display_class_attributes.py
>> > >> """Test the setting of class attributes."""
>> > >
>> > >
>> > >> class TestExample():
>> > >>     def __init__(self):
>> > >>         self.attribute = 1
>> > >
>> > >
>> > >>     def test_changing_attr(self):
>> > >>         """Change attribute on object."""
>> > >>         self.attribute = 2
>> > >>         assert self.attribute == 2
>> > >>         print('Finished test_changing_attr.\n')
>> > >
>> > >
>> > >>     def test_attr_is_changed(self):
>> > >>         """Test whether attribute is changed."""
>> > >>         assert self.attribute == 2
>> > >>         print('Finished test_attr_is_changed.\n')
>> > >
>> > >
>> > >>     def test_attr_is_unchanged(self):
>> > >>         """Test whether attribute is unchanged."""
>> > >>         assert self.attribute == 1
>> > >>         print('Finiahed test_attr_is_unchanged.\n')
>> > >
>> > >
>> > >> t = TestExample()
>> > >> t.test_changing_attr()
>> > >> t.test_attr_is_changed()
>> > >> t.test_attr_is_unchanged()
>> > >
>> > >
>> > >  Output:
>> > >
>> > >  > $ python display_class_attributes.py
>> > > >
>> > > > self.attribute == 2: True
>> > > >
>> > > > self.attribute == 2: True
>> > > >
>> > > > self.attribute == 1: False
>> > > >
>> > > > $
>> > >
>> > >  Thanks.
>> > >
>> > >  - dpb
>> > >
>> > >
>> > > _______________________________________________
>> > > testing-in-python mailing
>> > > listtesting-in-python at lists.idyll.orghttp://lists.idyll.org/listinfo/testing-in-python
>> > >
>> > >
>> > >
>> > > _______________________________________________
>> > > testing-in-python mailing list
>> > > testing-in-python at lists.idyll.org
>> > > http://lists.idyll.org/listinfo/testing-in-python
>> > >
>> > >
>>
>> > _______________________________________________
>> > testing-in-python mailing list
>> > testing-in-python at lists.idyll.org
>> > http://lists.idyll.org/listinfo/testing-in-python
>>
>>
>> --
>> about me:    http://holgerkrekel.net/about-me/
>> contracting: http://merlinux.eu
>
>
>
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
>



-- 
They've just been waiting in a mountain for the right moment:
http://modernthings.org/



More information about the testing-in-python mailing list