پروژهٔ ساخت ماشین حساب در زبان PHP و تست آن با استفاده از PHPUnit


در این آموزش قصد داریم یک پروژهٔ ماشین حساب ساده را با استفاده از یونیت تست تکمیل کنیم و برای آنکه تست‌های مرتبط با این پروژه از سایر تست‌ها مجزا باشند، داخل پوشهٔ tests پوشهٔ دیگری تحت عنوان calculator ساخته و داخل آن فایلی با نامی دلخواه همچون CalculatorTest.php به صورت زیر می‌سازیم:

<?php
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase
{
    public function testAddOperands()
    {
        $calculator = new \App\Calculator;
        $calculator->setOperands([5, 10]);
        $this->assertEquals(15, $calculator->add());
    }
}

همان‌طور که می‌بینیم، متدی نوشته‌ایم تحت عنوان ()testAddOperands که نام آن با کلمهٔ test شروع شده که این یک باید است و داخل این متد متغیری تعریف کرده‌ایم به نام calculator$ که مقدارش برابر با آبجکتی از روی کلاسی به نام Calculator است که هنوز ساخته نشده است.

در ادامه، متدی تحت عنوان ()setOperands را روی آبجکتی که ساخته‌ایم فراخوانی کرده و به عنوان آرگومان ورودی این متد هم آرایه‌ای حاوی مقادیر ۵ و ۱۰ در نظر گرفته‌ایم و در نهایت هم متد ()assertEquals از فریمورک PHPUnit را فراخوانی کرده و دو آرگومان ورودی برایش در نظر گرفته‌ایم که مورد اول عدد ۱۵ است که به نوعی نتیجه‌ای است که قصد داریم به آن برسیم و آرگومان دوم نیز فراخوانی متد ()add از کلاس Calculator است که هنوز نوشته نشده است.

در این مرحله از کار، با ران کردن تست خواهیم دید که اروری در معرض دیدمان قرار خواهد گرفت به طوری که حاوی پیام زیر است:

/var/www/phpunit$ ./vendor/bin/phpunit 
PHPUnit 8.1.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.4-1+ubuntu18.04.1+deb.sury.org+3
Configuration: /var/www/phpunit/phpunit.xml

.....E  6 / 6 (100%)

Time: 26 ms, Memory: 4.00 MB

There was 1 error:

1) CalculatorTest::testAddOperands
Error: Class 'App\Calculator' not found

/var/www/phpunit/tests/calculator/CalculatorTest.php:8

ERRORS!

می‌بینیم که در متن ارور آمده است که کلاس Calculator وجود ندارد که برای رفع این مشکل، داخل پوشهٔ app فایلی به نام Calculator.php به صورت زیر می‌سازیم:

<?php 
namespace App;

class Calculator
{
    
}

با ران کردن مجدد تست خواهیم داشت:

/var/www/phpunit$ ./vendor/bin/phpunit 
PHPUnit 8.1.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.4-1+ubuntu18.04.1+deb.sury.org+3
Configuration: /var/www/phpunit/phpunit.xml

.....E  6 / 6 (100%)

Time: 25 ms, Memory: 4.00 MB

There was 1 error:

1) CalculatorTest::testAddOperands
Error: Call to undefined method App\Calculator::setOperands()

/var/www/phpunit/tests/calculator/CalculatorTest.php:9

ERRORS!
Tests: 6, Assertions: 6, Errors: 1.

گرچه تست پاس نشد اما نوع پیام خطا تغییر کرد به طوری که گفته شده متدی با نام ()setOprands وجود ندارد که برای رفع این ارور، کلاس Calculator را به صورت زیر تکمیل می‌کنیم:

<?php 
namespace App;

class Calculator
{
    public $operands;

    public function setOperands(array $operands)
    {
        $this->operands = $operands;
    }
}

داخل این کلاس یک پراپرتی داریم به نام operands$ که این پراپرتی داخل متدی به نام ()setOperands مقداردهی خواهد شد. در واقع، این متد یک پارامتر ورودی تحت عنوان operands$ از جنس آرایه می‌گیرد که در نهایت این پارامتر به پراپرتی تعریف‌شده در بدنهٔ کلاس منتسب می‌گردد. به درج کلیدواژه‌ای همچون array پیش از نام پارامتر ورودی این متد اصطلاحاً Type Hinting گفته می‌شود که این تضمین را ایجاد می‌کند که پارامترهای ورودی این متد حتماً می‌باید از جنس آرایه باشند که در این ارتباط و برای کسب اطلاعات بیشتر، می‌توانید به مقالهٔ‌ آشنایی با مفهوم Type Hinting در زبان PHP مراجعه نمایید. حال اگر تست را ران کنیم خواهیم داشت:

/var/www/phpunit$ ./vendor/bin/phpunit 
PHPUnit 8.1.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.4-1+ubuntu18.04.1+deb.sury.org+3
Configuration: /var/www/phpunit/phpunit.xml

.....E  6 / 6 (100%)

Time: 25 ms, Memory: 4.00 MB

There was 1 error:

1) CalculatorTest::testAddOperands
Error: Call to undefined method App\Calculator::add()

/var/www/phpunit/tests/calculator/CalculatorTest.php:10

ERRORS!
Tests: 6, Assertions: 6, Errors: 1.

می‌بینیم که متن خطا مجدد تغییر کرد مبنی بر اینکه متدی تحت عنوان ()add وجود ندارد که این متد را نیز به صورت زیر پیاده‌سازی می‌کنیم:

public function add()
{
     return array_sum($this->operands);
}

متد ()array_sum با توجه به آرگومان ورودی‌اش که همان پراپرتی operands$ است مقداری را بازمی‌گرداند که آن مقدار توسط دستور return به عنوان خروجی این متد در نظر گرفته خواهد شد. در واقع، این متد جمع جبری اِلِمان‌های آرایهٔ ورودی را بازمی‌گرداند. حال اگر تست را ران کنیم، خواهیم دید که با موفقیت پاس خواهد شد:

/var/www/phpunit$ ./vendor/bin/phpunit 
PHPUnit 8.1.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 7.3.4-1+ubuntu18.04.1+deb.sury.org+3
Configuration: /var/www/phpunit/phpunit.xml

......  6 / 6 (100%)

Time: 24 ms, Memory: 4.00 MB

OK (6 tests, 7 assertions)

در ادامه، قصد داریم سه تست دیگر برای اَعمال ریاضیاتی تفریق، تقسیم و ضرب نوشته سپس کلاس Calculator را به منظور پاس شدن تست‌ها تکمیل نماییم.

این بخش از محتوا مخصوص کاربرانی است که ثبت‌نام کرده‌اند.
جهت مشاهدهٔ این بخش از محتوا لاگین نمایید.

همان‌طور که در این آموزش دیدیم، با استفاده از سَبک برنامه‌نویسی TDD به سادگی توانستیم ابتدا اقدام به نوشتن متدهای تست چهار عمل اصلی یک ماشین حساب کرده سپس دست به کدنویسی فانکشن‌های اصلی ماشین حساب زدیم تا جایی که در نهایت کلیهٔ تست‌ها با موفقیت پاس شدند. همچنین دیدیم که به چه شکل می‌توان با استفاده از فریمورک PHPUnit اقدام به تست کردن اِکسپشن‌ها نمود.



بهزاد مرادی

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان