Giter Club home page Giter Club logo

ruby_testing's Introduction

RSpec Playground

The purpose of this repository is to provide 'hands-on' RSpec lessons. These lessons were designed to equip students of the The Odin Project to write tests for their Tic-Tac-Toe and to TDD their Connect Four.

Topics

These lessons cover many topics, but it does not cover everything that RSpec is capable of testing. You should expect to learn foundational knowledge on the following topics:

  • Let Variables
  • Implicit and Explicit Subject
  • A variety of built-in-matchers
  • Setting values for instance variables to create test conditions
  • The 'Arrange, Act & Assert' testing pattern
  • Stubs, Mocks, and Doubles
  • Test Driven Development

Set-Up

Run rbenv versions to confirm that you have ruby version 3.2.2 installed. If you do not have this version installed, please refer back to these instructions to install it.

Run bundle install from the root directory.

How to use this playground

These lessons are numbered 01 - 16, in the spec folder. Start with the file: spec/01_string_spec.rb. The first 9 lessons are self-contained in the spec file. Starting with lesson 10, there will be 1-3 corresponding files in the lib folder.

If you get stuck on a lesson, there is a corresponding answer file located in the spec_answer folder.

Running Tests

Since this repository is full of tests, it is recommended to only run rspec on one individual file at at time. For example, to run the first test file from the root of this directory:

rspec spec/01_string_spec.rb

Tip: If you have tab completion set-up, you can hit 'tab' after the first few characters of the file name.

ruby_testing's People

Contributors

analyticalgoose avatar asartea avatar chargrilledchook avatar couchoftomato avatar crespire avatar dm-murphy avatar eduardo06sp avatar hykare avatar i3uckwheat avatar imfae avatar jee-el avatar joshdevhub avatar k-eversole avatar kevinmulhern avatar killzabit avatar lrdvnz avatar lukeshann avatar macauleydev avatar maheshkumar-novice avatar mehmetsamilerturk avatar mfm051 avatar mlgabe avatar moosecowbear avatar nikemman avatar rlmoser99 avatar scheals avatar thatblindgeye avatar uaitt avatar wwrk22 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby_testing's Issues

Use of instance_variable_set in testing?

Is using instance_variable_set a code smell, when used only in testing? For example:

Is it better to have @guess as a parameter, to be able to easily create a new instance of game for tests subject(:game) { described_class.new(0, 9, 4) }

def initialize(min, max, guess = nil)
  @min = min
  @max = max
  @guess = guess
end

Or is it better to have less arguments and to use game.instance_variable_set(:@guess, 4) in the few tests that require a value for @guess?

def initialize(min, max)
  @min = min
  @max = max
  @guess = nil
end

Typo

Hello @rlmoser99,

I know trivial, but I noticed the following typo on line 24 of proposal.md:

"but have been completed changed." - should this be completely?

Overall Concerns

These lessons need a thorough review to verify that the information & explanations are correct. Here is a list of particular areas that concern me:

  • These lessons may "spoon feed" more information than necessary.
  • The first 9 lessons are very simple ones and could be more of a hindrance/annoyance to some students.
  • Lesson 11 uses a shared example for multiple classes, which is not essential to Tic-Tac-Toe or Connect Four.
  • Lessons 13 - 16 explains a lot of different concepts like stubs, message expectations, doubles, TDD, class encapsulation, polymorphism, testing methods in module, etc.
  • Lesson 15 & 16 explains what methods should & should not be tested for these ruby terminal games, which is slightly different than in the "real world". (We could also change these lessons to instruct students to have all the procedural interaction code in a script and focus on having behavior and logic in classes, at least until this change happens in the OOP lessons)

The phrase 'publicly tested' is confusing to learners

Complete the following REQUIRED checkboxes:

  • I have thoroughly read and understand The Odin Project Contributing Guide
  • The title of this issue follows the location for request: brief description of request format, e.g. Exercises: Add exercise on XYZ

The following checkbox is OPTIONAL:

  • I would like to be assigned this issue to work on it

In 15a_binary_game_spec there is an explanation for why methods called from a game script method should be public and tested. The phrase used for this is 'publicly tested'. Someone asked about this on discord recently which reminded me I also didn't understand it when going through the exercises.

The wording is:

# full game. Since these methods are required to play the game, they should be
# publicly tested methods (even if you previously made them private). Pretend
# that someone will be using your class to make their own game with customized
# text. Any method that they would need in their game should be a publicly
# tested method.

I think it could be more explicit:

# full game. Since these methods are required to play the game, they should be
# tested and made public (even if you previously made them private). Pretend
# that someone will be using your class to make their own game with customized
# text. Any method that they would need in their game should be part of the
# public interface and have test coverage.

I hope I got that right, this is how I understand it now after finishing the ruby section.

There's one more mention of publicly tested on line 78, but I think that one could be left in. That way people have a detailed explanation but are still exposed to different wordings.

link to the discord discussion:
https://discordapp.com/channels/505093832157691914/704694487477387344/1019657256507281468

01_string_spec.rb - let helper explanation

The explanation of let in the string_spec lesson states it creates a variable that returns the computed value.

It actually creates a helper method with a memoized value that is cached for the same example but not across different examples.

In the example where favorite_color is set to 'navy blue' it is just creating a local variable and isn't related to the helper method created by let.

Bug - Exercises: Link to RelishApp doc for RSpec version older than Gemfile RSpec version

Complete the following REQUIRED checkboxes:

  • I have thoroughly read and understand The Odin Project Contributing Guide
  • The title of this issue follows the Bug - location of bug: brief description of bug format, e.g. Bug - Exercises: File type incorrect for all test files

The following checkbox is OPTIONAL:

  • I would like to be assigned this issue to work on it

1. Description of the Bug:

02_array_spec.rb on line 6, links to a relishapp doc for RSpec 2.11. The included Gemfile for the exercise uses RSpec 3.9. 1 example fails, where it should pass.

rspec_failing_example

2. How To Reproduce:

Run RSpec for this example: nested_subject_spec.rb in the ruby_testing project

3. Expected Behavior:

The examples should all pass.

4. Desktop/Device:

  • Device: Desktop
  • OS: Ubuntu 22.04.2 LTS
  • Browser: Chrome
  • Version: Chrome Version 113.0.5672.63 (Official Build) (64-bit)

5. Additional Information:

It looks like the behaviour of a subject in a nested group changed between RSpec 2.11 and RSpec 3.9,
from '(outermost wins)' to '(innermost wins)': RSpec 3.9 doc

Clarify the difference between subject and let

Suggestion made by programmurr, for Lesson 3:

Let and subject are explained, but the difference in using them under the 'describe' headers isn't really.
At a very superficial glance, they could be thought of as interchangeable.

I just grabbed this post on SO that helps explain the differences between them, but maybe there are better resources out there.
https://stackoverflow.com/questions/38437162/whats-the-difference-between-rspecs-subject-and-let-when-should-they-be-used

Bug - Relishapp Links not working

Complete the following REQUIRED checkboxes:

  • I have thoroughly read and understand The Odin Project Contributing Guide
  • The title of this issue follows the Bug - location of bug: brief description of bug format, e.g. Bug - Exercises: File type incorrect for all test files

The following checkbox is OPTIONAL:

  • I would like to be assigned this issue to work on it

1. Description of the Bug:

Relishapp, which hosts docs for RSpec that are linked throughout these exercises, is down and has been continuously down for about a week. Given the length of the outage, I think it's a good idea to consider some alternative.

More potential context: thread from r/ruby on the outage

2. How To Reproduce:

Visit any link to Relishapp

3. Expected Behavior:

N/A

4. Desktop/Device:
N/A

5. Additional Information:

  • Maybe the simplest solution would be to replace the current links with a Web Archive snapshot to relishapp.
  • There are 39 relishapp links in this repo. You can list them by doing grep -rno relishapp . in the root of this repo. That output will show the filenames and line numbers for each relishapp link.

Exercises: Further resource for RSpec mock

Complete the following REQUIRED checkboxes:

  • I have thoroughly read and understand The Odin Project Contributing Guide
  • The title of this issue follows the location for request: brief description of request format, e.g. Exercises: Add exercise on XYZ

The following checkbox is OPTIONAL:

  • I would like to be assigned this issue to work on it

1. Description of the Feature Request:
I think the explanation and linked resources for stub and mock in Exercise 13_ input_output are a little too technical and non-intuitive for the uninitiated beginner. It was difficult for me to understand why I might even need stub and mock and where they should be used when I first took the exercise.

For a simpler explanation -- both in words and in code, I found a resource online The ‘no problemo’ basic guide to doubles and stubs in RSpec that illustrated the concept of mock in a manner that's much more intuitive (and fun). I suggest adding it to the list of stub/mock resources in the exercise.

2. Acceptance Criteria:

3. Additional Information:

Remove one-line syntax & implicit subject

Suggestion made by programmurr, for Lesson 2:

I suggest removing the one-line syntax. I didn't know it existed until I saw this ha! That's great, I learned something new, but I think for beginning beginners (unlike experienced beginners like me lol), I think it's better just to focus on multi-line. Maybe mention one-line in a comment, but as the focus is on implicit/explicit subjects, keep the learners focused on that.

The implicit subject will come back up later on in lesson 11, but at the same time, I have even thought about removing #11 from the course too. As it is not required to use in tic-tac-toe or connect four.

Fix typos

Spec files 11a_shared_example_spec.rb, 11b_cat_spec.rb, and 11c_dog_spec.rb all have typos on lines 5, 8, and 8 respectively where, I believe, 15 should read 11. I believe, spec file 12_magic_seven_spec.rb is missing the word 'what' on line 52.

Bug - BinaryGame Spec: Comment indicating the method type for #display_turn_order is incorrect

Complete the following REQUIRED checkboxes:

  • I have thoroughly read and understand The Odin Project Contributing Guide
  • The title of this issue follows the Bug - location of bug: brief description of bug format, e.g. Bug - Exercises: File type incorrect for all test files

The following checkbox is OPTIONAL:

  • I would like to be assigned this issue to work on it

1. Description of the Bug:

File: ./spec/15a_binary_game_spec.rb
Example Group: describe '#display_turn_order' do
Issue: The first comment line says # This method is a Looping Script Method. but this seems to be indicating the method type for #display_binary_search as shown in the comment # Looping Script Method -> Test the behavior of the method (for example, it under the example group describe '#display_binary_search' do.
The method #display_turn_order seems to be a combination of Command Method and Script Method. If this is correct then the lines:

# This method is a Looping Script Method. In #display_binary_search,
# #display_turn_order will loop until binary_search.game_over?

should be changed to something similar to:

# This method is both a Command Method and a Script Method. It changes the
# observable state by incrementing the instance variable @guess_count by one,
# sends two command messages #make_guess and #update_range to the
# object binary_search of class BinarySearch, and sends one command
# message to `self` by calling #display_guess.

2. How To Reproduce:

N/A

3. Expected Behavior:

N/A

4. Desktop/Device:

  • Device:
  • OS:
  • Browser:
  • Version:

5. Additional Information:

N/A

.not_to/.to_not inconsistency

Throughout all of the lessons I have done so far, .not_to has always been used (as far as I have noticed) but in 10_drink_answer.rb on the 'is not full' test, .to_not is used.

On the Introduction to RSpec lesson at the end of the Basic syntax subsection, this is even said:
"The expect method is also chained with .to for positive expectations, or .to_not/.not_to for negative expectations. We prefer .not_to."

Using send for private methods?

If you have a method that could be private, but should be tested, for example because it is sending an outgoing command message. Should it be public so that it is easily tested or private and use send in RSpec to test?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.