rust-based-os-comp2022 icon indicating copy to clipboard operation
rust-based-os-comp2022 copied to clipboard

Rustlings advanced_errs2测试是否不够严谨

Open QIUZHILEI opened this issue 3 years ago • 3 comments

#[test] fn test_empty() { let res = "".parse::<Climate>(); assert_eq!(res, Err(ParseClimateError::Empty)); assert_eq!(res.unwrap_err().to_string(), "empty input"); }

#[test] fn test_short() { let res = "Boston,1991".parse::<Climate>(); assert_eq!(res, Err(ParseClimateError::BadLen)); assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields"); } 应该在加一个测试,测试的res为 "Boston",原因如下:

如果写的模式匹配是这样的:

fn from_str(s: &str) -> Result<Self, Self::Err> { let v: Vec<_> = s.split(',').collect(); let (city, year, temp) = match &v[..] { [some_str] => return Err(ParseClimateError::Empty), //some_str 可能是"" 或 "Boston" …… }; …… } 考虑以上匹配,如果按照原来的测试,给定的字符串是"",应该返回Empty 错误,但是如果给定的字符串是"Boston",那么也会匹配成功,但是应该返回的是BadLen错误

QIUZHILEI avatar Jul 09 '22 11:07 QIUZHILEI

我采取了不一样的处理方法,将字符串长度进行了单独处理,因此我觉得目前的测试案例已经比较完善,Empty的处理优先级应该是最高。因此在最开始进行处理会更好?

fn from_str(s: &str) -> Result<Self, Self::Err> {
    if s.len() == 0 {
        return Err(ParseClimateError::Empty);
    }
    let v: Vec<_> = s.split(',').collect();
    let (city, year, temp) = match &v[..] {
        ["", ..] => return Err(ParseClimateError::NoCity),
        [city, year, temp] => (city.to_string(), year, temp),
        _ => return Err(ParseClimateError::BadLen),
    };
    let year: u32 = year.parse()?;
    let temp: f32 = temp.parse()?;
    Ok(Climate { city, year, temp })
}

yfblock avatar Jul 09 '22 13:07 yfblock



//match这样写 也可以通过测试
     let (city, year, temp) = match &v[..] {
          [_] => return Err(ParseClimateError::Empty),
          ["",_,_]=> return Err(ParseClimateError::NoCity),
          [city, year, temp] =>(city.to_string(), year, temp),
          _ => return Err(ParseClimateError::BadLen),
      };
//如果你加一个这样的测试
    #[test]
    fn test_only_city(){
        let res = "Paris".parse::<Climate>();
        assert_eq!(res, Err(ParseClimateError::BadLen));
        assert_eq!(res.unwrap_err().to_string(), "incorrect number of fields");
    }

会测试失败

---- test::test_only_city stdout ----
thread 'test::test_only_city' panicked at 'assertion failed: `(left == right)`
  left: `Err(Empty)`,
 right: `Err(BadLen)`', src\main.rs:153:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

//我的match这样写的 ,加了那个测试也会成功 ,你的那个也会成功

    let (city, year, temp) = match &v[..] {
          [""] => return Err(ParseClimateError::Empty),
          ["",_,_]=> return Err(ParseClimateError::NoCity),
          [city, year, temp] =>(city.to_string(), year, temp),
          _ => return Err(ParseClimateError::BadLen),
      };

//所以第一个的match那样写应该有问题,但是不加那个测试就不会出问题 PS:这也是今天下午群里的人提出来的问题,我测试了一下,果真如此

QIUZHILEI avatar Jul 09 '22 14:07 QIUZHILEI

//这是写的那个 from_str
fn from_str(s: &str) -> Result<Self, Self::Err> {
        let v: Vec<_> = s.split(',').collect();
        let (city, year, temp) = match &v[..] {
            [""] => return Err(ParseClimateError::Empty),
            ["",_,_]=> return Err(ParseClimateError::NoCity),
            [city, year, temp] =>(city.to_string(), year, temp),
            _ => return Err(ParseClimateError::BadLen),
        };
        let year: u32 = year.parse()?;
        let temp: f32 = temp.parse()?;
        Ok(Climate { city, year, temp })
    }

QIUZHILEI avatar Jul 09 '22 14:07 QIUZHILEI