内容

名称

Test2::Event - 事件的基类

描述

所有通过 Test2 传递的事件对象的基类。

概要

package Test2::Event::MyEvent;
use strict;
use warnings;

# This will make our class an event subclass (required)
use base 'Test2::Event';

# Add some accessors (optional)
# You are not obligated to use HashBase, you can use any object tool you
# want, or roll your own accessors.
use Test2::Util::HashBase qw/foo bar baz/;

# Use this if you want the legacy API to be written for you, for this to
# work you will need to implement a facet_data() method.
use Test2::Util::Facets2Legacy;

# Chance to initialize some defaults
sub init {
    my $self = shift;
    # no other args in @_

    $self->set_foo('xxx') unless defined $self->foo;

    ...
}

# This is the new way for events to convey data to the Test2 system
sub facet_data {
    my $self = shift;

    # Get common facets such as 'about', 'trace' 'amnesty', and 'meta'
    my $facet_data = $self->common_facet_data();

    # Are you making an assertion?
    $facet_data->{assert} = {pass => 1, details => 'my assertion'};
    ...

    return $facet_data;
}

1;

方法

通用

$trace = $e->trace

获取事件生成时 Test2::EventFacet::Trace 的快照

$bool_or_undef = $e->related($e2)

检查两个事件是否相关。在本例中,相关意味着它们的跟踪共享一个签名,这意味着它们是在相同的上下文中创建的(或者至少是由共享 ID 的上下文创建的,除非有人在做一些非常糟糕的事情,否则它们是相同的)。

这可以用来可靠地链接由同一工具创建的多个事件。例如,一个失败的测试,如 ok(0, "fail" 将生成 2 个事件,一个是 Test2::Event::Ok,另一个是 Test2::Event::Diag,这两个事件都与在同一上下文中创建并由同一初始工具创建相关(尽管多个工具可能嵌套在初始工具下)。

如果无法检查关系,则将返回 undef,这种情况发生在任一事件的跟踪不完整或缺失时。如果跟踪完整但没有匹配,则将返回 0。如果匹配,则将返回 1

$e->add_amnesty({tag => $TAG, details => $DETAILS});

这可以用来为该事件添加赦免。在大多数情况下,赦免只影响失败的断言,但某些格式化程序可能会在通过断言甚至非断言的情况下显示它们。

赦免将阻止失败的断言导致整个测试失败。换句话说,它将失败标记为预期并允许。

注意: 这就是 'TODO' 在幕后实现的方式。TODO 本质上是带有 'TODO' 标签的赦免。详细信息是 TODO 的原因。

$uuid = $e->uuid

如果启用了 UUID 标记(参见 Test::API),则任何通过集线器的事件都将被标记为 UUID。在大多数情况下,新创建的事件尚未被标记。

$class = $e->load_facet($name)

此方法用于按名称(或键)加载方面。它将尝试加载方面类,如果成功,它将返回它加载的类。如果失败,它将返回 undef。这在类级别缓存结果,以便以后的调用更快。

$name 变量应该是用于在方面哈希引用中访问方面的键。例如,断言方面具有键 'assert',信息方面具有 'info' 键,错误方面具有 'errors' 键。您可以在名称末尾包含或省略 's',该方法足够智能,可以尝试 's' 和无 's' 形式,它将首先检查您提供的内容,如果未找到,它将添加或删除 's' 并再次尝试。

@classes = $e->FACET_TYPES()
@classes = Test2::Event->FACET_TYPES()

这将返回使用 load_facet() 方法加载的所有方面的列表。这不会返回任何未加载的类,或者直接加载而没有调用 load_facet() 的类。

注意: 核心方面类型会自动加载并填充到此列表中。

NEW API

$hashref = $e->common_facet_data();

子类可以使用此方法生成一个初始的 facet 数据哈希引用。这将使用 trace、meta、amnesty 和 about facets 来填充哈希引用。这些 facets 在几乎所有事件中都以相同的方式生成。

$hashref = $e->facet_data()

如果您没有覆盖此方法,则默认实现将尝试从旧版 API 生成 facets。此生成仅限于旧版 API 可以提供的范围。建议您覆盖此方法并编写明确的 facet 数据。

$hashref = $e->facets()

此方法将从 facet_data() 获取哈希引用,并将每个 facet 赋予适当的 Test2::EventFacet::* 子类。如果找不到任何给定 facet 的类,它将原样传递。

@errors = $e->validate_facet_data();
@errors = $e->validate_facet_data(%params);
@errors = $e->validate_facet_data(\%facets, %params);
@errors = Test2::Event->validate_facet_data(%params);
@errors = Test2::Event->validate_facet_data(\%facets, %params);

此方法将验证 facet 数据并返回一个错误列表。如果未发现错误,则将返回一个空列表。

此方法可以作为对象方法调用,不带任何参数,在这种情况下,将调用 facet_data() 方法来获取要验证的 facet 数据。

当用作对象方法时,可以省略 \%facet_data 参数。

当用作类方法时,\%facet_data 参数是必需的。

其余参数将被吸收到 %params 哈希中。

目前只定义了 1 个参数

require_facet_class => $BOOL

当设置为 true(默认值为 false)时,这将拒绝任何无法找到面类别的面。通常,没有类别的面被认为是自定义的,并且会被忽略。

什么是面?

面是事件如何向 Test2 内部和格式化程序传达其目的的方式。没有面的事件不会对整体测试状态产生任何有意影响,并且大多数格式化程序都不会显示它,除了可能说看到了未知类型的事件。

面由 facet_data() 子例程生成,您几乎总是应该覆盖它。facet_data() 预计返回一个哈希引用,其中每个键都是面类型,而值要么是包含该面数据的哈希引用,要么是哈希引用的数组。一些面必须定义为单个哈希引用,一些必须定义为哈希引用的数组,没有面允许两者。

facet_data() **不能** 对其返回的数据、主哈希引用和嵌套的面哈希引用进行祝福,**必须** 是裸的,尽管每个面中包含的项目可以被祝福。此方法返回的数据**应该** 也是内部数据的副本,以防止意外状态修改。

facets()facet_data() 获取数据并将其祝福到 Test2::EventFacet::* 包中。但是,这很少使用,EventFacet 包主要用于方便和文档。EventFacet 类在内部根本没有使用,而是使用原始数据。

以下是按包列出的面类型列表。这些包在内部没有使用,但文档保存在这些包中。

**注意:** 每个面类型都有 'details' 字段。此字段始终用于人类消费,并且在提供时,应该解释面的“原因”。所有其他字段都是特定于面的。

about => {...}

Test2::EventFacet::About

这包含有关事件本身的信息,例如事件包名称。此面的 details 字段是事件的总体摘要。

assert => {...}

Test2::EventFacet::Assert

如果进行了断言,则使用此面。此面的 details 字段是断言的描述。

control => {...}

Test2::EventFacet::Control

此面用于告诉 Test2::Event::Hub 有关事件导致的特殊操作。例如,停止所有测试、终止当前测试等。在此面中,details 字段解释了为什么采取了任何特殊操作。

**注意:** 这就是退出机制的实现方式。

meta => {...}

Test2::EventFacet::Meta

meta 面包含与事件相关的所有元数据。在本例中,details 字段没有特殊含义,但如果某些内容在事件上设置了 'details' 元键,则可能会存在。

parent => {...}

Test2::EventFacet::Parent

此面包含嵌套事件和子测试的类似详细信息。在此面中,details 字段通常是子测试的名称。

plan => {...}

Test2::EventFacet::Plan

此面告诉系统已设置计划。它的 details 字段通常为空,但如果存在,则解释了计划为何如此,如果计划是跳过所有内容,这将非常有用。

trace => {...}

Test2::EventFacet::Trace

此面包含与事件生成的时间和位置相关的的信息。这就是如何知道测试文件和断言失败的行号。此面还可以帮助您判断测试是否相关。

在此面中,details 字段会覆盖断言失败时提供的“在 test_file.t 第 42 行失败”消息。

amnesty => [{...}, ...]

Test2::EventFacet::Amnesty

赦免面是一个列表,而不是单个项目,这一点很重要,因为赦免可以同时来自多个地方。

对于每个赦免实例,details 字段解释了为何授予赦免。

注意:在格式化程序之外,赦免只起作用,以原谅失败的断言。

errors => [{...}, ...]

Test2::EventFacet::Error

错误面是一个列表,而不是单个项目,可以列出任意数量的错误。在此面中,details 描述了错误,或者可能包含原始错误消息本身(例如异常)。在 perl 中,异常可能是祝福对象,因此此面的原始数据可能包含嵌套的祝福项目。

并非所有错误都被认为是致命的,必须设置 fail 字段才能使错误导致测试失败。

注意:此面是唯一的,因为字段名称是 'errors',而包是 'Error'。这是因为这是唯一一个既是列表,又是名称的复数形式与单数形式不同的面类型。这可能会造成一些混淆,但我认为它比其他选择更不令人困惑。

info => [{...}, ...]

Test2::EventFacet::Info

“info” 面板是一个列表,而不是单个项目,任何数量的额外信息都可以附加到事件。一些信息可能是关键诊断信息,另一些可能只是评论性质的,这由 `debug` 标志决定。

对于此面板,`details` 标志是信息本身。此信息可以是字符串,也可以是用于显示的数据结构。这是少数几个可能包含祝福项目的方面类型之一。

LEGACY API

$bool = $e->causes_fail

如果此事件应导致测试失败,则返回 true。通常情况下,这应该是 false。

$bool = $e->increments_count

如果此事件应导致测试计数增加,则应为 true。

$e->callback($hub)

如果您的事件需要对 Test2::Hub 产生额外影响,您可以覆盖此方法。

这在您的事件传递给格式化程序 **之前** 被调用。

$num = $e->nested

如果此事件嵌套在其他事件中,则这应该是嵌套的深度。(这主要用于子测试)

$bool = $e->global

如果您的事件是全局的,请将其设置为 true,也就是说,所有线程和进程都应该看到它,无论何时何地生成它。这并不是一个常见的需求,它被 `bail-out` 和 `skip_all` 用于结束测试。

$code = $e->terminate

这在您的事件传递给格式化程序 **之后** 被调用。这通常应该返回 undef,只有在您的事件应该导致测试立即退出时才更改它。

如果您希望此事件导致测试退出,您应该在此处返回退出代码。退出代码 0 表示成功退出,任何其他整数表示失败退出。

这被 Test2::Event::Plan 用于在计划为 `skip_all` 时退出 0。这也被 Test2::Event:Bail 用于强制测试以失败退出。

这在事件被发送到格式化程序之后被调用,以确保事件被看到和理解。

$msg = $e->summary

这旨在成为事件的人类可读摘要。理想情况下,这应该只有一行长,但如果需要,您可以使用多行。这旨在供人类使用。您不需要让机器容易理解。

默认情况下,它只返回事件包名。

($count, $directive, $reason) = $e->sets_plan()

检查此事件是否设置了测试计划。如果它没有设置,它将返回一个空列表。如果它设置了计划,它将返回一个包含 1 到 3 个项目的列表,顺序为:预期测试计数、测试指令、指令原因。

$bool = $e->diagnostics

如果事件包含诊断信息,则为真。这很有用,因为非详细的测试工具可以选择隐藏不在此类别的事件。某些格式化程序可能会选择将这些信息发送到 STDERR 而不是 STDOUT,以确保它们被看到。

$bool = $e->no_display

默认情况下为假。对于格式化程序不应该显示的事件,这将返回真。

$id = $e->in_subtest

如果事件在子测试中,则应具有子测试 ID。

$id = $e->subtest_id

如果事件是最终的子测试事件,则应包含子测试 ID。

第三方元数据

此对象使用 Test2::Util::ExternalMeta,它提供了一种一致的方式,您可以使用它将元数据附加到此类的实例。这对工具、插件和其他扩展很有用。

来源

Test2 的源代码库可以在 http://github.com/Test-More/test-more/ 中找到。

维护者

Chad Granum <[email protected]>

作者

Chad Granum <[email protected]>

版权

版权所有 2020 Chad Granum <[email protected]>。

本程序是自由软件;您可以根据与 Perl 本身相同的条款重新发布和/或修改它。

参见 https://dev.perl5.cn/licenses/