有没有办法检测是否正在从 Rust 的测试中调用代码?

编程入门 行业动态 更新时间:2024-10-11 11:22:57
本文介绍了有没有办法检测是否正在从 Rust 的测试中调用代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我希望能够在我的代码本身中检查它是否正在从测试中运行.这样做是理想的,例如,与测试数据库、Web 服务等交互.一个简单的 bool 就足够了.

I'd like to be able to check within my code itself whether or not it is running from a test. It would be ideal to do this, for example, to interface with test databases, web services, etc. A simple bool would suffice.

Rust 是否有用于此的现有 API?

Does Rust have an existing API for this?

推荐答案

测试的运行时检测

运行测试时没有设置全局变量.您可以添加一个,但要正确处理非常复杂.这个例子没有完全正确:

Runtime detection of tests

There's no global variable that is set when running tests. You could add one, but it's pretty complicated to get it right. This example does not get it completely right:

use std::cell::Cell; thread_local! { pub static IS_TESTING: Cell<bool> = Cell::new(false); } fn my_code() -> u8 { if IS_TESTING.with(|t| t.get()) { 0 } else { 42 } } #[test] fn one() { IS_TESTING.with(|t| t.set(true)); assert_eq!(0, my_code()); IS_TESTING.with(|t| t.set(false)); }

要正确执行此操作,您需要处理以下事项:

To do this correctly, you need to handle a few things:

  • 测试是在多线程环境中运行的,因此您需要确保自己处理好.
  • 如果您的代码产生新线程,则使用线程本地可能是不正确的,因为变量不会传递给它们.
  • 即使测试因断言失败而提前中止,您也需要确保将标志设置回 false.
  • Tests are run in a multithreaded environment, so you need to make sure that you handle that.
  • Using a thread-local is probably incorrect if your code spawns new threads, as the variable won't carry over to them.
  • You need to make sure to set the flag back to false even when the test aborts early due to an assertion failure.
  • 测试的编译时间检测

    更有可能的是,您想要检测您是否正在编译进行测试.这要简单得多,而且您可能已经在使用相同的技术来有条件地自行编译测试:

    Compile time detection of tests

    More likely, what you want is to detect if you are compiling for tests. This is much simpler and you are probably already using the same technique to conditionally compile your tests themselves:

    fn my_code() -> u8 { if cfg!(test) { 0 } else { 42 } } #[cfg(test)] mod test { use super::*; #[test] fn one() { assert_eq!(0, my_code()); } }

    依赖注入更好

    在编辑上,从代码质量的角度来看,运行时或编译时检测是一个坏主意.与其用大量条件检查乱扔代码,这会使代码复杂化甚至减慢代码速度,不如引入依赖注入:

    trait ValueSource { fn value(&self) -> u8; } struct ProductionSource; impl ValueSource for ProductionSource { fn value(&self) -> u8 { 42 } } fn my_code<S>(source: S) -> u8 where S: ValueSource, { source.value() } #[cfg(test)] mod test { use super::*; struct TestSource(u8); impl ValueSource for TestSource { fn value(&self) -> u8 { self.0 } } #[test] fn one() { let src = TestSource(99); assert_eq!(99, my_code(src)); } }

    这会将相关细节集中到一个对象中,编译器会对调用进行单态化,从而生成优化的代码.

    This will concentrate related details into one object and the compiler monomorphizes the calls, producing optimized code.

    • 如何测试标准输入和标准输出?
    • 是否有更简洁的方法来测试使用需要用户在 Rust 中输入的函数的函数?
    • 有没有办法模拟 Java 行为,即调用父类的静态方法以进行简单的全局错误处理?

    更多推荐

    有没有办法检测是否正在从 Rust 的测试中调用代码?

    本文发布于:2023-06-03 23:43:02,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/485000.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:没有办法   代码   测试中   Rust

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!