Getting Started with Laravel Dusk

What is Laravel Dusk?

Laravel 5.4 came with a powerful new tool called Laravel Dusk. Laravel Dusk allows you to easily perform browser testing on your Laravel applications!

What is Browser Testing?

Browser Testing is a process to test web applications across multiple browsers and specifically to ensure that the UI meets functional requirements. Put in plain english, Browser Tests allow us to simply test that if I click add to cart, the add to cart functionality actually works!

But I already Unit Test?

Great news! You already write unit tests and that is very essential. The basis of your test suite consists of unit tests and they ensure that your classes do exactly as intended however browser testing is an important part of any testing suite and is essential to ensure that your UI works correctly!

Browser Tests In Detail

When it comes to browser testing, there are a number of pro’s/con’s to implement browser testing namely:

  1. Simulates User - It allows us to simulate exactly how a user would interact with our application.
  2. App works end-to-end - By simulating our user and interacting with our application. It allows us to ensure that our application works end-to-end.
  3. Slower - because we are not dealing directly with our data structures, it is slower as we have to interact with our User Interface.
  4. Need to make assertions through UI - This is a bit of a con as making assertions through our UI is brittle at best. If we update the front-end of our application, that could potentially lead to breaking our browser tests.

Laravel Dusk is very powerful and a pleasure to use for browser testing as it is simple to install (as we will cover below). It does not require any JDK or Selenium installs as it comes with a standalone headless ChromeDriver which is used to run our tests and it’s fluent API allows for very easy browser testing.

Overall while Browser Testing does have some drawbacks, it is essential in order to ensure that you are testing your application effectively and is an important base to cover. Let’s get started!

Setting up Laravel Dusk

In order to install Laravel Dusk to a sample Laravel 5.4+ application, you simply have to do the following:

Install the package using Composer.

composer require --dev laravel/dusk

Then run the install console command to setup the Dusk scaffolding:

php artisan dusk:install

Finally we must update our .env (and .env.example) to add our APP_URL otherwise Dusk will not know which URL to visit and your browser tests will fail.

in .env:
APP_URL="myapp.test"

You will now note that your testsuite will have a /browser folder and a DuskTestCase.php which is what we will be using.

Our First Browser Test

We can now write our first browser test, in this example we have a Podcast app which allows us to view podcasts. It’s a contrived example but it allows us to see the simplicity of using Laravel Dusk for browser testing. We also leverage model factories which I covered in a previous post here.

<?php

namespace Tests\Browser;

use App\Podcast;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;

class PodcastBrowserTest extends DuskTestCase
{
    use RefreshDatabase;
    /** @test */
    public function can_view_podcasts()
    {
        $podcasts = factory(Podcast::class, 2)->create();
        foreach ($podcasts as $podcast) {
            $this->browse(function (Browser $browser) use ($podcast) {
                $browser->visit("/podcasts/")
                    ->assertSee($podcast->name);
            });
        }
    }
}

Let’s break down what’s happening here… the RefreshDatabase function is caleld which allows us to ensure that our database is migrated and seeded for our test suite. We are also leveraging our Podcast model and model factory to create 2 fake podcasts and persist them into the database.

We then iterate over the created podcasts and use the browse function which is a DuskTestCase helper which visits our application. We pass in a closure with our default browser and pass in the current podcast that we are working with.

We then tell the browser (or in this case our ChromeDriver) to visit the podcasts web route and use the assertSee() helper. The assertSee helper will inspect the HTML of the returned response to our Browser and check that the podcast name is available as evident here:

  $browser->visit("/podcasts/")
    ->assertSee($podcast->name);

(Note that you will have to create the Podcast class yourself or you can simply swap it out with another class for your specific use case)

Running Tests

Awesome so now we have created our first browser test with dusk but how do we run it?

We simply run the following command:

php artisan dusk

This is simply an artisan command that will run our dusk testsuite. If all goes well, you will end up with the following:

Dusk Test Results

Wrapping Up

Let me know if you have any questions or feedback in the comments below.

Programming by Wishful Thinking

What is Programming By Wishful Thinking?

A great way to implement your programs when using Test Driven Development is using a top-down approach. Top-down programming is a programming style whereby the large concepts of a program are implemented and then broken down into successively smaller pieces. When implementing the larger design of a program, we implement stubs or mocks that will return what we expect but are not fully implemented functions. A way of modelling top-down development is as follows:

© i-programmer.info

A method stub or mock is a piece of code that acts as a substitute for our not-yet-implemented code. Implement stubs or mocks while coding is the act of coding by wishful thinking.

An example

To illustrate the approach of programming by wishful thinking, let’s look at an example. Let’s look at a simple problem of setting up the colours of a chess board and displaying them to the console.

In order to setup the colours of a chessboard, the following needs to occur.

  • We must model our chessboard.
  • We must iterate the cells of our chessboard.
  • We must check if the current cell is a white or black colour.
  • We must display the correct color and print it to the console.
An example chess board

To implement the theoretical solution above, let’s begin our example solution with stubs.

 
<?php
$boardWidth = $boardHeight = 8;

for ($row = 1; $row <= $boardHeight; $row++) {
    for ($column = 1; $column <= $boardWidth; $column++) {
        $cellColour = checkCellColour($row, $column);
        displayCell($cellColour);
    }
    
    // print newline after processing length of board for this row
    echo "\n";
};

We have now implemented the high level approach using stubs, note that the functions checkCellColour and displayCell are simply stubs. We know what functionality should be there however we have not implemented it. To further expand on our solution, we can now implement the first stub which is checkCellColour():

 
<?php

function checkCellColour(int $row, int $column) : string
{
    $cellValue = $row + $column;
    return ($cellValue % 2 == 0) ? "White" : "Black";
}

Our checkCellColour stub is now implemented. We have taken the current position that we are iterating over as arguments namely $row and $column and then we calculate the $cellValue by adding those two arguments together. If the $cellValue is even then we are on a white cell otherwise we are on a black cell. We then returned the corresponding value. We also define that our parameters must be integers and the return value of the function must be a string using PHP 7’s scalar type declarations.

We can now expand our second stub namely displayCell():

 
<?php

function displayCell(string $cellColour) : void
{
    echo($cellColour == "Black" ? "#" : " ");
}

We have now implemented our displayCell() function. This simply checks if the current cell’s colour is black and if so then we display a hash and if not then we display whitespace as that will be a white cell.

The full example is below:

 
<?php
$boardWidth = $boardHeight = 8;

for ($row = 1; $row <= $boardHeight; $row++) {
    for ($column = 1; $column <= $boardWidth; $column++) {
        $cellColour = checkCellColour($row, $column);
        displayCell($cellColour);
    }
    
    // print newline after processing length of board for this row
    echo "\n";
};

function checkCellColour(int $row, int $column) : string
{
    $cellValue = $row + $column;
    return ($cellValue % 2 == 0) ? "White" : "Black";
}

function displayCell(string $cellColour) : void
{
    echo($cellColour == "Black" ? "#" : " ");
}

?>

Remarks

The takeaway from our example was not the solution but the way that we coded the solution by first creating mocks and then expanding and implementing the functionality needed in order to reach our final solution.

The main advantage of coding by wishful thinking is that you abstract away the low-level implementation of your program and focus on the high-level (i.e. top down) approach first. This methodology allows you to deal with varying levels of abstraction. This is also a very natural way to code when writing tests (as we will see in another tutorial) as it allows you to focus on the test by using stubs and demonstrate expected test functionality before you have actually implemented the functions.

Let me know if you have any questions or feedback in the comments below.

Happy Coding!

My experience at Make Day Juliett

What is a Make Day?

Make Day Juliett was one of many “Make” days that OfferZen is offering to local developers around South Africa. OfferZen is hosting 20 developers per Make day to join in a full day of building things (hence the name) in a low-pressure environment that is focused on learning. You can find more details about OfferZen’s Make platform here.

What is Make Day Juliett?

Make Day Juliett was hosted by OfferZen and Root. Each Make day has a theme and the theme behind this Make day was that you build a chatbot utilizing the Root API. The essential takeaway of the day was to learn about building insurance chatbots. The elements that were focused on were namely:

  • Root's brand new Insurance API
  • Chat interface of your choice: Facebook, Slack, Google Assistant
  • NLP (Natural Language Processing) tool DialogFlow (previously API.AI)

If you want to find out more about the day then just look at this PDF which explains all about the Make Day and Root’s insurance platform.

Prep work

After being invited, OfferZen Make gave us some prep work to look at. The prep work mainly consisted of finding out about DialogFlow and Root, setting up our Root API accounts and making a request to the Root API. The prep work was vital for me as it ensured that I had a clear understanding of the technology that we would be using. The prep work was optional however I decided to revise it in order to ensure that I could get the most out of the day. My aim was to build a chatbot and learn about DialogFlow and Root insurance, not struggle getting my first intent setup or anything mundane.

Start of the day - 8:00am

The day started with all 20 developers going to the OfferZen Make space in Kloof street. Initially, I was a bit nervous about who I would be working with and what I would gain from this day. I knew one thing and that was that I was very excited to learn and the theme behind the make day was very appealing to me as I am quite interested in ChatBots (as you can tell from my other blog posts).

This worry was quickly dispelled as I was met with a friendly space filled with coffee, fruit and snacks to start the day. I first met every developer and we all introduced ourselves and then created a name badge that featured not only our names but also what language we wanted to work in on the day. This was great as we knew that we were going to team up and being able to see who might be a good fit to team up with based on language or interest was a great idea. In terms of who was there, there were developers of all skill levels which was refreshing. There was namely CTO’s, juniors, fresh graduates, developers, senior developers so the group was very diverse and this allowed for new perspectives and ideas.

The event begins - 8:30am

After the meet and greet and breakfast, the event officially started, we all gathered in the Make Space and OfferZen presented various talks on what we would be building. We had a talk on what Make Days are about and what the platform wanted us to gain as software developers.

A vital point that was presented was that this isn’t a competitive hackathon, the idea isn’t to build the greatest chatbot and win the event. The idea was very much a learning experience and even if we didn’t finish, the point was to learn and do something new. This was a great idea as quite often in workspaces or at other coding events, the focus is very much on deadlines and finishing the product which offers little flexibility for learning something new when you are expected to be knowledgeable and perform well.

Root then presented a short presentation on what Root is about namely a bank card for software developers. The presentation also covered how the Root Insurance API works along with an example of creating an application and issuing a policy to a user in this case for insurance. This was a great addition as it gave us insight into how the Root API works.

The next presentation then focused on how DialogFlow (previously API.AI) works and how to implement it. This was essential as quite frankly the learning curve around DialogFlow was not shallow so this presentation helped a lot in terms of the basics and getting to know about intents, entities and actions.

Make Presentation
Tips for the day from previous Makers

What I really enjoyed about these presentations is that the entire presentation slot was short and each presentation was around 15 minutes, this helped as it allowed for more time to do as the event suggested, “Make” things!

Teaming up - 9:30am

After the presentations, we all stepped out for coffee into the break area and developers started teaming up, this was really cool as people often teamed up with different people of different languages. A 3-person team even teamed up and decided to do the project in a new language altogether, I decided not to opt for this approach as I was more interested in learning about DialogFlow. I teamed up with another developer who also opted to use PHP for the project. The teaming up process was easy and within 30 minutes, we were all at our stations and ready to go!

Make station
My make station!

Working on Bots - 10:00am

Make developers hard at work
Make developers hard at work!

We decided to build a Slack bot using the wonderful PHP chatbot framework BotMan and DialogFlow and then hooking into the Root API. After some initial planning, we began working on the project. The idea was to allow a user to issue a command namely “Insure my iPhone 5” and then the bot would create the relevant insurance quote and then after some basic questions would allow the user to create an application and insure their phone! I utilized DialogFlow to handle all intents so while the logic was in BotMan and that handled the API work, BotMan itself was just listening for an intent and DialogFlow had the actual job of recognizing user input and then sending an event to our BotMan app.

The way that we developed the project was in-tandem, we used a single monitor (that OfferZen provided) and essentially pair-programmed our idea to completion. This was a really interesting mechanic as it ensured that team worked together and offered input. Pair programming was a great format for the Make day as it is a tried and tested way of learning new things. My team-mate and I continuously bounced ideas back and forth and reflected on how best to solve a problem or architect the application.

This structure ended up working out very well and while it was a bit frustrating to get DialogFlow to work as intended at times, the app ended up as follows:

My app!
My app!

What really helped a lot was that software developers that have previously attended Make were there as Make “masters” and were around to offer guidance if needed. This was beneficial as they not only offered guidance but also some suggestions for the projects.

The entire day they were moving about and helping software developers with their projects. What was also vital is that Root developers were available to help with any queries regarding the Root API. This was very beneficial and I think some form of direct communication is important regardless of what platform we are working with be it Root or another service especially when building software with that service in a time-span of one day.

Make Master assisting makers
Make master assisting makers

At the end of the day, every project was at various stages of completion and this was perfectly OK. Some had completed their projects and others had made great progress or ended up focusing on one portion and learnt a lot there.

Retrospective - 5:30pm

At the end of the day, there was a short retrospective hosted by OfferZen around a whiteboard. The name of the game here was that we all offered feedback on 3 key topics namely:

  1. What tech stack did we go with and what was our idea?
  2. What did we learn from the Make Day and would we come back?
  3. What was missing from the Make Day & what could be improved upon?

After this, everyone simply answered the above questions and it was found that my feelings of apprehensiveness were not alone as many of the other software developers were worried if they would be cut out for it, this may have however just been a case of mass imposter syndrome =)

A very nice element was that nobody presented their application and the benefit was two-fold. Firstly, it didn’t matter how far you had come, just mainly that you learnt something and secondly, it removed the element of competition from the Make day as there was going to be no judging of your application at the end of the day.

What did I learn from the Make Day?

I learnt a lot about how DialogFlow works and also how to setup BotMan with DialogFlow. This was a great takeaway as I’ll definitely leverage DialogFlow in my future chatbot applications. I also learnt a lot about the Root API which was a really cool experience as the Root API was very easy to work with and the documentation was incredible! I went from 0 experience in the API to allowing a Slack user to insure their cellphone!

Would I go again?

In conclusion, I found the Make day to be a refreshing way to learn new things especially with other people rather than sitting down at a desk and reading a book. I personally learn the most when I am working on a project and so this approach was perfect for my taste. I also found the aspect of continuous pair-programming to be a very beneficial element of the day as it allowed for continuous feedback and new ideas when creating the application, after all, two pairs of eyes are better than one. I’d definitely be back for another!