C # - Що робить метод Assert ()? Це все-таки корисно?


156

Я налагоджую точку перерви і усвідомлюю виклик затвердження? Я думав, що це тільки для одиничних тестів. Що це робить більше, ніж точка розриву? Оскільки я можу зламати точку, чому я повинен використовувати Assert?


9
До речі, якщо вас цікавлять твердження, вам обов'язково варто заглибитися в кодові контракти .
MasterMastic

Відповіді:


200

У компіляції налагодження Assertприймає булева умова як параметр і показує діалог помилок, якщо умова помилкова. Програма триває без будь-яких перерв, якщо умова справжня.

Якщо ви компілюєте у Release, всі Debug.Assertавтоматично вимикаються.


12
як я можу отримати таку саму поведінку Debug.Assert в режимі випуску?
Гаміш Грубіян

15
Trace.Assert для режиму випуску очевидно refs: msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell

8
@HamishGrubijan А чому б ти хотів Debug.Assertу режимі випуску?
Каміло Мартін

25
ІМО, опускаючи твердження від коду випуску - це як проводити вправи на рятувальній шлюпці під час стикування, а потім залишати рятувальні човни позаду, коли ви пливете. :)
chrisd

113
Твердження - це не рятувальний шлюп, це система виявлення айсберга. Оскільки користувач не керує судном, твердження у коді випуску просто повідомляє їм, що вони приречені; це не дозволяє їм уникати айсберга.
Стефан

97

Від коду завершено

8 Оборонне програмування

8.2 Твердження

Твердження - це код, який використовується під час розробки - зазвичай це рутина або макрос - який дозволяє програмі перевірити себе під час роботи. Коли твердження вірно, це означає, що все працює так, як очікувалося. Коли це неправда, це означає, що він виявив несподівану помилку в коді. Наприклад, якщо система передбачає, що файл інформації про клієнтів ніколи не матиме більше 50 000 записів, програма може містити твердження, що кількість записів менша або дорівнює 50 000. Поки кількість записів менше або дорівнює 50 000, твердження буде мовчати. Однак, якщо у нього зустрічається понад 50 000 записів, він голосно "стверджує", що в програмі є помилка.

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

Затвердження зазвичай бере два аргументи: булевий вираз, який описує припущення, яке повинно бути правдивим, і повідомлення, яке відображається, якщо його немає.

(…)

Зазвичай ви не хочете, щоб користувачі бачили повідомлення про твердження у виробничому коді; твердження в першу чергу для використання під час розробки та обслуговування. Твердження зазвичай складаються в код на час розробки та складаються з коду для виробництва. Під час розвитку твердження вимивають суперечливі припущення, несподівані умови, погані значення, передані підпрограми тощо. Під час виробництва вони складаються з коду, щоб твердження не погіршували продуктивність системи.


2
У книзі "Написання твердого коду" також є велика дискусія щодо використання аргументів. Вони - чудовий інструмент налагодження!
zooropa

39

Ви повинні використовувати його для випадків, коли вам не потрібно переривати кожну маленьку лінійку коду для перевірки змінних, але ви хочете отримати якийсь зворотній зв'язок, якщо є певні ситуації, наприклад:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

Якщо я додаю рядок коду, подібний до вашого вище, запуск моєї програми видає таку помилку: "помилка CS0103: ім'я" Налагодження "не існує в поточному контексті". Чи потрібно мені якесь використання оператора, щоб воно працювало?
Джош Десмонд

4
@JoshDesmondSystem.Diagnostics
Sinjai

16

Assert також дає ще одну можливість посміхнутися навичками Microsoft щодо розробки інтерфейсу користувача. Я маю на увазі: діалогове вікно з трьома кнопками «Скасувати», «Повторити», «Ігнорувати» та поясненням, як їх інтерпретувати в заголовку!


3
Аборт / повтор / ігнорування - класика! Чи були твердження, які раніше спричиняли відображення цього Windows 3.1?
devlord

В основному це тому, що він використовує MessageBox, який, як ви кажете, датується Windows 3.1 і має лише попередньо визначені мітки кнопок. Тож ви можете зрозуміти, чому хак стався, але не чому він все ще там у 2008 році!
Джо

4
@Joe Це те, що слід бачити лише розробникам, а не кінцевим користувачам, тому оновлення, можливо, є надзвичайно низьким пріоритетним пунктом. Якщо це турбує, ви можете змінити колекції Debug.Listeners або Trace.Listeners, щоб замінити обробник за замовчуванням на той, що робить все, що завгодно.
Dan Dan Fiddling Firelight

5
І добре, що зараз 2019 рік, і те саме діалогове вікно / кнопки все ще є тут!
Буке

10

Assert дозволяє стверджувати, що умова (пост або попередньо) застосовується у вашому коді. Це спосіб задокументувати свої наміри та повідомити про налагоджувальну машину діалоговим вікном, якщо ваш намір не виконується.

На відміну від точки перерви, Assert додається до вашого коду і може бути використаний для додавання додаткових відомостей про ваш намір.


10

Assert може допомогти вам надати окрему поведінку повідомлень між тестуванням та випуском. Наприклад,

Debug.Assert(x > 2)

перерву буде спровоковано лише якщо ви використовуєте збірку "налагодження", а не збірку релізів. Там є повний приклад такої поведінки тут


10

Перш за все Assert()метод доступний Traceі для Debugзанять.
Debug.Assert()виконується лише в режимі налагодження.
Trace.Assert()виконується в режимі налагодження та випуску.

Ось приклад:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Запустіть цей код у режимі налагодження, а потім у режимі випуску.

введіть тут опис зображення

Ви помітите, що в режимі налагодження ваш код Debug.Assertзаяви не працює, ви отримаєте поле з повідомленням, що показує поточний слід стека програми. У режимі випуску цього не відбувається, оскільки Trace.Assert()умова справжня (i == 4).

WriteLine() метод просто дає вам можливість записувати інформацію до виводу Visual Studio. введіть тут опис зображення


5

Твердження сильно притаманні проектуванню за контрактом (DbC), який, як я розумію, був введений / схвалений Майєром, Бертаном. 1997. Об'єктно-орієнтоване управління програмним забезпеченням.

Важливою особливістю є те, що вони не повинні створювати побічні ефекти, наприклад, ви можете обробити виняток або здійснити інший хід дій із оператором if (захисне програмування).

Твердження використовуються для перевірки умов договору до / після договору, відносин клієнт / постачальник - клієнт повинен забезпечити дотримання попередніх умов постачальника, наприклад. надсилає 5 фунтів стерлінгів, а постачальник повинен забезпечити, щоб дотримані умови були виконані, наприклад. доставляє 12 троянд. (Просто просте пояснення клієнта / постачальника - можна прийняти менше і доставити більше, але про твердження). C # також вводить Trace.Assert (), який можна використовувати для випуску коду.

Щоб відповісти на питання, вони все ще корисні, але можуть додати складності + читабельності коду та часу + важко підтримувати. Чи варто їм все-таки користуватися? Так, чи всі ми будемо ними користуватися? Можливо, ні, чи ні в тій мірі, як описує Меєр.

(Навіть курс OU Java, що я вивчив цю техніку, показав лише прості приклади, а решта кодів там не застосовувала правила затвердження DbC щодо більшості коду, але, як передбачалося, використовувалася для забезпечення правильності програми!)


3

Як я вважаю це Debug.Assert - це спосіб встановити договір про те, як слід називати метод, орієнтуючись на специфіку значень параметра (а не просто на тип). Наприклад, якщо ви не повинні відправляти нуль у другому параметрі, ви додаєте Assert навколо цього параметра, щоб сказати споживачеві не робити цього.

Це заважає комусь користуватися вашим кодом бездоганно. Але це також дозволяє цьому головному способу пройти виробництво і не дати неприємне повідомлення замовнику (припустимо, що ви будуєте збірку Release).


6
Важливо зазначити, що недійсні параметри публічних методів повинні виключати аргументи з винятками. Тільки приватні методи повинні підтверджувати введення твердженнями. Цінності, які надходять ззовні, завжди підозрілі!
Джеффрі Л Уітлідж
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.