Laravel test code bằng Phpunit

04/01/2022   Laravel

Laravel test code bằng Phpunit

Laravel có 2 cách để test: Unit testing và Feature testing. Unit test cho phép chúng ta test các class model, controller,... Mục tiêu của Unit test là kiểm tra tính đúng đẵn trong các xử lý của từng đơn vị mã nguồn. Còn Feature testing cho phép bạn test api, test kết quả trả về, test chức năng, hiệu năng cũng như khả năng chịu tải của ứng dụng.
Unit Test: Ta sẽ kiểm thử các class, method,...Mục tiêu của unit testing là kiểm tra tính đúng đắn trong các xử lý của từng đơn vị mã nguồn.
Feature Test: Có thể kiểm tra một phần lớn hơn code của bạn, bao gồm cả cách một số đối tượng tương tác với nhau hoặc thậm chí là một yêu cầu HTTP đầy đủ đến JSON endpoint.

Nội dung bài viết

1. Tạo 1 test, ta sử dụng câu lệnh.

2. Để Run test ta mở cmd trong thư mục vendor/bin/phpunit chạy lệnh

3. Assertions là gì

4. Ví dụ Unitest cho Login, Register, Logout

1. Tạo 1 test, ta sử dụng câu lệnh:

// Tạo 1 test trong thư mục Feature
    php artisan make:test UserTest
// Tạo 1 test trong thư mục Unit
    php artisan make:test UserTest --unit

Lưu ý: Nội dung bên trong thư mục Feature hay Unit phải có cấu trúc giống thư mục app/ ví dụ app/Http/Controller/UserController.php thì trong thư mục Unit phải là test/Unit/Http/Controller/UserTest.php

2. Để Run test ta mở cmd trong thư mục vendor/bin/phpunit chạy lệnh

//test trong Unit
phpunit ./../../tests/Unit/ExampleTest.php
//test trong Feature
phpunit ./../../tests/Feature/ExampleTest.php

Các lệnh khác

<!-- Run tất cả tests: -->
phpunit

<!-- Run theo testsuite -->
phpunit --testsuite Unit

<!-- Run từng file: -->
phpunit ./../../tests/Unit/ExampleTest.php

<!-- Format output: -->
phpunit --testdox

3. Assertions là gì: Hiểu đơn giản Assertion chỉ là 1 câu lênh nhằm mục đích xác nhận một khẳng định là luôn đúng tại đoạn code đó.

Ví dụ: Nếu assert rằng false là true thì test fail

function testExample()
{
    $foo = true;
    $this->assertFail($foo);
}

Một số assert thường dùng:

assertTrue() / assertFalse()
assertTrue() / assertFalse()
assertEquals() / assertNotEquals() : So sánh bằng
assertSame() / assertNotSame() : So sánh bằng, cùng kiểu
assertContains() / assertNotContains() : Array contain, String contains
assertArrayHasKey() / assertArrayNotHasKey()
assertInstanceOf() / assertNotInstanceOf() : Đối tượng thuộc class
assertCount()
expectException() : Expect sẽ có Exception khi gọi chạy unit
assertTitle($title)    Xác nhận page title match với $title
assertTitleContains($title)    Xác nhận page title chứa $title
assertPathIs('/home')    Xác nhận đường dẫn hiện tại match với /home
assertPathIsNot('/home')    Xác nhận đường dẫn hiện tại ko match với /home
assertRouteIs($name, $parameters)    Xác nhận URL hiện tại match với route name $name
assertQueryStringHas($name, $value)    Xác nhận truy vấn đã tham số $name có giá trị $value
assertQueryStringMissing($name)    Xác nhận truy vấn thiếu tham số $name
assertHasCookie($name)    Xác nhận có cookie $name
assertCookieValue($name, $value)    Xác nhận cookie $name có giá trị $value
assertSee($text)    Xác nhận có text $text trong page
assertDontSee($text)    Xác nhận ko có text $text trong page
assertSeeIn($selector, $text)    Xác nhận có text $text trong selector $selector
assertSeeLink($linkText)    Xác nhận có link $linkText trong page
assertInputValue($field, $value)    Xác nhận input $field có giá trị $value
assertChecked($field)    Xác nhận input type checkbox checked
assertRadioSelected($field, $value)    Xác nhận input type radio selected
assertSelected($field, $value)    Xác nhận input type dropdown selected
assertValue($selector, $value)    Xác nhận selector $selector có giá trị $value
$response->assertStatus($code)    Xác nhận trả về status code $code
$response->assertRedirect($uri)    Xác nhận chuển hướng đến url $uri
$response->assertHeader($headerName, $value = null)    Xác nhận response trả về có chứa header $headerName
$response->assertCookie($cookieName, $value = null)    Xác nhận có chứa cookie $cookieName
$response->assertPlainCookie($cookieName, $value = null)    Xác nhận có chứa cookie $cookieName không được mã hóa
$response->assertSessionHas($key, $value = null)    Xác nhận session có chứa key $key
$response->assertSessionHasErrors(array $keys)    Xác nhận session có chứa lỗi cho field $key
$response->assertSessionMissing($key)    Xác nhận session không chứa key $key
$response->assertJson(array $data)    Xác nhận response json trả về có chứa mảng $data.
$response->assertJsonFragment(array $data)    Xác nhận resonse json fragment trả về có chứa mảng $data
$response->assertJsonMissing(array $data)    Xác nhận response json trả về không chứa mảng $data.
$response->assertExactJson(array $data)    Xác nhận response json trả về trùng khớp với mảng $data
$response->assertJsonStructure(array $structure)    Xác nhận response trả về có cấu trúc json
$response->assertViewIs($value)    Xác nhận response trả về view $value
$response->assertViewHas($key, $value = null)    Xác nhận response trả về view có chứa key $key.

Ví dụ về Unittest cho Login, Register

1. Tạo Test bằng cmd 

php artisan make:Test BasicFeatureTest

Chạy Test bằng cmd

vendor\bin\phpunit tests/Feature/BasicFeatureTest.php

File BasicFeatureTest.php

<?php

namespace Tests\Feature;

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

class BasicFeatureTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExample()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

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

        $response->assertStatus(200);
        $response->assertViewIs('auth.login')->assertSee('Login');
    }
    public function test_user_cannot_view_a_login_form_when_authenticated()
    {
        $user = factory(User::class)->make();

        $response = $this->actingAs($user)->get('/login');

        $response->assertRedirect('/home');
    }

    
      public function test_user_can_login_with_correct_credentials()
    {
        $user = factory(User::class)->create([
            'password' => bcrypt($password = 'i-love-laravel'),
        ]);

        $response = $this->post('/login', [
            'email' => $user->email,
            'password' => $password,
        ]);

        $response->assertRedirect('/home');
        $this->assertAuthenticatedAs($user);
    }


}

File LoginTest.php

<?php

namespace Tests\Feature;


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

class LoginTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testExample()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
     public function testloginurl()
    {
        $response = $this->get('/login');

        $response->assertStatus(200);//
    }

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

        $response->assertStatus(200);

        $response->assertViewIs('auth.login')->assertSee('Login');
    }

    public function test_user_cannot_view_a_login_form_when_authenticated()
    {
        $user = factory(User::class)->make();

        $response = $this->actingAs($user)->get('/login');

        $response->assertRedirect('/home');
    } 

    public function test_user_can_login_with_correct_credentials()// KIEM TRA OCD login co dung ko
    {
        $user = factory(User::class)->create([
            'password' => bcrypt($password = 'i-love-laravel'), //create a fake user
        ]);

        $response = $this->post('/login', [ //send the fake user to database
            'email' => $user->email,
            'password' => $password,
        ]);

        $response->assertRedirect('/home');// co phai nhay den tran home hay ko 

        $this->assertAuthenticatedAs($user);
    }
    
     public function test_user_cannot_login_with_incorrect_password()
    {
        $user = factory(User::class)->create([
            'password' => bcrypt('i-love-laravel'),
        ]);
        
        $response = $this->from('/login')->post('/login', [
            'email' => $user->email,
            'password' => 'invalid-password',
        ]);
        
        $response->assertRedirect('/login');
        $response->assertSessionHasErrors('email');
        $this->assertTrue(session()->hasOldInput('email'));
        $this->assertFalse(session()->hasOldInput('password'));
        $this->assertGuest();
    }

}
 

File RegisterTest.php

<?php

namespace Tests\Unit;
use App\User;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class RegisterTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     */
    public function testExample()
    {
        $this->assertTrue(true);
    }

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

        $response->assertStatus(200);
        $response->assertViewIs('auth.register')->assertSee('register');
    }

    public function testCanRegister()
    {
       $response = $this->post('register', [
            'name' => 'JMac'.time(),
            'email' => 'jmac'.time().'@example.com',
            'password' => 'password',
            'password_confirmation' => 'password',
        ]);

        $response->assertRedirect(route('home'));
    }

}

VD File dành user xem, thêm, sửa, xóa: fuelquote

<?php
namespace Tests\Unit;
use App\Fuelquote;
use Tests\TestCase;
use App\User;
use Auth;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
class FuelTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
     public function testExample()
    {
        $this->assertTrue(true);
    }
    public function testUrl()
    {
        //Route::get('/', 'FuelController@listfuel');
        //listfuel có link lìa /
        $response = $this->get('/');
        $response->assertStatus(200);
        $response->assertViewIs('backend.fuel.listfuel')->assertSee('List Fuel');
        //assertViewIs gọi view backend.fuel.listfuel
        //assertSee xác nhận có chữ List Fuel trong view
        //$response->assertStatus(200);
    }
    
    //test file dang nhap moi xem duoc danh sach fule
    public function test_have_to_login_to_view_fuel_quote()
    {
        $user = factory(User::class)->make();
        //tao user de truy cap vao danh sach fuelquote
        //
        $response = $this->actingAs($user)->get('/fuelquote');
        //truy cap voi user vua tao vao ds fuel quote
        $response->assertStatus(200);//kiem tra cotruy cap thanh cong khong
    }
    //test khog dang nhap thi ko xem duoc ds fuel quote
    public function test_not_login_no_access_fuel_quote()
    {
        //$user = factory(User::class)->make();
        //tao user de truy cap vao danh sach fuelquote
        //
        $response = $this->get('/fuelquote');
        //chua dang nhap thi nó trả về trang login
        $response->assertRedirect('/login');
    }
    public function test_sau_khi_login_tao_fuel_quote(){
         
        $user = factory(User::class)->make();
        //duong dan luu fuelquote là fuelquote, phuong thuc post
        $response = $this->actingAs($user)->post('fuelquote', [
            'fuel_id' => 4,
            'gallonrequest'=>1,
            'suggestprice' => 1,
            'totalAmountDue'=>1,
            'deliverydate' => date("Y-m-d H:i:s"),
        ]);
        //tao xong thi chya den trang ds fuelquote
        $response->assertRedirect('/fuelquote');
    }
  }

 

Bài viết cùng chủ đề