Laravel Login PHP Unit Feature Test with Sqlite faker

Laravel Login Unit Test example tutorial explain you how to create login unit testing using PHPUnit with sqlite faker. Testing is more important for developer as well as tester. We test any project statically but laravel provide you all testing packages which you run and get any coding defects bugs easily.

Laravel provide you two major tests one for Feature test another is PHPUNIT test. Laravel feature test run our app feature which phpunit check the command and all functionalities. If you are in new and running phpunit or feature test in laravel, then we will teach you how its word with sqlite database. We all know sqlite is a database which is run in server side. Here we need to run sqlite and add some other things.

This article assumes that you would already have a project up and running on Laravel 5 and you would now like to perform quick unit/feature testing iterations while not affecting the actual database in use. Feel free to skip the next few sections if you already have a project running and continue from “Installing Sqlite”. Let’s start with Laravel Login feature Test.

Laravel Login Test using Sqlite

In SQLITE Database we need to install sqlite first. Check first which php version is you are running. Run  below command to run sqlite package.

sudo apt install sqlite

After running this command now we need to create a .env.testing to adding sqlite details on it. Create a new file .env.testing file add below code some code on it.

I’ll create this quickly by copying over our existing working copy of .env

.env

APP_NAME=Laravel
APP_ENV=testing
APP_KEY=base64:aH1DhVqPmRRqkmI0e8b5nFWct3j/msdSoS8um6x4krA=
APP_DEBUG=true
APP_URL=http://localhost

LOG_CHANNEL=stack

DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=:memory:
DB_PASSWORD=root

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

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}"

You just need to copy you .env data to .env.testing file and only add these 3 datas on it.

APP_ENV=testing
DB_CONNECTION=sqlite
DB_DATABASE=:memory:

After adding these creadiantions in your new env file now you need to run env=testing just run below command. Its update your sqlite database. You need to update your tests/TestCase.php file just add these on it.

use Illuminate\Foundation\Testing\RefreshDatabase;

use RefreshDatabase;

If you have no idea copy below code and add you tests/TestCase.php file.

<?php

namespace Tests;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication, RefreshDatabase;
}

After adding these now you need to run below command to setup your sqlite with laravel test.

php artisan migrate --env=testing

Now you laravel test is ready for your feature or phpunit test. Now you crate your first phpunit test or featch just run below code for your testing code for login page in laravel.

// Create a test in the Feature directory...

php artisan make:test LoginTest

// Create a test in the Unit directory...

php artisan make:test LoginTest --unit

If you are running feature test then you need to runn first command or if unit test run second command as well as. After running any one command add below command in your test phpunit or feature test of laravel.

tests/Feature/LoginTest.php

<?php 

namespace Tests\Feature; 

use Tests\TestCase; 

use Illuminate\Foundation\Testing\WithFaker; 
use Illuminate\Foundation\Testing\RefreshDatabase; 
use Spatie\Permission\Models\Role; 
use Faker\Factory as Faker; 
use App\User; 
use Hash; 

class LoginTest extends TestCase { 

  protected $faker, $user; 

  /** 
   * Create a new faker instance. 
   * 
   * @return void 
   */ 

   public function __construct() { 

     parent::__construct(); 
     $this->faker = Faker::create();
    }

    /**
     * Create a new user instance.
     *
     * @return array
     */
    private function validCredentials()
    {
        self::createRoles();
        $password   = $this->faker->password;
        $this->user = factory(User::class)->create(['password' => Hash::make($password)]);

        return [
            'email'    => $this->user->email,
            'password' => $password,
        ];
    }

    /**
     * Create a roles
     *
     * @return void
    */
    public static function createRoles()
    {
        $roles = [
            ['name' => 'admin'],
            ['name' => 'supplier'],
            ['name' => 'user']
        ];

        foreach($roles as $key => $role) {
            Role::create($role);
        }
    }

    /**
    * @test
    * Assert a user can view login form.
    *
    * @return void
    */
    public function user_can_view_a_login_form()
    {
        $this->get('/login')
             ->assertStatus(200)
             ->assertViewIs('auth.login');
    }

    /**
    * @test
    * Assert a admin can login
    *
    * @return void
    */
    public function a_admin_can_login()
    {
        $credentials = $this->validCredentials();
        $this->user->assignRole(['admin']);

        $this->post('/login', $credentials)
             ->assertRedirect(route('admin.index'))
             ->assertSessionHasNoErrors()
             ->assertStatus(302);
    }

 
    /**
    * @test
    * Assert a user can not login without email or password
    *
    * @return void
    */
    public function a_user_can_not_login_without_credentials()
    {
        $this->post('/login', [])
             ->assertSessionHasErrors([
                'email'    => 'The email field is required.',
                'password' => 'The password field is required.',
             ]);
    }

    /**
    * @test
    * Assert a user can not login without email
    *
    * @return void
    */
    public function a_user_can_not_login_without_email()
    {
        $credentials = $this->validCredentials();
        unset($credentials['email']);

        $this->post('/login', $credentials)
             ->assertSessionHasErrors([
                'email' => 'The email field is required.',
             ]);
    }

    /**
    * @test
    * Assert a user can not login without password
    *
    * @return void
    */
    public function a_user_can_not_login_without_password()
    {
        $credentials = $this->validCredentials();
        unset($credentials['password']);

        $this->post('/login', $credentials)
             ->assertSessionHasErrors([
                'password' => 'The password field is required.',
             ]);
    }
}

That’s over now your feature or phpunit test in laravel step by step, if you have any other testing about laravel feature or phpunit test please comment below as per your requirements.
Learn: Laravel Custom Authentication Tutorial with Example

Leave a Comment