


Introduction to PHP Design Patterns: Programming Idioms Page 1/3_PHP Tutorial
在这里总结的许多编程惯用法都是很值得做为单独一个章节的,甚至一本书的。你应该把这章做为PHP模式设计使用惯用法的相关介绍,而且查看一些列出的参考书来进行更深入的学习。
测试你的代码
可能没有什么代码惯用法比测试代码更加重要了。好的测试可以提高开发速度。
可能一开始,这句格言会和你的直觉相矛盾。你可能会断言,测试是自由的障碍物。事实上恰恰相反,如果你十分完整的运行那些测试来检查你的软件的公共接口,你就可能在不改变(或者更加糟糕,破坏)原来的应用软件的前提下改变自己系统内在的执行。测试并检验你的公共接口的精确性和正确性,并且让自己随意改变一些代码的内在工作来确保你的软件是正确而且没有bug(错误)。
在讨论更多关于测试的好处之前,先让我们看一个示例。这本书里面所有的测试实例都使用了PHP测试框架——SimpleTest 。这个测试框架可以在 http://simpletest.org 获取到。
考虑下面的代码
// PHP4
// the subject code
define(‘TAX_RATE', 0.07);
function calculate_sales_tax($amount) {
round($amount * TAX_RATE,2);
}
// include test library
require_once ‘simpletest/unit_tester.php';
require_once ‘simpletest/reporter.php';
// the test
class TestingTestCase extends UnitTestCase {
function TestingTestCase($name='') {
$this->UnitTestCase($name);
}
function TestSalesTax() {
$this->assertEqual(7, calculate_sales_tax(100));
}
}
// run the test
$test = new TestingTestCase(‘Testing Unit Test');
$test->run(new HtmlReporter());
上面的代码首先定义了一个常量——TAX_RATE,和一个计算销售税的函数。接着,代码包含了使用SimpleTest框架的必备组件:单体测试本身和一个用来显示测试结果的“reporter”模块。
类TestingTestCase继承于SimpleTest框架的UnitTestCase类。通过扩展UnitTestCase,类TestingTestCase里面所有使用Test开头的方法都将被认为是测试实例——创造条件来调试你的代码并断言结果。
TestingTestCase定义了一个测试,TestSalesTax(),它包含了一个断言函数AssertEqual()。如果它的前两个输入参数是相等的,它将返回true,否则返回false。(如果你想显示assertEqual()失败的信息,你可以传入三个参数就像这样$this->assertEqual(7,calculate_sales_tax(100), “The sales tax calculation failed”))。
代码的最后两行创建了这个测试实例的实体并且使用一个HtmlReporter运行了它。你可以访问这个web页面来运行这个简单的测试。
运行这个测试将显示测试名称,失败断言的详细情况和一个总结条。(绿色的意味着成功(所有的断言都通过了),而红色的暗示着失败(至少有一个断言没有通过))
(assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。)
注:(assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。)
上面的代码有一个(有意的)错误,所以运行是不能通过了,显示结果如下:
Calculate_sales_tax()这么一个简单的才一行的函数哪里出错了呢?你可能已经注意到这个函数没有返回结果。下面是正确的函数:
function calculate_sales_tax($amount) {
return round($amount * TAX_RATE,2);
}
修改后运行,测试通过。
但是一个简单的测试并不能保证代码是稳定的。比如,你把calculate_sales_tax()改成 function calculate_sales_tax($amount) { return 7; },代码也会通过测试,但只有当1美元等价于100的时候才是正确的。你可以自己增加一些额外的测试方法来测试其他的静态值。
function TestSomeMoreSalesTax() {
$this->assertEqual(3.5, calculate_sales_tax(50));
}
或者改变函数TestSalesTax()来验证第二个(和第三个,等等)值,如下所示
function TestSalesTax() {
$this->assertEqual(7, calculate_sales_tax(100));
$this->assertEqual(3.5, calculate_sales_tax(50));
}
到目前为止还有一种更好的方法,就是新增加一个测试:选择随即值来测试你的代码。具体如下:
function TestRandomValuesSalesTax() {
$amount = rand(500,1000);
$this->assertTrue(defined(‘TAX_RATE'));
$tax = round($amount*TAX_RATE*100)/100;
$this->assertEqual($tax, calculate_sales_tax($amount));
}
TestRandomValuesSalesTax()引入了方法assertTrue(),如果传入的第一个变量等于于布尔真则assertTrue()通过。(和方法assertEqual()一样,方法assertTrue()在接受一个可选择性的、额外的后将返回一个失败的信息)。所以TestRandomValuesSalesTax()首先认为常量TAX_RATE已经定义了,然后使用这个常量来计算随机选择的的数量的税收。
但是TestRandomValuesSalesTax()也存在一个问题:它很大程度的依赖于方法calculate_sales_tax()。测试是应该和特殊的实现细节无关的。一个更好的测试应该只建立一个合理的分界线。接下来的这个测试假定销售税永远不会超过20%。
function TestRandomValuesSalesTax() {
$amount = rand(500,1000);
$this->assertTrue(calculate_sales_tax($amount)<$amount*0.20);
}
确保你的代码正常工作是测试的首要的目的,但是在测试你的代码时候,你应该认识到除此之外还有一些额外的,相对次要的目的:
- 测试让你书写容易测试的代码。这使得代码松散耦合,复杂设计,而且具有很好的模块性。
- 测试能让你清晰的了解运行代码的期望结果,让你从一开始就注重于模块的设计和分析。通过测试,也会让你考虑所有可能的输入和相应的输出结果。
- 测试能很快速的了解编码的目的。换句话说,测试事例扮演着“实例”和“文档”的功能,准确的展示着如何构建一个类,方法等。在这本书中,我有时候通过一个测试事例来演示代码的期望功能。通过读取一个测试方法的声明,你可以清楚的了解代码是如何运行的。一个测试实例定义在代码在明确惯用法下的运行情况。
最后,如果你的测试集——测试实例的集合——是非常彻底的,而且当所有的测试都通过的时候,你可以说你的代码是完备的。有趣的是,这个观点也恰好是Test Driven Development(测试驱动开发)的特征之一。
Test Driven Development(TDD)也被认为是Test First Coding(编码前测试)。Test First Coding是一种把测试更提前一步的方法:在你写任何代码之前先写好测试。你可以从http://xprogramming.com/xpmag/testFirstGuidelines.htm下载到一份很好的,简洁的关于TDD的摘要文章,同时下载到一本很好的关于策略的入门书——Kent Beck著作的《Test Driven Development:By Example》(这本书的例子都是用JAVA开发的,但其中代码的可读性是很好的,而且对主题的介绍和说明都做的很好的)。
注:敏捷开发(Agile Development)
最近,单体测试——特别是测绘驱动开发——已经和敏捷开发方法学紧密的联系起来了,比如说极限编程(XP)。极限编程的焦点关注于快速的反复的发步功能性的代码给客户,并把变化的客户需求做为开发过程中的必备部分。下面是一些关于学习敏捷编程的在线资源:
函数性测试
这本书里面的大部分测试例子都是用来测试面对对象的代码,但是所有形式的编程都可以从中得到收获的。单体测试框架,比如说PHPUnits和SimpleTest,也都能很容易的用来测试功能函数的。例如上面的SimpleTest例子,它就是用来测试calculate_sales_tax()函数的。世界各地的程序员们:把单体测试用例放到你的函数库里面吧!
I hope that after the above discussion, you will also be inspired - "Test Infected"! (This term was originally coined by Erich Gamma. For details, please see the article http://junit.sourceforge.net/doc/testinfected/testing.htm), as Gamma wrote, at the beginning you You may feel that testing is tedious, but when you build a broad test set for your program, you will be more confident in your code!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP 8.4 brings several new features, security improvements, and performance improvements with healthy amounts of feature deprecations and removals. This guide explains how to install PHP 8.4 or upgrade to PHP 8.4 on Ubuntu, Debian, or their derivati

Visual Studio Code, also known as VS Code, is a free source code editor — or integrated development environment (IDE) — available for all major operating systems. With a large collection of extensions for many programming languages, VS Code can be c

If you are an experienced PHP developer, you might have the feeling that you’ve been there and done that already.You have developed a significant number of applications, debugged millions of lines of code, and tweaked a bunch of scripts to achieve op

JWT is an open standard based on JSON, used to securely transmit information between parties, mainly for identity authentication and information exchange. 1. JWT consists of three parts: Header, Payload and Signature. 2. The working principle of JWT includes three steps: generating JWT, verifying JWT and parsing Payload. 3. When using JWT for authentication in PHP, JWT can be generated and verified, and user role and permission information can be included in advanced usage. 4. Common errors include signature verification failure, token expiration, and payload oversized. Debugging skills include using debugging tools and logging. 5. Performance optimization and best practices include using appropriate signature algorithms, setting validity periods reasonably,

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

A string is a sequence of characters, including letters, numbers, and symbols. This tutorial will learn how to calculate the number of vowels in a given string in PHP using different methods. The vowels in English are a, e, i, o, u, and they can be uppercase or lowercase. What is a vowel? Vowels are alphabetic characters that represent a specific pronunciation. There are five vowels in English, including uppercase and lowercase: a, e, i, o, u Example 1 Input: String = "Tutorialspoint" Output: 6 explain The vowels in the string "Tutorialspoint" are u, o, i, a, o, i. There are 6 yuan in total

Static binding (static::) implements late static binding (LSB) in PHP, allowing calling classes to be referenced in static contexts rather than defining classes. 1) The parsing process is performed at runtime, 2) Look up the call class in the inheritance relationship, 3) It may bring performance overhead.

Pythonempowersbeginnersinproblem-solving.Itsuser-friendlysyntax,extensivelibrary,andfeaturessuchasvariables,conditionalstatements,andloopsenableefficientcodedevelopment.Frommanagingdatatocontrollingprogramflowandperformingrepetitivetasks,Pythonprovid
