Technical blog] Laravel 5.1 unit testing (PHPUnit) Getting Started

Laravel 5.1 unit testing (PHPUnit) Getting Started

v1.0

Author: ZBW, ZGJ

Brief introduction

Unit Testing Framework PHP applications most applications is PHPUnit, this framework Laravel also be integrated in, and Laravel adds some extra features to facilitate the development of Web-related tests. This will be a project-based unit test application, introduce relevant content Laravel with PHPUnit.

Note that this paper is based on Laravel 5.1, there may be some API changes in subsequent versions, but the overall use little changed.

Installation and Configuration

1. Install

Composer.json configuration dependency by the composer, and used composer installto install PHPUnit, the binary file installed in / vendor / bin /.

(May also be used to try apt install phpunitto install PHPUnit)

2. Configure

Laravel by default comes with the name phpunit.xmlof the configuration file, the file is already configured for us phpunit itself.

The project uses the configuration file as follows:

   <?xml version="1.0" encoding="UTF-8"?>
   <phpunit backupGlobals="false"
            backupStaticAttributes="false"
            bootstrap="bootstrap/autoload.php"
            colors="true"
            convertErrorsToExceptions="true"
            convertNoticesToExceptions="true"
            convertWarningsToExceptions="true"
            processIsolation="false"
            stopOnFailure="false">
       <testsuites>
           <testsuite name="Application Test Suite">
               <directory>./tests/</directory>
           </testsuite>
       </testsuites>
       <filter>
           <whitelist>
               <directory suffix=".php">app/</directory>
           </whitelist>
       </filter>
       <php>
           <env name="APP_ENV" value="testing"/>
           <env name="CACHE_DRIVER" value="array"/>
           <env name="SESSION_DRIVER" value="array"/>
           <env name="QUEUE_DRIVER" value="sync"/>
       </php>
       <logging>
           <log type="coverage-html" target="./tests/codeCoverage" charset="UTF-8"/>
       </logging>
   </phpunit>
   

Which should be noted the following:

  • <Testsuites> / <directory>: Here php code stored test
  • <Logging>: output test results provided herein location, the content output version of html coverage report which very detailed.
  • <Filter>: This section defines the path phpunit accessible, the above configuration we tested only the contents of the app folder.

    Based on the above, a convenient way to browse test reports, the report tests / codeCoverage folder under html document entrance soft links to public folders, which can be accessed directly from the browser:

   ln -s tests/codeCoverage public/tests

Thereby browser access routes: / tests to see the test report.

Preparation of test samples

1. Create a new test case

Standard approach is to use artisan New Test Sample:

php artisan make:test xxxTest

This command creates a new xxxTest.php in the tests folder, which contains a default test function.

2. Preparation of test functions

In this section, we mainly need to use assertions to check the input and output functions of the match. Assertions are phpunit itself with the function.

Some common assertions include:

$this->assertTrue(表达式) //检查表达式是否为真
$this->assertFalse(表达式) //检查表达式是否为假
$this->assertEquals(X,Y) //检查两个变量是否相等
$this->assertFileExists(文件) //检查文件是否存在

Specific predicate function can refer to documentation for PHPUnit

3. Write Web functional testing

The most convenient place Laravel integrated PHPUnit can write test on its Web controller and function.

Such as testing whether a page to access a normal test as follows:

    public function testIndex()
    {
        $this->visit('logout') ;
        $this->visit('/desexp')
            ->see("设计性实验")
            ->see("请选择实验")
            ->see("D01");

        $this->visit('/login')
            ->see('登录')
            ->type($this->gen_admin_email , 'email')
            ->type($this->gen_admin_password , 'password')
            ->press('login-submit');

        $this->visit('/desexp')
            ->see("设计性实验")
            ->see("请选择实验")
            ->see("D01");
    }

This part of the written test way is to run all functions required by the order in series.

3.1 Test Page Views

Some aspects of the visit follows function, this part of the function is generally used for test access and interact with the page.

visit('路由') // 访问某个地址
see('xxx') //检查访问的页面中是否出现了xxx
dontSee('xxx') //与see功能相反,检查是否没有出现xxx
type('输入内容',输入框name属性) //输入内容至输入框
check('单选框name属性') //选中checkbox
select(’内容‘,’下拉菜单区域‘) //选择下拉菜单项
press('xxx') //按下指定元素或按钮
attach('文件路径','文件上传name属性') //附加文件

In the example above, we can choose to manually before testing simulated landing operations.

3.2 Test JSON API

When the above test JSON API functions are often ineffective, then you need to use the following functions to initiate a request to the interface and the verification result.

get/post/put/patch/delete('address',[payloads]) //以以上的HTTP方法请求路由
seeJson([json内容]) //检查返回的json是否包含内容

Of course, before the visitmethod can be seen as no additional data get(note not without parameters, will be introduced later)

As an example, which part of the code to verify the contents of a table acquisition html correctness getTable function.

        $_GET['id'] = $this->report_id_pub ;
        $html_file = Config::get('phylab.experimentViewPath').$this->report_id_pub.".html";
        $str_html = file_get_contents($html_file);
        $this->visit('/getTable')
            ->seeJson([
                'status' => SUCCESS_MESSAGE ,
                'contents' => $str_html ,
            ]) ;

In addition, call('http请求方法','路由',‘数据’...)this approach in a more flexible way to initiate a request to the interface. This function returns the http request object Laravel native. You can then verify the results of which phpunit's assertion.

Laravel added some additional assertions to facilitate the user to check the results of Web requests. E.g:

->assertResponseOk(); //检查返回是否为HTTP 200
->assertResponseStatus($code); //检查返回是否是指定的状态码
->assertRedirectedTo($uri, $with = []); //检查是否有重定向

Specific reference may PHPUnit Assertions

3.3 Some problems

1. Middleware

In Laravel the part of the route through the middleware to ensure safety, such as many Auth API to middleware to ensure that only the user can log in using the interface, but often landed in the test will increase the complexity of the test, use is also a relatively session kinds of trouble approach.

We can add the following at the beginning of the test class

use WithoutMiddleware;

Thereby temporarily intermediate code file in this test does not have an effect

2. Database

Part of the function tests required for a database operation, and after the test needs to ensure the consistency of the database state. Manual operation for recovery is not realistic, fortunately Laravel built a number of ways so that we can easily test the databases

Using the Migration: use DatabaseMigrations;or use the transaction:use DatabaseTransactions;

The above is either added at the beginning of the test class, Laravel will complete the database recovery before and after the test for you

3. define the issue of

In our project, before the developers in many places we define some global variables, or can be said to be similar to the C language macro definition. Laravel comprising a frame itself also contains many such macro definition. The first time you run the test a very embarrassing problem we encountered was: can not have multiple test code file, otherwise phpunit will report an error similar to "duplicate definition" of.

A temporary solution is that, at the beginning of each test compound added:

    protected $preserveGlobalState = FALSE;
    protected $runTestInSeparateProcess = TRUE;

This means that each testing process is both independent and state between each test is not retained.

4. The load on the parameters of the HTTP request and

Some of the foregoing request methods for testing, which can be included with an array of additional parameters is actually a request that came payloads, but many times we have to initiate a request with parameters like this:

http://ip:port/getTable?id=1234567

If directly getset the method ['id'=>'1234567']will find a test run or direct requests /getTable, without any parameters

One solution is to directly modify the PHP test _GETvariables, such as

$_GET['id'] = '1234567' ;

I believe that this approach somewhat simple and crude, but have not found a better way, also please the reader exhibitions.

Run the test and see the results

1. Run the test

Run the test is very simple, just run in the directory where phpunit.xml: phpunitcan run all tests automatically.

If you want to run a single test file, as follows:

phpunit path\to\testFile.php

This will run all the test functions in the file.

You can also run one test function, but in this case better to specify the file where the function to avoid duplicate names situation:

phpunit --filter testFunction path\to\testFile.php

2. View Results

After configuring the soft part of the configuration of the link, you can go directly to the test report page

ln -s tests/codeCoverage public/tests

Direct access to ip: port / tests it automatically enters the test report page, click on each folder you can browse the contents of which test coverage.

Test coverage is divided into three columns, the first column is the number of rows of the covering, the second column is the number of ways, the third column is the number of classes covering.

Guess you like

Origin www.cnblogs.com/hardchoice/p/11007330.html