测试流水线(管道)编写指南及最佳实践
测试流水线是Testany平台中最重要的元素之一。关于详细定义,请参考词汇表。高效地使用和维护测试流水线可以显著提升自动化测试的效率,并提高故障排除的准确性和效率。
准备工作
流水线用于编排测试用例。每个在Testany中注册的测试用例都会有一个唯一的用例键值,你可以使用这些键值来构建流水线。
你可以从测试用例库中获取相关的测试用例键值。

在这个例子中,你有6个不同的测试用例,我们将使用其中的4个,它们的键值分别是:AC2F5A50
,9686C618
,43D41CA4
和 8FF75E7F
。
了解流水线YAML
在Testany平台中,流水线用于表达测试用例之间的逻辑关系及其在执行过程中的其他关联因素。为了确保精确且明确的表达,流水线必须严格遵守从数据结构角度看是多叉树的结构规则和约束。此外,为了方便编写和维护流水线,我们选择YAML作为定义流水线的数据序列化格式。
编写流水线YAML文件
在Testany平台中,我们使用具有预定义语法格式的YAML文件来定义流水线,也称为流水线编排。对于流水线编排,你需要遵循以下语法(基于rule/v1.2
):
run
: 定义要执行的测试用例。whenPassed
: 定义一个条件,表示当测试用例<TEST-CASE-KEY>
执行并成功时,调用run
中定义的测试用例。whenFailed
: 定义一个条件,表示当测试用例<TEST-CASE-KEY>
执行失败时,调用run
中定义的测试用例。expect: fail
: 这个属性用于更改测试用例的执行状态。对于流水线执行状态的定义,如果所有执行的测试用例状态都是Passed
,那么流水线的执行状态就是Passed
,否则流水线的执行状态为Failed
。如果某个测试用例的执行状态为Failed
,并且这个失败是预期的,你可以使用这个属性将其状态更改为Passed
,以使流水线的执行状态为Success
。relay
: 具有该属性的测试用例可以在执行完成后,将其预先声明的变量值作为输入传递给同一流水线中的其他测试用例。应使用 rule/v1.2 规则。
例如:
kind: rule/v1.2
spec:
rules:
- run: <TEST-CASE-KEY>
- whenPassed: <TEST-CASE-KEY>
run: <TEST-CASE-KEY>
- whenFailed: <TEST-CASE-KEY>
run: <TEST-CASE-KEY>
- whenFailed: <TEST-CASE-KEY>
run: <TEST-CASE-KEY>
将上述的执行逻辑写成符合Testany 测试流水线语法的yaml文件,如下所示:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- whenPassed: AC2F5A50
run: 9686C618
- whenFailed: 9686C618
run: 43D41CA4
- whenFailed: 9686C618
run: 8FF75E7F
这个yaml文件所代表的意思是:
invoke AC2F5A50
if AC2F5A50 executed with Passed then
invoke 9686C618
if 9686C618 executed with Failed then
invoke 43D41CA4
invoke 8FF75E7F
else
pipeline completed
else
pipeline completed
将该执行逻辑画成流程图的话,就如下图所示:

流水线执行结果规则
当流水线被编排并执行时,会生成流水线执行状态。关于状态的详细定义及其出现的条件,请参考《Testany平台状态解读:全面指南》 。
对于上面的例子,如果 AC2F5A50 执行成功,而 9686C618 执行失败,那么流水线的执行结果将是“Failure”。
在实际的测试工作中,有一种比较特殊的情况,就是我们非常清楚某个测试用例的结果将是失败,而且这个结果是预期的(例如,在代码准备之前测试脚本已经准备好)。对于这种情况,Testany特别提供了一个语法:expect: fail。例如:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- whenPassed: AC2F5A50
run: 9686C618
expect: fail
- whenFailed: 9686C618
run: 43D41CA4
- whenFailed: 9686C618
run: 8FF75E7F
在这个例子中,你知道 9686C618
将执行失败,并且该失败是预期的,因此即使 9686C618
失败了,你仍然希望流水线的执行状态为成功。你可以在 run:9686C618
(第7行)后添加 expect: fail
流水线编排示例:
让我们用几个例子来进一步说明如何编排一个满足测试要求和业务逻辑的流水线,使您的自动化测试更加准确和高效。
示例 A(有效):whenFailed条件下执行单一用例
场景:“当前一个用例失败时,执行下一个用例。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- whenFailed: AC2F5A50
run: 9686C618
- whenFailed: 9686C618
run: 43D41CA4
- whenFailed: 43D41CA4
run: 8FF75E7F
流程图

示例 B(有效):whenPassed条件下执行单一用例
场景:“当前一个用例的执行结果为”Pass”时,执行下一个用例。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- whenPassed: AC2F5A50
run: 9686C618
- whenPassed: 9686C618
run: 43D41CA4
- whenPassed: 43D41CA4
run: 8FF75E7F
流程图

示例 C(有效):whenFailed条件下执行多条用例
场景:“当前一个用例失败时,执行接下来的三个用例。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- whenFailed: AC2F5A50
run: 9686C618
- whenFailed: AC2F5A50
run: 43D41CA4
- whenFailed: AC2F5A50
run: 8FF75E7F
流程图

示例 D(有效):无条件执行
场景:“无论结果如何,按 YAML 文件中从上到下的顺序执行所有四个用例。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: AC2F5A50
- run: 9686C618
- run: 43D41CA4
- run: 8FF75E7F
流程图:

示例 E(有效):带中继且whenPassed的执行
场景:“这是一个标准且有效的输出中继示例。用例 DE96D6A0
从用例 5DC1106D
获取 ACCESS_TOKEN
,用例 3FD642B7
也从 5DC1106D
获取 ACCESS_TOKEN
。输出从 5DC1106D
中继到 DE96D6A0
,以及从 5DC1106D
中继到 3FD642B7
。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: F8C8B1EA
- whenPassed: F8C8B1EA
run: 5DC1106D
- whenPassed: 5DC1106D
run: DE96D6A0
relay:
- key: ACCESS_TOKEN # Define an environment variable 'ACCESS_TOKEN' for case 'DE96D6A0'
refKey: 5DC1106D/ACCESS_TOKEN # Set case 'DE96D6A0's 'ACCESS_TOKEN' equal to case '5DC1106D's 'ACCESS_TOKEN'
- whenPassed: 5DC1106D
run: 3FD642B7
relay:
- key: ACCESS_TOKEN # Define an environment variable 'ACCESS_TOKEN' for case '3FD642B7'
refKey: 5DC1106D/ACCESS_TOKEN # Set case '3FD642B7's 'ACCESS_TOKEN' equal to case '5DC1106D's 'ACCESS_TOKEN'
- key: STATUS # Define an environment variable 'STATUS' for case '3FD642B7'
refKey: F8C8B1EA/STATUS # Set case '3FD642B7's 'STATUS' equal to case 'F8C8B1EA's 'STATUS'
nonSecret: true # Set case '3FD642B7's 'STATUS' as non-secret (its value can be printed out in log)
流程图:

示例 F(无效):带中继且whenFailed的执行
场景:“用户在 YAML 中定义用例 B 同时中继了用例 A 并包含 whenFailed: A
,系统将认为该 YAML 无效。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: 5385B189
- run: A3D9405F
whenFailed: 5385B189
relay:
- key: NEW_URL
refKey: 5385B189/NEW_URL
nonSecret: true
- key: AAA
refKey: 5385B189/AAA
nonSecret: true

示例 G(有效):带中继的执行
场景:“用户在 YAML 中明确定义 B 中继 A,但未明确声明 B 的其他 whenpassed
或 whenfailed
,此时系统会隐式添加 whenpassed: A
。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: 5385B189
- run: A3D9405F
relay:
- key: NEW_URL # 定义环境变量测试用例'5385B189'的环境变量'NEW_URL'
refKey: 5385B189/NEW_URL # 定义测试用例'A3D9405F'的环境变量'NEW_URL'为来自测试用例'5385B189'的环境变量'NEW_URL'
nonSecret: true
- key: AAA # 定义环境变量测试用例'5385B189'的环境变量'AAA'
refKey: 5385B189/AAA # 定义测试用例'A3D9405F'的环境变量'AAA'为来自测试用例'5385B189'的环境变量'AAA'
nonSecret: true

示例 H(无效):中继输出用例未正确配置
场景:“用例 B 依赖于用例 A 的输出,但用例 A 未声明任何输出。在这种情况下,系统不会拒绝配置,但在流水线详细信息页面中,用户将看不到任何标记为中继输出用例标志的测试用例。同时,系统会提醒用户检查依赖关系设置。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- run: 4035A27B
- run: D2ADC651
relay:
- key: ACCESS_TOKEN
refKey: 4035A27B/ACCESS_TOKEN

用例 A 配置了中继的情况。

用例 A 未配置中继的情况。

示例 I(无效):用例之间相互依赖
场景:“用例之间相互依赖形成循环,在这种情况下,系统将认为 YAML 无效。”
流水线 Yaml:
kind: rule/v1.2
spec:
rules:
- whenPassed: 9D9671B4
run: 714A0A51
- whenPassed: 714A0A51
run: D2ADC651
- whenPassed: D2ADC651
run: 9D9671B4
