PHP 测试课程规则
示例
假设我们有一个LoginForm带有rules()方法的简单类(在登录页面中用作框架模板):
class LoginForm { public $email; public $rememberMe; public $password; /* rules() method returns an array with what each field has as a requirement. * Login form uses email and password to authenticate user. */ public function rules() { return [ //电子邮件和密码都是必需的 [['email', 'password'], 'required'], //电子邮件必须为电子邮件格式 ['email', 'email'], //RememberMe必须为布尔值 ['rememberMe', 'boolean'], //密码必须与此模式匹配(必须仅包含字母和数字) ['password', 'match', 'pattern' => '/^[a-z0-9]+$/i'], ]; } /** the validate function checks for correctness of the passed rules */ public function validate($rule) { $success = true; list($var, $type) = $rule; foreach ((array) $var as $var) { switch ($type) { case "required": $success = $success && $this->$var != ""; break; case "email": $success = $success && filter_var($this->$var, FILTER_VALIDATE_EMAIL); break; case "boolean": $success = $success && filter_var($this->$var, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== null; break; case "match": $success = $success && preg_match($rule["pattern"], $this->$var); break; default: throw new \InvalidArgumentException("Invalid filter type passed") } } return $success; } }
为了对此类进行测试,我们使用单元测试(检查源代码以查看其是否符合我们的期望):
class LoginFormTest extends TestCase { protected $loginForm; //在测试开始时执行代码 public function setUp() { $this->loginForm = new LoginForm; } //为了验证我们的规则,我们应该使用validate()方法 /** * This method belongs to Unit test class LoginFormTest and * it's testing rules that are described above. */ public function testRuleValidation() { $rules = $this->loginForm->rules(); //初始化以验证并对此进行测试 $this->loginForm->email = "valid@email.com"; $this->loginForm->password = "password"; $this->loginForm->rememberMe = true; $this->assertTrue($this->loginForm->validate($rules), "Should be valid as nothing is invalid"); //测试电子邮件验证 //由于我们将电子邮件设置为电子邮件格式,因此不能为空 $this->loginForm->email = ''; $this->assertFalse($this->loginForm->validate($rules), "Email should not be valid (empty)"); // It does not contain "@" in string so it's invalid $this->loginForm->email = 'invalid.email.com'; $this->assertFalse($this->loginForm->validate($rules), "Email should not be valid (invalid format)"); //将电子邮件恢复为下一次测试有效 $this->loginForm->email = 'valid@email.com'; //测试密码验证 //密码不能为空(因为这是必需的) $this->loginForm->password = ''; $this->assertFalse($this->loginForm->validate($rules), "Password should not be valid (empty)"); //将密码恢复为下一次测试有效 $this->loginForm->password = 'ThisIsMyPassword'; //测试记住我的验证 $this->loginForm->rememberMe = 999; $this->assertFalse($this->loginForm->validate($rules), "RememberMe should not be valid (integer type)"); //将retberMe恢复为下一次测试有效 $this->loginForm->rememberMe = true; } }
Unit在这里,测试究竟能为您提供什么帮助(不包括一般示例)?例如,当我们获得意外结果时,它非常适合。例如,让我们从前面的规则开始:
['password', 'match', 'pattern' => '/^[a-z0-9]+$/i'],
相反,如果我们错过了一件重要的事情,并写了这样的话:
['password', 'match', 'pattern' => '/^[a-z0-9]$/i'],
由于存在许多不同的规则(假设我们不仅使用电子邮件和密码),还很难发现错误。本单元测试:
//初始化以验证并对此进行测试 $this->loginForm->email = "valid@email.com"; $this->loginForm->password = "password"; $this->loginForm->rememberMe = true; $this->assertTrue($this->loginForm->validate($rules), "Should be valid as nothing is invalid");
将通过我们的第一个例子,但不会通过第二个。为什么?因为在第二个示例中,我们编写了带有错字(缺失+符号)的模式,这意味着它仅接受一个字母/数字。
可以使用以下命令在控制台中运行单元测试phpunit[path_to_file]。如果一切正常,我们应该能够看到所有测试都处于OK状态,否则我们将看到Error(语法错误)或Fail(该方法中至少一行没有通过)。
通过类似的附加参数,--coverage我们还可以直观地看到后端代码中测试了多少行以及哪些行通过/失败。这适用于已安装PHPUnit的任何框架。
示例PHPUnit测试在控制台中的外观(总体外观,而不是根据此示例):