Warning: include(/volume1/web/cyberhost.biz/wp-content/plugins/jaster_cahce/cache/top-cache.php): failed to open stream: No such file or directory in /volume1/web/cyberhost.biz/index.php on line 9
Call Stack:
0.0001 356256 1. {main}() /volume1/web/cyberhost.biz/index.php:0
Warning: include(): Failed opening '/volume1/web/cyberhost.biz/wp-content/plugins/jaster_cahce/cache/top-cache.php' for inclusion (include_path='.:/usr/share/pear') in /volume1/web/cyberhost.biz/index.php on line 9
Call Stack:
0.0001 356256 1. {main}() /volume1/web/cyberhost.biz/index.php:0
Как статический анализ может дополнять юнит-тестирование на примере NUnit | Хостинг за 90 р. от cyberhost.biz — платный хостинг
Довольно часто при обсуждении средств статического анализа для C# проектов программисты пишут о том, что в этом нет необходимости, потому что с помощью юнит-тестирования они отлавливают большинство ошибок. Я решил проверить, насколько хорошо протестирован один из самых известных юнит-тест фреймворков — NUnit, и посмотреть найдёт ли там что-нибудь наш анализатор. Введение NUnit — это портированная с Java на C# популярная библиотека для юнит-тестирования .NET проектов. Исходный код открыт и доступен на сайте проекта http://www.nunit.org/.
Стоит отметить, что JUnit — проект, с которого был портирован NUnit, создали такие известные программисты как Эрих Гамма — один из авторов книги о шаблонах объектно-ориентированного проектирования, и Кент Бек — создатель методологий разработки через тестирование и экстремального программирования. Я помню, как когда-то читал его книгу Test Driven Development By Example, где он рассказывает о разработке через тестирование на примере создания тестового фреймворка, аналогичного JUnit, следуя всем своим методологиям. То есть можно не сомневаться в том, что JUnit и NUnit разработаны в лучших традициях юнит-тестирования, о чём так же говорит цитата Кента Бека на сайте NUnit: "… великолепный пример идиоматического дизайна. Большинство тех, кто портировал xUnit просто переносили версию для Smalltalk или Java. То же самое сделали и мы с NUnit в первый раз. Эта новая версия NUnit является такой, какой она должна была быть, если бы была написана на C# с самого начала".
Я посмотрел исходники NUnit — там очень много тестов, ощущение такое, что протестировано всё что только можно. Учитывая отличный дизайн и тот факт, что NUnit используется тысячами разработчиков на протяжении многих лет, я думал, что PVS-Studio не найдёт в нём ни одной ошибки. Но нет, ошибка нашлась.
О найденной ошибке Сработала диагностика V3093 о том, что иногда программисты вместо операторов && и || используют операторы & и |. Проблема может возникнуть в том случае, когда важно чтобы правая часть выражения не выполнялась при определённых условиях. Посмотрим, как эта ошибка выглядит в NUnit. public class SubPathConstraint : PathConstraint { protected override bool Matches(string actual) { return actual != null & IsSubPath(Canonicalize(expected), Canonicalize(actual)); } } public abstract class PathConstraint : StringConstraint { protected string Canonicalize(string path) { if (Path.DirectorySeparatorChar != Path.AltDirectorySeparatorChar) path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); …. } } Даже если в метод Matches в качестве параметра actual придёт значение null, то правая часть оператора & всё равно будет вычислена, а значит будет вызван метод Canonicalize. Если посмотреть его определение, то видно, что в нём значение параметра path уже не проверяется на null, а сразу у него зовётся метод Replace, где и возможен потенциальный NullReferenceException. Попробуем воспроизвести проблему. Для этого я написал простой юнит-тест: [Test] public void Test1() { Assert.That(@"C:Folder1Folder2", Is.SubPathOf(null)); } Запускаем и смотрим результат:
Так и есть: NUnit упал с NullReferenceException. Даже в таком хорошо протестированном продукте как NUnit статический анализатор PVS-Studio смог найти реальную ошибку. Отмечу, что сделать это мне было не сложнее, чем написать юнит-тест — нужно выбрать из меню проверку проекта и проанализировать грид с результатами.
Заключение Юнит-тесты и статический анализ — это не исключающие, а дополняющие друг друга методики разработки программного обеспечения [1]. Скачайте статический анализатор PVS-Studio и посмотрите не обнаружатся ли там ошибки, которые не были найдены юнит тестами.
Warning: include(/volume1/web/cyberhost.biz/wp-content/plugins/jaster_cahce/cache/bottom-cache.php): failed to open stream: No such file or directory in /volume1/web/cyberhost.biz/index.php on line 13 Call Stack: 0.0001 356256 1. {main}() /volume1/web/cyberhost.biz/index.php:0 Warning: include(): Failed opening '/volume1/web/cyberhost.biz/wp-content/plugins/jaster_cahce/cache/bottom-cache.php' for inclusion (include_path='.:/usr/share/pear') in /volume1/web/cyberhost.biz/index.php on line 13 Call Stack: 0.0001 356256 1. {main}() /volume1/web/cyberhost.biz/index.php:0
Свежие комментарии