 Hello, everybody, how's everybody doing? Thank you for coming to my session, which is called Test All the Things, Automated Testing with Drupal 8. So who am I? My name's Sam Becker. I work for Previous Next, who's a Drupal agency based in Australia. My Drupal.org handle is Sam152, not on IRC as well. So in this session I'm going to go over some really broad testing concepts and tools that are used in Drupal Core and Drupal Contrib, and I'm also going to show you how you can use these exact same tools to write tests for your more bespoke Drupal builds that you might do as an agency or for the sites you might build in your organization. I'm also going to go over a bunch of different types of tests we can write and when they apply in different situations. So broadly speaking, what are tests? They're code that executes your code and asserts a set of constraints. So they would basically make sure that everything is functioning the way you expected to. And the obvious reason to write test for your code is to see fuel bugs in production. And as a result of this, it makes stakeholders and developers much happier. So it definitely makes developers happier. I don't know if you've ever been on a project where everyone was kind of scared to touch that particular part of the code base or do a deployment on a Friday because they're afraid they're going to break something. Writing a lot of automated tests really kind of alleviates that whole scenario. And it also helps you write better code. So code that is testable is generally considered better code for a whole bunch of reasons. And I'm going to go into some of those during this presentation. So how do we test code in Drupal 8? So everything I'm going to talk about in this presentation are tools that are shipped and packaged with Drupal 8 Core. And it's that whole set of tools that are used to test Drupal itself. They're all based on PHP unit, which is a PHP-based testing framework. And Drupal basically provides a bunch of test classes you can utilize and extend to write all of your tests. That's a list of them there. And I'm going to go over each of these test classes and show what a typical test for these different types of tests look like. And again, I love using these tools because they're relevant for writing Drupal contrary projects contributing to core. And once you get really familiar with them, they're really useful for all your other kind of Drupal development workflows. And since they're all based on PHP unit, they're also useful outside of Drupal. So it really is the de facto standard for testing PHP these days. Most other modern PHP frameworks are using PHP unit as well. No symphony do, Laravel do. So it really is a popular tool that, if you master, has a lot of transferrable skills that are applicable to a lot of other frameworks. So this is the basic anatomy of a PHP unit test. And this lives in the Drupal test's namespace, if you're working with Drupal. And this is what it looks like. It has a setup method, which is called at the beginning, to set up the environment for your test. And then it usually has one or more test methods, which assert a whole bunch of different things and just make sure everything is working. So PHP unit itself contains a lot of different types of assertions you can make during a test. I'm not going to go over all of these thankfully. There's probably about another hundred to add to the list, but there's a link to the documentation. You can go check them out. So one of the great features of PHP unit is mocking and the ability to create test doubles. So what this allows you to do is take in a class or an interface and apply some really fine-grained behaviors to how that thing should react. So when we're using things like dependency injection, we can create a whole bunch of test doubles for our test and pass those into the thing that we're testing and assert how it behaves under those different kind of scenarios. So mocking is pretty central to how you would do unit testing with PHP unit. And you can use as much or as little as the dependency as you like. So if you want to mock out a few methods and use a concrete implementation, you can do that as well. This is another great feature of PHP unit, which is kind of going to be referenced a lot throughout the rest of the presentation. It's the data provider annotations syntax. And what this allows you to do is create a method which returns an array of test cases. And those test cases are basically passed into the test method which specifies the at data provider annotation on top of the test. So here we've got two test cases, one which is printing a year, one which is printing a day using PHP's date function. And we're going to make sure that PHP's date function works, which is great. You wouldn't want that breaking. So once you're kind of up to speed with testing fundamentals, you're probably going to want to start running those tests. So if you're running tests in the context of Drupal, there's a whole bunch of environment variables that you have to set up which give the Drupal test access to a database that it can use for different types of testing. You can also use the PHP unit binary, which, if loaded with composer, will be in vendor, be in PHP unit. And my absolute favorite test runner in the whole world is actually PHPStorm, which is an ID a lot of people use. And PHPStorm has really fantastic PHP integration. So all of the tests that we write can basically be run straight from your IDE. You can right click on a whole folder or a whole module, run an entire suite, or even drill down onto specific test methods if you want to run a specific test inside a test class. So unit test case, this is Drupal's base class for unit testing. And it's anytime you basically want to test something completely in isolation. And you're just dealing with PHP classes, you're dealing with mocks, you're dealing with dependencies. You've got no concept of a database or a bootstrap Drupal installation at this point in time. And they're incredibly fast to run. And it allows you to test a lot of inputs and outputs and get right into the nitty gritty business logic of a particular application and just make sure all of that stuff is working. The other thing unit tests do is they help inform the design of your code. So I said earlier that testable code is good code. And one of the reasons this is true is because when you unit test something, it's really clear what your dependencies are. If you inject something into a class, you either have to instantiate that or create a mock for that. So that's effort on the testers behalf. In this little snippet of code, I believe this is a field formatter. We've actually injected entity manager here. And what's not really obvious about that line of code is there's actually two dependencies at play. So first of all, we have the dependency on entity manager. And we also have a dependency on entity definition interface, which is the return value of that get definition method core. So if you were to load this plugin into an automated test, you would realize that to actually execute that set of code, you actually have to mock two separate classes, which is painfully obvious when you're writing a test. So it allows you to kind of step back and think, well, how much access to other bits of information does my test class really need? Do I need the whole entity manager? Could I just inject the entity definition, for example? So it's really helpful of bringing those kind of dependencies to light when you're unit testing your code. So I'm going to go over some real world examples of unit tests from Drupal Contrib. And this is probably the absolute simplest one I could find. And this is from the Contrib module video on Bedfield. And this is a test which basically takes a whole bunch of inputs, which are YouTube URLs, and makes sure that the module can extract the correct ID out of that string. So on the right-hand side, that's the PHPStorm integration. And it's taken all of those test cases, and it's run them all, and it's shown me exact feedback of what's going on during that test. And it's quite a big, long, ugly, complex regex. And when bugs come out in the queue that it's not parsing something correctly, if someone submits a fix, it's a huge amount of confidence that fix isn't actually going to introduce a regression, because every time we do find a bug, we just keep adding to this test case that continues to expand the test coverage of the module. So this is a good example of a unit test, and where it's really appropriate. The next module I'm going to talk about is a little bit more complex. So it's called reference table formatter, and it takes an entity reference and a list of content entities and spits it out into a table. And this is what the unit test for it looks like. So we're creating a new instance of the entity to table renderer, and we're calling the get table method, and we're making sure that it looks like the table we expect it to look like. And it seems pretty simple from that screenshot, but if I flip to the next slide, under the hood, the left-hand side, all of those classes were all the mocks and test doubles required to actually run through that set of code. So it's quite a lot. It was painful to write the test, and it's possibly a few things at play there. So it could have been a sign that the code was designed really poorly. Why does it need access to all of these huge Drupal concepts and really big interfaces? Could we maybe have split it out into a couple of different classes? Could we have had a class that was just dedicated to processing the entity and pulling out fields and another one responsible for the table? So yeah, this is kind of like how that test informed the design of that code. It was definitely a pain to write and to maintain. It's about 150 lines of just pure mocking and the rest of it. And it could have also been an integration test. So when we mock all of those dependencies, we really are making quite a few assumptions about how those things behave in the real world. So maybe it would have been possible to actually use real versions of those dependencies in a bootstrap Drupal environment instead of making all these assumptions and mocking them out. So there are limits to unit testing. So this draw by itself is a completely functional draw. It slides in, it slides out, but you throw it in with the rest of the components in the real world and of course it isn't very functional at all. So that's a good segue into Kernel test base which is a brand new concept to Drupal 8 and it allows you to write those same PHP unit tests in a fully bootstrapped installation of Drupal and it tests your code integration with the rest of Drupal. You have access to all of the Drupal APIs. You can create entities, you can get services, you can use the plugin system and it's that same PHP unit framework where you're asserting things are happening. So here's the setup of a typical Kernel test. I'd say we specify modules. These modules actually go and get installed and one of the reasons Kernel test base is so fast is because it doesn't do a full installation in the background. It basically installs the parts of Drupal that are only essential to the test. So at the top of that setup method, one of the calls there is install entity schema. So when you during this test, we were gonna create a node. So we actually had to go and tell Kernel test base, hey, we're gonna need the node table for this. Can you go create it in the background? Cause we've got a real node coming that's gonna be used for this test. So it is blistering fast for that reason. And this is an example, similar to the reference table formatter test but it doesn't have any mocking. It's using all of the Drupal APIs to actually achieve the same result. So we're creating a brand new entity. We're setting a value on a field. We're rendering that field and then we're making sure that rendered field is exactly what we expected to. That first test case is testing a video thumbnail field formatter with that specified input and below that is the exact renderable array that you would expect that field formatter to produce. So as we add more settings and configuration and make these field formatters more complex, we know that everything that used to work before is definitely gonna work now and it's gonna go through the real Drupal APIs to test that stuff. That reference table formatter example had all of that test coverage and the module was actually broken for maybe six months during the Drupal 8 release cycle and that's because the interface changed for what field formatters actually have to implement but since what we're doing was basically mocking the whole environment around it and passing in all its dependencies, it wasn't sensitive to how it was used in the context of Drupal at all. So writing integration tests really alleviates that and you should have integration tests for your code for that reason. Browser test space is the first test class I'm gonna talk about which actually introduces the concept of a web browser and this is for functional end-to-end testing using a UI and simulating a bunch of the actions a user might actually do on your particular application and you basically write a series of instructions which set up a full Drupal environment, install all the right modules, create the right entities and then you tell the browser how the user's gonna interact with your site. So they might click on links, submit forms, log in and along the way they're asserting that everything is actually behaving the way it should. One of the caveats is they're incredibly slow to run. So in the background when you have to do a full Drupal installation that takes time and between each test it's a brand new version of Drupal with different modules installed and the database is essentially thrown out after every test. Mink is the API used to introduce the browser into these tests. So these are basically pluggable browsers. You can use one API for controlling a browser and you can specify which browser plugs into the back of that. So for a browser test base it uses a browser called Gout which is simulating how a browser might respond using just a normal kind of curl request response but there's no reason you can't plug more sophisticated browsers into the back end of this. So no testing talk would be complete without the pyramid screenshot. So this basically indicates how many tests of each kind you should generally be writing. So you should have a lot of unit tests, you should write integration tests and have some end-to-end UI tests. I like to go into the example of like an e-commerce checkout. If you have a project with a huge number of complex pricing rules it would be really cumbersome to make sure that your controlled browser goes and adds the right products at the right time and clicks through all the way through checkout to test your pricing rules. But you still need that test there to make sure checkout works. So it's kind of the approach that your unit test should be the backbone that are testing all of your really complex business logic but you should have other layers of testing on top of that. And this is also just a guide and common sense suppliers. If you're building a Drupal site in particular it might be really heavy on site building which unit testing obviously doesn't apply to and you really just want to browse it and click through all of your different content types and workflows, whatever you're creating. So if you end up with a lot of functional tests on a Drupal project I wouldn't really be surprised and you do get a lot more unit tests when you're introducing the more kind of nitty gritty business logic that comes from the development side of Drupal. So say you're building something like an info profile. Yes. You want to test that, hey we've done a Drupal install and then all these modules have been enabled all over the joint you want to go log in worked, this page worked, that page worked. Yes. When you're using a browser test case each test has got its own set of environments and it's not just, how do you test, in that case, how do you test that my whole site all set up with everything turned on actually the H1 I expected. Yeah so if you're writing an install profile one of the things you can do to instruct browser test base to do is to choose which install profile to install during the setup of Drupal. So by the time, it's a property on the class and the default is testing. It's a install profile packaged in Drupal core which is specifically lightweight cut down just to make testing really, really fast. So by default it's that one but if you switch it to your install profile when you start clicking around the screen with the browser or whatever it might be you're actually going to see the result as if you went through the Drupal installation selected your profile, hit save and hey presto you have a site. Just right, if you want to do a lot of tests on that single instance, I guess that's good enough just write a single test with a lot of assertions. Yeah you can do that. There's also a slide about five slides in the future which also addresses exactly that. So I'll jump forward to that one in a second. The other browser test base we have is JavaScript test base and this directly extends browser test base but adds full JavaScript testing. So mink that pluggable browsers API it swaps out the primitive browser which is really fast for a slower browser which is actually WebKit in the background. So the same thing that powers Chrome is actually going and clicking through your site and it can do any kind of UI interaction that a user would do with a page and it's actually WebKit in the background doing those interactions and along with all those interactions you have a whole bunch of assertions which are really specific to the environment of a browser. So does element with this CSS, matching CSS selector have this kind of contents? What's the order of these elements in the page? Is a particular element visible on the screen? And that's not just the initial HTML state of the test it's the state at that particular point in time. This is a JavaScript test and this is the real Colobox JavaScript test which is on the Drupal 8 Contrib module and we're basically visiting a node that has a Colobox set up for it. We're clicking the image which launches the Colobox we're waiting for it to do its animations and finish all what it has to do. And then we're saying the element that matches the ID Colobox is gonna contain the string test.png which is our test image. And since it is WebKit, this is actually a screenshot that JavaScript test base took during that testing process. So you can instruct it to take a screenshot at any time which is really useful for debugging what's going on but it can also create a timeline of what happened in the test. So if you wanna get a sense for what a test is actually doing you can just click through all of the verbose output that JavaScript test base gives you. You can take a bunch of screenshots in the process and you can really see that the UI is actually being tested in that process. So since we're extending a bunch of different test classes to add our own functionality in there that we're using across different test bases, the pattern that's kind of emerged has been utility traits which sounds really scary but it's basically a series of functions encapsulated in a trait that you can use on some of your different test classes. So this is a really simple one which helps us load entities. So that's relevant for browser test base. If we created an entity from the user interface we might wanna load that in the test and make sure that the underlying data structure is correct or whatever we might wanna do. So this is relevant to your question and this is cheating the setup aspect of the test. So in a lot of cases we create these tests and we don't necessarily want to reinstall Drupal every single time we run a different test. We might wanna just have an environment provisioned on a continuous integration server for example it might sink down a production database, it might sink one from QA, it might do a reinstallation of Drupal and import some config but we wanna take the burden off the developer for having to go and set up all the prerequisites required to do like a functional end-to-end test of the whole product. So this is where that comes in and we've been doing this for a while by kind of patching core in different places but there is a Drupal issue for it which allows you to simply set a property on the top of the test class and then when you go visit the homepage during a test you'd see the actual homepage of the environment where that test was running. It doesn't go and try reinstall Drupal, create a set of tables and do all the other stuff that comes along with it. And again that's useful for really broadly covering a site using functional end-to-end testing. And let's see I do the heavy lifting so developers are setting up all of those different pieces of functionality. One thing you do have to kind of keep a look out for is the deprecated test classes in Drupal 8. So if you create a new test class and you start writing in your ID, my test extends you're gonna get a whole bunch of suggestions which are actually deprecated and that's because a lot of this stuff has evolved really recently and for backwards compatibility reasons all of those old test classes are actually still in Drupal core. Web test base is an example of one which was a port of simple tests from Drupal 7 but there's even deprecated test classes literally called kernel test base and browser test base which you should try avoid. And the kind of key indicator of which ones are deprecated is they don't extend PHP unit. So yeah that was back when kernel test base was kernel test base the next generation but of course now it's just known as kernel test base. So one thing you have to do when you're writing a test suite is consider when to not write a test. So my rule of thumb is if the only reason the test is gonna fail is because a user went and changed some bit of code like that they intended to change with no side effects and it fails. It's probably not a really good test. So if I wrote a test for this and said the return value of get number of planets was always gonna be eight. The only time that test would fail is if someone opened that class and decided Pluto was a planet again and put nine there. So that probably is a really really useless test to write. So you kind of gotta weigh up the decisions around when to add a test and when not to add a test because they do carry a maintenance burden. They will break with false positives that you have to go fix. You do have to write them in the first place. They need love just like the rest of your code base. So you shouldn't just revert back to always testing every single method in every scenario. It kind of is a bit of common sense applies there as well. So my final thoughts are testing in Drupal 8 is really awesome. There's a ton of different test classes for a bunch of different scenarios and I would encourage everyone to go and read up more on the documentation of each of these and check them out. And the other thing is write lots of tests because it makes our projects more stable end of the day. That's a great goal for the Drupal community and Contrib. Thank you. Thank you very much, Sam. I've got Alex in the front here if this turns on in time. I think you have to hold it down. Yeah. We could come up here and turn this one around. Hello. Thank you very much for the presentation. Very good. Two things. First one, on the point of the ability to run on the existing websites, I'm actually a maintainer of a module called side tests. It allows you for Drupal 7. It allows you to basically run your site using simple tests or Selenium tests, whatever. But on the current side, that just basically overwrites some setup module, not usable for Drupal 8 at all. But then another question is about Behat. Yes. So a lot of what you presented was basically about the core and stuff. What about Behat? Can you use, because Behat has a lot of API integration and you can do lots of stuff with Behat. You can do a lot of stuff with Behat and I guess the reason we're kind of avoiding it or just neglecting it specifically for Drupal 8 is because the tools that we use for testing core and contrived are these suite of tools and they're full-featured and they're really, really powerful. So we don't wanna introduce some third-party tool that makes us context switch between working on client projects and working on core and contrived because a lot of the work we do involves getting our hand study with core and submitting contrived modules to Drupal.org. So keeping it all in that one testing ecosystem just has benefits for the team having to kind of learn and maintain one set of tools. So I'm just gonna ask a quick question from me. In case I missed it, about six months ago I found out that if you wanted to do integration testing with a contrived module you needed to use, effectively use core simple tests. Is that no longer the case now? Is it, can we do the integration tests fully with what you've shown us here? All of this stuff runs on the Drupal.org test spot. I have a deprecated slide at the end which is Drupal.org test spot tips, which didn't make the cut but it seems to be relevant. Inside your module info file you can specify your test dependencies and it will go and download all of those modules and have them available on disk on the Drupal.org test spot when you're writing them. So that's helpful if you wanna write integration tests with other modules. So it sounds like a lot of the changes that especially previous NECs to being pushing on the infrastructure have gone through to allow these things to happen. These are all usable and in fact, all the web test base which is the simple test kind of successor tests are being replaced with browser test based, JavaScript based tests. There's people working on that and it's coming. They're doing one huge patch which is gonna just blow them all away. So soon this will be the only thing you can use so it should be relevant. Lee who's one of my colleagues who's one of the primary architects of the movement to browser test base. Tell us what you really think about Beehart. Lee says, tell us what you really think about Beehart in case anyone. I might need a few more beers at the drinks to really get my real thoughts out there. So everyone ask that question later. That was my polite answer. Any other quick. I should be a politician. I'm only asking this because testing focuses on certain parts of the code base and certain subsets of functionality and you had a slide back there if you wanna go back to it that showed that you don't have to fully bootstrap Drupal to run certain sets of tests. Oh yeah, external test base. Yeah, so my question is is it possible to not fully bootstrap Drupal in some other more production like situations? Is there even discussion around that? I think, I know Lee knows a lot more about this but I think this kind of concept came out of exactly that having like a continuously running bootstrap that would serve requests or some kind of minimal bootstrap. So I think that is, am I right, being worked on? Yeah, so that does exist, yeah. So this concept I don't think was kind of came about as a result of testing but it just happens to be like a really awesome side effect of that work. And these field tests run in about three seconds per test case and that's not three seconds on the same Drupal installation. That's a brand new, fresh, empty version of Drupal every three seconds running a test case which is really cool. So it's kind of this hybrid test that has kind of elements of both the fully installed version and the unit testing version when you have nothing. So Lee, can I ask, are you guys especially interested in running Drupal not fully bootstrap but streamlined in production situations? Now I was sure it was simple bootstrap but there was more running Drupal at the time. Right. Rather than it. So it was serving requests through that, right? Yeah, right. Yeah, that was the original goal. Yeah, so elaborate on that is that in core we are doing all the shift from simple test and the obsolete kernel test base and the next plan is to add new test base for API, the testing system. So you send a request and you will get a response and you just test that and that's the goal. Like it can be XML, JSON, anything. So that's the goal of the new test base system. Yep. Just a quick one. You mentioned some traits. Do you guys like open source them? The traits that you use and project to project? Yeah, it kind of depends. Like a lot of them, I mean like Gibran said, are in core so you can use like the node creation trait. No, I'm talking more of more customized ones. More customized ones. Well, a lot of the traits we write would be project specific as well as really generic. So it's kind of a mixture. So we haven't ever kind of stepped back to say, well, which one of these should we just push out? It'd probably be the case of submitting it as a core patch. If it was really generic and really useful everywhere that would probably be appropriate for core. Otherwise we have traits which help us for specific websites. Like would that be your internal library in your company, right? Probably per project. I would have said there's traits which are useful for testing really specific sites because they have things like, go through the registration process that is part of this bespoke build. So that's kind of like the introduction of sharing code between these different tests. And it's only a side effect of not being able to create a website named test base because typically you would have done that in Drupal 7 and created methods on a base class. But since you have to extend JavaScript test base and you have to extend browser test base separately, multi polymorphism probably doesn't work out. Can I ask another question? Very quickly, if you can you go back to Drupal mocking the actual services of like? Yeah, sure. You kind of touched a little bit on that. So like I would recommend you go and read over the documentation. It's a really huge topic. And there's... No, no, no, no. Sorry, my question was, is are there any helpers in the core to mock some of the Drupal services to run your tests? So like you, so you wouldn't have to do like, you know, mock or get mock builder and create it every time. There possibly is. I don't know them off the top of my head. But in a lot of cases when you're kind of creating a mock, you're specifying how that dependency is going to behave, right? So when you create a mock for the entity manager and you call load, you couldn't just go get a generic mock because you're specifying during your unit test how that's going to behave and how that's going to interact with your system under test. So I don't know of any. I don't know if there would be, but there possibly is, I'd have to look it up. My experience on that is that if you think that there's something you want to mock and it's going to be a particular namespace can often help to just grep the core code base for that namespace in the test files to look at examples. I also found that you can get a lot of bad examples doing it that way of stuff that you probably don't want to do it that way. But like, and as Sam pointed out, there's deprecated test cases. Hopefully that all becomes clear, much clearer. But I think you will find that there are helpers. There's always helpers in cores. Like are we going to create a thousand tests that do all these things? Like make a helper around images or files? It's also a kind of, that is a proof that you're showing there. That mock is, yeah, should be good. So if you learn there, you're not learning through it, you're learning something that's a little bit more than what you're learning. And prophecy is also in core. So if you want to use the prophecy to generate a mock, it's different. It's more expressive. I think you could do an hour long session just on mocking best practices. And I was going to kind of go into a segue where there's multiple libraries that deal with mocking and they do it in completely different ways. And it's kind of confusing because you'll find examples of both in core. But personally, I've mainly used just the standard one before prophecy, what was that called? Yeah, mockery. Mockery, that's the one, yeah. So yeah, I mean, I'm just more familiar with it. I'm more productive with it. You can smash out, smash out mocks. As you can see, if I go to my really convoluted bad unit test, which mocks the whole universe, there's probably, oh, no, that's, there's probably hundreds and hundreds of lines of code that mocks everything to do with entities in Drupal to set up my really specific table of entities test case, which turned out to be a nightmare. So lesson learned. Yeah, that's mockery. And that's only because I'm more familiar with it more than anything else. It's on the to-do list to dive into prophecy. Have not got there yet. Do you have any other questions? I've got one up back there. What would you say the benefits of the webpage test, as opposed to say Selenium are? Well, I mean, that library, I was talking about mink, I believe Selenium is one of the browsers you can plug into that. So if you wanted to use the one API for testing user interfaces and you decided you really needed a feature of Selenium that the other browser that ships with Core doesn't have, you could swap that in and use that really easily. Again, it's a property on the class. So you point it at the Selenium driver and it's gonna go and spin up a Selenium instance for you and use it that way. So again, it comes back to using the one tool set for everything. If you're just using Selenium as a standalone tool, you're not really giving yourself an opportunity to go and actually get really familiar with all of the tools that come with Core and Contrib. So I will publish the slides on the website, but I can go back now. Which one do you want? Yeah, cheating set up. That's the one. That's the one. Oh, you just wanna look at it? Yeah. Are you sure? He just wants to look at the slide about it. Yeah. I was gonna put a picture of Jerry Springer on this slide, but I thought the pun might be a bit too abstract. So in Core, when we were converting a web test, which is obsolete now to the browser test base, the first test we convert was the test standard profile. So it's a big profile which install the standard profile in Drupal Core and test everything, login form, stuff like that. So to answer your question, is it possible? So Core is doing that. You just have to find test standard function and it is there. So it is doing everything in Core. Cool. Anyone else? Oh, I've got one. I've got two. I'll go to Adam first because he's closest. I just wanted to respond to the question over there about the stubs for mocking stuff. Some modules do have stuff like that. There's Migrate. Migrate has a test base class. So say you're writing a Migrate plugin, you can extend Migrate's test class and it has a bunch of functions in there to create mocks like for rows and stuff like that. So yeah, I guess if you're doing that kind of thing, then check the module that you're using. Does it mean that you can actually reuse that to test your own? So yeah, your test case then extends Migrate test case and then you have access to all those stubs that the Migrate module does. Sweet. I think huge is gonna be a related question so I'll just ask for a comment, yeah. Yeah, there's a config one as well I think, like for just, instead of having to use like config factories. There's a lot of them as well. But a lot of the test bases for specific modules also just extend web test base but you don't get the deprecation warning because you're through a level of test that isn't deprecated. So you gotta be careful when you're just picking random test bases to extend that you're not, extending a legacy legacy test base. Yeah, I think that's a trait so. Oh, it's a trait, okay, yeah. If I go ruin this regex, I should get a failing test case when I run this unit test. Hey, it's all dead. These are all the failed test cases, these are all the passing ones. So that's the PHP storm integration which I really use every single day. It's super, super awesome. Well, see me for a free one month license after this. Good work, Sam. Thanks, Jess. Just a question on the functional test. When you look like sort of if you're emulating, say a button click here, kind of working on a selector. I guess in some cases that might be hidden or not on the page which kind of be a broken test. Is there sort of ways around that sort of like? So yeah, like in addition to writing a test that clicks through a whole site and tests the functionality, you write assertions to make sure that everything's correct as it goes. But if it reaches a scenario that it can't satisfy during the test, like a button has disappeared, that's a like, that's a hard fail on the test and it'll stop right there. Well, I mean, since like if you're using the WebKit base one, you can do assertions and only interact with elements that are completely visible, for example. The test assertions and interactions with the browser in the MINC docs are really comprehensive. There's a whole bunch of stuff you can do. You can write them down to the granularity where you're hovering over a menu item, moving your cursor down 25 pixels and then making sure that the secondary menu is in the exact position 25 pixels adjacent to the first menu. So it's kind of up to you like how detailed you want to go with your assertions. And again, you don't want to over test it because maybe the client wants the menu on the right hand side and still a functional menu, but we've changed the behavior. Like Boris would say, you want to be able to change things and not change your tests, right? So there's a huge depth of knowledge here, so please thank Sam for sharing it.