Слишком много утверждений в этом модульном тесте? - PullRequest
7 голосов
/ 15 ноября 2010

Слишком много утверждений в этом модульном тесте?

[Fact]
public void Send_sends_an_email_message() {
    using (var server = new MockSmtpServer()) {
        server.Start();
        using (var client = new EmailClient("localhost")) {
            string from = "john.doe@example.com";
            IEnumerable<string> to = new[] { "jane.doe@example.com" };
            string subject = "Test";
            string body = "Test.";
            client.Send(from, to, subject, body);
            var session = server.Sessions.FirstOrDefault();
            Assert.NotNull(session);
            var message = session.Messages.FirstOrDefault();
            Assert.NotNull(message);
            Assert.NotNull(message.From);
            Assert.Equal(message.From.Address, "john.doe@example.com");
            Assert.NotNull(message.To);
            var recipient = message.To.FirstOrDefault();
            Assert.NotNull(recipient);
            Assert.Equal(recipient.Address, "jane.doe@example.com");
            Assert.Equal(message.Subject, "Test");
            Assert.Equal(message.Body, "Test.");
        }
    }
}

Я не думаю, что этот код требует каких-либо объяснений, но если это так, дайте мне знать.

Ответы [ 9 ]

6 голосов
/ 16 ноября 2010

Я думаю, он слишком большой.

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

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

6 голосов
/ 15 ноября 2010

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

  • sendWillSendAnEmail,
  • fromContainsSenderAddress,
  • toContainsRecipientAddress,
  • mailBodyContainsMailMessage,
  • mailContainsSubject
4 голосов
/ 15 ноября 2010

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

var session = server.Sessions.FirstOrDefault();
Assert.NotNull(session);

в

var session = server.Sessions.First();

First() в любом случае вызовет исключение, поэтому, просто изменив код, вы получите то преимущество, которое assert принесет вам без такого большого количества кода. Есть и другие места, где вы можете сделать подобные изменения.

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

2 голосов
/ 15 ноября 2010

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

1 голос
/ 01 июня 2016

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

Вы также можете найти этот пост интересным: https://timetocode.wordpress.com/2016/06/01/zen-of-unit-testing/

1 голос
/ 15 ноября 2010

Нет, в общем, чем больше утверждений, тем лучше. Распространенной ошибкой в ​​модульных тестах является недостаточная явность.

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

Единственный способ, которым вы можете иметь слишком много утверждений, - это если вы утверждаете одну и ту же вещь несколько раз, чего вы не делаете.

0 голосов
/ 16 ноября 2010

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

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

А в вашем модульном тесте

Send_sends_an_email_message

вы можете добавитьутверждает, что проверяет только равенства вместо проверки на NULL.

Возможно, вы можете создать 2 электронных письма в одном тесте и сделать утверждения равенства для обоих экземпляров.

0 голосов
/ 16 ноября 2010

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

0 голосов
/ 15 ноября 2010

Мне кажется, вопрос в том, изменяются ли значения assert () d независимо друг от друга?Если они изменяются независимо, то их следует тестировать в разных тестах, которые изменяют условия, связанные с каждым утверждением.

Если, однако, у вас есть единственный путь кода, который генерирует электронное письмо со всеми этими полями, тогда тестируйте всевсе в одном тесте уместно.

Теперь этот тест довольно сложен для чтения.Вы можете обернуть эти утверждения в описательный вспомогательный метод.Я не буду беспокоиться об этом, пока не найду тот же вспомогательный метод, который может быть полезен где-то еще.

...