Laravel

Ứng dụng Unit Test với các chứng năng cơ bản

Giới Thiệu

Unit Test – Kiểm tra mức đơn vị

Để có thể hiểu rõ về Unit Test, khái niệm trước tiên ta cần làm rõ: thế nào là một đơn vị PM (Unit)?

Một Unit là một thành phần PM nhỏ nhất mà ta có thể kiểm tra được. Theo định nghĩa này, các hàm (Function), thủ tục (Procedure), lớp (Class), hoặc các phương thức (Method) đều có thể được xem là Unit.

Vì Unit được chọn để kiểm tra thường có kích thước nhỏ và chức năng hoạt động đơn giản, chúng ta không khó khăn gì trong việc tổ chức, kiểm tra, ghi nhận và phân tích kết quả kiểm tra. Nếu phát hiện lỗi, việc xác định nguyên nhân và khắc phục cũng tương đối dễ dàng vì chỉ khoanh vùng trong một đơn thể Unit đang kiểm tra. Một nguyên lý đúc kết từ thực tiễn: thời gian tốn cho Unit Test sẽ được đền bù bằng việc tiết kiệm rất nhiều thời gian và chi phí cho việc kiểm tra và sửa lỗi ở các mức kiểm tra sau đó.

Unit Test thường do lập trình viên thực hiện. Công đoạn này cần được thực hiện càng sớm càng tốt trong giai đoạn viết code và xuyên suốt chu kỳ PTPM. Thông thường, Unit Test đòi hỏi kiểm tra viên có kiến thức về thiết kế và code của chương trình. Mục đích của Unit Test là bảo đảm thông tin được xử lý và xuất (khỏi Unit) là chính xác, trong mối tương quan với dữ liệu nhập và chức năng của Unit. Điều này thường đòi hỏi tất cả các nhánh bên trong Unit đều phải được kiểm tra để phát hiện nhánh phát sinh lỗi. Một nhánh thường là một chuỗi các lệnh được thực thi trong một Unit, ví dụ: chuỗi các lệnh sau điều kiện If và nằm giữa then ... else là một nhánh. Thực tế việc chọn lựa các nhánh để đơn giản hóa việc kiểm tra và quét hết Unit đòi hỏi phải có kỹ thuật, đôi khi phải dùng thuật toán để chọn lựa.

Cũng như các mức kiểm tra khác, Unit Test cũng đòi hỏi phải chuẩn bị trước các tình huống (test case) hoặc kịch bản (script), trong đó chỉ định rõ dữ liệu vào, các bước thực hiện và dữ liệu mong chờ sẽ xuất ra. Các test case và script này nên được giữ lại để tái sử dụng.

Ở bài này mình sẽ làm Unit Test với 1 vài hàm cơ bản thường dùng như store (lưu dữ liệu), update (cập nhật dữ liệu), find (tìm kiếm), delete (xóa dữ liệu). Vì ở đây mình chỉ làm Unit Test với các hàm cơ bản nên mình sẽ test trực tiếp các hàm trong CategoryRepository thay vì test các hàm trong CategoryController.

Ví dụ

Bước 1: Đầu tiên để đảm bảo không ảnh hưởng đến dữ liệu gốc, bạn cần tạo 1 cơ sở dữ liệu test và 1 file .env.testing để làm việc

Bước 2: Trong folder tests ta sẽ thấy có 2 folders là Feature và Unit. Ta chọn 1 trong 2 folder để tạo file test

  • Tạo trong folder Feature: php artisan make:test CategoryTest
  • Tạo trong folder Unit: php artisan make:test CategoryTest –unit

Ở bài này mình sẽ viết trong folder Feature

Bước 3: Viết code trong file CategoryTest.php.

Mình sẽ test các hàm dưới đây trong file CategoryRepository.php

<?php

namespace App\Repositories\Contracts;

use App\Eloquent\Category;

interface CategoryRepository extends AbstractRepository
{
    public function store($data = []);

    public function find($id);

    public function update($id, $data = []);

    public function delete($id);
}

Thường thường với mỗi hàm, chức năng thì ta sẽ viết 1 hàm riêng để test. Ở đây mình gộp vào chung 1 hàm test để kiểm tra cả 4 hàm trong Repositoy (mọi người đừng nên làm theo cách này)

Trong file CategoryTest.php mình viết đoạn code sau:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Repositories\Eloquents\CategoryEloquentRepository;

class CategoryRepositoryTest extends TestCase
{
    use RefreshDatabase;

    protected $categoryRepo;

    public function test()
    {
        $this->categoryRepo = new CategoryEloquentRepository();

        $category = [
            'name' => 'TestCategory',
            'slug' => 'slugTest',
            'description' => 'ABCDEDF',
        ];
        $insertCategory = $this->categoryRepo->store($category);
        $this->assertEquals($insertCategory->name, $category['name']);
        $this->assertEquals($insertCategory->slug, $category['slug']);
        $this->assertEquals($insertCategory->description, $category['description']);

        $category2 = [
            'name' => 'TestCategory2',
            'slug' => 'slugTest2',
            'description' => 'ABCDEDF2',
        ];
        $updateResult = $this->categoryRepo->update(1, $category2);
        $this->assertTrue($updateResult);

        $updateCategory = $this->categoryRepo->find(1);
        $this->assertEquals($updateCategory->name, $category2['name']);
        $this->assertEquals($updateCategory->slug, $category2['slug']);
        $this->assertEquals($updateCategory->description, $category2['description']);
       
        $result = $this->categoryRepo->delete(1);
        $this->assertTrue($result);
    }
}

Bước 4: mở Teminal chạy lệnh: vendor/bin/phpunit --filter=CategoryRepositoryTest và chờ kết quả Nếu không có lỗi thì tức là tất các hàm đều chạy đúng

Kết luận

Unit testing có thể làm tăng đáng kể chất lượng dự án của bạn. Ta chỉ cần bỏ chút thời gian sau khi code xong các chức năng và viết thêm 1 đoạn code ngắn là có thể tự kiểm tra nhanh các hàm mà mình đã viết, phần nào giúp cho công việc được hoàn hảo hơn.

Nguồn: tổng hợp từ internet.

Registration Login
Sign in with social account
or
Lost your Password?
Registration Login
Sign in with social account
or
A password will be send on your post
Registration Login
Registration