Как мне разделить большие юнит-тесты в ruby? - PullRequest
0 голосов
/ 23 июня 2010

Я пишу несколько юнит-тестов для одной из моих моделей рельсов.Это большая модель, и в некоторых случаях у меня есть десятки утверждений для многих методов.Я предпочитаю использовать обычный тест / модуль с синтаксисом активной поддержки rails, поэтому у меня есть файл, подобный этому:

require 'test_helper'
class ItemTest < ActiveSupport::TestCase
  test "for_sale? should be true if cond 1..."
  test "for_sale? should be true if cond 2..."
  test "for_sale? should be true if cond 3..."
  test "for_sale? should be true if cond 4..."
  test "for_sale? should be false if cond 1..."
  test "for_sale? should be false if cond 2..."
  test "for_sale? should be false if cond 3..."
  test "for_sale? should be false if cond 4..."
end

и так далее для каждого из методов.Проблема в том, что тесты становятся все более сложными, потому что я больше не могу полагаться на setup (), потому что контекст для каждой группы тестов очень сильно отличается для каждого метода.Кроме того, сложно просто протестировать метод, над которым я работаю, без запуска всех тестов.

Как другие справляются с большими тестовыми примерами, подобными этим?Есть ли лучшая практика?

Ответы [ 3 ]

1 голос
/ 23 июня 2010

Я бы порекомендовал musta, если вы хотите придерживаться test / unit.Вам не нужно использовать макрос musta, но он даст вам одну изящную особенность, которая применима здесь: контекст.Это позволяет вам разбивать свои модульные тесты на отдельные разделы с их собственными ранее, и они могут быть вложенными.

context "as a really cool user" do
  test "test number one..."
end

context "as a lame user" do
  test "test number two..."
end

Оттуда вы можете продолжать использовать весь синтаксис теста / модульного или, если вам следует выиграть - долженВы можете переключаться или смешивать н-матч.

0 голосов
/ 23 июня 2010

Юнит-тест должен проверять только одну вещь . Это звучит слишком много, проверено здесь. Для каждого условия должен быть проведен один тест.

require 'test_helper'
class ItemTest_Condition1 < ActiveSupport::TestCase
  test "for_sale? should be true if cond 1..."
  test "for_sale? should be false if cond 1..."
end

class ItemTest_Condition2 < ActiveSupport::TestCase
  test "for_sale? should be true if cond 2..."
  test "for_sale? should be false if cond 2..."
end
class ItemTest_Condition3 < ActiveSupport::TestCase
  test "for_sale? should be true if cond 3..."
  test "for_sale? should be false if cond 3..."
end
...
0 голосов
/ 23 июня 2010

Я не знаю, является ли это наилучшей практикой, но вот что я делаю.

Вместо того, чтобы все объекты, с которыми я хочу играть, были созданы в setup, у меня есть методы для создания определенного объекта,например create_credit_card_already_expired, create_credit_card_stolen, create_credit_card_valid.Иногда я помещаю эти методы в модуль, чтобы их можно было использовать для разных классов тестовых случаев.Я также создаю собственные методы утверждения, такие как assert_credit_card_rejected.

. Пример кода для меня будет

require "test/unit"

module TestCreditCardHelper
  def assert_credit_card_rejected(credit_card, failure_message)
    assert credit_card.rejected?, failure_message #A real method might be more complicated
  end

  def create_credit_card_stolen
    CreditCard.new(:stolen => true)
  end

end

class TestCreditCard < Test::Unit::TestCase
  include TestCreditCardHelper

  def test_stolen_credit_card_rejected
    credit_card = create_credit_card_stolen
    assert_credit_card_rejected(credit_card, "Doesn't reject stolen credit cards")
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...