Building data-driven web apps with Flask and SQLAlchemy Transcripts
Chapter: Testing web apps
Lecture: Testing the register viewmodel
0:00 So, let's test this register view model here
0:03 in the form of the post.
0:05 So basically we're trying to simulate the
0:07 essence of this register post here.
0:10 So, we're going to define another method called test
0:12 and then, these methods
0:14 they're never interacted with directly
0:16 by other programmers
0:17 they're only called by the test framework
0:20 which means they can be really descriptive
0:22 because that will help us in our reports.
0:23 So, let's make this register validation when valid.
0:29 Okay, so something like that.
0:30 We want to test the registration view model
0:33 that it's working when the right validation
0:35 when the right data is passed to it.
0:37 Now, this whole test here
0:39 is going to come with quite the challenge
0:42 that you may see coming
0:44 you might not see coming
0:45 but there's couple of things we have to run into.
0:47 Working with Flask as well as some other stuff.
0:50 Now, I like to be a little explicit
0:52 when I write my tests
0:53 and typically I want to use this little pattern
0:56 that's nice and mnemonic
0:57 on organizing the code within your test
0:59 don't have to write it out usually but
1:02 I find this helpful.
1:03 So, it's called the three A's of testing.
1:06 I'll put it here.
1:07 So, the three A's are arrange, assert, and act.
1:10 So the first thing we're going to do is arrange
1:13 and what that means is we want to get everything setup
1:15 the way that it needs to be.
1:16 So, we're going to create some form data
1:19 and then we're going to do an act.
1:22 That is, try to do the actual login.
1:25 We're also going to need our view model up here.
1:27 So we'll say vm = RegisterViewModel.
1:32 We need to import it like so
1:34 it's not imported at the top.
1:36 That's good, but here, we run into the first challenge.
1:40 Remember how the registration view model works.
1:42 It's nice and simple, but dig into it
1:45 you can see the first thing that it does
1:47 is it starts going to the request dictionary
1:49 and asking for the name.
1:51 Oh, well, how do we even get that into Flask?
1:55 How's this going to work?
1:56 So, this actually takes a little bit of reorganization
2:00 and a little bit of extra work here to make this happen.
2:02 So what we can use is this context manager.
2:06 We're going to go ahead and say
2:07 with something
2:11 we're going to create this view model
2:13 and it's going to pull that data back.
2:15 How is, what do we put here.
2:17 Well, this is where we get into one of the challenges
2:19 of testing the web.
2:22 So, what I'm going to do is I'm goin to define another file over here
2:26 that's going to hold some of this data for us
2:28 I'll call this test_client.
2:30 It's going to have a couple of things
2:32 and this actually talked about
2:33 over on the Flask documentation
2:36 and what I'm going to do
2:37 is just drop some code in here
2:38 that sort of pre-configures Flask
2:40 and we'll just talk through it real quick.
2:42 In pytest you can create what's called a fixture
2:45 also, that if you pass a variable called client
2:49 it will actually run this function
2:51 and give back this object.
2:53 So, we're not actually working with this here yet.
2:56 We're just going to work with this part but
2:59 we'll need them both as we go through this class.
3:01 So here, I'm going to say flask_app
3:04 I guess I have to type it up here
3:07 from tests.test_client import flask_app
3:12 We're going to get this
3:13 and we're going to come down here
3:14 and with this thing we can say
3:16 Okay, we'll say request_context
3:19 and then here, what do we want to set.
3:20 We basically want to say
3:21 that the URL they're requesting
3:23 is account/register
3:26 so, if we look at the URL
3:27 it looks correct.
3:29 Then we can say the data is going to be form data.
3:33 Now, within this context manager
3:35 when this view model goes and says
3:37 give me the data back
3:38 get all of the data out of the form
3:40 guess what?
3:41 It's going to think that this is actually
3:44 the form that's being submitted.
3:46 So, this should make everything work
3:49 that we're hoping for.
3:50 Then we go down here and say validate.
3:52 All right, that's the action that we're taking
3:55 and then the assert is the third thing.
3:57 The assert is, once we've set up everything
4:00 we've done our action
4:01 and then we want to verify whatever test we want to test
4:04 but this is where we do it.
4:06 So, we're going to say assert vm.error is None.
4:10 We're going to say there's no error in this case.
4:13 Why, because we provided all the data
4:15 and theoretically, this is a unique user.
4:19 Now, it actually exists in the database
4:21 but that's not a problem.
4:22 We're not talking to the database.
4:24 Are we? Let's find out.
4:29 Hmmm. Looks like that test failed.
4:31 Let's go look and see what went wrong.
4:33 register.failed TypeError.
4:37 Oh, I used the wrong thing here.
4:38 This is not request_context, this is test_request_context.
4:44 There we go. Let's try again.
4:46 Now, we got another error.
4:47 Now, what's the error?
4:50 The error is oh, the password must be five characters.
4:52 I guess this is not going to work
4:56 be super explicit. There you go, six. Six a's.
5:01 Now, we're getting to a different error here.
5:04 What is the problem?
5:06 NoneType is not callable.
5:08 That sounds like a problem.
5:09 We're going to create this session here
5:13 what are we doing?
5:14 We're talking to the database
5:16 and then we're calling the factory
5:19 but the factory itself
5:21 remember we're trying to call this sessionmaker factory
5:24 to create a session and we're going to return it
5:26 but we haven't setup the database on purpose.
5:28 We don't want to talk to the database
5:30 but here we are confronted with this error
5:32 trying to talk to the database.
5:34 So, while everything looked like it was going pretty well
5:38 it turns out that even though we're running our test
5:41 we need to do a little bit more work
5:43 to make sure that we don't actually talk to the database.
5:47 Let's make that happen.