Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Testing Output With RSpec
Elle Hallal 👩🏽‍💻
Elle Hallal 👩🏽‍💻

Posted on • Originally published atellehallal.dev on

     

Testing Output With RSpec

Originally posted atellehallal.dev👩🏽‍💻


This is a quick blog on testing output with RSpec. Currently, I am working on aTic Tac Toe game in Ruby, where a user can play against a computer.


Previous test attempts

I’ve experienced issues testing a loop in the game, where it keeps requesting moves from players until the board is full or a player has won.

defmain_gameplay_moveuntil@game.over?end_of_gameend
Enter fullscreen modeExit fullscreen mode

One attempt at testing this was to spy on theplay_move andend_of_game methods. This worked fine if a full board was provided.

However, this was proving difficult to test when an incomplete board was present. Despite simulating user input, the test would hang at this stage. The same issue occurred when usingobject doubles.


Testing output

One of my mentors suggested testing the output of theend_of_game method. Theend_of_game method prints the Tic Tac Toe board and the outcome of the game.

it'playsagamethatendswithawinningplayer'doexpect{controller.main_game}.tooutput("""  1 | x | x----------------  o | o | x----------------  x | o | oThe current player is xChoose a position from 1-9:  x | x | x----------------  o | o | x----------------  x | o | ox is the winner!""").to_stdout
Enter fullscreen modeExit fullscreen mode

The multi-lines and alignment was also proving difficult to get right for the expected output. The key element that needed to be tested was the outcome of the game, which was the last line of the output: 'x is the winner!'


StringIO

StringIO is a ‘string-based replacement for an IO object. It acts same as a file, but it’s kept in memory as a String’.

The idea is to catch the stream of output and redirect it. To check the last line of the output was correct, my mentor suggested trying the following:

it'playsagamethatendswithawinningplayer'docontroller=controller_setup([1,'x','x',4,'o','x','x',8,'o'])allow($stdin).toreceive(:gets).and_return('8','4','1')$stdout=*StringIO*.newcontroller.main_gameoutput=$stdout.string.split("\n")expect(output.last).toeq('xisthewinner!')end
Enter fullscreen modeExit fullscreen mode

In this test:

  • A new instance of thecontroller class is created, with an incomplete board

  • The input is simulated to play the three remaining positions on the board

  • The standard output$stdin is redirected to a new instance ofStringIO

  • Themain_game method is called to play and complete the game

  • The output is then saved to the variableoutput, converted to a string, and split at the points where there is a new line to create an array of strings

  • The last item in the array is expected to be 'x is the winner!'

I’ll continue to use this method when testing large blocks of text with multiple lines. It’s significantly simpler than trying to align multi-line outputs in a test.


Resources

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Senior Software Engineer. Leadership Team Member & Mentor at Coding Black Females 👩🏽‍💻
  • Location
    London, UK
  • Work
    Senior Software Engineer at 8th Light
  • Joined

More fromElle Hallal 👩🏽‍💻

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp