DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 966,904 amazing developers

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

Create account Log in
Cover image for TDD approach
Pranava S Balugari
Pranava S Balugari

Posted on

TDD approach

Thanks to my wife, this blog post is because of our morning tea discussion. She asked me to convert the discussion into a blog :)

  • You start with a test for a smallest unit of code you want to deliver (At this point in time it doesn’t exist yet)

describe 'Arithmetic::Sum' do
  describe '#add' do
   it 'is expected to take 2 and 3 and return 5' do
     expect(subject.add(2,3)).to eq(5)
   end
  end
end

Enter fullscreen mode Exit fullscreen mode
  • Ensure test fails with an error that Unit of code you are testing doesn’t exist yet.
 Arithmetic::Sum not found error

Enter fullscreen mode Exit fullscreen mode
  • Coding time...., write just minimum code necessary to make the test fail for the reason you expect.

    • Create Arithmetic module
    • Add class inside that module
    • Add method add (for now its empty)
   Code errors out saying nil and 5 are not equal.
Enter fullscreen mode Exit fullscreen mode
  • Coding time..., Now write the minimum code necessary to make the test pass.
  def add(a, b)
    return 5
  end
Enter fullscreen mode Exit fullscreen mode
  • Test should turn green at this point.
  • Add few more test expectations to deliberately make the test fail, and ensure that the failure messages are meaningful.
 describe 'Arithmetic::Sum' do
  describe '#add' do
   it 'is expected to take 2 and 3 and return 5' do
     expect(subject.add(2,3)).to eq(5)
   end

   it 'is expected to take 4 and 6 and return 10' do
     expect(subject.add(4,6)).to eq(10)
   end

   it 'is expected to take 100 and 100 and return 200' do
     expect(subject.add(100,100)).to eq(200)
   end
  end
 end

Enter fullscreen mode Exit fullscreen mode
  • As Uncle bob says, As the Tests get more Specific, the Code gets more Generic. Enhance add method to be more generic which could handle all the test cases mentioned above.
 module Arithmetic
   class Sum
     def add(a, b)
      return a + b
     end
   end 
 end

Enter fullscreen mode Exit fullscreen mode
  • Run the tests again and see all of them turn green.
  • Commit the code :)

Example given in this blog follows TDD approach i generally follow when writing ruby programs. Just curious how Java or Go community approach TDD as there is a compilation phase before running a program. I will research and if possible add another blog in continuation to this based on how their dev community approaches TDD.

Thanks to Uncle Bob and his clean coder videos :)

Top comments (4)

Collapse
 
michelemauro profile image
michelemauro

The TDD cycle needs another step: Think, before writing a failing test. That's clearly stated in the C2 Wiki where TDD was first defined, but somehow everyone forgets that step.

In compiled languages you use your tests to design your API: so, you describe in your tests how your API will look and feel, and then before running it for red, you write enough structure to make it compile.

In strongly-typed languages (Scala, Haskell) you may even design types that match so well the domain that if a program compiles, it is probably correct; the types prohibit you to even represent an invalid state of the system. If you can exclude most errors because you can't write them in code (the compiler blocks you when it checks the types), you can afford to write much less tests.

I also suggest you to view 7 minutes, 26 seconds, and the Fundamental Theorem of Agile Software Development: it's a short, but brillant piece of thather that will give you another perspective on this.

Collapse
 
elitenomad profile image
Pranava S Balugari Author

Interesting...
Thanks for that Andy

🌚 Browsing with dark mode makes you a better developer by a factor of exactly 40.

It's a scientific fact.