/kahlan-laravel

Laravel binding for Kahlan testing framework

Primary LanguagePHP

Jamesst20/kahlan-laravel

Kahlan is a full-featured Unit & BDD test framework a la RSpec/JSpec which uses a describe-it syntax and moves testing in PHP one step forward.

Why do I need this package

While it's true that you can use the vanilla Kahlan library, you cannot access to any of the Laravel TestCase helpers method.

Compatibility

Only Laravel 5.8 is currently supported because this library relies on phpdotenv v3.0 shipped with Laravel. It also only supports the latest Kahlan version (v4.6 as of now) because it is depedent on the new afterEach behavior deployed on v4.6.

Installation

composer require --dev jamesst20/kahlan-laravel:^1.0

Usage

Getting the application instance : $this->app, $this->laravel->app, app() are all equivalent ways and will return the same instance.

In a vanilla Laravel TestCase, we can access helpers by doing $this->insertHelperMethod such as $this->assertDatabaseHas('users', ['email' => 'test@email.com']);

In a kahlan environment, it is as simple as prefixing the method with $this->laravel->insertHelperMethod.

Please note that $this->laraveland $this->app is not accessible in beforeAll, afterAll callback but is as soon as in beforeEach.

Example

Vanilla Laravel TestCase (PHPUnit)

<?php

namespace Tests\Feature;

use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

    public function testUserCreation() {
        factory(User::class)->create(['email' => 'test@email.com']);
        $this->laravel->assertDatabaseHas('users', ['email' => 'test@email.com']);
    }
}

Kahlan

use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;

describe("Homepage", function() {
    it("loads successfully", function() {
        $response = $this->laravel->get('/');
        expect($response->getStatusCode())->toEqual(200);
    });
});

describe("User", function() {
    beforeAll(function() {
        $this->enabledTraits = array(RefreshDatabase::class);
    });

    it("should save user to database", function() {
        factory(User::class)->create(['email' => 'test@email.com']);
        // There are cleaner way than using assertDatabaseHas though.
        expect(function() {
            $this->laravel->assertDatabaseHas('users', ['email' => 'test@email.com']);
        })->not->toThrow();
    });
});

Laravel Traits

The recommended way of enabling Laravel traits in Kahlan-Laravel is by passing an array of traits in the beforeAll() closure.

describe("Something that needs database", function() {
    beforeAll(function() {
        $this->enabledTraits = array(RefreshDatabase::class);
    });
});

Currently supported traits RefreshDatabase, WithoutMiddleware, WithoutEvents, WithFaker

Environment

Environment variables are read in .env.testing and are also overriden by .env.kahlan

During initialization, before Kahlan is even loaded, if .env.testing exists, only this file is loaded. .env.kahlan is loaded a little later and will override .env.testing variables in case of collisions.

Please note that kahlan will raise an error if it is not executed in the testing environment.

Executing

There is currently 3 ways to execute kahlan but I am currently only supporting 2 officially.

Using artisan :

APP_ENV=testing php artisan kahlan:run

Using the binary

vendor/bin/kahlan-laravel

The difference between the 2 is that the binary will automatically read the APP_ENV from .env.testing or .env.kahlan before bootstraping.

Due to the current implementation of Laravel, there is no clean way to avoid the need to specify the APP_ENV=testing before the Artisan command. Laravel automatically loads .env if APP_ENV is undefined, otherwise .env.{environment}. While it would be possible to override .env with the testing ones, there could be some production variables that have no override candidate in the testing environment files.

What is missing

You tell me :) !

Credits

To all contributors of Laravel, Symfony and Kahlan.

This library was inspired by Sofa/laravel-kohlan and also elephantly/kahlan-bundle.