Skip to content

Instantly share code, notes, and snippets.

@leahgarrett
Last active March 29, 2019 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leahgarrett/06fe68fabd3589f7bdd6ea477b8ac8d1 to your computer and use it in GitHub Desktop.
Save leahgarrett/06fe68fabd3589f7bdd6ea477b8ac8d1 to your computer and use it in GitHub Desktop.
Minitest Review and challenge solutions

minitest review

  • testing is a part of ruby best practice

  • manual testing does not scale

  • TDD - Test Driven Development

  • Unit Tests

  • Integration Tests

  • Test Coverage

    • test for behaviour, 100% coverage is not required
  • where to write tests

We have been writing tests with the classes we have written.

Automated testing options

  • minitest

    • the default in Rails
    • part of xUnit test family eg: jUnit, nUnit etc
    • uses conventions
      • files are named after the class under test ie: class_name_test.rb
      • tests are named after the method they are testing test_method_name
      • Rails scripts will run all files that end in _test.rb
      • add the require for the monitest gem at the top of the test file require 'minitest/autorun'
      • add the require for the class under test
  • tests can help describe the expected behaviour of an app

New ruby syntax:

Inheritance

  • Inheritance a common pattern when using frameworks
  • we will use it a lot when using Rails
  • more next week when we look at the MVC design pattern

Example where we used inheritance

  class ProductTest < MiniTest::Test


.

Class method call

StringValidator.valid_email(email)

In the following example

  • class method declaration
  • const variable in a class (freeze is a rubocop tip)
# class to hide the regex details
class StringValidator
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.freeze
  def self.valid_email(email_string)
    email_string =~ VALID_EMAIL_REGEX
  end
end

Regex and strftime

  • not necessarily something you will need to use very often
  • good to know they exist and you kind find details on how to use them online

References

Test Driven Development: what it is, and what it is not

class AuctionItem
attr_reader :name, :reserve_price, :sold_price, :description
def initialize(csv_row)
@name = csv_row[:name]
@reserve_price = csv_row[:reserve_price].to_f
@sold_price = csv_row[:sold_price].to_f
@description = csv_row[:description]
end
def is_sold?
@sold_price > 0
end
end
require 'minitest/autorun'
require 'faker'
require_relative 'auction_item'
class AuctionItemTest < MiniTest::Test
def setup
@paragraph = Faker::Lorem.paragraph
@unsold_item = AuctionItem.new({
:name => 'Sample',
:reserve_price => '10.99',
:sold_price => 0.0,
:description => @paragraph,
})
@sold_item = AuctionItem.new({
:name => 'Other Sample',
:reserve_price => '10.99',
:sold_price => '200',
:description => @paragraph,
})
end
def test_name
assert_equal 'Sample', @unsold_item.name
end
def test_reserve_price
assert_equal 10.99, @unsold_item.reserve_price
end
def test_sold_price
assert_equal 0.0, @unsold_item.sold_price
end
def test_description
assert_equal @paragraph, @unsold_item.description
end
def test_is_sold?
failure_message = "Failed when checking is_sold on unsold item"
assert(@unsold_item.is_sold? == false, failure_message)
failure_message = "Failed when checking is_sold on sold item"
assert(@sold_item.is_sold? == true, failure_message)
end
end
# Create a class for AussieDate
# Keep adding code to create and implement methods until all the tests pass
# Beast
# Add more values to AuctionItem such as owner_name, purchase_date etc. For each one
# - add the test
# - add the implementation
# - use Faker to make the data
require 'date'
# class to hide the strftime details
class AussieDate
def initialize(year, month, day, hour = 0, min = 0)
@date = DateTime.new(year, month, day, hour, min)
end
def formal_formatted_date
@date.strftime("%A, %B #{ordinalize(@date.day)}, %Y")
end
def short_formal_formatted_date
@date.strftime("%B #{ordinalize(@date.day)}, %Y")
end
def short_date
@date.strftime("%-d/%-m/%Y")
end
def short_date_time
@date.strftime("%-d/%-m/%Y %H:%M")
end
def ordinalize(day)
return "#{day}th" if day == 11 || day == 12
test = day % 10
case test
when 1 then "#{day}st"
when 2 then "#{day}nd"
when 3 then "#{day}rd"
else return "#{day}th"
end
end
end
require 'minitest/autorun'
require_relative 'aussie_date'
class AussieDateTest < MiniTest::Test
def setup
@aussie_date = AussieDate.new(2019,5,4)
@aussie_date_time = AussieDate.new(2019,5,4, 10, 30)
end
def test_formal_formatted_date
assert_equal 'Saturday, May 4th, 2019', @aussie_date.formal_formatted_date
end
def test_short_formal_formatted_date
assert_equal 'May 4th, 2019', @aussie_date.short_formal_formatted_date
end
def test_short_date
assert_equal '4/5/2019', @aussie_date.short_date
end
def test_short_date_time
assert_equal '4/5/2019 10:30', @aussie_date_time.short_date_time
end
end
# Create a class for AussieDate
# Keep adding code to create and implement methods until all the tests pass
# Hint methods will look something like:
# def formal_formatted_date
# @date.strftime("%A %B")
# end
# Beast
# Add more format options to the AussieDate class. For each one
# - add the test
# - add the implementation
class Product
attr_reader :name, :price
def initialize(csv_row)
@name = csv_row[:name]
@price = csv_row[:price].to_f
end
end
require 'minitest/autorun'
require_relative 'product'
class ProductTest < MiniTest::Test
def setup
@product = Product.new({
:name => 'Widgit',
:price => '10.99'
})
end
def test_name
assert_equal 'Widgit', @product.name
end
def test_price
assert_equal 10.99, @product.price
end
end
# class to hide the regex details
class StringValidator
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.freeze
def self.valid_email(email_string)
email_string =~ VALID_EMAIL_REGEX
end
end
require 'minitest/autorun'
require_relative 'string_validator'
class StringValidatorTest < MiniTest::Test
def setup
@valid_emails = ['dkrishna@att.net',
'bryanw@comcast.net',
'muzzy@hotmail.com',
'jdray@live.com',
'monopole@yahoo.ca']
@invalid_emails = ['anicolaoyahoo.com',
'ournews@outlook',
'me.com',
'schwaang',
'ateniese@macc']
end
def test_email_valid
failure_message = "Failed when checking expected VALID email: "
@valid_emails.each do |email|
assert(StringValidator.valid_email(email) == true, failure_message + email)
end
failure_message = "Failed when checking expected INVALID email: "
@invalid_emails.each do |email|
assert(StringValidator.valid_email(email) == false, failure_message + email)
end
end
end
# Create a class for StringValidator
# Keep adding code to create and implement methods until all the tests pass
# Hint: use regex https://stackoverflow.com/questions/22993545/ruby-email-validation-with-regex
# Beast
# Add more validators to the StringValidator class. For each one
# - add the test
# - add the implementation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment