CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页/开源项目/Prometheus/规则的单元测试
文档目录
安装Prometheus Agent 模式存储联邦编写 HTTP 服务发现管理 APIPrometheus 3.0 迁移指南API 稳定性保证功能开关
配置定义记录规则告警规则模板示例模板参考promtool 的 HTTP 配置规则的单元测试HTTPS 和认证

Prometheus

规则的单元测试

你可以使用 promtool 来测试你的规则。 Prometheus 允许不同的告警规则使用相同的 alertname。因此在单元测试中,你需要在单个 <alerttestcase> 下列出该 alertname 的所有触发告警的并集。 这是一个通过测试的单元测试输入文件示例。test.yml 是遵循上述语法的测试文件,alerts.yml 包含告警规则。 在同一目录下有 alerts.yml...

你可以使用 promtool 来测试你的规则。

# For a single test file.
./promtool test rules test.yml

# If you have multiple test files, say test1.yml,test2.yml,test3.yml
./promtool test rules test1.yml test2.yml test3.yml

测试文件格式

# This is a list of rule files to consider for testing. Globs are supported.
rule_files:
  [ - <file_name> ]

[ evaluation_interval: <duration> | default = 1m ]

# Setting fuzzy_compare true will very slightly weaken floating point comparisons.
# This will (effectively) ignore differences in the last bit of the mantissa.
[ fuzzy_compare: <boolean> | default = false ]

# The order in which group names are listed below will be the order of evaluation of
# rule groups (at a given evaluation time). The order is guaranteed only for the groups mentioned below.
# All the groups need not be mentioned below.
group_eval_order:
  [ - <group_name> ]

# All the tests are listed here.
tests:
  [ - <test_group> ]

``

# Series data
[ interval: <duration> | default = evaluation_interval ]
input_series:
  [ - <series> ]

# Name of the test group
[ name: <string> ]

# Start timestamp for the test group. This sets the base time for all samples
# and evaluations in this test group.
# Accepts either a Unix timestamp (e.g., 1609459200) or an RFC3339 formatted
# timestamp (e.g., "2021-01-01T00:00:00Z").
# Default: 0 (Unix epoch: 1970-01-01 00:00:00 UTC)
#
# When set:
# - All input_series samples are timestamped starting from start_timestamp
# - The eval_time in test cases is relative to start_timestamp
# - The time() function returns start_timestamp + eval_time
[ start_timestamp: <int> | <rfc3339_string> | default = 0 ]

# Unit tests for the above data.

# Unit tests for alerting rules. We consider the alerting rules from the input file.
alert_rule_test:
  [ - <alert_test_case> ]

# Unit tests for PromQL expressions.
promql_expr_test:
  [ - <promql_test_case> ]

# External labels accessible to the alert template.
external_labels:
  [ <labelname>: <string> ... ]

# External URL accessible to the alert template.
# Usually set using --web.external-url.
  [ external_url: <string> ]

``

# This follows the usual series notation '<metric name>{<label name>=<label value>, ...}'
# Examples:
#      series_name{label1="value1", label2="value2"}
#      go_goroutines{job="prometheus", instance="localhost:9090"}
series: <string>

# This uses expanding notation.
# Expanding notation:
#     'a+bxn' becomes 'a a+b a+(2*b) a+(3*b) … a+(n*b)'
#     'a-bxn' becomes 'a a-b a-(2*b) a-(3*b) … a-(n*b)'
#     'axn' becomes 'a a a … a' (a n+1 times) - it's a shorthand for 'a+0xn'
# There are special values to indicate missing and stale samples:
#     '_' represents a missing sample from scrape
#     'stale' indicates a stale sample
values: <string>

``

Prometheus 允许不同的告警规则使用相同的 alertname。因此在单元测试中,你需要在单个 <alert_test_case> 下列出该 alertname 的所有触发告警的并集。

# The time elapsed from start_timestamp when the alerts have to be checked.
# This is a duration relative to start_timestamp (which defaults to 0).
eval_time: <duration>

# Name of the alert to be tested.
alertname: <string>

# List of expected alerts which are firing under the given alertname at
# given evaluation time. If you want to test if an alerting rule should
# not be firing, then you can mention the above fields and leave 'exp_alerts' empty.
exp_alerts:
  [ - <alert> ]

``

# These are the expanded labels and annotations of the expected alert.
# Note: labels also include the labels of the sample associated with the
# alert (same as what you see in `/alerts`, without series `__name__` and `alertname`)
exp_labels:
  [ <labelname>: <string> ]
exp_annotations:
  [ <labelname>: <string> ]

``

# Expression to evaluate
expr: <string>

# The time elapsed from start_timestamp when the expression has to be evaluated.
# This is a duration relative to start_timestamp (which defaults to 0).
eval_time: <duration>

# Expected samples at the given evaluation time.
exp_samples:
  [ - <sample> ]

``

# Labels of the sample in usual series notation '<metric name>{<label name>=<label value>, ...}'
labels: <string>

# The expected value of the PromQL expression.
value: <number>

示例

这是一个通过测试的单元测试输入文件示例。test.yml 是遵循上述语法的测试文件,alerts.yml 包含告警规则。

在同一目录下有 alerts.yml 时,运行 ./promtool test rules test.yml。

`test.yml`

# This is the main input for unit testing.
# Only this file is passed as command line argument.

rule_files:
    - alerts.yml

evaluation_interval: 1m

tests:
    # Test 1.
    - interval: 1m
      # Series data.
      input_series:
          - series: 'up{job="prometheus", instance="localhost:9090"}'
            values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
          - series: 'up{job="node_exporter", instance="localhost:9100"}'
            values: '1+0x6 0 0 0 0 0 0 0 0' # 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
          - series: 'go_goroutines{job="prometheus", instance="localhost:9090"}'
            values: '10+10x2 30+20x5' # 10 20 30 30 50 70 90 110 130
          - series: 'go_goroutines{job="node_exporter", instance="localhost:9100"}'
            values: '10+10x7 10+30x4' # 10 20 30 40 50 60 70 80 10 40 70 100 130

      # Unit test for alerting rules.
      alert_rule_test:
          # Unit test 1.
          - eval_time: 10m
            alertname: InstanceDown
            exp_alerts:
                # Alert 1.
                - exp_labels:
                      severity: page
                      instance: localhost:9090
                      job: prometheus
                  exp_annotations:
                      summary: "Instance localhost:9090 down"
                      description: "localhost:9090 of job prometheus has been down for more than 5 minutes."
      # Unit tests for promql expressions.
      promql_expr_test:
          # Unit test 1.
          - expr: go_goroutines > 5
            eval_time: 4m
            exp_samples:
                # Sample 1.
                - labels: 'go_goroutines{job="prometheus",instance="localhost:9090"}'
                  value: 50
                # Sample 2.
                - labels: 'go_goroutines{job="node_exporter",instance="localhost:9100"}'
                  value: 50

`alerts.yml`

# This is the rules file.

groups:
- name: example
  rules:

  - alert: InstanceDown
    expr: up == 0
    for: 5m
    labels:
        severity: page
    annotations:
        summary: "Instance {{ $labels.instance }} down"
        description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."

  - alert: AnotherInstanceDown
    expr: up == 0
    for: 10m
    labels:
        severity: page
    annotations:
        summary: "Instance {{ $labels.instance }} down"
        description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."

测试中的时间

需要注意的是,在所有测试中,无论是 alert_test_case 还是 promql_test_case,所有与当前时间相关的函数(例如 time() 和 day_of_*() 函数)都将为测试输出一致的值。

默认情况下,在测试评估开始时,time() 返回 0(Unix 纪元:1970 年 1 月 1 日 00:00:00 UTC)。eval_time 字段指定相对于 start_timestamp 的持续时间,因此默认情况下 time() 将返回 0 + eval_time 的值。

你可以通过在测试组中设置 start_timestamp 字段来为测试配置自定义起始时间戳。此字段接受:

  • Unix 时间戳(例如,1609459200 表示 2021 年 1 月 1 日 00:00:00 UTC)
  • RFC3339 格式的时间戳(例如,"2021-01-01T00:00:00Z")

当你设置 start_timestamp 时:

  • 所有 input_series 样本将从 start_timestamp 开始打时间戳
  • 测试用例中的 eval_time 字段被解释为相对于 start_timestamp 的持续时间
  • time() 函数将返回 start_timestamp + eval_time

文章大纲