functional test in pyramid using pytest

266 views
Skip to first unread message

Jaime Sangcap

unread,
Jan 24, 2017, 2:53:42 PM1/24/17
to pylons-discuss
Hi everyone! Im trying to learn python and getting my hands dirty with pyramid.

I would really appreciate it if there is anyone willing to give me a kickstart on how to do functional test?
Lets say I posted a data to a url and I want to test that the data has been saved to the persistent store or fake store.
How should I do it?

I have this test class:

class TestCatalogView:
def test_it_loads_catalog_add_page(self, testapp):
testapp.get('/catalog/add', status=200)

def test_it_adds_the_course_on_the_catalog(self, testapp):
response = testapp.post('/catalog/add', status='30*')
assert 'Course has been added' in response.body
        # here I want to assert that the data has been persisted

the testapp is a fixture with the following details:

@fixture(scope='session')
def pyramid_test_setup():
yield testing.setUp()
testing.tearDown()


@fixture(scope='session')
def testapp(pyramid_test_setup):
from tgpweb import main
from pyramid.paster import get_appsettings
settings = get_appsettings('testing.ini', 'main')
app = main(global_config=None, **settings)
return webtest.TestApp(app)


What are the things needed to test this? Im thinking of making a Repository Class which uses SqlAlchemy, and another one as Fake repository so that in case I dont want to hit a real database I can swap the implementation


If Im doing it wrong please guide me on how to make it right. maybe I have the wrong mindset in testing.


Thank you in advance!

Steve Piercy

unread,
Jan 24, 2017, 4:50:55 PM1/24/17
to pylons-...@googlegroups.com
Take a look at this step in the SQLAlchemy + URL Dispatch wiki tutorial.
http://docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/wiki2/tests.html

--steve


On 1/24/17 at 11:52 AM, jaime....@gmail.com (Jaime Sangcap) pronounced:
------------------------
Steve Piercy, Soquel, CA

Jaime Sangcap

unread,
Jan 25, 2017, 3:58:49 AM1/25/17
to pylons-discuss
I guess I missed a lot, I have to do the tutorial again and get back. quick tutorial is not that quick at all ;)

Thanks a lot.

Mikko Ohtamaa

unread,
Jan 25, 2017, 4:17:43 AM1/25/17
to pylons-...@googlegroups.com
For py.test and Splinter (over Selenium) based testing you might look for the inspiration here:

https://websauna.org/docs/narrative/testing/writing.html#testing-patterns

It also comes with patterns how to ramp up WebTest based web server for Selenium.

Using py.test and Splinter allows you to write much more cleaner test scripts that one would do with vanilla unittest2 and raw Selenium.

Thanks,
Mikko

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to pylons-discuss@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/a6af3a81-0e28-4718-8ac3-1bae60a90cd3%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

tonthon

unread,
Jan 25, 2017, 4:54:29 AM1/25/17
to pylons-...@googlegroups.com
Hi,

personnaly I use request.addfinalizer to rollback the transaction :

https://github.com/CroissanceCommune/autonomie/blob/master/autonomie/tests/conftest.py#L300

Hope this help

Regards

--

Gaston Tjebbes

http://majerti.fr
> --
> You received this message because you are subscribed to the Google
> Groups "pylons-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to pylons-discus...@googlegroups.com
> <mailto:pylons-discus...@googlegroups.com>.
> To post to this group, send email to pylons-...@googlegroups.com
> <mailto:pylons-...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/pylons-discuss/db009b1b-51c2-493a-809a-2582c6e85d9a%40googlegroups.com
> <https://groups.google.com/d/msgid/pylons-discuss/db009b1b-51c2-493a-809a-2582c6e85d9a%40googlegroups.com?utm_medium=email&utm_source=footer>.

Jaime Sangcap

unread,
Jan 25, 2017, 4:56:24 AM1/25/17
to pylons-discuss
looks interesting. Im thinking you can also use the Splinter with Behave if you prefer BDD style?

I'll keep it on my list and get back when its time for me to do browser test automation.

Thanks a lot!
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discus...@googlegroups.com.
To post to this group, send email to pylons-...@googlegroups.com.

Mikko Ohtamaa

unread,
Jan 25, 2017, 4:59:52 AM1/25/17
to pylons-...@googlegroups.com
personnaly I use request.addfinalizer to rollback the transaction :

https://github.com/CroissanceCommune/autonomie/blob/master/autonomie/tests/conftest.py#L300


This does work in full weight functional testing, as you need to run a web server in a separate thread from unit test main thread. Transactions are not shared between threads, so you need to commit transactions to the database in order to Selenium or other test client to see them.

Instead, the cycle is

* Do database set up

* Commit transactions

* Connect to the test web server using a browser

* Manipulate web page

* Read data back from the database

* Check that database matches expected values

* Drop database at the end of the test (or more usual, at the beginning of the next test)

Cheers,
Mikko

 
--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to pylons-discuss@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pylons-discuss/e43d7678-0e26-082c-ab6f-a9445f223027%40gmail.com.

For more options, visit https://groups.google.com/d/optout.

Jonathan Vanasco

unread,
Jan 25, 2017, 5:29:56 PM1/25/17
to pylons-discuss


On Tuesday, January 24, 2017 at 4:50:55 PM UTC-5, Steve Piercy wrote:
Take a look at this step in the SQLAlchemy + URL Dispatch wiki tutorial.
http://docs.pylonsproject.org/projects/pyramid/en/latest/tutorials/wiki2/tests.html 

+1 for that tutorial.  one of the projects we opensourced used that as inspiration.  

a general pattern I used for those type of tests is:

  1. insert objects into database via http tests
  2. check objects exist in database via raw sqlalchemy

in terms of datastores, I suggest using a different connection string for sqalalchemy -- test against a testdb (i would not test against sqlite if you're deploying on postgres/mysql as things can differ slightly)


at some point your functional tests will work better as part of integrated tests... at that point, i like using the `requests` library to work like a headless browser.  beautfifulsoup can help ensure you have the right content on the page.

it can take a little longer to write, but I found that `requests` worked significantly faster than selenium (as in "seconds instead of minutes", and one 26+ minute selenium test dropped to around 90 seconds when it was rewritten to requests.)

Roman Suzi

unread,
Jan 26, 2017, 12:27:40 AM1/26/17
to pylons-...@googlegroups.com
I do not know what is so hard about tests in Pyramid. Recently wrote all kinds of tests in Flask (completely new framework for me), and with pytest it is a dream: pytest fixtures and their combination is very intuitive compared to the classic approach (with setup/teardown methods), I was able to with just a little googling to do selenium, requests-level, database, etc.

Compared to my Pyramid experience: http://stackoverflow.com/questions/33776475/setting-up-pyramid-1-5-testing-the-right-way

I think, it's maybe time to rethink pyramid tutorial with pytest in mind, and provide a tool set (examples of fixtures) in addition to whole example?

Regards,
Roman

--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pylons-discuss+unsubscribe@googlegroups.com.
To post to this group, send email to pylons-discuss@googlegroups.com.

Steve Piercy

unread,
Jan 26, 2017, 1:39:50 AM1/26/17
to pylons-...@googlegroups.com
As of Pyramid 1.8, we use py.test in the tutorials, scaffolds,
and cookiecutters.
https://github.com/Pylons/pyramid/search?utf8=%E2%9C%93&q=pytest

But that's just the test runner, and doesn't address the core
matter you bring up.

Switching from the setup/teardown to pytest fixtures would be a
tremendous undertaking. As with any unsponsored open source
project, it would happen at the speed of volunteers, and would
necessitate buy in from the core maintainers and experienced
developers. I'd be interested in hearing more, both for and
against, about a switch.

--steve


On 1/26/17 at 7:27 AM, roman...@gmail.com (Roman Suzi) pronounced:
>>email to pylons-discus...@googlegroups.com.
>>To post to this group, send email to pylons-...@googlegroups.com.
>>To view this discussion on the web visit https://groups.google.com/d/
>>msgid/pylons-discuss/9cdded60-72af-4345-81b3-b5bfdf47c250%
>>40googlegroups.com
>>
><https://groups.google.com/d/msgid/pylons-discuss/9cdded60-72af-4345-81b3-b5bfdf47c250%
>40googlegroups.com?utm_medium=email&utm_source=footer>
>>.
>>
>>For more options, visit https://groups.google.com/d/optout.
>>
>

Mike Orr

unread,
Jan 27, 2017, 12:13:36 AM1/27/17
to pylons-...@googlegroups.com
I struggled with database tests in two applications, and I'm not sure
there is a wonderful and easy way. Regarding Roman's observation, you
could look at what the differences are between a Flax test and a
Pyramid test and that might answer why Pyramid is more difficult, and
if you come up with any reasons it would be good to let the Pyramid
developers know so we can think about addressing them. I don't know
much about Flask so I can't compare them. But I would guess that some
of the difficulty is setting up the setting up the
configurator/registry/routes/views and all that stuff, if you don't
just use 'get_app()' to do it all in one step (which you may not want
to do in a unit test if you're just testing part of the application).

As for testing "persistence", it depends on what exactly you mean.
Usually you write some date, flush/expire the SQLAlchemy session, then
query it back to make sure it has the new value. You can do that all
in one transaction using flush in the middle and a single rollback at
the end. But other tests may require a real commit and then checking
in another web request. In that case anything you write will remain
there, or if you order the tests you can have a later test delete it,
but py.test doesn't seem to let you control the order of tests.
Although you can use a module fixture or session fixture as an
umbrella around multiple tests, perhaps to delete what the tests did.
Or you just leave the changes, and restore the database from backup
whenever you want to go back to the start state. I don't do the
"create the database or tables in every request", I start with a copy
of the real data that has accumulated, and keep the same tables
throughout the tests, and either rollback after every test or know
that some scratch data will accumulate. Depending on the test,
persisted scratch data from an earlier test may or may not matter.
> https://groups.google.com/d/msgid/pylons-discuss/r473Ps-10122i-69AD82F34B814C59AC3A361D0A5D8883%40Steves-iMac.local.
>
> For more options, visit https://groups.google.com/d/optout.



--
Mike Orr <slugg...@gmail.com>

Jonathan Vanasco

unread,
Jan 27, 2017, 10:42:48 AM1/27/17
to pylons-discuss


On Thursday, January 26, 2017 at 1:39:50 AM UTC-5, Steve Piercy wrote:
I'd be interested in hearing more, both for and against, about a switch. 

A strength of Pyramid is that you can complete a task in almost any way imaginable.  This translates to a bit of a weakness though, in that "testing" usually requires a bit of structure.

Without commenting on a "switch", i'd like to advocate that the cookiecutter templates included more sample tests that are somewhat structured for "best practices".  right now, it looks like the sample tests are limited to checking for cookies. 

I think it might be beneficial if the templates generated more tests that could serve as examples and "good practices" to extend on for different types of testing situations:

• A test that checks for the response having correct content
• A test that checks some CRUD at a low-level
• A test that checks come CRUD at a high-level, by simulating browser flow (form view, form submit, check the database)

Perhaps the scaffold could also prep for tox to run the test suite as well.  (and hey, maybe set it up a flake8 section in a 'setup.cfg' too?)

While the tests would break once anyone changes the code, that would prompt them to edit/replace/write-new tests.

(sorry if this is a double post, browser crashed. though i may have been logged in as my wife...)

Bert JW Regeer

unread,
Jan 27, 2017, 12:26:27 PM1/27/17
to pylons-...@googlegroups.com
I’d definitely be interested in seeing what this looks like, do you have a PR for the Pyramid cookie cutter?

Bert

Steve Piercy

unread,
Jan 27, 2017, 2:51:42 PM1/27/17
to pylons-...@googlegroups.com
On 1/27/17 at 10:26 AM, xist...@0x58.com (Bert JW Regeer) pronounced:
For the CRUD tests, use this repo:
https://github.com/Pylons/pyramid-cookiecutter-alchemy

More test examples for the cookiecutters are welcome.
https://github.com/Pylons/pyramid/issues/2868

We have a long list of issues that mention the need for more
tests in Pyramid docs.
https://github.com/Pylons/pyramid/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aopen%20test

--steve
Reply all
Reply to author
Forward
0 new messages