what i dont get about testing

TDD, BDD, blah blah. I’ve procrastinated for a long time on learning testing. It’s probably held me back. Even though I’m determined to learn it, I still dislike testing. I still struggle with getting the concepts down. I’m working with a new gem.

gem 'shoulda-matchers'

It allows you to test neat things like

# spec/models/townhall_spec.rb 
 should validate_inclusion_of(:level).in_range(1..10).
 with_message("enter a number 1 to 10")

And in my model

# app/models/townhall_spec.rb
validates_inclusion_of :level, in: -> (townhall) { 1..10}, message:"enter a number 1 to 10"

Here’s what I don’t get. I don’t really care AT ALL whether that line of code is actually in there. Let’s say at a later date, I decide to remove the line of code from my model. It’s going to tell me dude you have a failing test on your model. You aren’t validating the level being 1 to 10. But it’s not even where I care about the implementation. I care about it for my sign up form. This test will not tell me to take out the question asking, “What level is your townhall?” on the sign up form. So I’ve now removed a line of code that makes a test fail, but the test doesn’t notify me of my now failing application. This is turning out to be an awful blog post. I guess that line of code is “good”. It’s more or less testing, can something be saved to the database that’s invalid? My real problem is that I’m going about it in a non-TDD approach at the moment. If I were doing a TDD approach, I would think to myself. Describe a townhall… Well, a townhall has a level, and it must be 1 to 10. Then I’d write a test, like the one above describing the townhall. Then I’d have to write a line of code that proves that. Hmm. I’ll keep going with this testing thing. It’s been a real learning curve and change in thinking.

Update #2, a real life example of a test that doesn’t cover implementation

Bottom line: I’m pissed because my tests aren’t tracking the implementation of methods. Here’s the scoop: I’m writing tests for my Clash of Clans Application. As of this moment, I developed most of the application without tests, and I’m going back and adding tests. As I’m writing tests, I actually ran across a method in my rails app that was not necessarily 100% correct and it deserves a refactoring! I started with this method:

def maxed_th_cumulative_time
 self.townhall.maxed_townhall.buildings.cumulative_time       end

The problem with the method is that Clash of Clans offers two different upgrade systems, a Laboratory and Builders. Builders build buildings and a Lab upgrades spells and units. It’s not correct to lump in their total time into one method. It only makes sense to differentiate the two. Since I’m attempting a more or less “TDD” approach, I decided to write my test first! A test that would fail in hopes of a good ole refactorment of the method. That’s right, I just made up the word refactorment. So I wrote the following test (please hold applause until the end)

RSpec.describe User, "#maxed_th_cumulative_time" do
  it "should equal the total time necessary to max out a townhall" do
    user = build_user_with_townhall(1)
    expect(user.maxed_th_cumulative_time("builders")).to eq(664)
    expect(user.maxed_th_cumulative_time("lab")).to eq(0)
  end
end

And I receive the following error message.

Failure/Error: expect(user.maxed_th_cumulative_time("builders")).to eq(664)
ArgumentError:
   wrong number of arguments (1 for 0)

Okay, yep. This error makes sense. So my TDD mind tells me, LET’S MAKE THIS TEST GREEN (triumphant march)! So let’s go fix the method in the model and make this test green. I updated the first line of code to…

  def maxed_th_cumulative_time(upgrader)

That returned a new error.

Expected 0
Got 664

Cool, the tests I wrote are working even better than expected. So I need to make even more changes to the method. Some TDD guys would be very excited right now and happy to see a noobie like me testing so well! So I updated the model code again!

def maxed_th_cumulative_time(upgrader)
  self.townhall.maxed_townhall.buildings.upgrader(upgrader).cumulative_time end

And now all the tests pass. And now my application is bug free! Except, remember how I added that new parameter to my method? Yeah, that’s going to be an issue every time I use that method. So my app worked “perfectly” from a user perspective. But now it’s completely broken, but my tests think it’s perfectly fine. But I’m just saying… I go to the home page and I’m greeted with the typical rails error. It makes complete sense, but my tests don’t test for the actual implementation of the method. Yes, my method now works as it is supposed to, but my test does not factor in the implementation. ruby on rails error   There’s gotta be a fix for that, right?

Post Content