英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论