Несколько утверждают в модульном тесте [дубликат]

12
задан mikesigs 21 May 2010 в 15:15
поделиться

7 ответов

Гораздо важнее тестировать только одну концепцию в каждом модульном тесте.

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

16
ответ дан 2 December 2019 в 05:14
поделиться

В подобных ситуациях, если я пытаюсь быть строгим в отношении одного утверждения для каждого теста, я буду утверждать равенство для Foo, а не для его компоненты. Это побуждает меня писать Foo.equals (), и это обычно хорошо само по себе. Но я не всегда строго придерживаюсь одного утверждения на тест. Посмотрите, что вам нравится.

5
ответ дан 2 December 2019 в 05:14
поделиться

В тесте часто используется несколько утверждений, но я не считаю, что это «лучшая практика».

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

Тем не менее, вы все равно можете использовать приспособление, чтобы исключить общность вашей настройки и разборки. Я не могу говорить с MSTest, но в UnitTest ++ вы бы сделали что-то вроде:

class FooFixture
{
public:
   FooFixture() : f(MakeFoo(kX, kY, kZ)) { }

   static const int kX = 1;
   static const int kY = 2;
   static const int kZ = 3;

   Foo f;
};

TEST_FIXTURE(FooFixture, IsXInitializedCorrectly)
{
   CHECK_EQUAL(kX, f.X);
}

// repeat for Y and Z

Это не намного больше набора текста, особенно с учетом вырезания и вставки. Черт возьми, в vim это просто esc y ctrl- {pp , а затем небольшие правки. Однако с такой настройкой вы можете увидеть, не работает ли только одно поле, а затем покопаться, чтобы понять, почему.

1
ответ дан 2 December 2019 в 05:14
поделиться

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

[Test] // NUnit style test.
public void SearchTypeAndInventory() 
{
    var specification = new WidgetSearchSpecification 
                    {
                        WidgetType = Widget.Screw,
                        MinimumInventory = 10
                    }; 
var widgets = WidgetRepository.GetWidgets(specification);
if( !widgets.Any() ) 
    Assert.Inconclusive("No widgets were returned.");
Assert.IsTrue( 
    widgets.All( o => o.WidgetType == Widget.Screw), 
    "Not all returned widgets had correct type");
Assert.IsTrue( 
    widgets.All( o => o.InventoryCount >= 10), 
    "Not all returned widgets had correct inventory count.");

* Хотя я мог бы объединить утверждения, я считаю более полезным разделить то, что пошло не так.


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

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

1
ответ дан 2 December 2019 в 05:14
поделиться

Как я читаю книги, вы должны делать «Красный, зеленый, рефакторинг». В части «Рефакторинг» вы должны провести рефакторинг как тестируемого кода, так и модульных тестов.

Я не вижу ничего плохого в следующем рефакторинге:

Исходный

[TestMethod]
public void TestOne()
{
    LetsDoSomeSetup();
    AssertSomething();
}

[TestMethod]
public void TestTwo()
{
    LetsDoSomeSetup(); // Same setup
    AssertSomethingElse();
}

Реорганизованный

[TestMethod]
public void TestOneTwo()
{
    LetsDoSomeSetup();
    AssertSomething();
    AssertSomethingElse();
}

Конечно, это предполагает, что два утверждения связаны, и, конечно, основывается на одном и том же сценарии.

0
ответ дан 2 December 2019 в 05:14
поделиться

AFAI видите, принцип, лежащий в основе практики

  • , состоял в том, чтобы проверить одну связную / логическую вещь за тест; что приводит к кратким и легко читаемым тестам.
  • , чтобы получить лучшую тестовую изоляцию. Один тест не должен завершиться неудачно по одной из n причин. Если это так, то не сразу понятно, как это исправить; без предварительного расследования, по какой причине он отказал. Одно изменение не должно подводить грузовик, казалось бы, несвязанных тестов.
  • стартовое правило из книги правил для начинающих TDD; чтобы они могли усвоить этот процесс.

дело не в том, что вам нужно одно утверждение 'NUNit' / 'xUnit' для каждого теста; скорее у вас есть одно логическое утверждение для каждого теста.

[Test]
public void MakeFoo_SeedsInstanceWithSpecifiedAttributes()
{
  Assert.AreEqual( new Foo(1,2,3), Foo.MakeFoo(1,2,3), "Objects should have been equal );
}

Здесь у меня есть одно утверждение NUnit (удовлетворяющее полиции утверждений): Однако он тестирует три вещи за кулисами (в Foo.Equals я бы проверял, равны ли все переменные).
Рекомендация состоит в том, чтобы предотвратить такие тесты (т. Е. Интеграционный тест, маскирующийся под модульный тест)

[Test]
public void ITestEverything()
{
  // humongous setup - 15 lines
  payroll.ReleaseSalaries();
  // assert that the finance department has received a notification
  // assert employee received an email
  // assert ledgers have been updated
  // statements have been queued to the printqueue
  // etc.. etc..
}

Мораль истории: Это хорошая цель, к которой стоит стремиться. Попробуйте собрать все вещи, которые вы хотите протестировать, в одно логическое / связное утверждение с хорошим названием. например Assert.True (AreFooObjectsEqual (f1, f2) . Если вы обнаружите, что вам сложно назвать связную проверку / утверждение - возможно, вам нужно пересмотреть свой тест и посмотреть, нужно ли его разделить .

4
ответ дан 2 December 2019 в 05:14
поделиться

На самом деле я написал дополнение для NUnit, чтобы помочь с этим. Попробуйте его на http://www.rauchy.net/oapt

2
ответ дан 2 December 2019 в 05:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: