Thanks, that clarifies things. You're right that an integration test is more the way to go rather than trying to unit test this.
What is the most straightforward way to run integration tests that span multiple requests? I could do 1 DummyRequest to log in, then take those Set-Cookie headers on the response and create a new DummyRequest and manually turn them into Cookie headers, but this seems error-prone. It would be me trying to do the work of a web client (such as browser) manually (i.e. the part you mentioned "Browser will process the response from the view in step 2, update its cookies and send a new request."). For example, maybe I'll set a cookie that shouldn't have been set because of the cookie's "path" attribute, expiry time, or something else I didn't consider (but a browser or proper web client would). request1 = DummyRequest(post=........) response1 = views.login(request1) # What's the least error-prone way of turning all the Set-Cookie's from response1 into Cookie's in request2? request2 = DummyRequest(post=.........) response2 = views.someotherview(request2) I took a look at the Integration testing and Functional testing sections at http://docs.pylonsproject.org/docs/pyramid/en/latest/narr/testing.html but they don't mention such a workflow. Is my only option to use something at a much higher level like Selenium? Hopefully not, as I like the idea of asserting things at the level of the pyramid view (like asserting with a dict that is returned by a view for example). What I'd like to do is write some use case integration tests, like: 1. User goes to login view and enters correct credentials. User then goes to private view and tries to submit form. It works 2. User goes to login view and enters wrong credentials. User then goes to private view and tries to submit form. It fails because user isn't logged in Is there some way to make DummyRequest cookie-aware, where if I use the same instance of a single DummyRequest, the second time a view is called with that request it will have the cookies set by the first time a view was called with that request? (If not maybe that could be a useful feature?) For example maybe something like cookie_request = CookieRequest() request1 = cookie_request.get_dummy_request(post=......) response1 = views.login(request1) request2 = cookie_request.get_dummy_request(post=......) response2 = views.someotherview(request2) Where request2 has all the cookies it needs. Or am I missing a much simpler way of doing this? On Wednesday, August 20, 2014 10:35:28 AM UTC+2, Wichert Akkerman wrote: > > On 20 Aug 2014, at 10:09, pyramidX <[email protected] <javascript:>> > wrote: > > On Wednesday, August 20, 2014 8:21:05 AM UTC+2, Wichert Akkerman wrote: >> >> On 19 Aug 2014, at 23:13, pyramidX <[email protected]> wrote: >> >> I'm using DummyRequest in my tests to test authentication, this is what I >> return from the view when login succeeds >> >> headers = remember(request, email) >> return HTTPFound(location=next, headers=headers) >> >> >> >> This is my test >> >> request = testing.DummyRequest(post={'usr': '[email protected]', >> 'pwd': 'mypassword'}) >> view = views.login(request) >> print(view.headers) >> >> >> The returned value there is a response object. >> >> print(request.headers) >> >> >> The exact response here will vary a bit depending on your authentication >> policy. For auth_tkt you should see a couple of Set-Cookie headers that set >> the authentication cookie. If you use a session authentication policy you >> might not see anything here, or only a Set-Cookie header to set the session >> cookie. >> >> print(unauthenticated_userid(request)) >> print(authenticated_userid(request)) >> >> >> Those function only work on an incoming request, not on a response object. >> >> > Am I using it incorrectly? I'm passing it an instance of a request > (DummyRequest). > >> How can I test that authentication has worked? >> >> >> That depends a bit on your testing style. The most reliable method is to >> write an integration test and do a second request and check the response to >> see if authentication succeeded. The pure unit-test approach is to insert a >> mock for remember() and check if the headers returned by remember() show up >> in the response headers. >> > > For unit testing, using DummyRequest is not sufficient? In the view, I do > "headers = remember(request, email)" where request is a DummyRequest. > Shouldn't I be able to inspect the request object then and see the headers? > > > DummyRequest is just fine for tests. However the > (un)authenticated_userid() functions only work on an incoming request that > has all cookies set. In other words the normal authentication flow is: > > > 1. Pyramid app receives a request > 2. Pyramid calls your view, which uses remember() to create a response > which will setup the necessary HTTP headers to create an authentication > session. *At this point the original request is untouched, and thus > anonymous*. > 3. Browser will process the response from the view in step 2, update > its cookies and send a new request. > 4. Pyramid received new request, which now includes the cookies that > remember() set. > > > You are trying to use (un)authenticated_userid() at step 2, which will not > work. If I was writing a unit test I would do something like this: > > import mock > > with mock.patch(‘mypackage.myview.remember’, > return_value=[(‘header’, ‘value’)]): > response = view(DummyRequest()) > assert (‘header’, ‘value’) in response.header_list > > > > Maybe the problem is I've set up an auth policy in the project itself, but > not in the unit tests. I've set up AuthTkt in my project's __init__.py, > something like > > authn_policy = AuthTktAuthenticationPolicy('----------', hashalg= > 'sha512') > config.set_authentication_policy(authn_policy) > > > That is a separate issue, and would not be caught by a unit test like I > suggested above, and that is also why I said the most reliably way to test > authentication is with an integration test. If you want to do a pure unit > test you would want to write a second test that checks the authentication > policy is setup correctly. that would look something like this: > > app = your_function_to_create_your_wsgi_app() > request = DummyRequest(registry=app.registry) > headers = remember(request, ‘userid’) > assert headers # Make sure headers is not empty > > > That gives you two tests: a test that checks a valid authentication policy > is configured, and a test to check if any headers generated by your > authentication policy are included in the response. > > Regards, > Wichert. > > -- 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/pylons-discuss. For more options, visit https://groups.google.com/d/optout.
