Laravel and Dusk on Codeship
Some time back, I posted on how to set up Laravel and Behat using Selenium and headless Chrome. But since that article, a new option has come into view — Dusk.
This has several advantages over Behat. For one, the install is greatly simplified. On top of that, the speeds and simplicity in testing the UI and JavaScript have all been wrapped into PHPUnit. Invented by the creator of Laravel, Dusk has amazing integration into the base of Laravel, from easily mocking events, jobs, models, etc. to running migrations and transactions.
In this article, I will cover a much-updated approach to getting all of this working on Codeship, including how to troubleshoot when things are not going as expected on a Codeship build.
Setting Up Your Local Environment
As in the last post, I reference Matthew Setter’s article about Laravel and Codeship. From there though, the next steps change from the previous article since there is no Behat or Selenium to set up.
If you miss the Behat Gherkin workflow, try Pickle.
Instead, I follow the installations docs as seen on Laravel Docs. This uses the standalone ChromeDriver, eliminating the need for installing Selenium as well. The docs on that page do a great job of explaining how to get set up.
The only thing I would point out is that if you are running your tests in your VM, which I do most of the time, you just need to set your VM to know the IP of your host machine. So when you’re running Dusk from inside of it and point to the URL of your app (eg, http://foo.com), then the VM’s /etc/hosts
file needs to match that domain to the host IP. This will then open up Chrome on your host machine via this driver.
In this example, I’ll keep it simple and run the server on my host machine. First, I’ll edit my .env
file to be APP_URL=http://127.0.0.1:8000
instead of the default and then in the terminal, type:
php artisan serve
You will end up seeing this:
Your First Dusk Test
We are now ready to write the first test. To begin, I’ll use the command to stub it out:
php artisan dusk:make FirstUITest
This will make a file, tests/Browser/FirstUITest.php
. Then I’ll just keep it simple and leave the default stubbed test in there:
browse(function (Browser $browser) { $browser->visit('/') ->assertSee('Laravel'); }); } }
Now, to run this locally and make sure all is working and running from my host machine:
php artisan dusk
You should see, as in the image below, Chrome pop up and run the tests.
Setting Up Codeship for Dusk
Now that we have our test, we need to get Codeship ready to run Dusk. First, I’ll add a .env.codeship
file:
APP_ENV=testing APP_URL=http://127.0.0.1:8000 APP_KEY=base64:nF7Ns2Gz9olX2rmfquKzblBRVHIvsFzicqh78TGHh6A=
Then, I’d like to make a ci/setup.sh
folder and file with this content:
#!/bin/sh set -e phpenv local 5.6 composer install --no-interaction ./vendor/laravel/dusk/bin/chromedriver-linux & cp .env.codeship .env php artisan serve > /dev/null 2>&1 & sleep 3
This makes it easier to debug a build when you SSH into Codeship, as I will demonstrate later on.
All right, now wrap up the two install settings on Codeship as seen in the image below.
Now push your code!
Troubleshooting a Build
Sometimes things will not work out on the CI as expected, and this is great! Well, great in that the CI really does catch the little details that are easy to miss when running tests locally. For example, a classic one for me is that on a Mac, I class with a filename FooBar.php
but the name class Foobar
will pass. But on the CI and pure Linux, it won’t. since the caps do not match. I’d much rather have this happen on the CI than on my server.
SSH and dump
One great feature of Codeship is the ability to SSH in and debug. Once you are logged in, you can run:
>sh ./ci/setup.sh >php artisan dusk
This is where, in my opinion, it pays off to just have these files instead of numerous lines to run.
After that, you should still see the fail. At this point, alter the test to look like this and add the dump()
:
{ $this->browse(function (Browser $browser) { $browser->visit('/')->dump() ->assertSee('Laravel'); }); }
Then after you run the test again, you’ll get a ton of output on the screen. For me, this led to a message that ChromeDriver could not connect to the APP_URL
, so I just made sure to rerun php artisan serve
. Once, I made the mistake of setting assets
to use https
, but as you see above, I am serving PHP over http
.
Logging and tail
This is a very simple workflow I do locally but it even comes in handy on Codeship. Using a terminal like iTerm, I can have one terminal open and two panes. Then in the top pane, I can SSH in and run the test, while in the bottom one I can tail the logs:
tail -f clone/storage/logs/laravel.log
That makes it easy to see results while running tests and trying new things in the top pane.
The log file will not be there until there is something to log.
SCP and screenshots
Finally, Dusk saves screenshots of failed jobs. They are located in tests/Browser/screenshots
and named after the function name and number, eg, failure-testExample-0.png
. This does not help you much in SSH mode! But if you’re lucky enough to have SSH running on your machine and a port open on your router, then:
scp -v ~/clone/tests/Browser/screenshots/*.png yourname@your_ip:~/
This will download those files locally to your computer. This is needed since SCP to Codeship requires a password, so you can’t just download those files from your machine.
!Sign up for a free Codeship Account
Gherkin and BDD
In case you’re missing BDD and the Gherkin syntax that Behat provides, I want to share how to use pickle
. By using Pickle, you can still have the same flow as before, where there’s a Gherkin-based test to run that will use Dusk.
To begin with, let’s install Pickle into the dev part of your app using Composer:
composer require alnutile/pickle -dev
The Pickle docs mention
cgr
and global install. This is great for your host machine or VM (Guest), but for Codeship, we’ll just include it into ourdev
composer.json.
Then in my project, I’ll make a folder and file, tests/features/example_pickle.feature
:
Feature: Running pickle on Codeship Scenario: Is the site loaded Given I am on the home page of my app Then I should see the intro text
Now we want to make our Dusk test out of this. I can later make a unit or integration test out of this same file as well:
vendor/bin/pickle initialize --context=browser tests/features/example_pickle.feature
This will stub out a file located at tests/Browser/ExamplePickleTest.php
for editing.
Just like before, it is stubbed out, but in this case, the file Pickle created is broken into steps
. This will allow you to build up your tests and your code, since this is happening before you start to code, one step at a time. By the time I’m done, it will look like this:
class ExamplePickleTest extends DuskTestCase { /** * @var Browser */ protected $browser; public function testsTheSiteLoaded() { $this->browse(function (Browser $browser) { $this->browser = $browser; $this->givenIAmOnTheHomePageOfMyApp(); $this->thenIShouldSeeTheIntroText(); }); } protected function givenIAmOnTheHomePageOfMyApp() { $this->browser->visit('/'); } protected function thenIShouldSeeTheIntroText() { $this->browser->assertSee('Laravel'); } }
Okay, now to run it locally:
vendor/bin/pickle run --context=browser tests/features/example_pickle.feature
All this is doing is wrapping Dusk, so as before, you could just run php artisan dusk
, seeing the test come together one step at a time. And that is it; we can leave Codeship settings as they are.
To make the Integration
or Feature
test out of this, run:
vendor/bin/pickle initialize tests/features/example_pickle.feature
As you are completing the steps in that file, you can run:
vendor/bin/pickle run tests/features/example_pickle.feature
And as with Dusk, Pickle is just wrapping PHPUnit, so in your Codeship test settings, make sure to add vendor/bin/phpunit --stop-on-failure
.
As you see, getting up to speed with Dusk and Laravel on Codeship is very easy. There really is no reason not to test your UI, even when it contains JavaScript.
Published on Web Code Geeks with permission by Alfred Nutile, partner at our WCG program. See the original article here: Laravel and Dusk on Codeship Opinions expressed by Web Code Geeks contributors are their own. |
Nice article on Laravel,
Do you know WHY LARAVEL IS CONSIDERED AS THE BEST PHP FRAMEWORK FOR YOUR WEB APPLICATION DEVELOPMENT?
https://www.titechglobal.com/laravel-considered-best-php-frame-work-web-application-development/