Hello everyone !

Something new for me to learn this topic. I have never practiced or tried it out but I have to try to summarize it because this is intersting for me. So, what is TDD?

TDD is acronym of Test Driven Development, basically is a development strategy in which you write unit test first before actually implementing the code because our code development is driven by test like the name, Test Driven.

Rule of TDD

TDD have a some rules like a game when you are practicing TDD. What’s rules?

  1. Write production code only to pass a failing unit test

This mean, before we start to write code, we need to write the test first and we have to make sure that the test will surely fail or red when executed.

  1. Write no more of a unit test than sufficient to fail

This means that we create test, make the test as small(atomic) as possible.

  1. Write no more production code than necessary to pass the one failing unit test

After we create a failing test. Now write code just enough to make that test pass. Not more code, just enough code.

After the test is success, we dont need to continue the code, instead we proceed to make the next failing test.

Cycle of TDD

To make easy, lets imagine the cycle of TDD. When you are doing TDD, just looked the cycle.

image

  • First is write test code to make it fail
  • Second, just writing code to make that test work.
  • Third, refactor if there is something to refactor. You can skip this step if nothing useful to refactor. If your code is complex, does not stop at just making your tests pass. Spend your time to refactoring your code to make more readable and clean while still make sure it passes the test.

Lets writing test case

Imagine that we will playing around data structure stack, test file will be called stack_spec.rb and we are going to test with 4 test:

  1. Creates Stack object
  2. Stack having a read method
  3. Stack invoke read method
  4. And method read return nil when empty stack

Add Test

Start adding simple test and make the test is failing

RSpec.describe Stack do
    it 'should return nil when reading an empty stack' do
        stack = Stack.new()
        expect(stack.read).to eq(nil)
    end
end

Run rspec and the test is failing.

image

Message error uninitialized constant Stack, they tell us that Stack class not defined.

Pass Test

Now, start writing code and try to pass that test. Just enough to make that test pass. Not more code.

class Stack
    def initialize
      @data = []
    end

    def read
        @data.last
    end
end

And than run it again. Don’t forget to commit after pass the test to see what we have to pass the test.

image

Yeay cool.

Repeat the process for the next unit tes

We remember that stack have push after we can read it. Lets make the test that we push 1 and read it.

RSpec.describe Stack do
    it 'should return nil when reading an empty stack' do
        stack = Stack.new()
        expect(stack.read).to eq(nil)
    end

    it 'should return 1 when reading a stack with data [1]' do
      stack = Stack.new()
      stack.push(1)
      expect(stack.read).to eq(1)
    end
end

Run with rspec -fd and we can see message error like this:

image

With rpech -fd, we can see that the first test is pass but second test is failing.

Pass Test

class Stack
    def initialize
      @data = []
    end

    def read
        @data.last
    end
    
    def push(element)
        @data << element
    end
end

And than run it again, don’t forget to commit and the output should be like this:

image

Yessss, GREEN!

The last that stack can remove stack with pop method. Let’s adding the test with pop.

RSpec.describe Stack do
    it 'should return nil when reading an empty stack' do
        stack = Stack.new()
        expect(stack.read).to eq(nil)
    end

    it 'should return 1 when reading a stack with data [1]' do
        stack = Stack.new()
        stack.push(1)
        expect(stack.read).to eq(1)
    end

    it 'should return 1 when popping a stack with data [1]' do
        stack = Stack.new()
        stack.push(1)
        expect(stack.pop).to eq(1)
    end
end

Run it and make sure the test is failing.

image

Pass Test

class Stack
    def initialize
      @data = []
    end

    def read
        @data.last
    end
    
    def push(element)
        @data << element
    end

    def pop
        @data.pop
    end
end

Run rspec again we will see our all test cases working fine and everything is green.

image

You can install tig to look into recent change logs when writing test or writing code to pass it. So, you can check other commits without running the command many times.

image

That’s it what can i share. Yess of course, this is only short introduction of TDD. Hopefully this helped you to introduction to what the TDD process is like.
Thank you !!!