如何使用 sql 查询中的逻辑测试函数?

How can I test function with logic inside sql querys?

我的问题是我有巨大的 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)'
        );
    }
}

那个returns这个

如果我使用这个设置(我创建这个只是为了举例,在 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, '2', '2021-03-01', '2021-03-10', 77.30),
  (3, '3', '2021-03-15', '2021-04-06', 1.30),
  (4, '1', '2021-03-28', NULL, 15.30),
  (5, '2', '2021-03-28', NULL, 6.30);

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

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

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

你想要的开头:

BEGIN TRANSACTON Test123

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

ROLLBACK TRANSACTION Test123

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

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

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