TDD demo

How you might unit test “by hand”

  • NB: This example is using minitest/spec
 1def fact(n)
 2   if n == 1
 3      1
 4   else 
 5      fact(n-1) * n
 6   end
 7end
 8
 9if (fact(1) != 1)
10   puts "Error when calling Factorial with 1"
11elsif fact(2) != 2
12   puts "Error when calling Factorial with 2"
13else
14   puts "Factorial function works."
15end
16
17
18
19

How can you automate this with tools

  • There are a huge variety of tools and techniques to avoid repetitious coding
  • We will be using the built-in unit testing framework called “minitest”
  • For this course focus ONLY on unit testing

A Cosi101 Factorial Function using minitest

 1require 'minitest/autorun'
 2
 3def fact(n)
 4   if n == 1
 5      1
 6   else 
 7      fact(n-1) * n
 8   end
 9end
10
11describe "factorials" do
12   it "works for 1" do
13      fact(1).must_equal 1
14   end
15
16   it "works for 2" do
17      fact(2).must_equal 2
18   end
19
20   it "works for 20" do
21      fact(20).must_equal 2432902008176640000
22   end
23
24   it "works for zero" do
25      fact(0).must_equal 0
26   end
27end
28

Notes

  • What other tests can we do to test this Factorial class?

Testing a full ruby class

 1require 'minitest/autorun'
 2
 3class PlayingCard
 4   attr_reader :rank, :suit
 5   def initialize suit:nil, rank:nil
 6      @suit = suit
 7      @rank = rank
 8   end
 9
10   def random
11      @suit = ["hearts", "spades", "diamonds", "clubs"].sample
12      @rank = rand(13)
13      self
14   end
15
16   def to_s
17      card_to_english
18   end
19
20   def card_to_engish
21      rank_to_english + " of " + @suit
22   end
23
24   def valid?
25      @rank >= 1 && @rank <= 13 && !@suit.nil?
26   end
27
28   private
29
30   def rank_to_english
31      if @rank == "1"
32         "Ace"
33      elsif @rank > 1 && @rank < 11
34         number_to_english(@rank)
35      elsif @rank == 11
36         "Jack"
37      elsif @rank == 12
38         "Queen"
39      elsif @rank == 13
40         "King"
41      end
42   end
43
44   def number_to_english val
45      %w(fail0 fail1 two three four five six seven eight nine ten)[val]
46   end
47end
48
49describe PlayingCard do
50   before do
51      @a_card = PlayingCard.new.random
52   end
53
54   it "creates a valid card" do
55      @a_card.valid?.must_equal true
56   end
57   
58end

Notes

  • What other tests can we do to test this PlayingCard class?