 They're full screen this. All right, for those of you who don't know, this is the BDD B-HAT session. If you're mistaken, this is not the twig session with Morton DK, so don't expect any Danish jokes. It's not too late if you want to take off for that one. So yeah, my name is Mike Nielsen, and this is Enabling Better Builds with BDD. So what today we'll be covering during this session? What is BDD? What is it good for? What it's not good for? How OpenSorcer uses it in our build stack? How to set up B-HAT? How to, and finally, how to give back to the community since that's really what we're all here about. First of all, to learn and to give back to the community and to network, and then secondly, to give back to the community. All right, can I see before? My D.to user name is Nielsenem, and my Twitter handle is OSWebGuy, because Nielsenem is those darn names. Nielsenem on Twitter is actually a Danish guy, so I wish I could have gotten that handle. Again, I work at OpenSorcery in sunny Portland, Oregon. All right, so what is BDD? BDD stands for Behavior-Driven Development. It's a variant of test-driven development in that you write your tests and then write code to pass those tests. It represents a paradigm that turns user stories, something that business developers and sales and marketing use to kind of grab and understand a project from a client's perspective. Those usually get translated into requirements or spec which then engineers see. BeHat basically turns user stories into usable working acceptance tests that can be run wherever, whenever, and however the engineering, QA, or project management staff sees fit. So BDD for PHP uses BeHat or it's for those who've played Cards Against Humanity, Bs? For PHP and Drupal especially, we have our version of BDD is called BeHat. So BeHat is the PHP framework for BDD. There's also one called Cucumber for Ruby which is why yet there's that subtle difference. The PHP framework translates human-readable text into something testable which is then passed off to another, you can use BeHat to test anything actually, you can test the command line if you wanted. BeHat then passed off to another PHP library called Mink and the Mink actually is the testing framework that runs drivers to either pass or fail a particular piece of BeHat, a particular BeHat scenario. And so Mink goes through the DOM and then lines in a BeHat scenario are referred to as steps and so every time you create a new step, if it's not already in the BeHat library, you have to create what's called a step definition and we'll cover that later. There are many drivers. You probably heard of one, Selenium. Anyone here done Selenium testing? Yeah, I feel you. How often did it break? All the time, daily, weekly? Oh wow, I've never had it break hourly on me. I've had it break daily. Most of the time the PMs would just be like, just ignore it, which is the worst possible thing if a testing framework fails because if a testing framework fails, it ought to at least deserve someone's attention. That's the big, that's the problem. So if you're ignoring Selenium tests failing because they fail too often, that's a problem with either the way that the tests are being implemented or with the testing framework itself. So Selenium, BeHat tests will actually run Selenium tests. So you don't have to write Selenium tests anymore. You just write BeHat tests and then you just specify to Mink, you tell Mink, okay, go use Selenium. The default out of the box one is one called Goot and it's basically a wrapper for curl. So it renders the page in HTML, Goot then curls for whatever you're looking for and then passes it back to Mink, which then gives it a thumbs up or a thumbs down. There's also ones, Sahi is another one. I haven't had a whole lot of experience with it. The other one that I've also heard is really, really sexy. They have a headless JavaScript Mink driver called ZombieJS and appropriately for headless JavaScript. And that one tests not just the DOM but also any kind of interactivity that JavaScript you might end up having. So for Drupal, we have Drupal where in BeHats and there are several projects that bring BeHat into Drupal. My personal preference is the Drupal extension and it's on D.Auto project, Drupal extension. And this one actually grew up out of the D.Auto 6-7 upgrade. They wanted to make sure there was no breakage and as opposed to having someone physically test every single piece of D.Auto for breakages, they actually contracted out with OpenSorcery among other people and some community members and wrote a whole bunch of BeHat tests to make sure that when they upgraded D.Auto to seven, it wouldn't break. And I'm personally, just full disclosure, I have a connection to this project. A couple of good friends of mine, Jonathan Headstrom and Melissa Anderson are the car maintainers on this module. So let's, so I'm kind of, I have a preference for this one. It's got some of the more active maintainers and then it also has probably some of the better step definitions, I'd like to say. So what is BeHat good for? BeHat is great at getting every member of the team speaking the same vocabulary or how to avoid this. Let's see if I can, on the full screen. I can't see this comic so you're gonna have to tell me if it's, if you can read it. So basically it's a comedy of errors on pretty much any software project. So you have the customer explained it, how project leader understood it, and how the analyst designed it. I can kind of see things. Scream at me if I'm going too fast. What the programmer wrote, that's not funny. I can definitely say I've implemented a couple of swings off of the branch. Yeah, what the beta tester sees. Since this is a DevOps check I figured that bottom, that bottom middle one was the most appropriate. And then the client, and then that was the last one. So really honestly it's kind of hilarious because how often do we get projects where the client has this big, exhaustive document and then six months into the project and you're like what do you actually want? How many times did it actually happen? It's happened to me at least once. There have been several times where yeah, the client is billed for a theme park and all they want is a tire swing. So that's what Behat is really great about. It's creating a central source for everyone. Also because these scenarios, Behat scenarios are human readable, they're client readable. Like they're really simple to read. And encourages the client to think critically about the project. And because the individual client, the whole team is involved in creating and curating the scenarios. That's a big piece of it. What is it not good for? Scenarios, they're meant to be read by the client. So unless your client is Edward Snowden, PHP unit tests are not gonna overlap with any Behat. So do not think that PHP unit tests or simple tests are competing directly with Behat. They're completely different spheres of operations. Also test coverage. There are several in the community that actually myself included. I'm trying to pull Behat tests out of my vocabulary because tests imply test coverage. And I know that's every engineer's dream to work on a project where you have test coverage. Where you can 100% flawlessly say the tests are passing, this thing works. It's bulletproof. Behat, you can't get test coverage. Unless you can matrix style Jack into a client's head and get absolutely every single business case and business value out of them, you're never gonna be able, it's a concept that's not analogous to Behat. So OpenSource uses Behat and we use it primarily as an acceptance testing framework. Like I said before, acceptance testing is making sure that the client's, what the client asked for is being achieved. And we also use it as a kind of a backdoor, kind of a backdoor regression testing. So if the Behat's test passed in the past, a lot of mouth for it there, if the Behat's tests passed previously and they are no longer passing, that means that something has happened and that the engineers need to go in and suss out what exactly happened. So, and the tests are run on Jenkins. We have a Jenkins server running locally and it happens anytime someone pushes to GitHub, we have a commit hook that pulls in the changes, runs the Behat tests on a build script and then runs a set of a build composer and then runs the tests. They can also be run locally by developers at any time. So it's a nice way for developers to kind of double check before they commit anything and blow up everyone else's work. So, since both developers in Jenkins do customize the Behat YAML for Dockroot, the Behat YAML file is basically, it's kind of like the settings.php, it's got a whole bunch of just settings for Dockroot, file system, region settings, all this stuff and obviously, environments vary from developer to developer and obviously the test host is a different host from locally, we split the Behat.YAML file, that's central settings file into three. So we have Behat.YAML, which is where we put our regions and the type of the tester, the driver, all that stuff and then we have a Behat.Local.YAML, that one is actually put in as a default and then is copied out of the repo per developer. So that's where each developer then customizes, okay, mine's under slash home, mic, work, whatever client and then for the Drupal root and then, or for the file system path and then the Drupal root will be something like client.dev, so that's that and then the Behat.Testing.YAML has the file path and URL for testing on the test host. So how to set up one word, composer, this is not working. There we go and get buffering, gift buffering. Really? Really? This was working flawlessly like 20 minutes ago. Not to go back. What? I'm sorry guys, folks, there we go. Just hoping for a little humor there. All right, so basically you go to composer. For those of you, composer is a package manager much in the same way app get or the app store, kind of. I'm stretching the metaphor there. It's a package manager for PHP. Basically you can tell PHP, your core PHP on your machine to go out and grab PHP packages. Symphony actually uses this. Composer, uses composer, Behat uses composer. There's a lot of big projects use composer to build and manage the package dependencies when you're building a something in PHP. So I'd recommend just Google that and figure out and there's a lot, there's a pretty big amount of steps. So after composer, so you copy the Behat.YAML file, you customize it, you run bin Behat, dash dash init, that will set up your features directory and if there's any errors, like if you didn't build something properly, it'll let you know and then follow the rest of the steps on Wilson Anderson's Behat setup page. And that's, oops, sorry, that's the URL for the Behat extension or for the Drupal extension for Wilson Anderson. So after init, you'll wanna check the step definitions and you do that by using the DL option and you'll get a pretty much a wall of text. What you can do is you can pass in DL and then something you're interested in. For example, you could do bin Behat DL node and it will show you all, it actually just does like a quick regex or something like that to figure out any step definitions that have node in the step title. So, and so before you should see step definitions, obviously some of them will have like, give an IM or user with roll through, that's obviously a Drupal one. The last one, one of the last ones I wanted to cover was giving back. The Drupal extension, one of the best parts about the Drupal extension is anytime you write a step definition, that's a piece of code that evaluates that human readable text and passes it to Mink for acceptance, anytime you write a step definition, you've basically expanded the vocabulary that Behat has at a moment's notice. So, you know, if you write one for say, for Beanslide or fieldable panels paints, if you write step definitions that tie in with those modules, if you contribute those back to the community and those, anytime anyone runs Bin Behat DL panel, they're gonna see fieldable panels paints if they've got their setup correctly. So, anytime you create a custom step definition, you've basically done the work that no one else should ever have to do ever again. So, writing Behat step definitions are pretty easy, but wouldn't it be so much easier if they were already written for you? If you could just literally search through, find the module you're, find the step definitions that correspond to the module you're looking for, and then just grab and go. My dream, personally, is if you have, you know, I know everyone at some point or other has built a brochureware site. If you could write a Behat set of scenarios, Behat features and scenarios for a brochureware site without ever having to write a custom step definition, that's my dream. So, you could literally pick up a project, you know, the marketing staff could suss out their needs. They could write the Beehat tests engineers might double check them and maybe rewrite them to see if they fit with the existing step definitions. The client would sign off on the revised steps, and then when that Behat scenario passes, you're done. How would that be for amazing? You know, the client signs off on a feature, a Behat feature, you create it, you make it pass. It passes the Behat, the Behat scenarios pass, you're done. And anytime the paths fail, you've got a regression, you fix it, it's no big deal. So, this is where you all come in. If anyone's got contrib modules, I thoroughly recommend if you can just start the basics. It's really, the big trick is to start simple with Behat scenarios, something, you know, stupid stuff like I should see a view or there should be a panel on this page or given I'm a member of this group, I should be able to access the group node, you know, testing OG permissions. These are simple things that almost everyone uses when they come to a contrib module. And the nice thing about it is if you set up your Behat.yaml file to look through like your site's all directory, it will find, it will look for Behat.includes files, which will be part of the contrib module and it will include those steps automatically. So, it's a single line in your settings file and every step for every contrib module would be loaded. So, if you're a maintainer or co-maintener of a contrib module, setting up steps, basic steps are super easy and would help a lot of people kind of getting on board. You know, if you've got a, if you're building your own steps, if you're building custom step definitions for a particular module, I'm not a module maintainer so I say don't open up an issue. I would say open up an issue, but maybe not be surprised if the module maintainer closes it, but at the least point you'll have, you know, you can put in the title Behat Step Definitions, Behat Step Definitions for this module and I guarantee you I would totally pick up those step definitions and use them. The nice, the best part about Drupal.org is the fact that the patches live on even if the issue is closed. So, the patches will be used. It will be put to good use, I can guarantee you that. My machine is really bogging down with this. All right, I know this is probably the quickest hour long presentation you've ever had. Does anyone have any questions? Just so we're recording this, so would you mind queuing up at the mic so we can make sure we have all of, we have the questions recorded for posterity. Thank you. Do you have any strategies for debugging? Because it seems like a lot of times I'll get my tests written and then it'll be looking for something on the page that if I do a dump, there it is and the test fails and that's as far as I get. Oh boy, so you're already using show last response. That's show last response, there's, okay, so basically what'll happen, Behat has this amazing step that's in, I think it's actually in core, in Behat core. And it basically says, given I am here and this happens, show last response. You got me. That's pretty much, yeah. Show last response is probably the best one. You can also, there's also print last response. Have you tried using that one? That one actually prints the, it actually just prints the whole DOM out. And so you can double check to make sure that what you're, what's being looked for in the driver is being actually output by into the browser. So, you know, kind of that reconciliation between what the test is, what the scenario's expecting, excuse me, what the scenario, that disconnect between what the scenario's expecting and what the browser's producing, you know, you can reconcile that. I, my two favorite, my favorite one is probably show last response and then print last response. They're probably my two favorites. You should be able to, like do like a print R, a Drush print R that should be able to output any of that other markup. Did that answer your question? All right, thank you. So my company is currently working on migrating from Selenium to Behat. Excellent. And I'm like sort of spearheading that. And I was wondering what your strategies were for dealing with multiple sources of scenarios. So one person, we're having a lot of people write them and one person might say a custom step and I press whatever and another person might use something similar to communicate that. Like I click, you know, X. So it's to humans, it might mean the same thing, but to Behat, those are separate steps. And so we get two step definitions and that can get kind of hairy if there's a lot of custom step definitions. Yeah. I would probably say the best, this is obviously, you know, 70% of all software problems are people problems, you know. I would actually probably say if you have like an architect position or like a project manager or someone doing IA, that seems like, basically what you're saying is, you know, they're people that are communicating and they're not, they're using a semi unified vocabulary and what needs to happen is you need to have someone on the team that has enough clout to kind of say, you know, you click buttons, you don't press them. I mean, it's simple enough to write a custom step definition that just says when given I press this, you know, you basically just say return given, click that, you know. It's simple enough, but yeah, it's kind of maddening. Usually I would say, my personal opinion is up to the project managers to kind of be like, hey, QA staff or client, you know, these steps are, you know, we have an established method for this. Go with it. Reconciling is probably, is the best way. I would say the workaround, if that's totally not an option, is just the duct tape and bailing wire of just, you know, throwing in a couple of custom step definitions. The third option definitely is, of course, you can also, because the way Behat works is that just, it writes regexes for these, you could rewrite the regex for the click, push, button thing. That's probably, that's an equally valid thing, but it might, you know, for some of us who aren't Perl developers might not be the, it might not be the easiest way. So, thank you. Hi. If one of my primary outputs of Drupal is services, can Behat test the services, the JSON or whatever. JSON services. That's an interesting question. What was that? It does? Excellent. I have, services are definitely something that are, I would love to say that, apparently it does. I can't speak to that. I've never actually, I've never seen that happen. But again, like I said, implementing step definite, custom step definitions is easy enough. If the, if the tests, if the steps aren't what you're anticipating, that's one avenue to go with. I would say it's definitely, it's definitely possible. It would not surprise me at all. So what the gentleman in the back actually mentioned is that you can, you can use XD bug to step through. That's another, that's probably, probably my last, my last best chance is to see if, if various bills are being set using XD bug, stepping through the, you know, stepping through the boot process and all that stuff. I would definitely say that's, that's probably the most exhaustive way. It's the bet, the downside is it's the most exhaustive way. So the other behats, it's a bit, it's a bit magical. It's a bit of a black box. Any other questions? All righty. Well, thank you everyone. You can, you're only, you're only a half an hour past Morton's, or Morton DK's twig session. So if you want to feel free, jump into that. All right, thank you everyone.