exercism / rust-test-runner

GNU Affero General Public License v3.0
3 stars 15 forks source link

Tests are skipped if enough data is written to stdout #54

Closed roxgib closed 1 year ago

roxgib commented 2 years ago

TL;DR tests should fail if they exit because of excessive output.

I'm mentoring a student on the Rust track who submitted this code for the lasagna exercise:

pub fn remaining_minutes_in_oven(actual_minutes_in_oven: i32) -> i32 {
    let minutes_left_in_oven = expected_minutes_in_oven() - actual_minutes_in_oven;
     while actual_minutes_in_oven <= 40 {
         println!("The remaining minutes in the oven is: {} ", minutes_left_in_oven);
     }
    return minutes_left_in_oven
}

Of course this code will loop forever, printing each time. After some discussion it seems that a test is skipped if enough data is written to stdout. For this exercise Exercism shows "five tests passed" when there are six tests for this exercise. If you simply loop without printing anything the tests fail with a timeout as expected. I've reproduced this with a different exercise in Rust, but I assume it affect any language capable of writing fast enough to beat the timeout.

It's not uncommon for a student to accidentally submit code that gets stuck in a loop, and it'll be confusing for them if the tests pass just because they happen to have a print statement in there.

Edit: BTW I don't recommend running the above code locally for obvious reasons!

github-actions[bot] commented 2 years ago

Hi and welcome to Exercism! :wave:

Thanks for opening an issue :slightly_smiling_face:

iHiD commented 2 years ago

@roxgib Thanks. This is a bug in the rust test runner so I've moved this there. Feel free to PR a fix if you fancy digging into the code.

@ErikSchierboom Could you tag it up appropriately pls (you might also like to fix it if you fancy some Rust and @roxgib doesn't 🙂 ).

roxgib commented 2 years ago

@iHiD Thanks, I'll dig into it a bit today and see if it's something I can fix

sudhackar commented 2 years ago

I found the same problem with a solution a few days back while mentoring

#[derive(Debug, PartialEq)]
pub enum Error {
    SpanTooLong,
    InvalidDigit(char),
}
pub fn lsp(string_digits: &str, span: usize) -> Result<u64, Error> {
    if span > string_digits.len() { return Err(Error::SpanTooLong); }
    if span == 0 { return Ok(1); }
    for starting_index in 0..string_digits.len() {
        println!("start: {}", starting_index);
        while starting_index < span {
            let mut index = starting_index;
            print!("index: {} ", index);
            index += 1;
        }
    }
    Ok(0)
}

image There are more than 4 tests

ZloeSabo commented 2 years ago

Hey everyone, I've put together #55 to fix the issue. Could someone please take a look once you have a chance?