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 email@example.com. 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.