Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs suggestion - TestApp context manager #3329

Closed
jvanasco opened this issue Aug 17, 2018 · 4 comments
Closed

docs suggestion - TestApp context manager #3329

jvanasco opened this issue Aug 17, 2018 · 4 comments

Comments

@jvanasco
Copy link
Contributor

Writing some unittests for oAuth flows were a battle, because I needed a single instance of webtest.TestApp(app) that was used by two different consumers (client browser and client server), and TestApp stores it's cookies locally.

I ended up solving this with a context manger to swap the cookiejar out for a bit. I wanted to offer this for the narrative docs (or perhaps webtest?) because it eliminated so many headaches in our testing.

class IsolatedTestapp(object):
    """
    This class offers a ContextManger that uses it's own cookiejar

    Requirements:
        import webtest.app

    Attributes:
        ``testapp`` active ``webtest.TestApp`` instance
        ``cookiejar_original`` original cookiejar for testapp. It will be replaced on exit.
        ``cookiejar_local`` local cookiejar to context manager.
    """
    testapp = None
    cookiejar_original = None
    cookiejar_local = None

    def __init__(self, testapp, cookiejar=None):
        """
        args:
            ``testapp`` active ``webtest.TestApp`` instance
        kwargs:
            ``cookiejar`` standard library ``CookieJar`` compatible instance, or ``None`` to create an automated jar
        """
        self.testapp = testapp
        self.cookiejar_original = testapp.cookiejar
        if cookiejar is None:
            cookiejar = webtest.app.http_cookiejar.CookieJar(policy=webtest.app.CookiePolicy())
        self.cookiejar_local = testapp.cookiejar = cookiejar

    def __enter__(self):
        return self.testapp

    def __exit__(self, *args):
        self.testapp.cookiejar = self.cookiejar_original

Which is then used like the below, which will use a single testapp in which res1 and res3 use the default cookies but res2 uses it's own set.

        res1 = testapp.get('/endpoint/1', headers=req.headers, extra_environ=extra_environ, status=200)
        with IsolatedTestapp(testapp) as isolated_testapp:
            res2 = isolated_testapp.get('/endpoint/2', headers=req.headers, extra_environ=extra_environ, status=200)
        res3 = testapp.get('/endpoint/3', headers=req.headers, extra_environ=extra_environ, status=200)
@stevepiercy
Copy link
Member

A generic implementation would belong in WebTest docs, whereas one specific for Pyramid would belong either in https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/testing.html or https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/testing/index.html.

This use case seems rare to me, so I'm inclined to think it belongs in the Cookbook.

@jvanasco
Copy link
Contributor Author

I can generate some text for either, but it's the test-flow is not rare (while the use-case is). The same contextual cookie manager can be used for things like swapping out different users to ensure privacy permissions work. This actually let me migrate a lot of integrated tests that use requests against a live server, or mock connections with responses, into shorter much shorter tests.

@mmerickel
Copy link
Member

This needs to be submitted as a well formed PR to either the pyramid docs or to the cookbook. I would suggest the cookbook because we're way less strict on what patterns we advocate there and this looks like it fits the purpose of the cookbook perfectly.

With respect to the content itself, I can't see anything here that can't be accomplished by simply defining testapp1 and testapp2, each wrapping the app separately and maintaining their own cookiejars.

@jvanasco
Copy link
Contributor Author

@mmerickel that sounds like a great approach. i didn't realize TestApp was just a wrapper around a configured pyramid app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants