שתי גישות לתיקון באג

01/09/2018

הרבה פעמים אני מתקן באג או כותב פיצ'ר בלי לכתוב בדיקה כי אני בטוח שזה ירוץ הרבה יותר מהר וממילא התיקון הוא קטן ומאוד ברור. הנה דוגמא מהימים האחרונים. הקוד הבא עובד:

  def expired?
    expires_at = DateTime.new(card_validity_year.to_i, card_validity_month.to_i, 1, 0, 0, 0) + 1.month
    Time.zone.today > expires_at
  end

והוא גם כל כך פשוט שכשאתה כותב אותו אתה לא מרגיש צורך לכתוב בדיקת תקינות. אין מה לבדוק פה.

אבל הימים עוברים ומישהו (כן זה הייתי אני) חושב שזה טיפשי לייצר אוביקט DateTime על משהו שמייצג תאריך והשעה לא חשובה בו ולכן "מתקן" את הקוד לגירסא הבאה:

  def expired?
    expires_at = Date.new(card_validity_year.to_i, card_validity_month.to_i, 1, 0, 0, 0) + 1.month
    Time.zone.today > expires_at
  end

ופה זה כבר כאב כשזה נשבר, כי בשביל ליצור תאריך ברובי מספיק להעביר 3 פרמטרים ורובי לא ידע מה לעשות עם כל ה-6 אז זרק Exception.

את הבדיקה היה לוקח דקה וחצי לכתוב וממילא היא רצה אוטומטית בכל עדכון של המערכת. ככה היא היתה נראית אם אתם סקרנים:

require 'rails_helper'

describe PaymentToken do
  describe '#expired?' do
    it 'should return true when card is expired' do
      p = PaymentToken.new(card_validity_year: 1.year.ago, card_validity_month: 1)
      expect(p.expired?).to be(true)
    end
    it 'should return false when card is not expired' do
      p = PaymentToken.new(card_validity_year: 1.year.from_now, card_validity_month: 1)
      expect(p.expired?).to be(false)
    end
  end
end

ככל שאנחנו לוקחים יותר ברצינות את המערכות שאנחנו כותבים כך מגלים שאי אפשר לברוח משיטות עבודה נכונות גם בדברים הקטנים.