如何使用 sql 查询中的逻辑测试功能?

问题描述

我的问题是我有巨大的 sql 查询,其中包含逻辑,需要以某种方式进行测试。我正在使用 PHP 并一起尝试 PHPUnit。我有大量与此类似的功能,其中包含不同级别的逻辑,我需要对每个功能进行自动化测试。例如,某些内容返回的查询取决于多个表和状态。代码示例:

<?PHP

use \somewhere\controller;

class cidade extends controller {
    // query() comes from controller,and it's a pdo query
    public function listar () {
        return $this->query(
            'SELECT 
                c.id,s.descricao,c.dataInicial,c.dataFinal,c.valor 
            FROM comissao c left join servico s ON (c.servico = s.id)
            WHERE (CURDATE() BETWEEN c.dataInicial AND c.dataFinal)
                OR (CURDATE() > c.dataInicial AND c.dataFinal IS NULL)'
        );
    }
}

返回这个

enter image description here

如果我使用此设置(我仅在 sqlfiddle.com 中创建此设置)

CREATE TABLE IF NOT EXISTS `servico` (
  `id` int(6) unsigned NOT NULL,`descricao` varchar(50) NOT NULL
) DEFAULT CHARSET=utf8;
INSERT INTO `servico` (`id`,`descricao`) VALUES
  (1,'Algo'),(2,'Alguma coisa'),(3,'Outra coisa');
  
CREATE TABLE IF NOT EXISTS `comissao` (
  `id` int(6) unsigned NOT NULL,`servico` int(6) unsigned NOT NULL,`dataInicial` date NOT NULL,`dataFinal` date,`valor` decimal(15,2) NOT NULL
) DEFAULT CHARSET=utf8;
INSERT INTO `comissao` (`id`,`servico`,`dataInicial`,`dataFinal`,`valor`) VALUES
  (1,'1','2021-03-01','2021-03-10',12.30),'2',77.30),'3','2021-03-15','2021-04-06',1.30),(4,'2021-03-28',NULL,15.30),(5,6.30);

但在我的日常工作中,我会更改此数据库,将测试更改为新结果会很复杂。

我已经读过的一点点:我想创建一个数据库只是为了测试,但这将是一项巨大的设置工作,所以我开始寻找一种方法来“创建”一个基本的假货这些查询数据库,但我找不到。所以我只是阅读了关于 dbunit 的一分钟,但似乎不适用于 PHPUnit 新版本,所以我认为这已被弃用。在 PHPUnit 文档的其他一些地方,我找到了关于依赖注入和模拟我的数据库结果的内容,但实际上,我需要测试我的查询会得到什么结果,而不是自己设置结果。

解决方法

如果你想在你的实时数据库中运行测试而不改变它,那么你需要使用命名事务。

一开始你想要:

BEGIN TRANSACTON Test123

然后在完成测试 SQL 代码后,运行

ROLLBACK TRANSACTION Test123

现在您可以对实时数据库进行任何您想要的更改,但它不会生效。 您还可以在外部事务中包含子事务,因此您不必担心嵌套测试。只需确保自动生成唯一名称,而不是上面的“Test123”。

为了测试,我建议制作开始和结束包装方法。 Start 将调用 begin tran 并设置您的测试数据。然后最终包装器将对您的输入数据进行增量比较,然后通过回滚进行清理。在这期间你做你的测试。

对于测试预期与实际结果的超级简单方法,我强烈推荐 AirSquirrels 的 Beyond Compare。它有一些非常强大的命令行选项,我每天都在我的测试例程中使用它们。如果您采用一种简单的方法将数据(预期的和实际的)导出到文本文件,它可以只对它们进行比较,然后在存在差异时返回报告。