#tracing #async #tracing-subscriber #fluent-assertions

tracing-fluent-assertions

一种用于追踪的流畅断言框架

6个版本

0.3.0 2022年2月9日
0.2.0 2021年12月17日
0.1.3 2021年11月30日

#745 in 调试

Download history 4413/week @ 2024-03-14 4104/week @ 2024-03-21 3057/week @ 2024-03-28 4840/week @ 2024-04-04 3414/week @ 2024-04-11 9493/week @ 2024-04-18 13175/week @ 2024-04-25 11479/week @ 2024-05-02 13237/week @ 2024-05-09 15399/week @ 2024-05-16 16288/week @ 2024-05-23 17966/week @ 2024-05-30 13842/week @ 2024-06-06 13115/week @ 2024-06-13 15389/week @ 2024-06-20 13581/week @ 2024-06-27

每月 59,474 次下载

MIT 协议

36KB
637

tracing-fluent-assertions

tracing提供的流畅断言框架。

概述

虽然已经有许多包处理测试——模拟、测试双倍、高级断言等——但没有任何包允许用户从整体上了解其tracing实现是如何被使用的。虽然有一些包,如tracing-test,存在用于确定代码块是否发出了某些事件,但没有一种通用的方式来提出像

  • 跨度A是否曾经被创建或进入?
  • 它是否曾经关闭?
  • 它是否至少进入/退出/关闭了N次?
  • 模块路径X中的任何跨度是否曾经被创建?

这就是tracing-fluent-assertions旨在解决的问题。

用法

这个包与提供流畅断言的其他包看起来没有太大区别,但由于它围绕跨度展开,跨度是调用点定义的,因此在使用它时需要一些样板代码,与直接针对函数的结果等定义断言相比,使用起来稍微复杂一些。

首先,它提供了一个必须安装的Subscriber层,以便它可以拦截跨度事件并跟踪跨度的生命周期。其次,提供了一个AssertionRegistry,用于创建和存储断言。

一个Assertion定义了它应该匹配哪些跨度,以及跨度必须匹配哪些行为才能成功断言。

简化的使用可能看起来像这样

use tracing_fluent_assertions::{AssertionLayer, AssertionRegistry};
use tracing_subscriber::{layer::SubscriberExt, Registry};

fn main() {
    // Create the assertion registry and install the assertion layer,
    // then install that subscriber as the global default.
    let assertion_registry = AssertionRegistry::default();
    let base_subscriber = Registry::default();
    let subscriber = base_subscriber.with(AssertionsLayer::new(&assertion_registry));
    tracing::subscriber::set_global_default(subscriber).unwrap();

    // Create an assertion.  We'll look for a span called `shave_yak`,
    // and assert that it's closed at least twice, signalling two full
    // create/enter/exit/closed instances of the span.  Essentially, at
    // least two yaks were completely shaved.
    let more_than_one_shaved_yak = assertion_registry.build()
        .with_name("shave_yak")
        .was_closed_many(2)
        .finalize();

    // Now, call our method that actually shaves the yaks.
    shave_yaks(5);

    // Assuming all five yaks were shaved, this assertion will pass,
    // and no panic will be generated, yay!
    more_than_one_yak_shaved.assert();

    // An advanced usage of assertions can be to figure out when a span
    // has finally been entered.  This can be useful for ascertaining when
    // an asynchronous function has made it through other await points and
    // is now waiting at a piece of code that we control, with its own span.
    //
    // For this, we can use the fallible `try_assert`, which won't panic
    // if the assertion criteria has yet to be entirely met:
    let reached_acquire_shaving_shears = assertion_registry.build()
        .with_name("acquire_shaving_shears")
        .was_entered()
        .finalize();

    let manual_future = shave_yaks_async(5);

    assert!(!reached_acquire_shaving_shears.try_assert());
    while !reached_acquire_shaving_shears.try_assert() {
        manual_future.poll();
    }

    // Once we break out of that loop, we know that we have entered the
    // `acquire_shaving_shears` span at least once.  This example is a bit
    // contrived, but a more useful scenario (albeit with more code required
    // to demonstrate) would be to figure out that one asynchronous task is
    // finally awaiting a specific resource, when it has to await other resources
    // that can't be deterministically controlled when under test.
}

依赖项

~1MB
~18K SLoC