如何在Rust中使用assert_eq!来显示多行字符串

huangapple go评论65阅读模式
英文:

How can I make assert_eq! in Rust show multiline strings

问题

以下是要翻译的内容:

我有以下的Rust单元测试:

    #[test]
    fn test_multiline_strings_are_equal() {
        let expected = "\
one
two
three
four
";
        let actual = "\
one
two
four
";
        assert_eq!(actual, expected);
    }

当它失败时,会输出以下内容:

---- printer::tests::test_multiline_strings_are_equal stdout ----
thread 'printer::tests::test_multiline_strings_are_equal' panicked at 'assertion failed: `(left == right)`
  left: "one\ntwo\nfour\n",
 right: "one\ntwo\nthree\nfour\n"', src\printer.rs:600:9

有人可以告诉我如何使它显示"one"、"two"、"three"和"four"在不同的行上,以便更容易进行比较吗?

英文:

I have the following Rust unit test:

    #[test]
    fn test_multiline_strings_are_equal() {
        let expected = "\
one
two
three
four
";
        let actual = "\
one
two
four
";
        assert_eq!(actual, expected);
    }

When it fails, it outputs the following:

---- printer::tests::test_multiline_strings_are_equal stdout ----
thread 'printer::tests::test_multiline_strings_are_equal' panicked at 'assertion failed: `(left == right)`
  left: `"one\ntwo\nfour\n"`,
 right: `"one\ntwo\nthree\nfour\n"`', src\printer.rs:600:9

Can anyone tell me how to make it show "one", "two", "three" and "four" on separate lines, for easier comparison?

答案1

得分: 7

The pretty_assertions库可以实现这一功能。只需添加以下代码:

use pretty_assertions::assert_eq;

其替代的 assert_eq! 宏将产生逐行差异;在你的示例中:

Diff < left / right > :
 one
 two
>three
 four

它还适用于非字符串值的 Debug 输出:

use pretty_assertions::assert_eq;

#[test]
fn test_struct() {
    #[derive(Debug, PartialEq)]
    struct Foo {
        x: &'static str,
        y: &'static str,
    }

    assert_eq!(
        Foo { x: "x", y: "y" },
        Foo {
            x: "x",
            y: "surprise!",
        }
    );
}
Diff < left / right > :
 Foo {
     x: "x",
<    y: "y",
>    y: "surprise!",
 }
英文:

The pretty_assertions library does this. Just add

use pretty_assertions::assert_eq;

and its replacement assert_eq! macro will produce a line-by-line diff; in your example:

Diff < left / right > :
 one
 two
>three
 four

It also works with the Debug output of non-string values:

use pretty_assertions::assert_eq;

#[test]
fn test_struct() {
    #[derive(Debug, PartialEq)]
    struct Foo {
        x: &'static str,
        y: &'static str,
    }

    assert_eq!(
        Foo { x: "x", y: "y" },
        Foo {
            x: "x",
            y: "surprise!",
        }
    );
}
Diff < left / right > :
 Foo {
     x: "x",
<    y: "y",
>    y: "surprise!",
 }

答案2

得分: 3

The assert_eq! 宏将在数值不相等时 "打印表达式的调试表示形式及其值"。这使用了 Debug 格式说明符,对于字符串,它会转义换行符和其他控制字符。因此,你不能在不使用某种使 Debug 实现使用 Display 实现的类型包装字符串的情况下覆盖它。

然而,一个替代方法是该宏允许你使用普通格式化语法提供自己的消息。因此,你可以提供非调试输出:

assert_eq!(actual, expected, "\n扩展左侧: {actual}\n扩展右侧: {expected}\n");
线程 'test_multiline_strings_are_equal' 在 'assertion failed: `(left == right)`
  left: `"one\ntwo\nfour\n"`,
 right: `"one\ntwo\nthree\nfour\n"`: 
 扩展左侧: one
two
four

扩展右侧: one
two
three
four

', src/lib.rs:14:5

这看起来有点奇怪,因为我不认为该宏真的期望自定义消息具有换行符(参见末尾的 src/lib.rs:14:5),但希望它能够工作得足够好。

如果这不够好,自己制作一个宏也不会太难。

英文:

The assert_eq! macro will "print the values of the expressions with their debug representations" if the values are not equal. This uses the Debug format specifier, which for strings will escape newlines and other control characters. So you can't override that without wrapping the strings in some type that makes the Debug implementation use the Display implementation.

An alternative though is the macro allows you to provide your own message using the normal formatting syntax. So you could provide the non-debug output as well:

assert_eq!(actual, expected, "\n expanded left: {actual}\nexpanded right: {expected}\n");
thread 'test_multiline_strings_are_equal' panicked at 'assertion failed: `(left == right)`
  left: `"one\ntwo\nfour\n"`,
 right: `"one\ntwo\nthree\nfour\n"`: 
 expanded left: one
two
four

expanded right: one
two
three
four

', src/lib.rs:14:5

It looks a bit weird since I don't think the macro was really expecting the custom message to have newlines (see the trailing ', src/lib.rs:14:5) but it hopefully it works well enough.

If that's not good enough, it wouldn't be too hard to make your own macro.

huangapple
  • 本文由 发表于 2023年5月13日 23:05:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76243409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定