Hello,
i was tasked to do Unit Testing for one of my projects, the test case that i was tasked with is :-
- User can login and see Dashboard
- User can login and see Developer Portal
- User can login and see Administration Panel
basically the test is quite easy and straight-forward right?
so im off with installing Laravel Dusk
since this kind of test involves with the actions of seeing the UI itself.
if you're not familiar with Laravel Dusk, Laravel Dusk is a official library that are supported by the Laravel itself.
Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your machine. Instead, Dusk uses a standalone ChromeDriver installation. However, you are free to utilize any other Selenium compatible driver you wish. - Laravel Dusk
So Without further ado,
The Preparation
Make sure that you have created the user factory, user seeder as well as enable user factory inside DatabaseSeeder.php
file before starting this unit test. since its requires dummy user to test the test case.
Laravel Dusk Installation
installing Laravel Dusk is quite the breeze, just run this into the CLI of your project composer require --dev laravel/dusk
after installing the packages you can then run php artisan dusk:install
to install your laravel dusk.
Laravel Dusk Environment Configuration
By Default, when the laravel dusk environment configurations file .env.dusk
is not exist, it will automatically use the .env as the environment configuration temporarily. in our case, we need to use a separate database which is called dusktest
database and create the .env.dusk
file onto your root project folder. Here's the sample of my .env.dusk
Important Make sure to generate the APP_KEY as well. run
php artisan key:generate
then copy the key from.env
to.env.dusk
APP_NAME=dusk
APP_ENV=local
APP_KEY={your-key-here}
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
LOG_CHANNEL=stack
FLARE_KEY=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dusktest
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=array
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=array
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_NAME="${APP_NAME}"
MAIL_FROM_ADDRESS="no-reply@ksud.com"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
The Test Scripts
Run php artisan dusk:make CommonTest
onto your CLI , it will created the Test File inside my-project/tests/Browser/CommonTest.php
. After that we need to create the test case inside the test scripts . Here's the test scripts that i've created .
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Artisan;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;
class CommonTest extends DuskTestCase
{
use DatabaseMigrations;
/**
* Can Login and see Dashboard
*
* @return void
*/
public function testCanLoginAndSeeDashboard()
{
//Seed dummy user data
Artisan::call('db:seed');
$user = User::first();
$this->browse(function ($first) use ($user){
$first->loginAs($user)
->visit('/dashboard')
->assertSee('Dashboard');
});
}
/**
* Can Login and see Developer Portal
*
* @return void
*/
public function testCanLoginAndSeeDeveloperPortal()
{
//Seed dummy user data
Artisan::call('db:seed');
$user = User::first();
$this->browse(function ($first) use ($user){
$first->loginAs($user)
->visit('/developer')
->assertSee('Connective Exchange');
});
}
/**
* Can Login and see Administration Panel
*
* @return void
*/
public function testCanLoginAndSeeAdministrationPanel()
{
//Seed dummy user data
Artisan::call('db:seed');
$user = User::first();
$this->browse(function ($first) use ($user){
$first->loginAs($user)
->visit('/admin')
->assertSee('Resources');
});
}
}
Github Action Workflow
So basically if you're familiar with github actions , the github action workflow scripts should be inside my-project/.github/workflows/actions.yml
you can rename the file as you desired.
# my-project/.github/workflows/actions.yml
name: Unit Test
on:
push:
branches: [develop]
pull_request:
branches: [master, develop]
jobs:
PHPUnit:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0.21
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: dusktest
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
- uses: actions/checkout@v2
- name: Configure Application
run: bin/ci
- name: Configure Laravel Dusk
run: bin/ci-dusk
- name: Execute Dusk tests via PHPUnit
run: php artisan dusk
you have to create some of this bash files to ensure the scripts working.
# my-project/bin/ci
#!/usr/bin/env bash
cp .env.example .env
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
chmod -R 777 storage bootstrap/cache
php artisan key:generate
php artisan config:clear
# my-project/bin/ci-dusk
#!/usr/bin/env bash
php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
chmod -R 0755 vendor/laravel/dusk/bin/
php artisan serve > /dev/null 2>&1 &
curl localhost:8000 &
./vendor/laravel/dusk/bin/chromedriver-linux > /dev/null 2>&1 &
Simpy push your codes to github, and it should be good to go! Thank you for reading.
Honorable Mentions
- Nasrul Hazim (Helping out with the workflow configurations)
Top comments (1)
Nice post, on a quick thought wouldn't it be better and abit faster if you used factories to make user data instead of seeding the data via an artisan call.