28 个版本
0.14.0 | 2021年9月22日 |
---|---|
0.12.1 | 2021年5月18日 |
0.12.0 | 2021年2月9日 |
0.11.3 | 2020年5月7日 |
0.1.0 | 2017年7月31日 |
#234 在 测试 分类中
每月下载量:32
被用于 lorikeet-dash
80KB
1.5K SLoC
Lorikeet
DevOps 的并行测试运行器。
概述
Lorikeet 是一个命令行工具和 Rust 库,用于运行烟测试和集成测试。Lorikeet 目前支持 bash 命令、简单的 HTTP 请求以及系统信息(内存、CPU)。
测试计划在 YAML 文件中定义,可以使用 tera 进行模板化。测试计划中的每个步骤可以有多个依赖项(在其他步骤之前运行某些步骤)并且可以对每个命令的输出有预期。
默认情况下,步骤并行运行,使用系统可用的线程数。如果步骤有依赖项,通过 require
或 required_by
属性,则它将等待这些步骤完成。
例如,以下是一个测试计划,用于检查 Reddit 是否运行,然后如果运行则尝试登录:
check_reddit:
http: https://www.reddit.com
regex: the front page of the internet
login_to_reddit:
http:
url: https://www.reddit.com/api/login/{{user}}
save_cookies: true
form:
user: {{user}}
passwd: {{pass}}
api_type: json
jmespath: length(json.errors)
matches: 0
require:
- check_reddit
( 顺便提一下,我们添加了 jmespath: length(json.errors)
& matches: 0
因为无效的 Reddit 登录仍然返回 200 OK
状态 )
lorikeet 的输出
$ lorikeet -c config.yml test.yml
- name: check_reddit
pass: true
output: the front page of the internet
duration: 1416.591ms
- name: login_to_reddit
pass: true
output: 0
duration: 1089.0276ms
该名称来自 彩虹鹦鹉,一种非常色彩鲜艳的澳大利亚鸟类。就像煤矿中的金丝雀一样,lorikeet 旨在在事情出错时提供通知方式。它不是运行一个测试框架(一种颜色),而是旨在更全面,因此选择了彩虹羽毛的鸟类。
它们也是非常吵闹的鸟类。
0.14.0
版本中的更改
- 重大变更:为HTTP请求添加默认超时时间(
timeout_ms
),默认为30,000毫秒(30秒),此默认值可以根据以下HTTP选项进行更改。
0.13.1
版本中的变更
- 添加了对Slack webhook的支持。如果有任何步骤出现错误,这将发送到webhook。
lorikeet -s https://hooks.slack.com/services/<your_webhook_here> test
0.13.0
版本中的变更
- 重大变更:
run_steps
方法现在返回步骤完成的流,而不是等待所有步骤完成。 - 更多Clippy Lints
- 修复了在OS X上的编译错误。
0.12.1
版本中的变更
- 修复了所有Clippy问题。
- JMESPath字符串不再需要加引号。
- 添加了在后续请求中包含步骤输出的功能。您可以通过包含
${step_output.<step_name>}
来实现,其中<step_name>
是要包含为输出的步骤名称。目前您仍然需要“require”此步骤。
example_output:
require: another_step
http:
url: http://example.com
body: |
${step_output.another_step}
0.12.0
版本中的变更
- 更新到Tokio 1.0。
- 更新了所有库依赖项。
0.11.0
版本中的变更
- 初始异步版本。
- 更新了库依赖项。
0.10.0
版本中的变更
- 升级到2018 crate格式。
- 修复了在Ubuntu 19.10上的终端绘制问题。
- 对库版本进行了一些小的更新。
0.9.0
版本中的变更
-
升级到Reqwest
0.9.x
分支,感谢norcali! -
为HTTP请求类型添加了multipart支持、body支持和headers支持。
要添加自定义headers,提供一个header_name: header_value
的map。
Example Header:
http:
url: https://example.com
headers:
my-custom-header: my-custom-value
Multipart与现有的form
选项工作方式相同,但允许您指定要上传的文件。
Example Multipart:
http:
url: https://example.com
multipart:
multipart_field: multipart_value
file_upload:
file: /path/to/file
您也可以通过字符串设置一个通用的body。
Example Body:
http:
url: https://example.com
body: |
This is a generic POST body
0.8.0
版本中的变更
-
如果存在读取、解析或运行步骤的问题,CLI应用程序将不会崩溃,而是会输出一个
lorikeet
步骤来显示错误信息,并通过webhooks等提交它。 -
为步骤添加了初始延迟。如果您想在运行步骤之前等待任意时间,则可以使用
delay_ms
参数设置初始延迟。此延迟仅在步骤通常开始时执行,因此如果您的步骤有依赖关系,它们将首先运行,然后是延迟,然后是步骤。 -
在重试策略中添加:如果测试失败,可以通过设置
retry_count
属性来重试 n 次。您还可以通过设置retry_delay_ms
参数来延迟重试。 -
delay_ms
和retry_delay_ms
都以毫秒为单位,必须是一个正整数。 -
添加了初始的
junit
输出,以便您可以使用 lorikeet 与 Jenkins 或支持 junit xml 报告的另一个 CI 服务器。使用-j report.xml
输出 junit 报告。
0.7.0
的变化
- 这里的主要变化是将 YAML 解析更改为移除恐慌,并返回一个
Result<Vec<Step>>
,这是一个破坏性更改 - 一个新的函数
get_steps_raw
,它接受一个&str
yaml 以及实现Serialize
的任何内容作为配置上下文。这主要允许库在不需要触摸文件系统的情况下用于配置或步骤。get_steps
仍然可以用路径提供
安装
Lorikeet 在 crates.io 上,所以您可以选择运行
cargo install lorikeet
或者克隆并构建此存储库
cargo build --release
用法
命令行用法由 lorikeet -h
提供
USAGE:
lorikeet [FLAGS] [OPTIONS] [test_plan]
FLAGS:
-h, --help Prints help information
-q, --quiet Don't output results to console
-V, --version Prints version information
OPTIONS:
-c, --config <config> Configuration File
-j, --junit <junit> Output a JUnit XML Report to this file
-w, --webhook <webhook>... Webhook submission URL (multiple values allowed)
ARGS:
<test_plan> Test Plan [default: test.yml]
测试计划
测试计划是 lorikeet 的主要驱动程序,并且已经非常灵活。下面提供示例和测试语法。默认情况下,lorikeet 将期望在当前目录中有一个文件 test.yml
。
配置选项
Lorikeet 使用 tera 作为模板引擎,因此您可以在 yaml 测试计划中包含变量。使用 -c
您可以提供测试计划的上下文作为单独的 yaml 文件。此文件可以是任何形状,只要它是有效的 yaml。
例如,假设您想检查是否有多个服务器处于运行状态并连接。您可以有一个这样的配置
instances:
- server1
- server2
- server3
然后编写您的测试计划
{% for instance in instances %}
ping_server_{{instance}}:
bash: ping -c 1 {{instance}} 2>&1 >/dev/null
{% endfor %}
并运行它
$ lorikeet -c config.yml test.yml
- name: ping_server_server1
pass: true
duration: 7.859398ms
- name: ping_server_server2
pass: true
duration: 7.95139ms
- name: ping_server_server3
pass: true
duration: 7.740785ms
Webhook
测试运行完成后,您可以使用 webhook 将结果提交到服务器。这将使用 submitter::WebHook
形状 POST 一个 json 对象
{
"hostname": "example.hostname",
"has_errors": true,
"tests": [{
"name": "Example Webhook",
"pass": false,
"output": "Example Output",
"error": "Example Error",
"duration": 7.70
}]
}
测试计划语法
测试计划是一个 yaml 文件,它被分成几个步骤
<step_name>:
<step_type>: <options>
(<description>: <value>)
(<expect_type>: <value>)
(<filter_type>: <list or value>)
(<dependence_type>: <list or value>)
每个步骤都有一个唯一的名字和步骤类型。可选的,还可以有一个期望类型,以及一个依赖项或依赖者的列表。
您还可以在名称旁边包含测试执行描述,这样您就可以提供对测试执行更详细的解释
步骤类型
目前可以配置 5 种步骤类型:bash、http、system、step 和 value
Bash 步骤类型
Bash 步骤类型只是运行 bash
命令以执行 shell 脚本
say_hello:
bash: echo "hello"
可选地,您可以选择不返回输出,如果您只对应用程序的返回代码感兴趣
dont_say_hello:
bash:
cmd: echo "hello"
get_output: false
HTTP 步骤类型
HTTP 步骤类型可以使用 reqwest 执行对 web 服务器的 HTTP 命令。目前这是一个非常简单的步骤类型,但支持状态代码和按域名存储 cookie。
您可以指定仅 URL
check_reddit:
http: https://www.reddit.com
matches: the front page of the internet
或者提供以下选项
url
:提交请求的URLmethod
:要使用的HTTP方法,例如POST、GET、DELETE。默认为GET
headers
:请求中任何自定义头部的键/值对get_output
:返回请求的输出。默认为true
save_cookies
:在此域上保存任何设置的cookies。默认为false
status
:检查返回状态是否等于此值。默认为200
user
:基本认证的用户名pass
:基本认证的密码timeout_ms
:请求的超时时间(毫秒),默认为30000
(30秒)。如果设置为null
或~
,则永远不会超时。form
:表单POST提交的键/值对。如果方法设置为GET
,则此选项将方法设置为POST
multipart
:多部分请求。与form
选项类似,但允许文件上传。body
:类似于form/multipart
选项,但用于JSON上传的是原始字符串而不是表单数据。verify_ssl
:验证远程主机上的SSL。默认为true
。**警告**:禁用SSL验证会导致Lorikeet信任它与任何主机通信,这可能使您面临许多漏洞。您应仅作为最后的手段使用此功能。
以下是一个更详细的示例
login_to_reddit:
http:
url: https://www.reddit.com/api/login/{{user}}
save_cookies: true
form:
user: {{user}}
passwd: {{pass}}
api_type: json
对于多部分,您可以指定文件如下
Example Multipart:
http:
url: https://www.example.com
multipart:
multipart_field: multipart_value
file_upload:
file: /path/to/file
对于JSON上传,您可以使用body
字段
Example Raw JSON:
http:
url: https://www.example.com
body: |
{ "json_key": "json_value" }
系统步骤类型
系统步骤类型将使用sys-info crate返回有关系统信息,例如可用内存或系统负载。
例如,要检查内存
check_memory:
description: Checks to see if the available memory is greater than 1gb
system: mem_available
greater_than: 1048000
系统类型有一个固定的值列表,返回各种系统信息
load_avg_1m
:1分钟内的平均负载load_avg_5m
:5分钟内的平均负载load_avg_15m
:15分钟内的平均负载mem_available
:可用内存量mem_free
:空闲内存量mem_total
:总内存量disk_free
:空闲磁盘空间量disk_total
:总磁盘空间量
使用greater_than
或less_than
期望类型意味着您可以为环境资源设置阈值。
system_load:
description: Checks the System Load over the last 15 minutes is below 80%
system: load_avg15m
less_than: 1.6
‘步骤’步骤类型
如果您想对单个步骤进行更多断言,可以使用‘步骤’步骤类型。此类型仅返回其他步骤的输出。
say_hello:
value: hello
test_step:
step: say_hello
matches: hello
这也会隐式要求先运行它从中获取输出的步骤作为依赖项,这样您就不必担心顺序。
值步骤类型
值步骤类型将简单地返回一个值,而不是执行任何操作。
say_hello:
value: hello
过滤器类型
您可以通过正则表达式、jmespath或完全删除输出来过滤您的输出。过滤器可以一次性提供,或作为列表提供,因此您可以链接过滤器。
example_step:
value: some example
filters:
- regex: some (.*)
您还可以在步骤上简写提供过滤器,如下所示
example_step:
value: some example
regex: some
注意:如果过滤器无法匹配值,则视为测试错误
正则表达式过滤器
简单过滤器根据匹配的值过滤步骤的输出。
say_hello:
value: hello world!
regex: (.*) world!
您可以将它作为 regex
属性添加到步骤中,或者添加到过滤列表中
say_hello:
value: hello world!
filters:
- regex: (.*) world!
默认情况下,它将匹配并返回整个正则表达式语句(例如,`hello world!`),但如果您只想匹配某个组,也可以这样做
say_hello:
value: hello world!
regex:
matches: (?P<greeting>.*) world!
group: greeting
这将输出简单的 hello
JMES Path 过滤器
您可以使用 jmespath 过滤 JSON 文档,返回一些或更多值
show_status:
value: "{\"status\": \"ok\"}"
jmespath: status
与正则表达式一样,这可以是过滤链的一部分
show_status:
value: "{\"status\": \"ok\"}"
filters:
- jmespath: status
无输出过滤器
如果您不想将输出打印在结果中,可以添加无输出
dont_show_hello:
value: hello
do_output: false
您也可以将其添加到过滤链中
dont_show_hello:
value: hello
filters:
- nooutput
有时您可能从请求中返回太多内容,因此可以使用此功能确保打印的内容不包括在内
check_reddit:
http: https://www.reddit.com
filters:
- regex: the front page of the internet
期望类型
目前有3种期望类型:匹配输出、大于和小于。期望类型将取步骤类型的原始输出并对其进行验证。这样,您可以使用它来匹配来自Web服务器的返回的HTML或bash文件的输出。
匹配期望类型
匹配期望类型将使用正则表达式匹配命令的输出。
say_hello_or_goodbye:
value: hello
matches: hello|goodbye
如果正则表达式转换为有效的正则表达式查询时出现错误,则这将被视为失败。
大于或小于
如果您的输出是数值,则可以使用大于或小于来比较它
there_are_four_lights:
value: 4
less_than: 5
依赖关系
默认情况下,测试并行运行并提交到线程池执行。如果一个步骤有依赖关系,则不会运行,直到依赖步骤完成。如果没有步骤的依赖关系,则一有空闲线程就运行。如果您没有指定任何依赖关系,则没有保证执行顺序。
依赖关系很重要,例如在检查API之前设置cookie,但会导致您的测试运行时间更长,因为它们在等待其他步骤完成。
定义依赖关系,您可以使用 require
和 required_by
参数来控制这个依赖关系树。所需步骤由其名称给出,可以是单个值或名称列表。
step1:
value: hello
step2:
value: goodbye
require: step1
step3:
value: yes
require:
- step1
- step2
Lorikeet 如果
- 存在循环依赖
- 依赖关系中的步骤名称找不到
所需
required_by
是 require
的逆,可以在测试计划中使它更易读。
所以这个步骤计划
step1:
value: hello
step2:
value: goodbye
require: step1
等同于这个
step1:
value: hello
required_by: step2
step2:
value: goodbye
更复杂的依赖关系示例
you_say_yes:
value: yes
i_say_no:
value: no
require: you_say_yes
you_say_stop:
value: stop
require:
- i_say_no
- you_say_yes
required_by:
- and_i_say_go_go_go
and_i_say_go_go_go:
value: go go go
重试次数和延迟
有时您希望在另一个步骤运行后延迟一段时间执行步骤。有时如果步骤失败,您可能还希望在放弃之前重试它几次。
添加延迟
您可以通过设置 delay_ms
值来添加延迟
step1:
value: hello
delay_ms: 1000
输出
$ lorikeet test.yml
- name: step1
pass: true
output: hello
duration: 1004.1231ms
添加重试
您可以使用 retry_count
重试步骤几次,并使用 retry_delay_ms
添加延迟。
this_will_fail_but_take_3_seconds:
value: hello
matches: goodbye
retry_count: 3
retry_delay_ms: 1000
输出
$ lorikeet test.yml
- name: this_will_fail_but_take_3_seconds
pass: false
output: hello
error: Not matched against `goodbye`
duration: 3015.933ms
JUnit 报告
您可以使用 -j
命令生成 JUnit xml 报告
lorikeet -j report.xml test.yml
输出主要用于与 Jenkins BlueOcean 一起使用,报告格式可能略有变化。
示例
将这些示例保存为 test.yml
以运行它们
从 bash 提示符回显 hello
测试计划
say_hello:
bash: echo hello
输出
$ lorikeet test.yml
- name: say_hello
pass: true
output: |
hello
duration: 2.727446ms
匹配 bash 命令的输出
测试计划
say_hello:
bash: echo hello
matches: hello
输出
$ lorikeet test.yml
- name: say_hello
pass: true
duration: 2.68431ms
检查 Reddit 是否宕机
测试计划
check_reddit:
http: https://www.reddit.com
matches: the front page of the internet
输出
$ lorikeet test.yml
- name: say_hello
pass: true
duration: 2.68431ms
登录 Reddit
对于测试的配置参数,如用户名和密码,将其分离到不同的文件中是有意义的
配置文件
user: myuser
pass: mypass
测试计划
login_to_reddit:
http:
url: https://www.reddit.com/api/login/{{user}}
form:
user: {{user}}
passwd: {{pass}}
api_type: json
输出(不要忘记使用 -c
指定配置文件)
$ lorikeet -c config.yml test.yml
- name: login_to_reddit
pass: true
output: {"json": {"errors": [], "data": {"need_https": true, "modhash": "....", "cookie": "..."}}}
duration: 1420.8466ms
依赖关系
~22–39MB
~578K SLoC