【问题标题】:Unit test application including database is too slow包含数据库的单元测试应用程序太慢
【发布时间】:2012-02-29 13:28:31
【问题描述】:

我做了很多单元测试(主要是 PHP/Mysql),但是用于创建数据库的 SQL 脚本运行起来太慢了,所以我浪费了很多时间。我不能总是模拟数据库(遗留代码,太复杂而无法处理),那么我能做什么?直接复制数据Mysql文件?以其他方式加载我的数据库?

加载大量数据很快,只有 CREATE TABLES 很慢。

【问题讨论】:

  • 你没有做单元测试。单元测试意味着您在没有任何外部系统(例如文件系统、Web 服务或数据库)的情况下单独测试应用程序逻辑。你所做的就是集成测试。
  • 对。事实上,我两者都做,纯单元测试运行起来非常快。

标签: mysql database unit-testing performance


【解决方案1】:

阅读另一个问题给我一个答案:只需将我的测试数据库移动到内存中。在 Debian/Ubuntu(我的情况)下,我只需将我的测试数据库的目录移动到 /dev/shm,创建一个链接以将旧目录链接到新目录,重新启动 mysql 服务器,然后 tada!!

需要 140 秒才能运行的套件现在只需 10 秒即可运行。这样做很明显!这个项目在测试期间使用了大量的数据库。 另一个项目在 18/20 年代运行,数据库在磁盘上,但在内存中的数据库运行速度并不快,但它比其他项目有更多的单元测试,并且在集成测试中创建的表更少。

【讨论】:

    【解决方案2】:

    您可以使用已初始化(测试)的数据库。这样,您只需:

    1. 开始交易,
    2. 将特定于您的测试的数据插入到数据库中,
    3. 运行测试
    4. 回滚交易。

    执行此操作时,您需要维护一个数据库迁移脚本,该脚本允许您在架构更改时更新测试数据库,但您可能已经使用当前方法执行此操作,并且您需要随时执行此操作推出新版本软件时的方式。

    这样做仍然会很慢,但比为每个测试运行所有 DDL 脚本要快得多。如果可能的话,去编写单元测试,而不是集成测试,但是你已经说过考虑到系统的状态(遗留)这很难。

    【讨论】:

    • 真可惜:我仍然没有使用真正的数据库引擎来支持所有项目的事务,但对于较新的,这是一个好主意。
    • MySQL 不支持事务?
    • MyISAM 引擎没有,InnoDB 有,而且我们在 InnoDB 上的应用程序仍然很少。
    【解决方案3】:

    您可以使用 MySQL 的 MEMORY 引擎。

    它比 innoDB 快得多,虽然它不支持所有功能(例如外键),但它对测试非常有用。

    假设您有一个从头开始设置数据库的脚本(例如,在初始化测试时运行该脚本),您只需将引擎定义从 InnoDB 预先添加/替换到 MEMORY。

    您甚至可以将引擎设置为您的测试套件的参数,这样您就可以在每次保存/提交时运行快速的 MEMORY 版本,以及在发布之前使用 innoDB 运行更长但更健壮的版本。

    与此处的其他建议相比:

    • 它是跨平台的(而不是通过仅适用于 Linux 的复制将数据库移动到内存)
    • 比使用虚拟服务器 a-la Docker/VMWare 更简单、更快捷

    【讨论】:

      【解决方案4】:

      我也遇到过类似的情况。我创建了一个仅用于测试的玩具数据库。 这个数据库只有很少的记录。

      【讨论】:

      • 不是记录的问题,而是DDL指令的问题。我可以立即加载数千条记录(几乎;-))但是 40 个 CREATE TABLES 需要太多时间。
      • 如果您转储包含结构的数据库(即创建表等),那么重置不会花费太多时间。实际上,我过去曾为一个项目做过这个,而且只需要几秒钟。花费大量时间的是用超过 10 万条记录填充数据库。 DDL 非常快。
      • 40 CREATE TABLE 需要 10 秒,50 次测试需要不到 2 秒的时间来运行。我使用的记录少于 10 万条,但希望尽快运行测试套件。
      【解决方案5】:

      我愿意:

      1. 按照我想要的方式创建测试数据库
      2. 使用 --add-drop-table 和 --no-autocommit 对数据库进行 mysqldump,这样只有一个大事务
      3. 在您想要重置数据库时导入转储

      【讨论】:

      • 这就是我做的,多了几张桌子就很慢了。
      【解决方案6】:

      另一个选项是在 VMWare 实例中设置数据库...然后在需要时重置它。

      【讨论】:

      • 如何快速重置我的虚拟机实例?快照回滚是否很快?
      • 是的 - 几分钟后...就像在最坏的情况下复制一个大文件一样。
      • @Randy,OP 谈到在这里运行 unit 测试,并且可以在至少几秒的范围内工作。
      • 是的 - 但与通过脚本将数据库重新加载到初始起点相比 - 这会更快。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 2012-03-02
      • 2018-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多