Как эмулировать 100% покрытие для двойной проверки выражения? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть некоторый код, где есть две проверки на нулевую цену (например).Если первая проверка не пройдена, вторая проверка не достигнет очереди или нет?Как я могу создать тест, который может покрыть 100% этого кода?

def products
  # first check on zero price
  products = database.query 'SELECT * FROM product WHERE price > 0;'
  products.map do |product|

    # second check on zero price
    unless product[:price] > 0
      warn 'wrong price'
      next
    end

    # some operation under product
  end
end

1 Ответ

0 голосов
/ 21 сентября 2018

Правда 100% покрытие действительно не практично.Если ваш код не является полностью автономным и четко определенным, то доказать правильность программы в принципе невозможно.

Это зависит от базы данных, в которой могут быть ошибки, от процессоров, которые могут работать со сбоями, от памяти, которая можетбыть ненадежными, диски, которые могут выйти из строя, файловые системы, которые могут быть повреждены и так далее.При тестировании, однако, вы не можете принять это во внимание, тестирование на редкие случайные события почти всегда является необоснованной паранойей.

Представьте себе следующий код:

def return_items(items)
  items.each do |item|
    if (world_about_to_be_hit_by_asteroid?)
      warn "World about to be destroyed, may not be able to process this refund in time!"
    end

    item.return_to_inventory!

    if (item.could_not_be_returned_due_to_zombie_outbreak?)
      item.cancel_return!
      warn "The living dead are now taking over, return cancelled."
    end

    item.estimate_shipping unless (Alerts.speed_of_light_changed?)

    if (sun_about_to_explode?)
      warn "Head to shelter immediately."
    end
  end
end

Вместо этого попробуйте охватить 100% функциональности, которую вы можете разумно протестировать в условиях, которые необходимы для его работы.В этом случае вы проверяете, что запрос к базе данных дает правильные результаты?Вы проверяете, что ваш драйвер базы данных возвращает данные?Проверяете ли вы набор данных с различными ценами, такими как -1, 0 и 1, чтобы убедиться, что вы получаете только одну правильную запись?

Помещение warn в середине производственного кода, как этокрайне вредная привычка и ее следует избегать.Во время разработки вы можете иметь утверждения типа «утверждать», которые намеренно взрывают программу, если определенные условия нарушаются, но они должны быть зарезервированы только для самых серьезных ситуаций, в которых выполнение может иметь катастрофические последствия.

проблема здесь заключается в том, что метод не только чрезмерно параноидален, это кодировка шляпы из фольги, но не сообщает, что он делает.Лучший подход:

def products(above_price: 0)
  database.query('SELECT * FROM product WHERE price > ?', above_price)
end

Если вы уверены, что database.query сработает, потому что этот код тестируется где-то еще, как в тестовом наборе для вашего драйвера базы данных.Вы проверяете свое взаимодействие с ним следующим образом:

# Create products at prices -1, 0, 1 and 100

assert_equal 2, products.length
assert_equal 1, products(above_price: 20).length
assert_equal 4, products(above_price: -100).length

Где вы можете проверить более подробно, чтобы убедиться, что возвращаются правильные продукты, а не только правильное количество некоторых случайных продуктов.

...