 Yeah. Thank you. Hi. Good afternoon, everyone. Welcome to the second session. And the next speaker is Michael from previous next. He's a senior developer at previous next. And he's going to talk about X debug. And if you after the session for the round table discussions, if you want to be part of the discussion or come on the screen, please just raise your hand. And then we will, we will make you part of the discussion on the screen. And over to you, Michael. Thanks for that. As he mentioned, I'm going to be talking about X debug. For this session, we're going to be using PHP storm and D dev. You can use any local environment you'd like. You can use land or you can use VS code or anything like that. And we're also just going to be debugging this basic triple site that uses the migrate module to pull in homebrew recipes from a JSON feed. So to get started, we're going to talk about some debugging concepts. And then we're going to go through some practical examples and some configuration at the end. So the first, the concept that I want to talk about is break points. So perhaps if you haven't used X debug before, maybe you have done something like this where you want to see the value of a variable. So you put in a bar dump and then load up the page in your browser and then realize, hang on, that's not the variable I want. And you rinse and repeat until you finally get the right information that you're looking for. That's not what I'm talking about with break points. And perhaps you've put in a triple add message into an if statement or a loop or something like that to try and see if your code's actually being run. And again, that's not what I'm talking about here. I know to some of you, XD bug will be second nature. So hopefully there's something for you to learn as well. So I'm going to jump right into PHP storm here and show you how to set a break point. So essentially this is massaging the JSON feed before we actually process it in my great API. So what I want to do is just stick, click in the left column here. It's going to put a nice red circle and that's going to indicate that as a break point there. Then we have to make sure that we're listening for XD bug connections and then simply load up this page in the browser and XD bugs going to trigger straight away. So what we can see here is this is the stack trace of everything that's come before where we are now. And this section here shows the current variables that are in scope. So we've got the URL which is passed into this function. We've got the current object, this and all of these superglobals as well. So once we've reached our break point that we can begin doing our step debugging. So basically we've got these buttons across here where I can hit step over, which is just going to evaluate the current line of code. And then I'll be able to see the new variables that are available. So response which came from line 31 there. And we can continue hitting step over and inspecting, you know, what's changed. Finally, when we come to a function call where we actually want to jump into it and see what's happening inside that function, we can hit step into. And that's going to jump us down to that piece of code. It could be in another file or in the same file. And that's going to get added to the stack trace here. So then this is a for each loop. So if we just keep stepping over and doing our debugging, you know, having a look at what's changing. And we realize, OK, we no longer want to be in this loop. It's actually going to iterate, I think, 50 times here. We don't want to just keep clicking through it. So we can then hit step out. And that's going to return us back to where we came from. And then finally, once we've finished, we just want to let the page keep loading. We'll just hit resume over here. And that's actually going to take us. This function gets called multiple times on this page. So it's actually going to break again. Or if we had other break points that are reached, it'll break on those. But if we just want to let the page keep running, we can just mute the break points here and hit resume. So the next concept is the debugging console. So I'm actually just going to reload this page again. OK, and the debugging console is just on this button here. So if we just skip over this line, we can see here's that response object here. We look at this stream. It's actually a resource and we can't really do anything with it. We can't see what it is. So we can jump into the console and we can start typing. We can basically evaluate any PHP expression. So response.getContents and we can have a look at what's in it. So that can be really handy if you think, you know, you want to change some logic in this function and you want to kind of draft it up and see in real time the output that you're going to get from it. And, you know, that can be a lot better than basically typing it straight into here and reloading the page and then going back and forth every time you get it wrong. The next thing I want to talk about is conditional breakpoints. So as I mentioned, this is a data migration. And let's say we just happen to notice that one of the nodes that was imported has some data missing. So on this one here, the mesh temperature, there's no value there. So we want to know what's going on. So I'm going to debug the actual migration itself. So I'm just going to grab the get plugin from the migrate module and I'm going to pop a breakpoint into this transform method here just so we can inspect each of the values that are coming into the migration. So I've got the breakpoint there. I'm going to run, this is the migrate commands. And it's going to break on the first row of the migration. We can jump into the console again and have a look at, let's say, row.getSourceProperty. And we can see that it's number one here. We're actually looking for, it was number 169 was the problematic one. So basically what we can, you know, keep stepping through it and reevaluating this, we're going to see, okay, now we're on row two and it's going to take a long time to keep clicking through until we get to 169. So what we can do is grab that expression here and right click on the breakpoint and place it in as a condition. So when that is equal to 169, that's when we want to break. So just resume the program and, you know, here's the migration happening and that should break once we get to that particular ID. So let's have a look at the source. So there we are, BRID 169. And we can see, okay, the temperature value is null, which is probably the problem here. So I was actually also going to show you there's a watch column here. So basically any of these expressions can be added to a watch list. So I'm just going to remove the condition on this breakpoint and keep stepping through it. You can see, so the value of it here has changed to number 170. So basically if you want to keep track of a variable or an expression or anything like that, you can add it as a watch. If I move that breakpoint down towards the return statement, you can keep track of the return value. So it's 68 in this particular row where the ID is 171. You know, kind of do your debugging that way. So now onto some more debugging scenarios. So you've seen debugging the browser. You can also debug Josh commands or PHP unit on the command line. But you do have to make sure that this environment variable is set. I'm going to go over some config stuff a bit later. But indeed, this is set for you automatically. The next thing you can do is run your PHP unit tests directly in PHP Storm without having to invoke it on the command line. So I've written a blog post to show you how to set that up because I'm not going to have time to go all the way through it. And there's a instructional video as well for how you can go from nothing to a full running Drupal site where you can debug all sorts of tests in there. So check that out if you have time. But I will just give you a quick demo. So I'm just going to open up the node module because it has a whole bunch of different tests. So if we have a look at this unit tests, we can pop a breakpoint inside a test. And we've got this little icon here that lets me click on it and hit debug. And that will break inside the test and we can have a look at what's going on. Similarly, you can do the same thing for kernel tests, functional tests, functional JavaScript tests. For this site, I'm using Drupal test traits which you may have seen before. But what's interesting here is you might want to debug the test itself, but you may also want to test the Drupal site that is being run behind the test. So here we can set a breakpoint in the test, but we can also set a breakpoint in the Drupal site. So I'm going to stick it in index.php. And then if I hit debug here, it should break first in my test. Okay, here we are and we're going to step over this and it's going to try and visit node one in the headless Chrome browser. And here we are, it's breaking inside the Drupal site so we can debug the Drupal site as well as the test. Okay, so to get started with XD bug, it's going to depend a lot on what environment you're using. So if you're using DDEV, a lot of it sort of works out of the box. And Lando does a fair bit in that way as well. So in your Lando file, you need to add this config XD bug setting. In DDEV, you can just enable it on the command line with DDEV XD bug on. And if you're building your own docker images, you'll have to install the extension and enable it. And that's probably similar if you're using a local server like BAMP or XAMP or something similar like that. Then there's a few key configuration variables. Just by the way, I'm talking about XD bug 3 here. Everything's a bit different in XD bug 2 and I'd suggest just jump straight ahead to XD bug 3. It's a lot more performance as well and easier to configure. So if we set the XD bug mode to debug, that's going to enable our step debugging. The client host setting resolves the docker container to your local machine. And the client port is where PHP Storm is going to listen for connections. And finally, this start with the request can be set to either yes or trigger. So if it's yes, every single PHP request is going to try and connect back to your debugger, PHP Storm or whatever. Or if it's set to trigger, then you need to use a browser extension or an environment variable to basically tell XD bug you want to start doing debugging. And that extension is called XD bug helper. So in your IDE, this is PHP Storm. You need to make sure you've got your port numbers configured the same as you had that extension configured. This is the default out of the box. Again, make sure you're using the latest version of PHP Storm, which supports XD bug 3. And you can click this validate button up here, which brings up this dialogue where if everything works correctly, you should get all these green ticks to say that XD bug is working. And finally, you need to make sure that XD bug or PHP Storm knows about your server. So on this, on DDEV, the absolute path to your code on the server is via www.html. And that's got a map to where the project is on your local machine. You don't need to worry about mapping the vendor directory or the web directory just as long as you've got the whole project mapped out. And the host needs to map, needs to match the domain name in your browser. This is the browser extension I was talking about earlier. There's one for Firefox and one for Chrome. Otherwise, just use DDEV XD bug on, which will use the start with request equals yes setting. And you can turn it on and off. I'm not going to have time to go through the configuration for these tests, but I'll refer back to the blog post. So if you can paste a link into the chat, that would be great. So yeah, we're running a code sprint tomorrow. Debugging is probably going to be pretty helpful. So come along, give it a try and see what you can contribute tomorrow. Thanks for the presentation, Michael. If anybody wants to share or just general discussions on backend and testing, development and testing, just raise your hand and bring you to the screen or you can even just put question or a discussion topic in the live Q&A, which is in the control panel of your screen. I would like to share another thing which we have. Basically, you know, the XD bug has also another option called startup on error. And that's essentially, you know, you just basically, you know, any error, any exception thrown in your PHP code, XD bug will stop there. It's like a break point on every error, which is very helpful when you're mostly doing the, what do we say, console-based applications or, you know, grass-based imports and stuff like that. There is one question for you, Michael. How can you add watch to a specific variable from Liton? How can you add a watch to a specific variable? That's right. Yeah, okay. So let me just bring that back up. So basically this watch's column here, you can hit this new watch and you can basically type in, you know, anything that's available. So if I put source data there, it's going to be, there's nothing in it. But if I, let me put a break point in here. The source data is null. If I skip over it, skip over again, there we are. So like that. There's also a setting that may be relevant. Some expressions can't be evaluated or can't be watched because they could be risky because they can actually change values. But if you know what you're doing and you want to add them anyway, there's a setting here, safe evaluation mode in value hints and watchers frame. And I think that may have actually been used where I was, it was in the, when I was doing a row dot get source. Something like that. Yeah, does that answer the question? Yeah. Does anyone here want to share the experience with X debug or their setup in their own organization or something? If not, I'll continue the discussion of the beat head versus Drupal testing traits. So, you know, in our organization, we've been using beat head for a while and, you know, it was taking almost, you know, so many hours to do it. And then we switched to Drupal traits testing traits, which saved a lot of time. And, you know, those hours now just became minutes. And, you know, we can do a functional test, all of the kernel test using those threads. And they've been very helpful. So can you explain a little bit what Drupal test traits are? So what's the difference between that and a beat head test and a, you know, a core functional test? So basically, you know, three types of tests we do, like functional unit test and kernel test. So Drupal test traits kind of beat head test is like a functional test and you are replacing a person going and clicking a button, right? And the functional test, you know, you do it under the, you know, a headless Chrome browser, which is basically essentially a computer doing the same thing. You know, your test case is just going and clicking instead of a person. And so beat head was, you know, using, you know, another language which was naturally, you know, like you can write natural expressions and stuff like that while Drupal test traits is, you know, is the similar logic, but Drupal test that is all PHP. You don't have to interpret your things. And, you know, you can just write your functional test naturally with, you know, with use cases and test cases using, using PHP unit framework, which was why it's more faster than, you know, a beat head once. And so, you know, I'll show you, I can show you one piece of code with my help just to give you and let me just see. Can you guys see my screen? Yeah, cool. So I'll just quickly share my which is strong. Yeah. So, and for example, you know, and another side, where we just basically use this functional test. And it's very clearly saying, you know, just going to the page and clicking, so I'll just show you this one. So it's creating a landing page, which is essentially, you know, a Drupal node. And, and then, you know, we're finding an element with, you know, with basically, so let me just zoom so people can see. We're going to that URL, you know, finding an element with certain ID, you know, and then if the element exists, you know, we just want to basically add some values to that element. And, you know, and it submits the form just like you click on the submit button. And then, you know, a certain whether it's, you know, actually, you know, doing the, we actually got the right search time in the URL or not. So this is just a small example. But essentially, you can, you can do, you know, many things like this, you know, using the Drupal test rates. So I'm just trying to see if I can share we and see their scenario there. Meanwhile, meanwhile, I would really appreciate if somebody else also want to probably share their setup, how they do debugging and testing. Yeah, we don't need to be focusing just on debugging. So if there's any sort of backend tool or process or whatever that you use that you want to share, that'll be great. Something that we have been talking about was code quality tools. So things like PHP Stan, you know, Coder module, anything like that. If anyone has any of that to share. Has anybody using PHP Stan for the CI CD pipeline or testings? Yeah, we have it enabled on every pull request. Yeah. Do you want to run quickly what is PHP Stan? Yeah. So I guess PHP Stan is a static analysis tool that inspects your codes for potential errors. And it can be set to various levels depending on how strict you want to be. So it's going to detect, for example, maybe you're passing the result of a function to another function. Let's say it's like you pass something to an array, but perhaps it might not be an array that's being passed. It's going to, like, if there's a potential that it's not going to be an array, it's going to say, hang on, this could actually be null. And an array doesn't know how to handle that. So PHP Stan is going to detect that for you. Depending on what level you've got it set. We're also using for CI CD pipelines. Yeah. So we've got a couple of people. So Michael Priest and Bevan talking about. So Michael is using PHP Stan and Code Sniffer in CI. Bevan, yes, you do need to add it to your tooling chain. For Drupal 10, we're going to be requiring Drupal PHP 8 or perhaps even PHP 8.1. And I know there's a process at the moment where Garbo is trying to get the upgrade status module to run PHP Stan against every contrived module that's out there to detect PHP 8 compatibility issues. So, yeah, if you need to do a PHP version upgrade, then it's a great tool to use. Another very good tool we found for the, for the testing specifically for kernel testing is called Prophecy. I'm sure a lot of people would be using that to mark the objects. And, you know, it's a great tool as well to, you know, test the logic of your classes rather than, you know, the functionality. So, so that made difference between functional and kernel would be the functional test takes more time because it's actually your machine going and clicking things and, you know, evaluating results. Sometimes they time out as well. But, you know, with kernel test, it's just testing the logic, right? So it's mostly, you know, a very lightweight wrapper around how you're going to test things. And you can, with Prophecy, you can create literally, you know, any type of objects existing in your system. You can expect output and then you can basically, you know, test your things. So I just have a question. And this is for everyone. How does the, you know, how Drupal Core does it right? What's basically Drupal Core's way of testing core and contrary modules? We see that, you know, sometimes when you submit a patch, it says the test field and test. So I've, you know, readily clicked on it and found a Jenkins job. But I was always being interested if somebody want to share in their experience. Maybe, Michael, have you ever come across? Yeah, I'm just going to, can I share my screen again? Yeah, sure. Let's have a look. So when a patch is submitted on Drupal.org. So it's going to run the Drupal test spot automatically. It's running 28,000 tests, which can take, I think it takes about an hour. So yeah, if we click into the dispatcher, we can actually have a look at what's actually being run. So we've got the, the console output here shows you, you know, every single test that's been run. And basically for a patch to get accepted, every single test has to pass. And you need to be writing a test for the new piece of functionality or the bug that's being fixed as well. What else can we see? We can see the build artifacts. So from here, if you have a look at like, yeah, you can have a look at, that's going to try and download the file. But basically you can, you know, have a look at the error log if there's a problem. Any of the artifacts from running the tests you can find in here. And this runs on Contrib modules as well. If the project is configured to do it. I've got a question from Morad Farshid about, are you able to show a scenario where, where I can use extBug browser extension? Yeah, sure. So it's a bit tricky because DDEV is configured. Let me show you. So I'll just close all of this. If I say DDEV extBug off, and I put a breakpoint just in index.php, I had to load up the site. Nothing's going to happen, right? So if I have extBug configured in trigger mode, basically I want to click, this is the extension here, set it to debug instead of disable. And that's going to send a cookie along with the request when you reload the page. And that, that would break when you reload the page. But since I don't have extBug configured that way, in DDEV, I can't show you that live. But yeah, I think if you're using Lando, that's the default configuration, is to have it in trigger mode. But yeah, let me show you the PHP info page for DDEV. So this is all set out of the box in DDEV, but you'll see... Yeah, so mode is actually set to debug, develop. So debug will add some other settings. I'm not sure off the top of my head exactly what it is. But if you're still on extBug 2, basically you have to set like eight or nine different variables where setting the mode to debug just does that for you. There's a page on the extBug site that explains the differences. Previously you'd have to say all of these things, which is now extBug mode is debug. There's some other things that extBug can do, like it can give you a coverage report of your unit test to tell you 90% coverage or whatever. You'll have to read up on here how to set that up. And you can also do performance profiling with xhprof as well. But I'm not going to be able to show that to you right now. I can even share like I'm using extBug on my screen. So I'll just show you on my screen. So basically, extBug is this extension, which Michael was mentioning earlier. So you enable that extension. And when it's green, basically you are in the debug mode right now. So every request it sends, it will basically say, I'm coming from 1, 2, 7, 0, 0, 1. So that's basically my setup on my local where it's coming from. And you have to get the PHP, basically IDE key, which you can set up by default. It comes with PHP strong, but you can add anything, other IDEs as well. So that's on my browser. And on the PHP strong side, I just put this where the request will come and filter anything with PHP storm IDE key. And I just started like a remote debug sessions on that. And that's pretty much all you need, right? And then I said, okay. And then when you want to start debugging, you just click on the listening thing. And I have put a break point here. And hopefully, when it runs, it's pretty slow. I think that's because of the cached thingy. But essentially, when it runs, it would just talk wherever your break point is. So that's how I set up. Like it's essentially the thing is you set it up as a remote break point. And then just enable the browser extension for it to get run. I hope that answers your question. So I might actually go through some of the settings that I have for running these unit tests in PHP storm. So essentially, if I can just have my screen back on, there we go. So essentially, we need to have a PHP CLI interpreter configured. So you can have just your local PHP installation on your machine. For this, I'm using DDEV. So that's actually loading in the Docker compose file that's generated by DDEV. And connecting to the actual DDEV container to run the unit test. Let's see. So under the test framework section, I've set it to use. So I went PHP unit by remote interpreter. And that's where I've chosen my DDEV interpreter, which is here. And you can tell it the path to the auto loader, composer's auto loader, and that's going to detect PHP unit, as well as your configuration file. That's the basis for it. Then the other thing is your PHP unit XML file. So essentially, like your simple test base URL is required for the functional tests. But it needs to be a URL that's accessible to your local machine for debugging, but also to the PHP container. So in DDEV, the domain name is exposed both inside the container and outside of the container. So you can just use exactly the same that you would use in the browser. A lot of the time, depending on your configuration, you'll probably just have something like local host here. Same goes for the database. So if you see this here, this is MySQL inside DDEV. So the host name is DB. The username and password is DB. And the database itself is DB. I'm actually using SQL Lite because it runs a bit faster for kernel tests and functional tests. For Drupal test traits, it's a bit different because you need a real-life database. So it actually just uses what you've got configured in settings.php. And so the same thing. So this Chrome here and Chrome driver here, the Docker containers that I've got set up in DDEV, you'll have to refer to my blog post about how to set those up. But that's so that Selenium and Chrome driver can talk to the site for running the functional JavaScript tests and the Selenium tests. Right. I never thought of SQL Lite before. I'm not sure if Drupal's CI uses it, but I've definitely seen something on Drupal.org about it. It'd be good to see the statistics of how much faster it is, but it's pretty cool. It doesn't work on every single module. So if your module does some strange database manipulation, perhaps it's doing it the wrong way. It might fail in SQL Lite. Another thing is I've been using XDebug for a while, but I've never used stepover, which you mentioned in your presentation. Yeah. So I probably use stepover a lot more than I do step into, or at least to narrow down. Sometimes you don't know exactly where you want to be debugging. You can kind of skip line by line. Yeah. And I guess sometimes you might see one function call, but that turns out to actually invoke like a hundred other functions. And if you step into each and every one of those, it's going to take you forever to get back to the next line. Yeah. Yeah, that's cool. Also we found that when we split up the container, so the container with XDebug is a separate service and the normal is a separate service that helps a lot. And so somebody, you know, like for example, because XDebug takes a lot of memory for running tests and stuff, like for example, if you're running PHP, you need a functional test, like switch to normal, you know, without XDebug container. And then for, you know, to debug that test, you go back to the debug container and then use it. Yeah, that's right. So in XDebug 3, it's not so much of an issue having the extension enabled kind of all the time because it's so much faster and more performant than XDebug 2. But we actually run a similar setup. So I haven't actually used DDEV until about two weeks ago. But yeah, what we do is we have engine X configured. So if it sees that cookie coming from the browser extension, then it passes the request to the XDebug container instead of the standard container. Right, interesting. And that has basically the start with the request set to yes instead of trigger. XDebug 3, does it have any dependency on which PHP version or it works on all? No. Yeah. I mean, maybe, maybe going way back to. Yeah. But if you have used it on 7.4, probably 7.2, I'm not sure. Yeah. Well, it's been nice. And thanks very much for sharing all the knowledge. Yeah. XDebug is, I think, very important utility in your toolbox. Definitely. Yeah. Yeah. Thanks for coming along. And I hope you've learned something. Yeah. If anyone has last question, feel free to post it in. So you all let the code sprint tomorrow. It's free. Yep. You don't need a ticket. Don't need to know what you're doing either. We've got mentors that'll, yeah. We've got mentors that'll guide us, guide everyone through the process. Sure. And I heard they also guide for how to contribute to group or like creating patch and stuff as well. Yeah. That's right. So essentially there's a bunch of tickets that have already been or issues on jiva.org that have already been tagged as ones we might like to look at. You can work on any issue you want. But yeah, those are the ones that we're going to be focusing on. So if you, if you want help with a particular issue, bring it up at the code sprint tomorrow. Yeah. No, is anything XDebug set up? Anybody want to bring up tomorrow in the code sprint? Yeah. I'm just going to help you with your setup. Sure. I will try. Right. Right. Thanks. I think that's a wrap then. Thank you, Michael. And thanks everyone for participating. Cheers.