Building Data-Driven Web Apps with Flask and SQLAlchemy Transcripts
Chapter: Testing web apps
Lecture: Integrated tests
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
It's time to do a full test part of our application the so-called integration test. Where we fire up all of Flask, run all of our application
0:09
send a request through the Flask infrastructure into our view methods, do the process in there and get the result all the way back out.
0:16
And I'm going to do one test method here a test of a single method here so that you can see how it works.
0:22
We're going to test this index for the account. So there's two scenarios. One, if there is a user around
0:29
then they should be able to see their account page. If they don't have a user logged in remember, what it's going to do is, over here
0:35
it will redirect you to account/login. So that's the kind of thing that we want to test but we're going to do it in the full-featured way.
0:42
Now, how do we do that? Let's go down here, I'm going to define another test method. And I'm, did a little renaming here.
0:49
I started calling these tests test_vm and then down here for just the views test:v, then off test:int for integration and then what we want to test is
1:00
account home, let's suppose you are not logged in. Okay, so that's the test we are going to do first. How do we do that?
1:09
Can we just go fire up, you now import the app and call run? No, it's not going work. It'll actually really run flask, we don't want that.
1:18
So this is where our cool little fixture our pytest fixture comes in. So we're going to go over to this thing
1:24
and we're going to say that this here takes a client and that corresponds this right here. And what it does is, when you pass it as a variable
1:34
it's going to pass the return value, here, in there. So we're going to go in and get our test client
1:41
from our flask_app and we're going to register the routes the blueprints, set up the DB maybe in the end we don't really want to use it
1:48
but sometimes you'll see we do want to use the database and then we'll yield out a client here. So then what we're just going to do
1:55
is something super super simple. We're going to say a response which is a response = client.get that's it. What do you want to get slash account.
2:06
Which can get slash account. Then we can make various assertions. Like we can assert that response dot status code is let's say, 200.
2:16
Now, is this going to work? Is it going to let us go in there? It's unlikely we're not going to be logged in
2:21
it should probably be a three or two redirect. So let's just run this, see that's actually operates gives us error and then we'll switch it over
2:29
to the right redirect code and check the location. In order for this to work we have to import client appear like so. Alright. Let's run this again.
2:40
ohh, what did we get? There's an error. It sent us a three or two that's a redirect code. Where do they want us to redirect to?
2:48
Well that's kind of what we wanted. So let's say this is task code direct two and we'll say location is going to be
2:53
/account/login. This should pass. It doesn't. What have I messed up here? Ahh, HTTP localhost login, okay. That's not quite what I was hoping for
3:06
but it's going to be just fine. But that is the effect we were looking for. Let's run one more time. There you go. Perfect.
3:15
So now we've done a test all the way through. However, did that run, did that hit the database? Well, no, but it might have.
3:23
It might have tried and why would it potentially try? Because if we go over here it's going to this IndexViewModel which is going find user by user_id.
3:33
So I guess it probably did hit the database, yeah. It didn't get a result back because we didn't pass some kind of user_id but nonetheless
3:40
it probably did try to go to the database. So here we need to mock this out if we want to make that not happen.
3:46
So I guess the last thing that we should do here is go ahead a do with unittest.mock.patch target and return of value that is none.
3:59
And the target going to be, let's see pypi_org.services.user_service.find_user_by_email okay so this probably won't look any different to you
4:11
but the actual behavior is different. Let's do one more. Let's supposed that we do want to test the case when they have a login. Say with login.
4:20
So here what we want to do is create a test user which is going to be a user and the name is going to be Micheal and the email
4:30
is going to be michaeal@talkpython.fm. And so when they ask for the user we're going to send back the test user and we can go ahead and run this
4:41
this will fail because it's no longer redirect hopefully fails because the left is 200, just like we hoped. So we can again check that
4:51
but we can also check in data we can go and assert that, something like Micheal remember it says, "welcome Micheal" or something like that
5:00
is in response on data. Now this gets a little trick cause that's binary so we have to put a b here. Let's give a shot and it still passes.
5:11
All right so these two right here show us how we can use the client pytest fixture to do integration testing with our app
5:19
and we can either as we saw in this first case choose to let it hit the database or if once we applied our mocking
5:28
and definitely here, once we applied our mocking it actually no longer hit the database. So most cases you don't want to let it hit the database
5:35
but when we get to this site map testing you might actually want to let it do that there.