Detailed explanation of PHP unit test framework PHPUnit usage

  • 2021-11-13 07:00:40
  • OfStack

This article illustrates the use of PHP unit testing framework PHPUnit. Share it for your reference, as follows:

Before learning IOS development has written Objective-C unit test article, IOS development learning unit test, today again summarize how to use unit test in PHP.

1. Preface

In this article, we use composer's dependency package management tool to install and manage phpunit packages. The official address of composer is https://getcomposer. org/. Follow the prompts for global installation. In addition, we will also use a very easy-to-use Monolog logging component to record logs for our convenience.

Create a configuration file for coomposer. json in the root directory and enter the following:


{
  "autoload": {
    "classmap": [
      "./"
    ]
  }
}

The above means loading all the class files in the root directory and executing them on the command line composer install After, a folder of vendor will be generated in the root directory, and we will pass the composer Any third-party code installed will be generated here.

2. Why unit tests?

Whenever you think of typing something into an print statement or debug expression, replace it with a test. -Martin Fowler

PHPUnit is an open source software developed with PHP programming language, which is a unit testing framework. PHPUnit was created by Sebastian Bergmann and originated from SUnit of Kent Beck, which is the first framework of xUnit family.

Unit testing is the process of testing individual code objects, such as functions, classes, and methods. Unit testing can use any one piece of written test code or one existing test framework, such as JUnit, PHPUnit, or Cantata + +. Unit testing frameworks provide a set of common and useful functions to help people write automated detection units, such as checking whether an actual value meets an assertion of our expected value. Unit test frameworks often include reports on each test and give you coverage of the code you have covered.

In a word, using phpunit for automatic testing will make your code more robust and reduce the cost of later maintenance. It is also a relatively standard specification. Nowadays, the popular PHP framework has unit testing, such as Laraval, Symfony, Yii2, etc. Unit testing has become standard.

In addition, unit test cases manipulate test scripts through commands, rather than accessing URL through browsers.

3. Install PHPUnit

Use composer to install PHPUnit. Please see here for other installation methods


composer require --dev phpunit/phpunit ^6.2

Install Monolog log package for phpunit test log.


composer require monolog/monolog

Once installed, we can see that the coomposer. json file already has these two extension packs:


"require": {
  "monolog/monolog": "^1.23",
  },
"require-dev": {
    "phpunit/phpunit": "^6.2"
  },

4. Simple usage of PHPUnit

1. Single file test

Create the directory tests, create a new file StackTest. php, and edit it as follows:


<?php
/**
 * 1 , composer  Installation Monolog Log Extensions, Installation phpunit Unit test extension pack 
 * 2 , introduction autoload.php Documents 
 * 3 Test case 
 *
 *
 */
namespace App\tests;
require_once __DIR__ . '/../vendor/autoload.php';
define("ROOT_PATH", dirname(__DIR__) . "/");
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use PHPUnit\Framework\TestCase;
class StackTest extends TestCase
{
  public function testPushAndPop()
  {
    $stack = [];
    $this->assertEquals(0, count($stack));
    array_push($stack, 'foo');
    //  Add Log File , If not installed monolog , the relevant monolog You can comment out the code of 
    $this->Log()->error('hello', $stack);
    $this->assertEquals('foo', $stack[count($stack)-1]);
    $this->assertEquals(1, count($stack));
    $this->assertEquals('foo', array_pop($stack));
    $this->assertEquals(0, count($stack));
  }
  public function Log()
  {
    // create a log channel
    $log = new Logger('Tester');
    $log->pushHandler(new StreamHandler(ROOT_PATH . 'storage/logs/app.log', Logger::WARNING));
    $log->error("Error");
    return $log;
  }
}

Code explanation:

StackTest is a test class

StackTest inherits from PHPUnit\ Framework\ TestCase

Test method testPushAndPop() The test method must have public permissions, starting with test, or you can choose to annotate it @ test

Within the test method, similar to assertEquals() Such an assertion method is used to assert the match between the actual value and the expected value.

Command line execution:

phpunit Command Test File Naming


➜ framework# ./vendor/bin/phpunit tests/StackTest.php
//  Or you can omit the file suffix 
// ./vendor/bin/phpunit tests/StackTest

Implementation results:

➜ framework# ./vendor/bin/phpunit tests/StackTest.php
PHPUnit 6.4.1 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 56 ms, Memory: 4.00MB
OK (1 test, 5 assertions)

We can view our printed log information in the app. log file.

2. Class file introduction

Calculator.php


<?php
class Calculator
{
  public function sum($a, $b)
  {
    return $a + $b;
  }
}
?>

Unit test classes:

CalculatorTest.php


<?php
namespace App\tests;
require_once __DIR__ . '/../vendor/autoload.php';
require "Calculator.php";
use PHPUnit\Framework\TestCase;
class CalculatorTest extends TestCase
{
  public function testSum()
  {
    $obj = new Calculator;
    $this->assertEquals(0, $obj->sum(0, 0));
  }
}

Command execution:


> ./vendor/bin/phpunit tests/CalculatorTest

Implementation results:

PHPUnit 6.4.1 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 117 ms, Memory: 4.00MB
There was 1 failure:

If we deliberately miswrite the assertion here, $this- > assertEquals(1, $obj- > sum(0, 0));

Look at the execution results:

PHPUnit 6.4.1 by Sebastian Bergmann and contributors.
F 1 / 1 (100%)
Time: 117 ms, Memory: 4.00MB
There was 1 failure:
1) App\tests\CalculatorTest::testSum
Failed asserting that 0 matches expected 1.
/Applications/XAMPP/xamppfiles/htdocs/web/framework/tests/CalculatorTest.php:22
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

The method error message and line number will be reported directly, which will help us find out bug quickly

3. Advanced usage

Are you tired of putting an test before every test method name, and are you struggling with writing multiple test cases just because the parameters are different? My favorite advanced function, which is now grandly recommended to you, is called Framework Generator.

Calculator.php


<?php
class Calculator
{
  public function sum($a, $b)
  {
    return $a + $b;
  }
}
?>

Start the test case from the command line, using the keyword-skeleton


composer require --dev phpunit/phpunit ^6.2

0

Implementation results:

PHPUnit 6.4.1 by Sebastian Bergmann and contributors.
Wrote test class skeleton for Calculator to CalculatorTest.php.

Is it very simple, because there is no test data, so add test data here, and then re-execute the above command


composer require --dev phpunit/phpunit ^6.2

1

Each method in the original class performs the @assert Detection of annotations. These are converted into test code, like this


composer require --dev phpunit/phpunit ^6.2

2

Implementation results:

./vendor/bin/phpunit tests/CalculatorTest
PHPUnit 6.4.1 by Sebastian Bergmann and contributors.
....
Time: 0 seconds
OK (4 tests)

For more readers interested in PHP related content, please check the topics on this site: "Summary of PHP Error and Exception Handling Methods", "Summary of php String (string) Usage", "Encyclopedia of PHP Array (Array) Operation Skills", "Summary of PHP Operation and Operator Usage", "Summary of PHP Network Programming Skills", "Introduction to PHP Basic Syntax", "Introduction to php Object-Oriented Programming" and "Summary of php Excellent Development Framework"

I hope this article is helpful to everyone's PHP programming.


Related articles: