 Hi everyone, I'm here to talk about B-hat and phantom.js and a little bit about mink that you can use to test almost all the things. I have stage fright, so ignore my shaking. It usually doesn't affect so much. Like someone once said, learn the most by sharing your knowledge with others. Code rabbi, so whee, let's do that. Because of my stage fright, I like if we have this as a conversation, so if everyone can come so close to the forward line as possible that will really help me. This talk is entry level. So it means if you done B-hat before, you probably won't learn much. But here is a cute kitten picture for you. And here is a picture of me with a dragon. I'm Michelle Sanver. I'm a co-president of PHP Women, where I use a group in the PHP community that enforces a friendly community for everyone in the world, not just women. We help send people to conferences, give scholarships, and we have an IRC channel called PHP Women on FreeNode. Just join us, chat, and have fun. So you don't spend all the talk wondering which accents I have or accents. It's from one of these countries, or all of them in the world. I'm Swedish and half Danish. I lived in Netherlands for six years and I recently moved to Switzerland for this awesome company called Leap. At Leap, I'm actually a backend developer, and I have a confession to make. I never touched Drupal at all. I don't know how Drupal works. I know it's a CMS, that's about all I know. I'm a symphony developer and I mainly make APIs. This talk is open source, so if you have any input about how Drupal works in some contexts or if you have questions, you can ask at any time. Speaking of open source and contribution, let's make your first contribution to my talk. Do you test your application today? Sometimes, okay. Do you know how grumpy programmer is? He wouldn't force you to test. But it's okay, I don't bite. There was this attendee at another conference I was at who said, my code is so awesome, I don't need tests. But the truth is, you do need tests and you do need to test your application. I'm about to show you that it's easy to do with BeHat and that you don't have to be afraid to get into testing. If you have a good test suite, it means if you change something, something else doesn't break. And with BeHat, you can even test legacy code. You don't have to care about units and everything. Do you use PHP unit today? Okay, that's good because, of course, you care about the units if you have units, but if you don't, you can still test your applications. Don't let that be an excuse. Anyone try test driven development? Will you write your test first? A few people. Have anyone tried behavior-driven development already? Anyone knows what BeHat is already and behavior-driven? Okay, so you won't get anything out of this talk, you can go to the next room. So first, I will explain how the individual parts of BeHat and Phantom.js and everything works and give a short overview and then how it all fits together. So BeHat is several components, BeHat, Mink and Phantom.js in this case. You have Gherkin, which is what defines your behavior and this is human readable and quite awesome. Then you have BeHat, which runs your test and is your test suite. Then under BeHat, you have Contexts and these need drivers. In this case, I use Phantom.js or WebDriver in Symphony, but there's a lot of different drivers that you can use. So what is BeHat anyway? It's a behavior-driven development framework. What is behavior-driven development anyway? It's clearly defined behavior and English spoken tests. So instead of writing tests in code which may be a little bit hard to read, it's really nice to read. Basically, I like to say that BDD is TDD plus spices. No one got that, okay. Why we chose BeHat at Leap and the team I work for is, well, let's just do an awkward confession first. We wanted to use Codeception because this was new and cool and everyone else was using it. But at the time, we were stuck with PHP 5.3. So BeHat supported it, which was awesome. Nowadays, I can admit we use the latest PHP versions, which is cool. And also, we had a lot of change requests. This project I was working for had been running for more than a year, two years, and at some point, you don't know, is this behavior we actually had once at Benna Time, or is it really a bug? And reading through our tests that we had by then, it was hard to tell if it was a logical test error in the test, so we never actually tested the behavior, or if it's, yeah, we needed something with clearly defined behavior so that we didn't have to dig through emails, conversations, and support tickets, and all those things to figure out if this is the behavior that was interned. So let's now talk about how we actually define our behavior. In BeHat, we use this language called Gherkin, or I would say syntax called Gherkin. Remember that Gherkin is only there to define and not really to test. Your tests, you still have to write in PHP, I will show you how that works, but it's really, really nice. This is, for instance, how a Gherkin scenario could look like. It's pretty straightforward, but let's walk through the steps. First, you have a feature. This is often your user story. You can write anything you want in here, describing what your feature does. And then inside of your feature, you can have as many scenarios as you want. For instance, this one, Larry Garfield at a conference. Given I'm Larry Garfield and I am at a conference, then I should wear a blue shirt and I should wear a leather vest. And I should not fall asleep right outside the room. And then we have givens, wins, and thens. These are your steps. And I will show you how steps work in a bit. And these are your keywords and your verbs. You can also connect them with ands and buts. And I am at the conference and I should wear a leather vest. But it's also important that you have some kind of background. If every test has something that has to be set up before you run the scenario, you can have a background to not be repetitive. So here, for instance, we set up an administrator and then we set up the scenarios, which always run the background first and then the scenario. And then to also make sure we're not repetitive, we have scenario outlines. For instance, we have these two scenarios, but imagine you want to test a lot of different numbers and it becomes really annoying and repetitive. Five, 20, yeah. Just use scenario outlines, keep it dry at the Drupal company. So given there are number of beers, when I drink number of beers, then I should have something left. And you use it from the table, which is really useful, especially if you test large data sets, you know, minus 1,000, at least third, those things. Yeah, I think no one got the joke. And in Gherkin, you can also have tagged hooks if anyone paid attention, logged in, et cetera, we've already seen. But I will talk more about hooks in a bit. So let's look at the steps, because the steps are actually your tests and what you will have in a context later. Each keyword as I talked about, given, when, then, and, but, is a step. And a really, really cool thing about BeHat and Gherkin is that you can implement accepting context. This means that if you have a step that is not defined yet and implement snippet accepting context, then it will automatically give you the code that you can copy paste into your context. So if you have, for instance, given I am at DrupalCon and then I have snippet accepting context, then that given will automatically add to my context. I will show you context later so that you understand better. Any questions so far? So then we have the results, of course. We have pending, failed, skipped, ambiguous, redundant, undefined, and finally successful, yay. I think these are pretty straightforward. Any questions about those? Should I define any better? So let's talk about hooks. In BeHat, you can hook into the process at many spots in your context and in your application, which means that you can have things happening before a scenario, after a scenario, or before suites, before features. As I said before a scenario, or before a step. Hooks you implement by having a tag. So here we have a before scenario. This is a typical before scenario that we use a lot in our application. So what this one does is that we can see the at before scenario, and then if we're using the Selenium 2 driver, then we want to resize the window because we want it to be desktop size. Otherwise we want to use the client from Symphony 2 in this case, and that way we can have dynamic drivers and switch in between them easily. And then we can have as many scenarios as we want with tagged hooks, database, and ORM. You can run these nicely. Or you can find that you can only run these two together. So here you can do database or ORM, and here you can do database and fixtures at the same time. So for instance, do they return a true or false then this or that? Okay, I will show you how to use the hooks in a bit. But how it works is that you can run your tests we had at database and then only run those tags. But in this case, this will only run if you run the tag, database, and fixtures at the same time. But here you can use either the ORM or the database. Okay, so the context. It's how your application actually behaves. This is where you write your actual tests, which is awesome. And feature is describing the behavior while context is testing the behavior. You can never write a feature without having a context that matches because then it will be skipped and not run because there's no code in the backend. Gherkin never tests for you. You have to have the context. So let's look at the feature context class. So here you see the annotation when I do something with argument. So for instance, when I do something with link, we have these, I do something with. You can name the function anything you want. It's only the annotation that matters. And in this annotation, you can also use regex if you want. So you can do when I do something, when I do anything, it all matches the same method. So let's look at context class requirements. The context class always has to implement the context interface. And it should be called feature class, feature context. But you can define it later. It has to be discoverable and loadable by behat, which means it has to be in your outer loading. And important to know is that your context class is initialized every time before your each scenario is run. A context is isolated from each scenario's context. And every step is executed inside a common context instance. And we can have as many contexts as we want. In behat two, this was really difficult to do. But in behat three, it's a simple behat.yaml file where you define your context. So here we have feature context, second context, third context, and we can add as many as you want. And that way you can split your tests into logical parts. For instance, you have a part to test your commerce and a part to test your users and a part to test anything. So you would have a user context, commerce context, et cetera. Now, writing these tests in behat is pretty straightforward. All you have to do is write these functions inside of your context class and define the annotation to match your gherkin. And a test only fails if an exception is thrown. So you can use anything. You can write your own logic, throw your own exceptions. You can use PHP unit assertions, which means that assert fails so your test fails. It's as simple as that. Anything you like, just throw exceptions. So for instance, we have this then I should be redirected to path. And then you see we have assert session, which is something from mink and address matches path. And if the assertion fails, the test fails. And there you go, you have a failing test. If the assertion succeeds, you have a succeeding test and we can all be happy. Yay! So mink is actually just a context that has a lot of things already built in. So you want to extend the mink context and use it. Because you have things like clicking links and you really don't want to implement it yourself. This is how it looks like. And this is where you can start to see the regex. So here you can see public function click link and you can see that you get the session, you get the page and you click the link. Mink does nothing that you can't do manually yourself, but it saves you a lot, a lot of time. You can also fill fields. So for instance, this fills in fields with a table. That's also the table syntax you saw earlier in the scenario outline. You can use it inside of your B-hat tests or your gherkin and then define a table. And that you do with the following syntax and the column that you see. And this is how it can look like. For instance, we wait for 500 milliseconds, we get the login link and we click it. And that's how we use Mink. There's a lot of things you can do with Mink. For instance, you can drag and drop, you can click, you can visit pages, you can take screenshots and many other things. Mink is really awesome and it tests basically everything in a simple application. So often if you use Mink, you don't have to write your own context. You just use these. When I fill in the following or when I click and then if basically you have a lot out of the box, which is really, really awesome. Now, we found that this was really cool. We started testing both JavaScript and PHP in the same application. It's very straightforward if you want to test just your PHP parts, but if you want both, we found out that the mocking wouldn't work because in a PHP part it worked, but there was no way for it to go from a PHP process to a node process to PHP again and know which fixtures we were using. And also anytime the API responses changed, we literally cried because we had to spend hours in and hours out changing all the fixtures. Before we go on, is there someone here that doesn't know about mocking and fixtures? I can explain it a little bit. Okay, so you all know what mocking and fixtures are? No, okay. So every time when you test something, you want, you have an API response, for instance, or you have an HTTP response. And this response, you can go live and you can get it back. But the problem is if you test something, let's say discounts of this week, then every week it's different discounts and you just want to see, so you have discounts on that page and the logic works. So what you do is that you mock the call and the response yet. So you say, okay, instead of having the live call, let's just, every time I'm here, mock this and give me this response, which is by default always this JSON or by default always this HTTP response. So then you can get always, for instance, crisps as a discount. And that's really, really handy when things change, so you always get the same thing. And we used fixtures a lot, which was basically JSON files. So you have a list of JSON files and you say, okay, when I call this, mock the response with this JSON file and you get that instead of the actual response. And this worked really, really cool in the setup we had before, but we found that with BeHat and Phantom.js testing everything, we got into trouble. And also we wanted to change this every time API changed that we had to change every fixture to match it. So we had to change the JSON files to have the new things that API provided. So we sold this in the end by implementing something called PHP VCR. PHP VCR is like a record player. Basically you record HTTP interactions and you replay them when your test runs. So here you can see a system on the test and you can see PHP VCR in between that records everything you do, no matter what you do. And then it goes to the API, if there's no recording, if there is a recording, it goes to the disk and then it gives it back to you. So you never go to the API. Is this clear or any more questions? Sorry, can you go to the mic or say it a bit louder, come here. Ajax, yes, it will record anything. So anything that goes to the, the question was, will it record Ajax? Ajax, yes, it will, but only if it's during your test run. So for instance, if you start recording, actually I will explain it while I go through this. That's a good question, thank you. So PHP VCR means it's much faster test because you never have to go to an actual online server and have to delay but you just get your file directly and then there you go, you run your test. And it also means you can run them in a train or on the plane, which I found is really, really useful because you have everything already on your computer and you can run your test suite offline and avoid things like rate limits because if you have a lot of tests hitting an API, you're going to get there quickly. And also PHP VCR means you just record it. You hit record, you record anything and that's it. No more manual mocking, no more taking the JSON response or HTTP response, writing it in a file and find that I want to use this. It's no more manual work. And as I said, you can use it for a lot of things. A lot of people use this not only for tests but for offline programming, which is pretty cool. So this is how it works. This is a small example in PHP. First, you turn on VCR, like turn on the record player. Then you insert a cassette, it can be anything. And then you can do anything. So for instance, you can wait for an iJax request. So you can have dynamic requests, you can have anything that you want and record how much you want. So if you know that you're going to wait for JavaScript to execute iJax calls or something, then have a wait in between or do something where you know that it will only eject it after you're actually done. And then you have everything inside of birds.yaml and you can turn off your cassette player. And there you go, you have your first PHP VCR recording and then you can use it by mocking it. And this is out of the scope of this talk but I would be happy to talk more about it if I have more time. But mocking, you can use mockery in PHP, which is an awesome, awesome tool. So here we can see, for instance, that we use custom cassettes. And before each scenario, we set a cookie with a cassette name, which works really, really well. So let's get into testing JavaScript because we want a one tool that does the job. We can write gherkin and we can test JavaScript, we can test PHP and we can be really, really awesome with this. Phantom.js is a headless browser and what confuses a lot of people if you want to use it in gherkin, you have to use it as a ghost. And a ghost means that Phantom.js pretends that it is Selenium. So you set up a ghost driver pretending it is Selenium running on a porch. And when it pretends it is Selenium, you can run things like save screenshots with the Selenium driver and in the back end, it actually uses the Phantom.js driver. But your code has no idea, it just thinks it's using Selenium. So to test JavaScript, you use the JavaScript tag and that's all you need to do to define that it's actually Selenium that you're using or in this case Phantom.js. So here I'm searching for Tomaten, which is tomatoes in German. And this test would obviously fail because I'm searching for tomato. Given I am on sortiment groceries, I search for tomatoes, I should see you search for tomatoes yielded. It won't work, but the scenario is wrong. So here you can see the test, it's actually pretty simple. I search for search term. So first you get your session, then you get your page. So you have your session and your page and from there you can use mink to do anything you want. So for instance, here we're finding CSS and we click. So here we can see if we click the search input and we set the value to be the search term, in this case tomatoes. And then we want to find the search button. So we find the CSS, which has the class search button ptn, and then we click it. And then we have actually clicked the search button, box in JavaScript. And this is what your browser actually does. So in this case, your headless browser goes ahead, selects, clicks, sets the value and clicks that button. And then what we can do is that we can set the time out and say, okay, wait for a certain time because I know I will always get results after, let's say one second, or we can evaluate a JavaScript expression. What this means is that it will wait until the JavaScript expression is true. So in this case, I know that it's done when I actually have a search title, which is longer than length zero. Then this is done, it's true and it has found my search results and it's done. If it doesn't find it or times out, then the test fails. And then in this case, I'm saving a screenshot for debugging. And saving screenshots is really, really easy to do because with mink and the B-head driver, you can just save screenshot, done. And Phantom.js in the backend takes a screenshot and it saves it to a defined location, which is the second parameter here, self-debug path. And the screenshot will always be exactly what your headless browser is seeing and it's a way to actually hook into the process and get something out of it and it's really, really useful for debugging. And also, we started using it for image comparison. So you take a screenshot and then next time you have all the screenshots of defined, okay, it should look like this. And then you compare the image code. If the image code is different from previous image code, then it's wrong. And if it's the same, then it's correct. We found that we didn't use this that much and it does better image comparison libraries that gives you exactly what's wrong and that has some kind of outline. And we tested mostly that we had the correct syntax on the pages rather than testing images because it changes so often with color or let's have the padding slightly different. But testing that everything is on the page is a really, really good thing to do. So let's fit everything together that we just learned. We have Gherkin, which is defining your behavior in pure English. And this is really cool because someone like a product owner can also define your behavior or even your client can just define your behavior in pure Gherkin and send it to you, which really, really helps you because in the end they've wrote half of your test already. Especially if they have things like using mink already, you can give them, okay, these are the wends and dens and all the keywords that we have. So you can define clicking on something, you can define drag and drop something, you can find taking screenshots, you can define doing all these things. These are the things we support out of the box if you want something else. For instance, then I should see a list of discounts is what we often have. Then you have to implement that in your own context. And that's a B hat is in the backend to run all of these things for you, which works as any testing tool. You just write B hats. And then if you want to run any other tags you write the tags you want to run. And then under this, it's execute the context so that it matches the gherkin together with the context. And a lot of this, it matches with the mink context that you're already using. And underneath this, you need a browser of some kind, a driver. Headless driver is a lot quicker because what a headless driver means in Phantom JS case is that it has no graphical interface. And when it has no graphical interface, it means it doesn't have to render the page in all these ways. What Phantom JS does in the backend is that it uses webkits. And webkit is pretty fast. But you may want to test other things like internet explorer or Firefox, et cetera. So then you would need some Selenium tests. So you could use Selenium next to everything as well. But for 99% of the cases, I choose to ignore internet explorer honestly. So we had is a BDD framework with clearly defined behaviors. And you have context and steps. The steps live inside your context where you define the gherkin with annotations. You use mink as a driver and anything like Phantom JS to test the dynamic parts of your website. It's still not mature for CSS and image comparison. We had to write this context on ourself while we compared image code. And I would wish that we have something cooler out of the box for image comparison right inside of this toolbox. But we don't, so we had to use third-party tools, so it means it's not everything in one testing framework, which is why I said test almost all the things. Behat is open source, which means that maybe someone will add one of these things, which is cool. As developers in an open source community, the decision is ours, where it will go and how it will be used. We started using Behat for other use cases as well, not only for offline recording, but for actually testing live APIs, for instance. So we can have a test server and run it directly against an API and saying, when I am on this path, then I should see this or against the website. To do testing after your website is actually live, and you can see so that nothing went wrong with deployment. And then you can deploy to your production after you deploy to your test to make sure that everything works exactly like it should. So integration testing with Behat works really, really well because you can use the same gherkin test, but you just define the path and you have no mocking, for instance, and then you know exactly how it works. It's also really, really cool for testing legacy applications because if you have a modern application, you often have everything split into units, which works really, really well. So you have your unit testing and your logic is neatly tested and you have your Behat tests in another part of your application and it works really, really well. But if you have a legacy application, you maybe don't have units. You have everything in a big mess, it's spaghetti and you don't wanna test the code. You just want to make sure that everything works exactly how it should. So therefore you can do things like click around and do all those things. You would do manually defined and you define all your behaviors and for a legacy application, this is priceless because when you change something, something else will break. It's not that it might break, but it will break. And when you run your test with it, you will know that it broke and it's awesome, especially if it's a really, really big legacy application that you're testing. Make sure to have some kind of integration tests running against it so you know when something breaks. So contribution, any questions regarding Behat in Drupal? Obviously, I don't know much about Drupal, so you would have to contribute. Okay, I repeat it. There's a Drupal extension that adds on top of Behat. Okay, so it tests very Drupal-y things. It has over 60 different scenarios already. Okay, so it has a lot and a lot of scenarios. So it's basically like a mink context, but a Drupal version. So you have all these scenarios already made out for you to test different parts of your Drupal application, like your nodes and anything you have in Drupal. That's really cool, thanks. Okay, so with the extension, you can test outside and inside of Drupal. That's cool, thanks. Any concerns or questions about how to actually use this in your application? Yeah, I'm very interested in testing, which I guess all of us here are, which is why we're here. I'm not very clear of, in the end, once I've got all this code, and if I figured out how to write Behat and all these other bits, what my front end in terms of actually testing looks like, is it like a selenium-style thing where I'm in a browser and I can see a list of tests, or is it more a command line thing? Are you able to give a demo, for example, or show us what it would look like? Let's show you something. So in this case, we have a lot of gherkin scenarios. So we have gherkin files that says, for instance, given I am on the category and then we define a category, and then we have some order or some sorting, then we visit that with the specific slug that we have, or given I am on a discount category, then I visit a specific path, and this is extending to fit our application, or I am on a brand or I am on different places, or in this case, it's a JavaScript context. Thank you, no one said that. So this is, obviously we don't have a bear context, but I had to comment that up for privacy of a client. And in this case, it's, you have your gherkin files, so you have your features, and all your features can be things like, let's scroll down. I am on category, I am on discount category, you see a lot of context in here, and we have a lot of different contexts, and which you could define in your behat.yaml. So we have this bear context, we maybe have wine context or Drupal context, and then we have the gherkin files. So we have list feature, or bear feature, very big thing today, or we have anything, any feature that we want, and we have the context that matches the features. And then we run them by doing behat, just output behat, and it runs all of these defined in the gherkin. And that's how you test your application. Is that a good answer, or do you want more of a demo? Yeah, I'm still, this last bit, you know, you run behat, you know, what are you doing? You're typing behat, the name of this file, a command line, or how's that aspect I'm kind of missing? Right, I can't show this without showing you too much of my client, let's see. It's recorded. Okay, I can just show you instead. So for instance, we would do, can everyone read this or should it be bigger? Okay, so to run behat, we could do minus, minus tags. So we can run behat in any kind of way that we want, and when we run it, we can either get the outputs. I should have had this in my slides. So we can get the outputs which is test failed, test succeeded, and then it will tell you exactly what's failed. Or you can define an output like in PHP unit where you get your dots, and then your F if it fails, or an S if it's skipped. And that's how your output, and you can see exactly how many failures, how many passes you have. I wish I could show you a demo, but it would get kind of awkward for the client. It's all command line, but what we do is also that we implement it in our continuous integration, and it means that every time we push up our code, it goes through all the tests before, and we can see, okay, these tests, they failed. So it's all a command in the command line and all shows the output in the command line. There's never a graphical interface. I don't know if the Drupal extension has a graphical interface, no. It's all in the command line. You can combine two other contexts in your own custom context. Let's say Drupal has its own context, so let's say you want to combine mink and Drupal context. Okay, so if you want to combine mink and Drupal context, then you can use both contexts. You define them in your behet.yaml. You define, you use the Drupal extension, and you can also use the mink context. So you can extend the mink context and anything that matches in your gherkin, it can either match any of your Drupal scenarios, like I am on Node or whatever it is, or it can match the mink scenarios. I click on page. So it... Yes, exactly. Each sentence has to refer to only one, or it will give the ambiguous error. So if you have something that matches in both mink and Drupal, it will give you errors and it won't work. So you have to be a bit careful with that. I don't know because I never used the Drupal extension if it's compatible with the mink context, or if it actually it is, okay. So you can use both by simply defining them and having your own context. It's also worth mentioning that there's an HTML formata plugin as well, which is quite useful. Wait, so you can output pretty print reports, which is kind of useful for customers to look at and give you pie charts and things. I can't remember the name of the plugin, but it's an extension, I think, for Behat that you can download, I think it's on GitHub somewhere. Ah, cool. So, yeah. Thanks. There is one that you can use together with Phantom.js. I forgot the name of it right now. But there are, if you simply do a quick Google Phantom.js image comparison, you will get a couple that you can use. Right now, they're all in JavaScript or together with Selenium. There is not many good ones in PHP itself as far as I know. Sorry, it's a bit hard to hear you. Can you go to the mic? Okay, so the question is if we need something specific to test mobile devices. In this case, we test mobile devices by defining the screen size. So for instance, I know that an iPhone has a specific screen size. It's narrow, and then I can test on that if my website is responsive or not, if I see the mobile classes I'm supposed to see. And this I do by defining the screen size in your context itself. Do you have any recommendations on how to set this up? Like, any links or steps to follow? Do you know set up BeHat, Mink, and Phantom.js? Because I myself struggled with setting up BeHat with Mink for the Drupal extension. With the Drupal extension, I'm not sure, but the BeHat itself has really, really, really good documentation for BeHat version three. So if you go to the BeHat documentation, they have step-by-step how to get started and how to get into BeHats. Sure. And also to share that we had a lot of problems in debugging. Like some of the scenarios would fail without any reason. And we had a lot of pain trying to debug because after a point, you can't debug at all. You just don't know why it fails. Okay, so what you can do to debug is, for instance, if you're using a headless browser, you can debug by hooking into the process and printing screenshots or you can use Xdebug, which I found really, really helpful to see exactly where your application, what steps you go through. And debugging is a complex topic and in Drupal, I'm not sure how, I'm sure there's a session about it here. Hi, two things. First of all, you were mentioning the front-end screenshot tools. I think Wraith is one that uses phantom.js or Casper. Oh, thanks. And people I've worked with have used that with some success. The other thing was a question. At the beginning, you said you wanted to use codeception, but you couldn't because of the PHP versions. If you were starting again now, would you use codeception in preference to BeHat or would you still stick with what you've got set up? If I start again, I won't use BeHat because it really, really worked for use cases and especially with Gherkin and it's no PHP. A codeception for those who don't know, it's a behavior-driven development framework written in PHP where you also write your tests in PHP. So it would be I am, web guy, I do this. And it's really helpful for a developer to write tests, but with BeHat, anyone including the designer can write the Gherkin files and we write the context. So I think for our use case, actually it turned out to be better, which is really cool. Great, thank you. Thanks. Do you have any advice or recommendations for actually configuring a testing environment? For example, what we've done, I don't know if it's a good approach or not, is we've pre-built a vagrant machine. So everything's inside that and it's part of our QA repo. So anybody can then download the repo, get the vagrant machine and just do vagrant up and provision so they can have a running QA, a working QA environment. Because configuring this can be quite a nuisance if each person's doing it separately. Yeah, exactly. What we do is also that we use vagrant, which is a virtual machine. And inside of vagrant, everyone has the exact same development machine with BeHat already installed. And with Phantom.js, which I forgot to mention requires Node.js. And everything is already installed in vagrant and you can simply go ahead and write BeHat inside of vagrant and everything works like it should. If everyone has to set up their own environments, it becomes kind of tricky if you have a big team. So I do advise you to use something like vagrant or Docker. Okay. So the question was during the lifecycle of an application, there's a lot of change and the tests have to change as well. So how do you cope with change? In BeHat, when something changes, I think it's easier to cope with change than it is if you have everything written like we had before in functional tests, which is just a lot of random names and we try to define everything in logic directly. In BeHat, we know, okay, this is the behavior that has to change. So we change this feature directly. So for instance, if the search page changes, we change the feature for the search page and then it breaks and then we change, actually implement the feature until it doesn't break and then we know, okay, cool, we have implemented a new change request. Any other questions about performance? Is PhantomJS as fast as you can go? It's faster than Selenium because it's a headless browser, but it's definitely slower than running PHP unit and unit tests directly. If you want to test JavaScripts, it's everything will be kind of slow because you have to wait for things to load, et cetera. So there's nothing that's really, really quick. So what I try to do is that I try to test as much as I possibly can without JavaScripts in PHP directly and do only the things that is actually interactive in JavaScript tests, like clicking in the search button, boxing, searching, I have to do in JavaScript or filling in a form I have to do in JavaScript, but other things like checking if an element is on the page, I can do with a normal test without involving PhantomJS at all.