回归测试编写
来自 PostgreSQL wiki
跳转到导航跳转到搜索为 PostgreSQL 编写新的回归测试
在尝试编写新的回归测试时,我发现关于这方面的文档缺乏。本文档是我尝试记录我学到的知识供将来参考。
文件布局
所有回归测试文件都位于 GIT 中的 pgsql/src/test/regress/
。
调度文件
- parallel_schedule
- serial_schedule
- 这些文件由
pgsql/src/test/regress/pg_regress
可执行文件解析和处理。这些文件具有以下格式:空行和带尾部“#”符号的行将被忽略,以“test:”代码字开头的行定义要运行的测试,以“ignore:”代码字开头的行形成忽略列表。当pg_regress
遇到忽略列表中的测试时,它会照常运行测试,但会忽略测试的失败。您可以在每个“ignore:”行中指定一个测试名称,以及每个“test:”行中最多指定 20 个测试名称。如果您在一个“test:”行中指定了多个名称,则这些测试将以并行模式运行(parallel_schedule
以这种方式执行)。如果只有一个测试名称,则该测试将以单一模式运行(serial_schedule
以这种方式执行)。parallel_schedule
用于运行 make check 命令。serial_schedule
用于 make installcheck。如果您想添加新的回归测试,则应将其名称添加到parallel_schedule
和serial_schedule
中。
- 这些文件由
测试的 SQL 代码和预期结果
- sql/
- 该目录包含测试工具将运行的 sql 脚本。回归测试工具的输出将每个文件列为单独的测试项,因此习惯上每个 sql 文件测试一个“功能”。
- expected/
- 该目录包含
*.out
文件,其中包含每个回归脚本的预期输出。输出文件除包含任何查询的结果外,还包含 sql 文件的内容,包括任何注释。
- 该目录包含
- results/
- 该目录虽然不包含任何用户生成的文件,但包含回归脚本运行后的输出。这里的
*.out
文件通常可以在编写新测试时复制到 expected/ 目录中。
- 该目录虽然不包含任何用户生成的文件,但包含回归脚本运行后的输出。这里的
特殊测试
- input/
- output/
- 包含
*.source
文件,这些文件需要在分别变为*.sql
和*.out
文件之前进行预处理。
- 包含
- data/
- 需要数据文件的测试(目前仅限于复制测试,不过 我 目前也正在开发一个大型对象测试)将它们存储在该目录中。需要访问该目录中文件的测试需要利用上面的预处理机制,并将该目录引用为
@abs_srcdir@/data/
,它将被替换为数据目录的绝对路径。
- 需要数据文件的测试(目前仅限于复制测试,不过 我 目前也正在开发一个大型对象测试)将它们存储在该目录中。需要访问该目录中文件的测试需要利用上面的预处理机制,并将该目录引用为
替换变量
@abs_srcdir@
- 源代码树中 src/test/regress 目录的绝对路径
@abs_builddir@
- 构建树中 src/test/regress 目录的绝对路径,在 VPATH 构建(即在源代码树之外构建)中,它与源代码树不同。
@testtablespace@
@DLSUFFIX@
示例测试
为了说明回归测试是如何构建的,我将创建一个简单的(虽然毫无意义)测试来展示它是如何完成的。
sql/simple.sql
该脚本是将要运行的实际回归测试
-- -- A simple brain-dead test to show how one is written -- -- Create a table CREATE TABLE simple_test (a integer, b text); -- Add a couple of rows COPY simple_test FROM stdin; 1 foo 2 bar 3 baz 4 floob \. -- Select it back out in reverse order SELECT * FROM simple_test ORDER BY a DESC; -- remove a row DELETE FROM simple_test WHERE length(b) > 3; -- Select again SELECT * FROM simple_test ORDER BY a DESC; -- Clean up DROP TABLE simple_test;
expected/simple.out
该文件包含上面回归脚本的预期输出
-- -- A simple brain-dead test to show how one is written -- -- Create a table CREATE TABLE simple_test (a integer, b text); -- Add a couple of rows COPY simple_test FROM stdin; -- Select it back out in reverse order SELECT * FROM simple_test ORDER BY a DESC; a | b ---+------- 4 | floob 3 | baz 2 | bar 1 | foo (4 rows) -- remove a row DELETE FROM simple_test WHERE length(b) > 3; -- Select again SELECT * FROM simple_test ORDER BY a DESC; a | b ---+----- 3 | baz 2 | bar 1 | foo (3 rows) -- Clean up DROP TABLE simple_test;
parallel_schedule
simple
测试需要添加到调度中才能运行。找到一个可能的组并将其添加到列表中。我将其放在“第四组并行测试”中。
这是将它添加到该组的 cvs diff。当您尝试时它可能不再适用,因为该文件可能会在 CVS 中更改。这仅作为将新测试放入其中的示例,因此不要过分认真对待它。
@@ -79,7 +79,7 @@ # ---------- # Another group of parallel tests # ---------- -test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete +test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete simple # ---------- # Another group of parallel tests
serial_schedule
该调度用于 make installcheck。将您的测试放在该文件中,顺序与 parallel_schedule
大致相同,以便于维护。关于 parallel_schedule
修补程序的相同注释也适用于此修补程序。
Index: serial_schedule =================================================================== RCS file: /home/jeremyd/local/postgres/cvsuproot/pgsql/src/test/regress/serial_schedule,v retrieving revision 1.33 diff -c -r1.33 serial_schedule *** serial_schedule 30 Aug 2006 23:34:22 -0000 1.33 --- serial_schedule 24 Sep 2006 23:52:05 -0000 *************** *** 76,81 **** --- 76,82 ---- test: hash_index test: update test: delete + test: simple test: namespace test: prepared_xacts test: privileges
更新现有的回归测试
更新现有回归测试的典型方法是:向 sql/foo.sql 文件中写入新的命令,运行一次测试套件,检查失败;如果一切都如您所愿,将 results/foo.out 文件复制到 expected/,然后再次运行测试套件,现在希望一切都能通过。只要您没有处理任何从 source/
和 output/
构建的特殊测试,或者没有变体预期文件,这种方法就很好。然后您需要将差异合并到这些不同的文件中。包 rcs 中的“merge”命令可以提供帮助,例如:
merge output/largeobject.source expected/largeobject.out results/largeobject.out
或者
merge expected/json_1.out expected/json.out results/json.out
(在将 results/json.out
复制到 expected/json.out
之前)。