Sokan Academy

PHPUnit یک فریمورک یونیت تستینگ مبتنی بر معماری xUnit برای زبان برنامه‌نویسی پی‌اچ‌پی است که توسط Sebastian Bergmann ابداع گردیده است به طوری که در این فریمورک، همچون بسیاری از دیگر فریمورک‌های یونیت تستینگ، از مفهومی تحت عنوان Assertion به منظور نشان دادن صحت کارکرد یک بلوک از کد (Unit) استفاده می‌شود که در ادامهٔ این آموزش بیشتر در این باره بحث خواهیم کرد.

درآمدی بر Composer

کامپوزر یک پَکیج مَنِجر است بدان معنا که توسعه‌دهندگان زبان برنامه‌نویسی پی‌اچ‌پی با استفاده از آن قادر خواهند بود تا به سادگی از طریق کامندلاین وابستگی‌های پروژه‌های خود را مدیریت کنند که به منظور استفاده از فریمورک PHPUnit نیز نیاز به نصب این ابزار خواهیم داشت که در همین راستا و پیش از ادامهٔ این آموزش توصیه می‌شود به مقالات زیر از وبلاگ سکان آکادمی مراجعه نمایید:

Composer چیست؟
آموزش نصب Composer روی سیستم‌عامل گنو/لینوکس توزیع اوبونتو

لازم به یادآوری است که در این دورهٔ آموزشی از سیستم‌عامل گنو/لینوکس توزیع اوبونتو استفاده خواهیم کرد اما در عین نکات آموزشی قابل‌پیاده‌سازی در سایر پلتفرم‌ها نیز می‌باشند.

برای شروع، در مسیر var/www/ پوشه‌ای تحت عنوان phpunit ساخته و پس از ورود به آن، کامند زیر را اجرا می‌کنیم:

/var/www/phpunit$ composer require --dev phpunit/phpunit

آنچه در کامند فوق نیاز به توضیح دارد اینکه آپشن dev-- حاکی از آن است که این پکیج صرفاً در محیط توسعه نصب خواهد شد. چنانچه کامند فوق بدون هیچ‌گونه مشکلی اجرا شود، از این پس ساختار پروژه‌ای که ساخته‌ایم به صورت زیر خواهد بود:

phpunit
├── composer.json
├── composer.lock
└── vendor

 

همان‌طور که می‌بینیم،‌ فایلی ساخته شده تحت عنوان composer.json که حاوی محتویات زیر است:

{
    "require-dev": {
        "phpunit/phpunit": "^8.1"
    }
}

می‌بینیم که فریمورک PHPUnit به عنوان وابستگی این پروژه در نظر گرفته شده است. همچنین با استفاده از دستور vendor/bin/phpunit/. به صورت زیر، می‌توانیم اطلاعاتی در مورد این فریمورک کسب نماییم:

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

Usage:
  phpunit [options] UnitTest [UnitTest.php]
  phpunit [options] <directory>

Code Coverage Options:
  --coverage-clover <file>    Generate code coverage report in Clover XML format
  --coverage-crap4j <file>    Generate code coverage report in Crap4J XML format
  --coverage-html <dir>       Generate code coverage report in HTML format
  --coverage-php <file>       Export PHP_CodeCoverage object to file
  --coverage-text=<file>      Generate code coverage report in text format [default:
                              standard output]
  --coverage-xml <dir>        Generate code coverage report in PHPUnit XML format
  --whitelist <dir>           Whitelist <dir> for code coverage analysis
  --disable-coverage-ignore   Disable annotations for ignoring code coverage
  --no-coverage               Ignore code coverage configuration
  --dump-xdebug-filter <file> Generate script to set Xdebug code coverage filter

Logging Options:
  --log-junit <file>          Log test execution in JUnit XML format to file
  --log-teamcity <file>       Log test execution in TeamCity format to file
  --testdox-html <file>       Write agile documentation in HTML format to file
  --testdox-text <file>       Write agile documentation in Text format to file
  --testdox-xml <file>        Write agile documentation in XML format to file
  --reverse-list              Print defects in reverse order

Test Selection Options:
  --filter <pattern>          Filter which tests to run
  --testsuite <name>          Filter which testsuite to run
  --group <name>              Only runs tests from the specified group(s)
  --exclude-group <name>      Exclude tests from the specified group(s)
  --list-groups               List available test groups
  --list-suites               List available test suites
  --list-tests                List available tests
  --list-tests-xml <file>     List available tests in XML format
  --test-suffix <suffixes>    Only search for test in files with specified suffix(es).
                              Default: Test.php,.phpt

Test Execution Options:
  --dont-report-useless-tests Do not report tests that do not test anything
  --strict-coverage           Be strict about @covers annotation usage
  --strict-global-state       Be strict about changes to global state
  --disallow-test-output      Be strict about output during tests
  --disallow-resource-usage   Be strict about resource usage during small tests
  --enforce-time-limit        Enforce time limit based on test size
  --default-time-limit=<sec>  Timeout in seconds for tests without @small, @medium or
                              @large
  --disallow-todo-tests       Disallow @todo-annotated tests

  --process-isolation         Run each test in a separate PHP process
  --globals-backup            Backup and restore $GLOBALS for each test
  --static-backup             Backup and restore static attributes for each test

  --colors=<flag>             Use colors in output ("never", "auto" or "always")
  --columns <n>               Number of columns to use for progress output
  --columns max               Use maximum number of columns for progress output
  --stderr                    Write to STDERR instead of STDOUT
  --stop-on-defect            Stop execution upon first not-passed test
  --stop-on-error             Stop execution upon first error
  --stop-on-failure           Stop execution upon first error or failure
  --stop-on-warning           Stop execution upon first warning
  --stop-on-risky             Stop execution upon first risky test
  --stop-on-skipped           Stop execution upon first skipped test
  --stop-on-incomplete        Stop execution upon first incomplete test
  --fail-on-warning           Treat tests with warnings as failures
  --fail-on-risky             Treat risky tests as failures
  -v|--verbose                Output more verbose information
  --debug                     Display debugging information

  --loader <loader>           TestSuiteLoader implementation to use
  --repeat <times>            Runs the test(s) repeatedly
  --teamcity                  Report test execution progress in TeamCity format
  --testdox                   Report test execution progress in TestDox format
  --testdox-group             Only include tests from the specified group(s)
  --testdox-exclude-group     Exclude tests from the specified group(s)
  --printer <printer>         TestListener implementation to use

  --order-by=<order>          Run tests in order:
                              default|reverse|random|defects|no-depends
  --random-order-seed=<N>     Use a specific random seed <N> for random order
  --cache-result              Write test results to cache file
  --do-not-cache-result       Do not write test results to cache file

Configuration Options:
  --prepend <file>            A PHP script that is included as early as possible
  --bootstrap <file>          A PHP script that is included before the tests run
  -c|--configuration <file>   Read configuration from XML file
  --no-configuration          Ignore default configuration file (phpunit.xml)
  --no-logging                Ignore logging configuration
  --no-extensions             Do not load PHPUnit extensions
  --include-path <path(s)>    Prepend PHP's include_path with given path(s)
  -d <key[=value]>            Sets a php.ini value
  --generate-configuration    Generate configuration file with suggested settings
  --cache-result-file=<file>  Specify result cache path and filename

Miscellaneous Options:
  -h|--help                   Prints this usage information
  --version                   Prints the version and exits
  --atleast-version <min>     Checks that version is greater than min and exits
  --check-version             Check whether PHPUnit is the latest version

 

در ادامه، ابتدا پوشه‌ای تحت عنوان app می‌سازیم که قرار است دربرگیرندهٔ کدهای اصلی پروژه باشد سپس پوشهٔ دیگری به نام tests می‌سازیم که به منظور نگهداری یونیت تست‌های پروژه استفاده خواهد شد به طوری که از این پس خواهیم داشت:

 

phpunit
├── app
├── composer.json
├── composer.lock
├── tests
└── vendor

حال نیاز به یک فایل پیکربندی برای فریمورک PHPUnit خواهیم داشت که در همین راستا در مسیر روت پروژه، فایلی تحت عنوان phpunit.xml حاوی محتویات زیر می‌سازیم:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./vendor/autoload.php" 
         colors="true"
         verbose="true"
         stopOnFailure="false">
    <testsuites>
        <testsuite name="Test Suite">
            <directory>./tests/</directory>
        </testsuite>
    </testsuites>
</phpunit>

آنچه در ارتباط با کدهای اکس‌ام‌ال فوق حائز اهمیت است اینکه مقداری همچون vendor/autoload.php/. برای اتریبیوت bootstrap در نظر گرفته‌ایم بدان معنا که فایل autoload.php در پوشهٔ vendor نقطهٔ شروع برنامه است. اتریبیوت colors هم حاکی از آن است که خروجی تست‌ها در کامندلاین در قالب رنگ‌های مختلف به منظور شهودی‌تر بودن خروجی‌ها نمایش داده شوند و اتریبیوت verbose نیز اطلاعات جامعی از خروجی تست در اختیارمان خواهد گذاشت. در ارتباط با اتریبیوت stopOnFailure که مقدار false را برای آن در نظر گرفته‌ایم باید گفت که این مقدار باعث می‌گردد تا اگر چندین تست داشته باشیم و یکی از آن‌ها با شکست مواجه شد، اجرای ادامهٔ تست‌ها متوقف نشده و کار ادامه یابد و در صورتی که مقدار true برای این اتریبیوت در نظر بگیریم، به محض اینکه یکی از تست‌ها به اصطلاح Fail شد، اجرای سایر تست‌ها متوقف خواهد شد.

در ادامه به تگ <testsuites></testsuites> می‌رسیم که داخل آن یک جفت تگ <testsuite></testsuite> بیشتر در نظر نگرفته‌ایم به طوری که تگ <directory>./tests/</directory> حاکی از آن است که این فریمورک جهت تست می‌باید به پوشهٔ tests مراجعه نماید. 

در این مرحله از کار، مجدد دستور vendor/bin/phpunit/. را اجرا می‌کنیم به طوری که به عنوان خروجی خواهیم داشت:

/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



Time: 81 ms, Memory: 2.00 MB

No tests executed!

می‌بینیم با توجه به اینکه تاکنون هیچ‌گونه تستی برای پروژهٔ خود ننوشته‌ایم، عبارت !No tests executed در معرض دیدمان قرار می‌گیرد (چنانچه مقدار "colors="false را در نظر گرفته و مجدد کامند فوق را اجرا کنیم، خواهیم دید که خروجی دیگر به صورت رنگی نخواهد بود.) در واقع، این خروجی حاکی از آن است که از این پس فایل پیکربندی phpunit.xml در حین اجرا مبنا قرار داده خواهد شد.

unit testیونیت تستتست نرم‌افزار

sokan-academy-footer-logo
کلیه حقوق مادی و معنوی این وب‌سایت متعلق به سکان آکادمی می باشد.