如何加速SimpleTest?你应该采取哪些步骤?

6
我正在为Drupal 6项目编写一些测试代码,但是与其他语言和框架(如Ruby on Rails或Django)相比,这些测试运行起来非常缓慢,让人难以置信。
Drupal.org认为这个问题是垃圾邮件,并且不会给我证明我是人类的方法,因此我认为SO是下一个最好的地方来询问这样的问题,并对我的测试方法进行检查。
在这个代码清单中,以下测试代码相对简单。

http://gist.github.com/498656

简而言之,我正在做以下事情:
  • 创建一些内容类型,
  • 创建一些角色,
  • 创建用户,
  • 以用户身份创建内容,
  • 检查他们是否可以编辑内容
  • 检查它是否对匿名用户可见
当我从命令行运行这些测试时,输出如下:


Drupal test run
---------------

Tests to be run:
 -  (ClientProjectTestCase)

Test run started: Thu, 29/07/2010 - 19:29

Test summary:
-------------

ClientProject feature 52 passes, 0 fails, and 0 exceptions

Test run duration: 2 min 9 sec


我试图在每次将代码推送到中央存储库之前运行此类测试,但如果在项目早期就花费了这么长时间,我不敢想象当我们有更多测试用例时会怎样。
有什么方法可以加快速度吗?
我正在使用MacbookPro,配置如下:
- 4GB的内存, - 2.2GHz的Core 2 Duo处理器, - PHP 5.2, - Apache 2.2.14,没有任何opcode缓存, - Mysql 5.1.42(Innodb表是默认设置), - 5400 RPM的笔记本硬盘
我知道在上面的示例中,每次都要引导Drupal,这是一个非常昂贵的操作,但这对于其他框架(如Ruby on Rails或Django)也不是没有先例,我不明白为什么在这个项目中平均每个测试用例需要一分钟以上。

这里有一个不错的Drupal 7加速技巧列表,其中许多看起来也适用于Drupal 6,但我还没有试过,很希望听听其他人的使用情况,以免进一步陷入困境。

在这种情况下,你在使用Drupal 6时做了什么,并且有哪些快速获胜的方法

每个测试用例需要一分钟的时间,而我预计会有超过一百个测试用例,这感觉太疯狂了。

3个回答

8
根据 qa.drupal.org上Drupal 7测试性能调优提示,似乎运行测试数据库在ram磁盘中会带来最大的速度提升。

DamZ为Debian 5编写了一个修改后的mysql init.d脚本,可以完全在tmpfs中运行MySQL数据库。它在http://drupal.org/files/mysql-tmpfs.txt,附加在http://drupal.org/node/466972上。

这使得双四核机器从50分钟的测试和巨大的InnoDB磁盘I/O转变为每个测试不到3分钟。它现在作为PIFR v1的#32用于testing.d.o。这绝对是唯一的方法。

我没有也不会立即在InnoDB上尝试它,如果有人想要省略下面的skip-innodb步骤并在tmpfs上尝试它,请随意。

此外,在这里有一些关于在OS X上创建ram磁盘的说明,虽然这是将整个mysql数据库库存移到ram磁盘中,而不仅仅是单个数据库:

更新 - 我现在已经尝试过这种方法,并记录下了我的发现

通过切换到ram磁盘,我已经能够将测试时间缩短30-50%。以下是我采取的步骤:

创建ram磁盘

我选择了1GB,主要是因为我有4GB的RAM,而且我不确定我需要多少空间,所以我会保险一些:

    diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://2048000`

安装mysql

接下来,我运行了mysql安装脚本,在新的ramdisk上安装mysql。

    /usr/local/mysql/scripts/mysql_install_db \
        --basedir=/usr/local/mysql \
        --datadir=/Volumes/ramdisk

然后,我采取了以下步骤:确保之前的mysqld已经停止运行,然后启动mysql守护进程,并确保我们告诉它使用ram磁盘作为我们的数据目录,而不是默认位置。

  /usr/local/mysql/bin/mysqld \
      --basedir=/usr/local/mysql \
      --datadir=/Volumes/ramdisk \
      --log-error=/Volumes/ramdisk/mysql.ramdisk.err \
      --pid-file=/Volumes/ramdisk/mysql.ramdisk.pid \
      --port=3306 \
      --socket=/tmp/mysql_ram.sock

添加测试数据库

然后,我使用drush从我们的staging站点下载了最新的数据库转储文件,并更新了settings.php指向它的位置:

drush sql-dump > staging.project.database.dump.sql

创建符号链接 - 这是因为默认情况下mysql命令会查找/tmp/mysql.sock,将其符号链接到我们的短期ram磁盘上比不断更改php.ini文件更简单。接下来需要将这些数据导入本地测试设置中的ram磁盘中。这涉及创建一个指向ram磁盘数据库套接字的符号链接,并创建数据库,授予在drupal安装中指定的mysql用户权限,然后加载数据库以开始运行测试。步骤如下:
ln -s /tmp/mysql_ram.sock /tmp/mysql.sock

创建数据库(从mysql提示符处使用命令行)

CREATE DATABASE project_name;
GRANT ALL PRIVILEGES ON project_name.* to db_user@localhost IDENTIFIED BY 'db_password';

将内容加载到新数据库中...

mysql project_database < staging.project.database.dump.sql  

在命令行上运行测试

最后,在命令行上运行测试,并使用growlnotify告诉我测试何时完成。

php ./scripts/run-tests.sh --verbose --class ClientFeatureTestCase testFeaturesCreateNewsItem ; growlnotify -w -m "Tests have finished."

两个测试用例需要大约一分半钟的时间,仍然非常慢 - 比我之前使用过的其他框架慢了几个数量级。

我在这里做错了什么?

这绝不能是使用Drupal运行测试的标准方式,但我没有找到任何关于Drupal测试套件需要花费多长时间的统计数据来告诉我不同的情况。


5

Drupal的SimpleTests最大的问题在于安装Drupal需要很长时间,而每个测试用例都需要进行安装。

因此,使用simpletest_clone -- 基本上,在安装后刷新数据库并将其用作每个测试用例的起点,而不是运行整个安装程序。


2

我理解你的痛苦,你的观察很准确。一个需要几分钟才能运行的测试套件会阻碍TDD。我已经转而使用在命令行上运行的普通PHPUnit测试,这些测试来自Rails环境,速度非常快。真正的关键是完全避免访问数据库,使用mocks和stubs。


有没有任何工具或插件可以用来模拟/存根Drupal的核心? - Julien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接