6

首先,我不知道它是否称为单元测试。如果它有不同的名称,请随时纠正我。

我目前正在开发这样的网络应用程序。

假设我正在开发一个表单来将值保存到数据库中。我开发 HTML 和 PHP。我不时在浏览器中按 F5 并检查 HTML/jQuery 是否没有错误,并且 PHP 不会给出错过分号之类的错误。

当它完成并且一切都准备好进行测试时,我开始测试我的一小部分代码。像;

  1. -$_POST 数组是否正确地从表单文件中获取值?(我用 print_r 测试)
  2. -“$email”变量是否被正确清理为有效的电子邮件?(我用不同的可能性对其进行测试,例如:aaa@bbb、aa@bb.com、a@@b.net 等)
  3. - 提交的表单是否通过所有控制,并成功插入数据库?(我检查了我的 MySQL 表。)
  4. - 表单是否正确显示错误/成功消息?
  5. -...ETC。

如果它以正确的值工作,并且以错误的值失败;我相信表单按预期工作并且没有错误,所以我转向其他事情。

我不想这样做,而是想确保一切正常运行,否则会在不向浏览器发送垃圾邮件 F5 的情况下通知我问题。

像这样;

<?php
/* Unit Testing Start --
-ensure: isset($_POST['submit']) returns TRUE;
-ensure: isset($email) returns TRUE;
-ensure: isValidEmail($email) returns TRUE;
-ensure: connectDatabase() returns TRUE;
-ensure: getMysqlAffectedRows() returns 1;
-ensure: hasErrors() returns false;
*/

?>

我的表单代码,使用我上面发布的功能。

当它运行时,它应该向我显示这样的消息:(最好也记录它)

Test complete. Tested (6) possibilities, (4) succeeded, (2) failed. 
Failed 1: isValidEmail() returned FALSE, expected: TRUE. 
Failed 2: getMysqlAffectedRows returned NULL/0, expected INTEGER 1.

这样的事情会节省我很多时间,并且更容易维护我的代码。

我不想这样做:

$email = 'xxx@yyy.com';
echo isValidEmail($email) ? 'true' : 'false';

然后我必须从我的 PHP 脚本中删除这些行。测试必须永远留在那里,除非我手动删除它们。它们应该像评论一样在生产网站中,它们不会被执行。但是,在我的开发 PC 中,我将安装我需要安装的任何东西,并且必须解析/记录这些评论。

是的。就这样。现在进入问题:

  • 有可能与PHP有关吗?如果是这样,我该怎么做?

  • 它叫什么,单元测试,还是什么?

  • 你们如何测试你开发的任何东西?

  • 你们如何在不担心的情况下设法开发大型 Web 应用程序?“如果我改变这个功能,整个网站可能会崩溃。”?另外,您如何确定更改功能没有破坏任何东西?X 页面可能工作正常,但 Y 页面可能会因为您之前没有想到的事情而损坏。比如,X 页除以 3 可以正常工作,但是 Y 页除以 0 肯定会出错,但你只检查了 X 页?

如果您能回答我的问题并帮助我成为更好的开发人员,我将非常高兴。

谢谢!

4

3 回答 3

7

是的,自动化测试是可靠的软件开发的基石,正是因为通过单击浏览器来手动检查所有内容是不可能的。单元测试通常是“技术”测试,可确保特定“单元”(通常是函数或类)返回指定输入的预期返回值。功能测试测试更大的代码单元的正确行为。验收测试 从用户的角度测试最终的应用程序。

有许多框架和工具可以满足这些不同的需求:

  • PHPUnit - PHP 的事实上的单元测试框架
  • Behat - 一个专注于提供“业务可读”测试的测试框架
  • Codeception - 一个试图兼具可读性和技术性的框架

以上所有内容都有出色的文档,可让您轻松考虑使用单元测试。我建议您从阅读 PHPUnit 开始,然后看看 Behat 或 Codeception 可以为您提供什么。


作为一般建议:测试您的代码是否行为正确。不要测试“什么是做什么”,测试你做某事时是否得到你期望的结果。例如,不要测试isset($_POST['submit']). 这太详细了,用测试覆盖应用程序的每一行是没有意义的。相反,测试更大的代码单元。测试当您提交具有已知给定值的表单时,您的代码正确地将您重定向到下一页。或者测试您的身份验证系统是否正确拒绝非特权用户的访问。您希望测试如下所示:

Scenario: Login
  Given I am on the login page
  When I log in as user "Jon" with the password "foo"
  Then I should be logged in

或者:

Scenario: Deny unprivileged user
  Given I am logged in as the user "Jon" with access level 1
  When I try to access the action "restricted"
  Then I should be denied access

不是:

Scenario: Login
  Given I submit a form with the values "Jon" as username and "foo" as password
  When I check the $_POST array I should see "Jon" in the key "name" and ...
  ...

顺便说一句,以上内容实际上可以是 Behat 中的测试。


为了确保您编写的这些测试确实有价值,您需要定期运行它们。也许您在版本控制系统中创建了一个触发器,以便在签入代码时自动运行您的测试套件,并拒绝未通过测试的签入。最好的是如果你有一个持续集成服务器设置它定期从您的存储库中获取最新代码并在其上运行测试。如果您设置得当,您将自动收到有关在常规开发过程中容易被忽略的各种边缘问题的通知。例如,CI 服务器应该每次都尝试从头开始设置和运行应用程序,并且可能会提醒您从您所依赖的第三方获取依赖项时出现问题,或者您的数据库迁移脚本中存在问题。否则您不会注意到的事情,因为您并不总是获取依赖项并且并不总是重新运行您的迁移脚本。

最后,您的目标是从所有可能的角度持续自动“执行”您的代码。这是找到问题的唯一方法。

对于 CI 软件,我个人非常喜欢TeamCity,但JenkinsHudson非常受欢迎,还有很多其他 CI 工具

于 2013-02-28T09:55:39.507 回答
1

根据维基百科:

在计算机编程中,单元测试是一种方法,通过该方法,源代码的各个单元、一个或多个计算机程序模块的集合以及相关的控制数据、使用程序和操作程序,被测试以确定它们是否适合使用。

我猜这你正在做的可以称为单元测试。

UnitTest 的最佳方式是使用众所周知的框架。PHP的很少。我猜最流行的是PHPUnit。Appart 通过测试它会做其他很酷的事情,比如代码覆盖率报告(我相信其他框架也会这样做)。

我在 Eclipse 上工作,并且我的 IDE 集成了 PHPUnit。在开发过程中,我不必在窗口之间切换。我只是运行一个测试,看看我的代码是否有效。它节省了大量时间。

于 2013-02-28T09:54:53.717 回答
0

听起来您应该检查一下simpletest

于 2013-02-28T09:52:52.720 回答