Write PHP code have you ever had a unit test?
In fact, in the beginning I wanted to do unit test (units testing), but the time is long, also don't want to.
To become an expert in the technical field through PHP programming, in fact, the effort is outside of PHP. The database must read at least a few books, XML at least read a book, unit testing at least read a book, software engineering at least read one, data structures and algorithms at least read a copy, *nix at least read a copy, Web server at least read a book, Buddhist scriptures have to read a book, the Book of the Ching may also have to read, and so on Keep looking down.
Concept
To write unit tests, you have to have some basic concepts. These concepts PHP is not going to teach you.
We first draw a little nourishment from the Baidu Encyclopedia.
The factory tests each component before assembling a television, which is unit testing.
Unit testing refers to the inspection and validation of the smallest testable unit in the software. For unit testing in the meaning of the unit, in general, according to the actual situation to determine its specific meaning, such as the C language unit refers to a function, Java unit refers to a class, graphical software can refer to a window or a menu. In general, the unit is the minimum measured function module that is artificially defined. Unit testing is the lowest level of test activity to be performed during the software development process, and the independent unit of the software will be tested in isolation from other parts of the program.
Unit testing is done by the programmer himself, and ultimately the programmer himself. It is the responsibility of the programmer to write the functional code and to write unit tests for their own code. Performing unit tests is to prove that the code behaves as we expect it to.
--Baidu Encyclopedia
Installation
PHPUnit the current stable version has reached 4.6, many of the online posture has been invalidated. For example, the distribution method, previously used pear to install, now, is directly Phar package or composer way to rely on the installation.
wget https://phar.phpunit.de/phpunit.phar? chmod +x phpunit.phar? sudo mv phpunit.phar /usr/local/bin/phpunit? phpunit --version
{ "require-dev": { "phpunit/phpunit": "4.6.*" }}
But another important thing for beginners is that Phpunit-skelgen is not included in this package and is difficult to find. Download Address: Https://phar.phpunit.de/phpunit-skelgen.phar
wget https://phar.phpunit.de/phpunit-skelgen.pharchmod +x phpunit-skelgen.pharmv phpunit-skelgen.phar /usr/local/bin/phpunit-skelgen
The problem solved
In the development process, when you need to make changes to the internal structure of the software, you are actually making it easier to understand and easier to modify without affecting its visible behavior, and the test suite is invaluable for making these so-called refactorings safe. Otherwise, you may be able to make the system worse during the reorganization process without knowing it.
When you use unit tests to confirm that the transformation steps of a refactoring do maintain the original behavior and do not introduce errors, the following conditions help to improve the coding and design of the project:
All unit tests are running correctly.
Code communicates its design principles.
The code is not redundant.
The number of classes and methods contained in the code is minimized.
When you need to add new functionality to your system, you first write tests for it. Then, when the test runs correctly, it marks the completion of the development.
Advantages
1, it is a validation behavior.
Each function in the program is tested to verify its correctness. It provides support for future development. Even in the late stages of development, we can easily add functionality or change the structure of the program without worrying about breaking important things in the process. It also provides a guarantee for code refactoring. In this way, we can improve the program more freely.
2, it is a design behavior.
Writing unit tests will allow us to see and think from the caller. Especially the first write test (Test-first), forcing us to design the program into easy to call and testable, that forces us to remove the coupling in the software.
3, it is a kind of writing document behavior.
Unit testing is a priceless document, which is the best document to show how a function or class is used. This document is compiled, can be run, and it remains up-to-date, always in sync with your code.
4, it has the regression.
Automated unit testing avoids code regressions, and when written, you can run tests quickly and anywhere.
Practice
What time is the test?
The earlier the unit test, the better, early to what extent?
Extreme Programming (Extreme programming, or XP, for short) is about TDD, which is test-driven development, where you write test code before you develop it. In the actual work, it is not necessary to overemphasize the first what after what, it is important to be efficient and feel comfortable.
From experience, first write the framework of the product function, then write the test function, write the test case for the function of product function, then write the code of the product function, run the test every function point, and add the test case at any time.
The so-called first product function of the framework, is to write the function of the empty implementation, the return value of the direct return of a suitable value, compile and then write the test code, at this time, the function name, parameter table, return type should be determined down, the written test code will need to modify the possibility of less.
Who Tests?
Unit testing differs from other tests in that unit testing can be thought of as part of the coding effort and should be done by the programmer, that is, the code that passes the unit test is the completed code, and the test code is submitted when the product code is submitted. The testing department can make a certain degree of audit.
Be sure to read the official documentation: .
For adequate unit testing, it is generally necessary to write test code specifically and isolate it from the product code. But for beginners, there is always a bit awkward, because the feeling of extra work, the impact of development efficiency. In fact, like PHPUnit, it is also supported to mark a test method with a @test callout in the document comment block (docblock) of the class method. In this way, the idea of our code as a document is thoroughly implemented.
现实难题
我们到底要测什么?算法?一般很少。
大都是在编写业务功能。而且大多数是基于数据库的系统开发。这是我们实施PHP单元测试最大的难点所在。需要整合PHPUnit的DBUnit测试,也就是一开始就得学习DBUnit的知识。
在各种编程语言中,许多入门与中级的单元测试范例都暗示着这样一种信息:很容易用简单的测试来对应用程序的逻辑进行测试。但是对于以数据库为中心的应用程序而言,这与现实相去甚远。一旦开始使用诸如 Wordpress、TYPO3、或 Symfony(配合 Doctrine 或 Propel)之类的东西,就很容易在用 PHPUnit 时碰到超多问题:正是由于这些库和数据库之间实在耦合的太紧密了。
你大概会在日常工作面对的项目中经历这一幕。你打算把你那或生疏或纯熟的 PHPUnit 技能用到工作中去,结果被以下问题之一卡住了:
待测方法执行了一个相当大的 JOIN 操作,并且得到的数据用于计算某些重要的结果。
业务逻辑中混合执行了 SELECT、INSERT、UPDATE 和 DELETE 语句。
为了给待测方法建立合理的初始数据,需要在两个以上(可能远超过)表里设置测试数据。
DbUnit
DbUnit扩展大大简化了为测试设置数据库的操作,并且可以在对数据执行了一系列操作之后验证数据库的内容。
DbUnit所支持的供应商
DbUnit 目前支持 MySQL、PostgreSQL、Oracle 和 SQLite。通过集成 Zend Framework 或 Doctrine 2,也可以访问其他数据库系统,比如 IBM DB2 或者 Microsoft SQL Server。
数据库测试的难点
为什么所有单元测试的范例都不包含数据库交互?这里有个很好的理由:这类测试的建立和维护都很复杂。对数据库进行测试时,需要考虑以下这些变数:
数据库和表
向表中插入测试所需要的行
测试运行完毕后验证数据库的状态
每个新测试都要清理数据库
许多数据库 API,比如 PDO、MySQLi 或者 OCI8,都十分繁琐且书写起来十分冗长,因此,手工进行这些步骤绝对是噩梦。
测试代码应当尽可能简短精确,这有若干原因:
另外,必须认识到,对于代码而言,本质上来说数据库是全局输入变量。测试套件中的两个不同的测试可能是运行在同一个数据库上的,并且可能把数据重用好多次。一个测试中出现的失败很容易影响到后继测试的结果,从而让整个测试过程变得非常艰难。前面提到的清理步骤对于解决“数据库是全局输入”的问题是非常重要的。
DbUnit 以一种优雅的方式来帮助简化数据库测试中的所有这些问题。
PHPUnit 无法帮你解决的问题是,相对于不使用数据的测试而言,数据库测试是非常慢的。随着数据库交互规模的增大,运行测试可能需要耗费可观的时间。然而,只要保持每个测试所使用的数据量较小并且尽可能用非数据库测试来对代码进行测试,即使很大的测试套件也能轻松在一分钟内跑完。
数据库测试的四个阶段
Gerard Meszaros 在他的书《xUnit 测试模式》中列出了单元测试的四个阶段:
建立基架(fixture)
执行被测系统
验证结果
拆除基架(fixture)
什么是基架(fixture)?
基架(fixture)是对开始执行某个测试时应用程序和数据库所处初始状态的描述。
对数据库进行测试至少要处理建立与拆除的步骤,在其中完成清理工作,并将所需的基架数据写入表内。然而对于数据库扩展模块而言,在数据库测试中有很好的理由将这四个步骤还原成类似下面这样的工作流程,这个流程对于每个测试都会完整执行:
清理数据库
由于总是会有某个测试运行在并不确定表中是否有数据的数据库上,PHPUnit 在所有指定表上执行 TRUNCATE 操作来把它们清空。
建立基架
PHPUnit 随后将迭代所有指定的基架数据行并将其插入到对应的表里。
3–5. 运行测试、验证结果、并拆除基架
在所有数据库都完成重置并加载好初始状态后,PHPUnit 才会执行实际的测试。这个部分的测试代码完全不需要数据库扩展模块的参与,可以随意测试任何想要测试的内容。
在测试中,验证的目的可以使用一个名为 assertDataSetsEqual() 的特殊断言来实现。当然,这完全是可选的。
一些术语
单元测试
集成测试
回归测试
测试用例
断言
基架Fixture