Input / Output Tests

This is an example of how you can mock input values and test the output stream of student code.

The student must use the puts function to prompt the user for their first name, then use gets.chomp to collect the first name without a newline attached, and again for their last name. Then, print Hello, firstname lastname! including the person's first and last name.

Sample Run:

What is your first name?
Jane
What is your last name?
Doe
Hello, Jane Doe!

It assumes the student's file name is example.rb. Replace the require with whatever your student's file name is.

Note: This code converts the output to all lowercase and removes spaces to compare against the correct value.

Grading Tests:

require 'rspec'
require 'stringio'

student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end

RSpec.describe "CodingRoomsUnitTests" do

    describe 'Giving code Jane and Doe as inputs' do
        it "output should equal 'Hello, Jane Doe!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Jane"
            input.puts "Doe"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Jane Doe!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

    describe 'Giving code Joe and Mazzone as inputs' do
        it "output should equal 'Hello, Joe Mazzone!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Joe"
            input.puts "Mazzone"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Joe Mazzone!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

end

RSpec, the unit testing framework we are using, seems to have a hard time replacing the standard input stream. That is why you see this code at the beginning of our test file.

student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end

To allow RSpec to load a new standard input stream, we need to replace all instances of gets and use $stdin.gets. Instead of teaching students to not use gets and always use $stdin.gets, we can simply add the above code to replace all instances of gets with $stdin.gets.

Note: On Coding Rooms, the testing instance copies the student code so the above doesn't actually modify the student submission, it just changes it for the test. Other platforms or your local may behave differently.

Sample Solution:

example.rb
puts 'What is your first name?'
firstname = gets.chomp

puts 'What is your last name?'
lastname = gets.chomp

puts 'Hello, ' + firstname + " " + lastname + "!"

Last updated