PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 30. 回归测试 | 下一页

# 30.2. 测试评估

有一些正确安装并且具有完整功能的PostgreSQL 可能会在一些回归测试中"失效"，这主要是因为浮点数的形式和时区支持的问题。 目前的测试只是简单的用`diff`与参考系统的输出进行比较， 因而对一些细小的系统区别很敏感。当一项测试报告"失败"时， 只要检查一下预期和实际的结果，你就会发现区别并不大。当然， 我们仍然在努力维护所有我们支持的平台的准确参考文件，这样我们就可以假定所有测试都通过。

回归测试的实际输出在`src/test/regress/results`目录里的文件里。 测试脚本使用`diff`比较每个输出文件和存放在`src/test/regress/expected` 目录里的参考输出。任何区别都存放在`src/test/regress/regression.diffs` 里面供你检查。（当运行一个测试套件而不是内核测试时， 这些文件当然会显示在相关的子目录中，而不是在`src/test/regress`中。）

如果你不喜欢默认的`diff`选项，设置环境变量 `PG_REGRESS_DIFF_OPTS`为`PG_REGRESS_DIFF_OPTS='-u'`。 你也可以自己运行`diff`。

如果获得一个"失败"的测试结果，但实际上输出结果是正确的， 你可以通过添加新的比较文件来抑制错误报告。参见第 30.3 节获取更多细节。

## 30.2.1. 错误消息差别

有一些回归测试涉及到有意的非法输入值。错误消息可能会来自PostgreSQL 代码或来自主机平台系统过程。对于后者，信息可能在平台之间区别比较大， 但应该反映相似的信息。这些信息上的差别将会导致一个"失败"的回归测试， 我们可以通过检查文件发现这一点。

## 30.2.2. 环境差别

如果你在一台服务器上运行测试，而该服务器是用一种非 C 区域设置初始化的， 那么可能因为有排序顺序和其它类似的差别导致的失败。 回归测试套件处理这种问题的方法是提供可选的结果文件，这些文件一起处理一大堆的区域。

当使用临时安装在一个不同的区域中运行测试时，在`make` 命令行传递适当的区域相关的环境变量，例如：

    make check LANG=de_DE.utf8

回归测试驱动附件`LC_ALL`，所以它不使用那个变量选择区域。 要不使用区域，取消所有区域相关的环境变量（或设置它们为`C`） 或使用下列的特殊调用：

    make check NO_LOCALE=1

当对一个现有安装运行测试时，区域设置取决于现有安装。要改变它， 通过传递适当的选项到`initdb`，用一个不同的区域初始化数据库集群。

通常，作为生产用的区域设置上运行回归测试是明智的，因为这将练习区域和编码相关的代码部分， 并将实际在生产中使用。取决于操作系统环境，你可能会得到错误， 但是然后你将至少知道在运行实际应用时，预期什么区域特定的行为。

## 30.2.3. 日期和时间差别

大多数日期和时间测试结果依赖于时区设置。参考文件是为`PST8PDT` 时区(伯克利，加州)准备的，因而如果测试没有设置为那个时区是显然会失败的。 回归测试的驱动器把`PGTZ`环境变量设置为`PST8PDT`， 基本可以保证正确的测试。

## 30.2.4. 浮点数差别

有些测试涉及到对表中的数据列进行 64 位浮点数(`double precision`)计算的问题。 我们观察了涉及到计算`double precision`字段的数学函数的结果差别。 `float8`和`geometry`测试尤其容易在不同平台， 或者甚至是不同的编译器最优化设置之间产生小差别。 这时需要肉眼对这些差别进行比较，以判断这些差别究竟有多大，我们发现是在小数点右边 10 位左右。

有些系统把负零显示为`-0`，而其它的只是显示`0`。

有些系统在`pow()`和`exp()` 出错时产生的信号与目前PostgreSQL代码里期望的机制不一样。

## 30.2.5. 行顺序差别

你可能会看见同样的行以与预期文件的不同的顺序输出。在大多数情况下，严格说来这不算Bug。 大多数回归测试脚本都不会迂腐到在每个`SELECT`中都使用`ORDER BY`的地步， 因此根据 SQL 规范，它们的结果行顺序并非定义得非常好的。实际上， 因为我们是在同样的数据上用同样的软件运行同样的查询，所以在所有平台上通常都获得同样的结果， 因此即使缺少`ORDER BY`也不算什么大问题。不过有些查询的确存在跨平台的排序问题。 在测试一台已安装的服务器的时候，排序的差别也可能因为非 C 区域设置，或者非缺省的参数设置， 比如客户自己设置的`work_mem`或者规划器开销参数设置受影响。

因此，如果你看到一个排序差异，应该不是什么要担心的问题(除非明确使用了`ORDER BY`)。 不过，如果有这样的现像，请告诉我们，这样我们就可以在那条查询上加一个`ORDER BY` 从而在以后的版本里消除这种伪"失败"。

你可能会问，为什么我们不对所有回归测试的 SELECT 进行排序以一次性消灭所有这类问题。 原因是这样做只能让回归测试用处更少，而不是更多， 因为它们会试图使用那些生成顺序结果的查询规划，而不再使用那些不排序的查询规划。

## 30.2.6. 堆栈深度不够

如果`errors`测试导致在`select infinite_recurse()` 命令的时候服务器崩溃，这就意味着平台对进程堆栈的限制小于 max_stack_depth参数值。 我们可以通过在更高的堆栈限制的数值上运行服务器绕开这个问题(缺省 `max_stack_depth`建议值是 4MB)。如果你无法这么做， 那么另外一个方法是减少`max_stack_depth`的值。

在支持`getrlimit()`的平台上，服务器应该自动选择一个 `max_stack_depth`安全值；所以除非你已经手动重写这个设置， 否则这种类型的失败是一个可报告的bug。

## 30.2.7. "随机" 测试

`random`测试脚本的目的是生成随机结果。在很罕见的情况下， 这会导致回归测试失败。键入：

    diff results/random.out expected/random.out

会产生仅仅一行或几行差别。你不必担心这些，除非随机测试在重复测试中总是失败。

## 30.2.8. 配置参数

当针对现有的安装运行测试时，一些非缺省的参数设置会导致测试失败。 例如，修改了参数比如`enable_seqscan`或 `enable_indexscan`会导致规划改变， 影响使用`EXPLAIN`的测试的结果。

上一页 | 起始页 | 下一页
运行测试 | 上一级 | 平台相关的比较文件