rust 如何Assert代码不会在测试中编译?

4nkexdtk  于 2023-01-05  发布在  其他
关注(0)|答案(3)|浏览(140)

我目前正在编写一些不安全的代码,需要一定程度的手动管理生存期,并将这些生存期暴露给外部用户。我一直在编写测试,虽然编写测试来验证编译代码的正确性非常容易(至少在未定义行为的可能性允许的范围内),但我一直在寻找确保某些类型的不健全代码无法编译的方法。
假设我有以下人为的例子:

pub struct MyBox<T> {
    ptr: *mut T,
}

impl<T> MyBox<T> {
    fn new(t: T) -> Self {
        MyBox {
            ptr: Box::into_raw(Box::new(t)),
        }
    }
    fn get(&self) -> &T {
        unsafe { &*self.ptr }
    }
}
impl<T> Drop for MyBox<T> {
    fn drop(&mut self) {
        unsafe { Box::from_raw(self.ptr) }
    }
}

fn test<'a>() -> &'a i32 {
    MyBox::new(7).get()
}

我如何确保test函数在rust的测试框架中继续编译失败?
显然,将错误代码放到一个单独的文件中,并使用实际的测试函数作为美化的构建脚本是可行的,但这会变得非常繁琐和笨拙,特别是当我想要测试的坏例子不止一两个时。如果这有帮助,我不关心错误的细节,只关心错误是否存在。

b0zn9rqh

b0zn9rqh1#

您可以将其编写为带有compile_fail attr的doctest,这样您就可以在注解中编写多个预期会同时失败的测试。

/// ```compile_fail,E0515
/// use path_to::MyBox;
///
/// fn test<'a>() -> &'a i32 {
///     MyBox::new(7).get()
/// }
/// ```
fn _doc_test() {}

,E0515表示您期望的错误号,它可以避免任何其他可能导致测试假阴性的错误。(如果货物不是夜间运行,则将忽略此错误号检查)
注意,这要求您的机箱是lib而不是bin,因为doctests当前不支持bin。(问题#50784

sirbozc5

sirbozc52#

如果您确实关心编译器发出的特定错误,另一种方法是使用trybuild

cwxwcias

cwxwcias3#

您可以在doc-test中使用compile_fail注解编写测试函数:

pub struct MyBox<T> {
    ptr: *mut T,
}

/// ```compile_fail
/// fn test<'a>() -> &'a i32 {
///     playground::MyBox::new(7).get()
/// }
/// ```
impl<T> MyBox<T> {
    fn new(t: T) -> Self {
        MyBox {
            ptr: Box::into_raw(Box::new(t)),
        }
    }
    fn get(&self) -> &T {
        unsafe { &*self.ptr }
    }
}
impl<T> Drop for MyBox<T> {
    fn drop(&mut self) {
        unsafe { Box::from_raw(self.ptr) }
    }
}

Playground
但是请注意,您只能以这种方式测试公共函数。

相关问题