假设我们有一个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测试在控制台中的外观(总体外观,而不是根据此示例):