 Hello, everyone. My name is Mario Parchera. Hard to pronounce for a non-Spanish speaker. And I work at Bloomberg. I'm here today to speak about testing doubles and the different kinds that we have and how to work with them in Python. So first of all, the clicker doesn't work. So first of all, so what are testing doubles? So testing doubles is just an object that looks like the original one, but where the creator is in control of its behavior. So as in the movies, you probably want your baby to be there. So you just put a testing double that you have control over just for the system and the test that you're testing. And you might be wondering, why do we need testing doubles? So you just leave uni. You go to a company and they tell you, hey, you need to test out this function, which is a really important function. We have no tests. We want you to write some tests for it and see if there's any bug. And this is going to predict the department expenses. So you say, OK, I've started this thing. I'm going to try some values, its cases, blah, blah, blah. Then you say, oh, whatever. I'm going to drop an array of numbers. I'm going to test a lot of things with different badges. Then your phone rings. And they tell you, hey, Mario, the whole management board is receiving emails about the department expenses for next year. Can you please stop doing whatever you do? So testing doubles are here to help you isolate the system under a test that you're testing. They are great to simulate the scenarios. Let's say that, for example, you want to try out what happens if when sending an email, which this function was doing and we didn't notice, what happens if when sending an email something fails. And it's also good to be able to scope your tests. So the first of all is, how do you create them in Python? Because we just said that testing doubles are just objects that can be used to replace other objects. Which you can just create, for example, here, this is Mario double, my name is Mario. You can just create this object that could behave as a real Mario. But in Python, we are lucky that we have the mock library within the mock module within unit test. But just using, for example, the mock class, you can create this kind of object much easily, as we'll see in the following slides. So this whole talk is around testing double. And sometimes, you might not need mock at all. For example, in some situations, you might have a class. Well, you might have a function that you want to test. Or you might have arguments that you just want to fail. In those situations, a good testing double can just be simply known or a string. This is known. So there's a lot of naming conventions around testing and testing doubles and the kind of testing double. If you're interested, I'm going to put a lot of links at the end. For those of you quite familiar with testing, I'm going to put how this is referred by Mesos and other philosophers of testing that you can find out in the wild. This is known as a dummy. And it's just basically a testing double that you just use to basically fill a parameter. There's no behavior you want to control. There's nothing you want to do around them, but just basically fill a parameter. But things get more interesting. And it can happen that you have this function that is checking if the email sender. So this function is now taking the email sender, so we won't make the main mistake as before. And it's just checking if the email sender is enabled and then just sending the email. So as we said, we have this mock class that helps us create this kind of testing doubles. We can use it in this way, which all it's going to do is create this kind of object, as we saw before, that we can create manually. But in this case, it's just going to create this object where when you call it, it's just going to return success. And when you pull his attribute is enabled, it's just going to return true. So with this way, we can easily create a mock. And I want to ask you guys, I want to know if this is too basic. How many people already knew all this? Well, is there anyone here who didn't knew this? OK, so I'll speed up. Don't worry, there is more advanced contents later in the slides. So OK, so this is all good. When you're creating mocks, it can also happen when you're using what's known as a stop in the testing terminology. You might not even care what's inside. You just want to fill the parameter, but still the object is being interacted within the function of your testing. And you can just basically create a mock. This is something really cool about mocks in Python. Mocks will automatically create child mocks whenever you access a property of them. So what this means is that in this function, when you call email sender, which is a mock, and you call dot is enabled, this is going to return a mock. Or when you call the mail sender, it's going to return a mock. Every single time you call any method in a mock, it's just going to return you a child mock. OK, so this is all cool. But then it can happen as well that within your function, you might be using what's called magic methods. And in this situation, if you run this with a mock, as we saw before, this is going to race because the mocks don't have implemented magic method. So basically, you use a magic mock, which is a mock with magic methods. The only magic method which is actually implemented in mock is call. Call is implemented both in mock and magic. But for the rest, you need to use a magic one. But let's speed up, because we said all of you already know this. OK, yes. So really quickly, what can you do with mocks when you want to define behavior, and you want to instrument it to do more complex behavior than we saw before? We said that you can use, for example, return value to say what's going to return whenever you call it. You can also use side effect. You can pass a list of values that are going to be returned in order. So here, if you call, for example, email sender four times, it's going to return first two, 10, 20, and zero. If you call it again, it will raise stop iteration. You can use side effect to raise exceptions. And you can also use side effect to call a function. Has anyone seen anything that they haven't seen before so far? Raise points? OK, it's going up at least. That makes me feel a little bit better. But what happens if, as we saw in the first example, the object that we want to patch, well, sorry, the object that we want to use at testing double is an internal dependency of the function? Here you can see that the function doesn't take email sender as an argument, but it can be a class that has it as an attribute, or it can be some kind of a global object. So in this situation, we have the mock library has a patch function that you can pass a string and it will just replace whatever you have in there for a magic mock. This can be used as a decorator, or as a context manager, or manually. And then, basically, it returns you the magic mock that it substitutes the object with, and then you can control how it's going to behave. If we have time, which I'm sure we will, because I'm going to go fast, we'll see how this actually works, which is quite cool. The patch function has a couple of arguments that allows you to, so as we said by default, it's going to create the magic mock. You can change what it creates. You can also change the object that you want to pass in if you want to put your own object, and we'll see some more afterwards. You can also verify the interactions that you have with your mock. So here, we said we are passing a mock that's going to intrate and provide internally to it into the function. And we can also do this with, which is going to check that the mock was called with those arguments. Does it make sense? Has anyone noticed the bug? Because this is going to fail. So this last function is going to erase. This send email has never been called, because here, what the function is actually calling is send mail. This is, I think, the thing I hate the most about mock. So when we are working with mocks, which are testing doubles that try to verify the interactions, the mock object, well, the mock class in the mock module of the unit test library, sometimes can play against you. So how do you solve these kind of situations? So you can use spec. Spec allows you to make your testing. Well, it allows you to make your mock have the same interface as the object that you are mocking. So here, if you pass mailing, which is like an existing class, the mock is going to have the same interface. And if you try to use something that's not part of IndeedFail, like send email, because we saw that the original one was send mail, this is going to raise an attribute error. When you're using patch, there is an argument that you can pass, which is called autospec. And because you are patching an existing object, it will be able to infer as well the interface from here. OK. Now, this is all cool. But then you have this. So you go to the training, and they tell you what spec. Yeah, you always have the spec. It's so great. But Python and typing, and how is spec going to figure out what the mock is going to return? Because if you use spec here, for example, on your mock in this, when you call send email, well, send mail, what that's going to return is just a mock, a magic mock. And that magic mock doesn't have a spec, right? So how do you fix that? How do you work with that? And the thing is, because we have the test like that, and we're working with a mock, what we're doing is we create the magic mock here, right? We then, sorry, so this email sender is actually a mock. So here, we define the expectation and the behavior of the mock. We are then going to call the method here. But if this function that we are testing calls anything in the mock that's outside of this specification, it's going to fail. And you can see here, there is not the problem, which is that we are calling dot data here, and we are doing dot payload. And again, this assert call is going to fail. But this is going to go through smoothly. And if you're working with a mock that we want to verify how it works, you ideally want it to fail here, right? Because this is not what you define. So you can see that when you're writing a test and you're using a mock, what you really want is, OK, I declare the mock, I declare its behavior. Here is ultra useful the property of creating child mocks. But here, I don't want child mocks. If I'm working with a mock that I'm going to verify the behavior, I don't want it to create child mocks. If you have worked with G mocks, for example, in C++, they have different type of mocks, so you can handle this. And this is the good news. From Python 3.7, you have a new function called seal where you can freeze a mock. Who has seen this before? Who has seen seal? Hands up. Great. Yes. So now you can do seal. And seal is recursively going to freeze your whole mock. This will allow you to effectively now define your mock, seal it, freeze it. That's the behavior it's going to have. And when you pass it to this function, if there is something that doesn't match, it will like the real object. Well, like the object you define. So it's going to raise an exception. Yes. Now, something I find extremely useful is if you have done JavaScript, you know what spies are. Basically, sometimes you have a real object that you want to pass to a function. But you want to verify the function, how the function interacts with it. So with mock, you can have the wraps keyword. And what this is going to do, this is going to say, hey, create the mock. And I want the mock to whatever function that's being called, just pass it to the real object. But I want you to record all the interaction that it's doing so then I can assert on them. So not only we can, well, as all the mocks, we can then verify the interaction with them. We can get the arguments that we're calling. So it's basically recording everything that happened. And you can verify how the function that you're testing is interacting with others. This can happen. This can be useful, for example, if you have your calling. If you have some integration test where you're calling outside, you'd still want it to go outside. You want to call it to a fake database or something like that. And you don't want to re-implement the whole thing, but you just want to be able to record what's going on. This is really handy. OK. So basically, we've seen, I haven't flown through the naming, sorry about that. I shouldn't have explained you what the names are. This is on the slides online. So there are diamonds, fakes, studs, spies, and mocks, which is basically the namings for different use cases of the mock. We see that how unit test.mock can help you create them. How patch can be used to testing double song internal dependencies. How you can use spec or seal to freeze your mock. And how RAPS allows you to create spies. Now, if there is something I want you to take away from this talk, is there anyone from the organization here? Because they are not going to like that. But if there is something I want you to try out in this conference, in this trip to Edinburgh, is there anyone here from outside Scotland? OK, amazing. So there's something you have to try before you leave your Python. And it's a deep fried Mars bar. I'm hooked to them. But anyway, we have time for more content. So I'm going to show as well some other features of the mock libraries. So this is what's called sentinels. Basically, there are some situations, like the first example we saw, where you might have an argument that you might just pass through an internal dependency of the functions, and you want to verify. So you can pass a string, for example, a lot of money. I have a problem coming with strings, because I was wondering, is the function actually returning what I tell him to return? Or is it internally going to be like that? So mock had what's called a sentinel. And basically, it allows you to create unit objects. But just calling, for example, here, you see unitest.morgan.sentinel. And you can do sentinel.budget. And that's always a unique object. So you can assert on it. It's just handy. But I'm sure many people have had problems with patch. Who has had problems when patching things and they don't work, right? Great. So these three slides ideally will solve for your problems from now on. So how does patch actually work? The thing is, when you try to patch something, what's going to happen is the mock model is going to go to, well, you're passing this string, right? That this string is half to set, and attribute to set. And all that mock is going to do is it's going to do a setator on it. So as we saw that the patch has different key word arguments to the different magic, but here we're just going to focus on the basic one. So this is just going to do a setator. And the way it works is, so here you have the package module target. And you say, hey, I want to patch package module target. So what's going to do? Magic mocks on it, right? That's easy to understand. Now what happens when you have a real program and you have this myfile.py, and it's import target, if you tell unittest.mock to, hey, can you please patch package module target? What's going to do? It's going to go to package module target and put a magic mode there. Is that what you want? Nope. What you want is to patch that one, right? But because what's doing is it's going to the namespace here, going to target and just doing a setator. It's not what you expected it to do. So what you wanted to do is you want to patch target in myfile. If you do that, mock is just going to do it and put it there, which is what you want. So whenever you are patching anything, remember to patch where you are using. That's usually the easiest way to understand that. If you understand that all that patch is doing is literally going to the dictionary of the namespace or whatever you are telling him to go, and then patching that doing a setator on the target, it will be much easier to mentally understand what's actually going on. Also, as a bonus, when you do patch, you can, as we say, patch a new. And if you're trying to patch something that still doesn't exist, a patch has a keyword argument called create that instead of doing the setator, will actually put something there. So you can do a patch even if that doesn't exist. But well, the key on how that patch work and if you have problems with that is always patch wherever you're using it. And then all problems go away. OK. How are you doing with it? OK, great. So next thing, something I loved. How many people here use PyTest? Great. So if you combine PyTest with Mox, you can do something really cool, which is you can create fixtures that are just Mox. And if you have really big Mox, which can happen on foot on through, you can just create, for example, this is a super simplified version that you can create this, for example, all system Mox. And you can just depend on them. And you can define the behavior in a single fixture. And this will be quite useful because you won't have to repeat them. Something that happens quite often when you're patching, if you have multiple Mox that you're patching the function and you're passing it as arguments, is remember that because of what patch is going to do is, it's going to patch the oldest thing. And then when you use it as a decorator, it's going to add an argument at the end that gives you the mode that you're working on. So if you have two patches, remember that the first patch, I should have put a slide about this, the first patch will be the last argument. The second patch will be the second argument. Just think on how it works, which is that it's appending at the end when you decode the decorator. It's a little bit weird at the beginning. But if you see it as it works, which is probably not the best answer, you can understand why it works like that. If you use a lot of Mox, you say, wow, this is amazing, right? I can mock all my stuff. If you use a lot of Mox, it can happen that when you are debugging, you're seeing your logs and everything, you see things like this, which is rather unuseful. So Mox has a keyword argument when you create them called name. And you can name your Mox. And whenever you use wrapper or a string, because you are printing them or checking them in PDB, you can see which Mox you were referring. If you then use the child Mox thing where you are accessing interviews, you will also see the whole name of it, which is quite handy. And we have time for Kahoot. So as I told you about the Mars bar, I really like Sweet. And how many people have tried this? This is a UK Sweet, which is absolutely amazing. So we are going to do a quiz. And the person who wins takes this. And it's about Mox. So if you have a phone, you can go to kahoot.it. And let me bring that up. I want to have this thing. Also, you'll get all the glory of being the person who won. One second, internet. Come on, you can do it. So you can put choo choo choo choo. Has anyone played Kahoot before? So there should be a code somewhere here. So if you go to kahoot.it, you can put that code. Names will start to appear. And we'll start with a quiz. Four questions. The fastest and correct one will win the T-cups. I love them. I have like five of them at home. Let's give 10 seconds. I have five minutes. OK, plus questions? Plus questions? Great. OK, let's go. Ooh, still people joining? 7-4-3-7-7. You see the room number. So there we go. Full screen. So the first of all is who is the original art of the Mox module, which is around the conference. You can back him. So Michael Ford, Victor Stiner, Ron Obius, or the Blackknife. Hey, hey, hey, hey, hey. It was not that easy. It gets harder. There's a stop. Which of the following aloes to create the spy? So yeah, which of those ones, or we can create spies in Python? He puts your music. Cool. That was easy. So you were actually paying attention. Wow. I should tell my family this. OK, which of the following lines will erase? You'll have some more time here. So you can choose. So this is the code. And it's either A, B, or none of them. So we're using SEAL here. You remember SEAL would recursively freeze all your Mox? And here we see that we have Mox, Colourable 1, Python. So it was the blue one. Why was that? So there's something I didn't tell you. So you fail these questions specifically, which is that when you SEAL a Mox, it will only SEAL recursively. As far as the Mox is a child Mox of the Mox you are sealing. So what that means is that here when you do Mox.Colourable, this Mox that is being automatically created is marked as a child of the first one. But as a way to be able to disable this recursiveness on SEAL, if you pass your own Mox, it won't SEAL it. So it's basically going through the child's rather than checking all the Mox inside. That was tricky, right? And the last one, another, I like exceptions. So there you go. So you have Mox.Cold. This is a normal Mox, not SEAL or anything. Mox.Cold, Mox.AssertFakeCold, Mox.Assert on scoreCold. Which one will fail? Is any of them going to raise an exception? This one was, whoa, are you serious? This one was really hard. OK, wow, I'm impressed. You should come and give the talk instead of me. So for both of you that either hit all of them by mistake or like, hey, let's try it out. So Cold is raising an exception because Cold is actually an attribute of Mox and it just returns a number. And if you try to call numbers, it's going to raise an exception. Now AssertFakeCold, if I were you, I would have expected that to create a child Mox. But it doesn't because there was a check in the Mox library that if the name starts by Assert on the score, well, by Assert, it's going to raise. Because there were so many mistakes about people mistyping something and then you are in this situation where like, is the test passing because the Assert actually work or is the test passing because the Assert is created in a child Mox? So there were so many types of typos with that that there is now a check that if it's Assert, it will raise if it starts with Assert. And the third one, which I'm impressed you knew about it, there is also a check in case you mistyped Assert. And you do Assert. Wow, you're amazing. Okay, so, Philly, who's Philly? Oh, no, are you serious? Come on, man. Please, a hand for Philly. Okay, so with that, I'll upload the slides. You have a bunch of links here. The Mox module itself is kind of easy to read if you dare. And then some other slides about testing in general and a cool talk if you want to know more about the patch function and, well, the module itself. And now should be time for questions. When anyone of you has questions, you can just come in front of the mic. Either question for Mario or for me, the raceful winner. Yeah, you should take them all. So, any questions for Mario? Any question for him? Okay, so there are a lot of questions. Then let's give a thank you for Mario for his... Thank you. Thank you.