程序测试

测试属性

在测试函数前加上#[test]属性:

  1. #[test]
  2. fn it_works() {
  3. assert!(false);
  4. }

其中assert!宏接受一个参数,如果参数为false,它会导致panic!
运行cargo test命令,可见该测试失败。如果要反转测试失败,
可以加上#[should_panic]属性:

  1. #[test]
  2. #[should_panic(expected = "assertion failed")]
  3. fn it_works() {
  4. assert_eq!("Hello", "world");
  5. }

测试模块

在测试模块前加上#[cfg(test)]属性:

  1. pub fn add_two(a: i32) -> i32 {
  2. a + 2
  3. }
  4. #[cfg(test)]
  5. mod test {
  6. use super::add_two;
  7. #[test]
  8. fn it_works() {
  9. assert_eq!(4, add_two(2));
  10. }
  11. }

测试目录

对于集成测试,可以新建一个tests目录,这样其中的代码就不需要再引入单元风格的测试模块了。

文档测试

对于包含有测试例子的注释文档中,运行cargo test时也会运行其中包含的测试。

  1. //! The `adder` crate provides functions that add numbers to other numbers.
  2. //!
  3. //! # Examples
  4. //!
  5. //! ```
  6. //! assert_eq!(4, adder::add_two(2));
  7. //! ```
  8. /// This function adds two to its argument.
  9. ///
  10. /// # Examples
  11. ///
  12. /// ```
  13. /// use adder::add_two;
  14. ///
  15. /// assert_eq!(4, add_two(2));
  16. /// ```
  17. pub fn add_two(a: i32) -> i32 {
  18. a + 2
  19. }

错误处理

Rust明确区分两种形式的错误:失败 (failture) 和恐慌 (panic)。
失败是可以通过某种方式恢复的错误,而恐慌(panic)则不能够恢复。

最简单的表明函数会失败的方法是使用Option<T>类型:

  1. fn from_str<A: FromStr>(s: &str) -> Option<A> {
  2. }

其中from_str()返回一个Option<A>。如果转换成功,它会返回Some(value)
如果失败,直接返回None。对于需要提供出错信息的情形,可以使用Result<T, E>类型:

  1. enum Result<T, E> {
  2. Ok(T),
  3. Err(E),
  4. }

如果不想处理错误,可以使用unwrap()方法来产生恐慌:

  1. let mut buffer = String::new();
  2. let input = io::stdin().read_line(&mut buffer).unwrap();

ResultErr时,unwrap()panic!,直接退出程序。另一个更好的做法是:

  1. let input = io::stdin().read_line(&mut buffer)
  2. .ok()
  3. .expect("Failed to read line");

其中ok()Result转换为Optionexpect()unwrap()功能类似,
可以用来提供更多的错误信息。

此外,还可以使用宏try!来封装表达式,当ResultErr时会从当前函数提早返回Err