Мы выпускаем новый продукт — CodeRush for Roslyn (далее CRR).
![](https://habrastorage.org/files/ebe/3b5/fc3/ebe3b5fc3eda4c04935fbc03639bf492.png)
Первая часть была про Unit Test Runner, а в этой статье пойдет речь пойдет о фичах CRR, которые помогают улучшать качество кода:
Все примеры в статье сделаны в Visual Studio 2015 на исходниках проекта OpenCover.
Visual Studio проверяет код при наборе. Например, для этого фрагмента кода в Error List появится предупреждение The variable'testValiable' is declared but never used (CS0168).
![](https://habrastorage.org/files/b60/f27/e3a/b60f27e3a557421989d6c08ae822fcd6.png)
В Visual Studio 2015 формирование таких ошибок реализовано в специальных классах, которые называются Roslyn Code Analyzer. Code Analyzer — это, упрощенно говоря, часть реализации паттерна Visitor для Roslyn Syntax Tree. Но если поискать в MSDN по коду ошибки CS0168, найдется эта статья, в ней CS0168 называют «Compiler Warning», а не Analyzer или Diagnostic, как принято в Roslyn. Это связано с тем, что CS0168 появился в те времена, когда в Visual Studio еще не использовался Roslyn, и эта ошибка выявлялась на этапе частичной компиляции кода. Не будем углубляться дальше в детали, но полезно знать, что в Visual Studio 2015 почти все сообщения в Error List формируются с помощью Roslyn Code Analyzers. Подробнее о них можно почитать тут. Полный список стандартных диагностик для .NET можно найти тут. CRR добавляет к этому набору следующие диагностики:
![](https://habrastorage.org/files/1c9/840/18a/1c984018a553463c97c1549db8ccfae8.png)
Этот скриншот сделан из стандартного студийного ruleset-редактора, т.е. если вы пользуетесь студийным анализатором кода, достаточно добавить CRR диагностики в ваш ruleset.
Проверим проект OpenCover используя стандартные диагностики Visual Studio. Для этого надо открыть свойства solution и выставить настройки, как показано на картинке.
![](https://habrastorage.org/files/ffb/be0/f18/ffbbe0f1801c42c5bc116eb38c0361c4.png)
И, в результате, получим около тысячи сообщений в Error List.
![](https://habrastorage.org/files/d8b/d3b/2dc/d8bd3b2dc1674f35b9352c8d1e296887.png)
Тысяча сообщений — не предел, потому что использовался не самый большой набор диагностик. Однако, важно не количество диагностик, а их качество. Привлекать внимание разработчика стоит, только когда это действительно нужно.
Попробуем проанализировать OpenCover используя наши диагностики. Есть три способа сделать это:
Если проект большой, статический анализ в фоне может мешать нормальной работе Visual Studio. Это связано с тем, что диагностики разворачивают синтаксические деревья и в некоторых ситуациях это приводит к значительному потреблению памяти. После проверки полные синтаксические деревья становятся ненужными, и происходит высвобождение памяти. Но это создает трафик памяти, и приводит к тому, что большая часть вычислительных ресурсов будет расходоваться на сборку мусора. Ручной режим проверки сделает предсказуемыми моменты когда Visual Studio работает медленно. Для запуска статического анализа в этом режиме, надо нажать на кнопку Refresh в окне Code Issues (кнопка Refresh первая слева).
![](https://habrastorage.org/files/b3a/70d/018/b3a70d01869547a0bcbec69a40ea4ad8.png)
Также ручной запуск диагностик предусмотрен в интерфейсе Visual Studio. Но в этом случае придется добавить CRR диагностики в ruleset как описано тут.
В Visual Studio есть стандартный механизм выполнения статического анализа кода в фоновом режиме. Этот механизм описан тут. Как уже было сказано, проверка в фоне на больших проектах может вызывать фризы студии. Включайте с осторожностью. Чтобы CRR диагностики выполнялись в этом режиме, необходимо выставить опцию Include CodeRush diagnostics into the VisualStudio background analysis.
![](https://habrastorage.org/files/b55/ebe/5e0/b55ebe5e0e394e4e8f2ef730eb45bf83.png)
В составе CRR есть исполняемый файл, который можно запустить из командной строки на машине разработчика или на сервере сборки. Файл называется DevExpress.StaticCodeAnalysis.exe. Найти его можно в директории плагина (можно открыть из CodeRush | Support | Extension Folder...). Файл представляет собой полностью автономную консольную версию CRR диагностик. Никаких дополнительных файлов для его работы не требуется. Благодаря этому он легко интегрируются в любую систему сборки. Достаточно скопировать DevExpress.StaticCodeAnalysis.exe на сервер сборки и вписать простой вызов в сборочный скрипт:
В результате в results.txt будет сформирован отчет с результатами проверки.
Мы не гонимся за числом диагностик, а реализовали только действительно полезные, уделив много внимания ложным срабатываниям. Результат проверки исходников OpenCover показан ниже.
![](https://habrastorage.org/files/f4e/437/650/f4e43765024345c5a5224424e76d7b69.png)
Нашлось всего пару странных мест:
![](https://habrastorage.org/files/7c8/912/61e/7c891261e5814fc99e4155cd6b0e7541.png)
В этом участке кода диагностики обнаружили, что CurrentCulture и CurrentUICulture присваивается дважды. Диагностика отработала корректно, но судя по всему, это делается для того, чтобы получить текст exception на английском.
Второе странное место нашлось в тестах.
![](https://habrastorage.org/files/ca9/7a8/5af/ca97a85afc0b464bb1766e4c42b54b18.png)
Переменная result присваивается два раза. Диагностика отработала корректно, хотя автор теста в комментариях написал, что так и задумано. Отличный результат — ни одного ложного срабатывания.
В CRR проверка именования и проверка орфографии так же реализованы в виде Roslyn Code Analyzer. Эти проверки по умолчанию отключены, потому что перед их использованием необходима настройка. Например, если включить без настройки на проекте OpenCover, в Error List будет огромное количество сообщений о нарушении правил именования. Для настройки правил именования есть страничка в Options. В ней можно включить и настроить проверку именования для типов, пространств имен, свойств и так далее.
![](https://habrastorage.org/files/049/6d8/bdd/0496d8bdd3984df8a7963ae80fe7748c.png)
Проверка правописания реализована на ядре DevExpress Spellchecker. Опечатки попадают в Error List, а так же выделяются в коде волнистой линией. В контекстном меню spellchecker формирует список предполагаемых замен.
![](https://habrastorage.org/files/ebe/3b5/fc3/ebe3b5fc3eda4c04935fbc03639bf492.png)
Кроме диагностик есть еще один способ улучшить свой код. Это покрытие кода тестами. В предыдущей статье был обзор возможностей нашего Test Runner, но про запуск тестов с анализом покрытия не рассказали. В Test Runner есть режим запуска тестов, в котором производится инструментирование кода. В этом режиме прогон тестов занимает большее время, поэтому для запуска тестов с анализом покрытия предусмотрены отдельные кнопки.
![](https://habrastorage.org/files/b7a/3ef/563/b7a3ef563d904895ac49c03e796b093e.png)
Покрытие можно посмотреть в Code Coverage Tool Window. На этом скриншоте видно, что тестами не покрыта else ветка условия во втором цикле.
![](https://habrastorage.org/files/866/b6a/5a0/866b6a5a00514cb1ae24630b5954bb31.png)
По результатам анализа покрытия обычно пишут новые тесты, которые увеличивают процент покрытия. Следует помнить, что 100% покрытие кода тестами не гарантирует отсутствие проблем в нем. Например, этот фрагмент кода имеет высокий процент покрытия.
![](https://habrastorage.org/files/ae2/6ad/80a/ae26ad80a3f74b3f94a2f6a8c961c5a0.png)
Но среди тестов нет такого, который проверяет условное ветвление, когда срабатывает условие
И если бы покрытие считали не по операторам, а по ветвлениям условных операторов, то цифра была бы другой.
CodeRush for Roslyn — новый удобный инструмент, который помогает писать правильный код и исправлять проблемы в существующем. Скачать попробовать можно в Visual Studio Gallery .
![](https://habrastorage.org/files/ebe/3b5/fc3/ebe3b5fc3eda4c04935fbc03639bf492.png)
Первая часть была про Unit Test Runner, а в этой статье пойдет речь пойдет о фичах CRR, которые помогают улучшать качество кода:
- Статический анализ (Static Analysis).
- Проверка орфографии (Spell Checker).
- Проверка именования (Naming Conventions).
- Анализ покрытия кода тестами (Test Coverage).
Все примеры в статье сделаны в Visual Studio 2015 на исходниках проекта OpenCover.
Статический анализ
Visual Studio проверяет код при наборе. Например, для этого фрагмента кода в Error List появится предупреждение The variable'testValiable' is declared but never used (CS0168).
![](https://habrastorage.org/files/b60/f27/e3a/b60f27e3a557421989d6c08ae822fcd6.png)
В Visual Studio 2015 формирование таких ошибок реализовано в специальных классах, которые называются Roslyn Code Analyzer. Code Analyzer — это, упрощенно говоря, часть реализации паттерна Visitor для Roslyn Syntax Tree. Но если поискать в MSDN по коду ошибки CS0168, найдется эта статья, в ней CS0168 называют «Compiler Warning», а не Analyzer или Diagnostic, как принято в Roslyn. Это связано с тем, что CS0168 появился в те времена, когда в Visual Studio еще не использовался Roslyn, и эта ошибка выявлялась на этапе частичной компиляции кода. Не будем углубляться дальше в детали, но полезно знать, что в Visual Studio 2015 почти все сообщения в Error List формируются с помощью Roslyn Code Analyzers. Подробнее о них можно почитать тут. Полный список стандартных диагностик для .NET можно найти тут. CRR добавляет к этому набору следующие диагностики:
![](https://habrastorage.org/files/1c9/840/18a/1c984018a553463c97c1549db8ccfae8.png)
Этот скриншот сделан из стандартного студийного ruleset-редактора, т.е. если вы пользуетесь студийным анализатором кода, достаточно добавить CRR диагностики в ваш ruleset.
Проверим проект OpenCover используя стандартные диагностики Visual Studio. Для этого надо открыть свойства solution и выставить настройки, как показано на картинке.
![](https://habrastorage.org/files/ffb/be0/f18/ffbbe0f1801c42c5bc116eb38c0361c4.png)
И, в результате, получим около тысячи сообщений в Error List.
![](https://habrastorage.org/files/d8b/d3b/2dc/d8bd3b2dc1674f35b9352c8d1e296887.png)
Тысяча сообщений — не предел, потому что использовался не самый большой набор диагностик. Однако, важно не количество диагностик, а их качество. Привлекать внимание разработчика стоит, только когда это действительно нужно.
Попробуем проанализировать OpenCover используя наши диагностики. Есть три способа сделать это:
- Запуск проверки вручную.
- Проверка в фоне.
- Проверка из консоли.
Запуск проверки вручную
Если проект большой, статический анализ в фоне может мешать нормальной работе Visual Studio. Это связано с тем, что диагностики разворачивают синтаксические деревья и в некоторых ситуациях это приводит к значительному потреблению памяти. После проверки полные синтаксические деревья становятся ненужными, и происходит высвобождение памяти. Но это создает трафик памяти, и приводит к тому, что большая часть вычислительных ресурсов будет расходоваться на сборку мусора. Ручной режим проверки сделает предсказуемыми моменты когда Visual Studio работает медленно. Для запуска статического анализа в этом режиме, надо нажать на кнопку Refresh в окне Code Issues (кнопка Refresh первая слева).
![](https://habrastorage.org/files/b3a/70d/018/b3a70d01869547a0bcbec69a40ea4ad8.png)
Также ручной запуск диагностик предусмотрен в интерфейсе Visual Studio. Но в этом случае придется добавить CRR диагностики в ruleset как описано тут.
Проверка в фоне
В Visual Studio есть стандартный механизм выполнения статического анализа кода в фоновом режиме. Этот механизм описан тут. Как уже было сказано, проверка в фоне на больших проектах может вызывать фризы студии. Включайте с осторожностью. Чтобы CRR диагностики выполнялись в этом режиме, необходимо выставить опцию Include CodeRush diagnostics into the VisualStudio background analysis.
![](https://habrastorage.org/files/b55/ebe/5e0/b55ebe5e0e394e4e8f2ef730eb45bf83.png)
Проверка из консоли
В составе CRR есть исполняемый файл, который можно запустить из командной строки на машине разработчика или на сервере сборки. Файл называется DevExpress.StaticCodeAnalysis.exe. Найти его можно в директории плагина (можно открыть из CodeRush | Support | Extension Folder...). Файл представляет собой полностью автономную консольную версию CRR диагностик. Никаких дополнительных файлов для его работы не требуется. Благодаря этому он легко интегрируются в любую систему сборки. Достаточно скопировать DevExpress.StaticCodeAnalysis.exe на сервер сборки и вписать простой вызов в сборочный скрипт:
DevExpress.StaticCodeAnalysis.exe EditorsDemos\EditorsSamples_CS.sln results.txt
В результате в results.txt будет сформирован отчет с результатами проверки.
Результаты проверки
Мы не гонимся за числом диагностик, а реализовали только действительно полезные, уделив много внимания ложным срабатываниям. Результат проверки исходников OpenCover показан ниже.
![](https://habrastorage.org/files/f4e/437/650/f4e43765024345c5a5224424e76d7b69.png)
Нашлось всего пару странных мест:
![](https://habrastorage.org/files/7c8/912/61e/7c891261e5814fc99e4155cd6b0e7541.png)
В этом участке кода диагностики обнаружили, что CurrentCulture и CurrentUICulture присваивается дважды. Диагностика отработала корректно, но судя по всему, это делается для того, чтобы получить текст exception на английском.
Второе странное место нашлось в тестах.
![](https://habrastorage.org/files/ca9/7a8/5af/ca97a85afc0b464bb1766e4c42b54b18.png)
Переменная result присваивается два раза. Диагностика отработала корректно, хотя автор теста в комментариях написал, что так и задумано. Отличный результат — ни одного ложного срабатывания.
Проверка именования и опечаток в названиях
В CRR проверка именования и проверка орфографии так же реализованы в виде Roslyn Code Analyzer. Эти проверки по умолчанию отключены, потому что перед их использованием необходима настройка. Например, если включить без настройки на проекте OpenCover, в Error List будет огромное количество сообщений о нарушении правил именования. Для настройки правил именования есть страничка в Options. В ней можно включить и настроить проверку именования для типов, пространств имен, свойств и так далее.
![](https://habrastorage.org/files/049/6d8/bdd/0496d8bdd3984df8a7963ae80fe7748c.png)
Проверка правописания реализована на ядре DevExpress Spellchecker. Опечатки попадают в Error List, а так же выделяются в коде волнистой линией. В контекстном меню spellchecker формирует список предполагаемых замен.
![](https://habrastorage.org/files/ebe/3b5/fc3/ebe3b5fc3eda4c04935fbc03639bf492.png)
Проверка покрытия кода тестами
Кроме диагностик есть еще один способ улучшить свой код. Это покрытие кода тестами. В предыдущей статье был обзор возможностей нашего Test Runner, но про запуск тестов с анализом покрытия не рассказали. В Test Runner есть режим запуска тестов, в котором производится инструментирование кода. В этом режиме прогон тестов занимает большее время, поэтому для запуска тестов с анализом покрытия предусмотрены отдельные кнопки.
![](https://habrastorage.org/files/b7a/3ef/563/b7a3ef563d904895ac49c03e796b093e.png)
Покрытие можно посмотреть в Code Coverage Tool Window. На этом скриншоте видно, что тестами не покрыта else ветка условия во втором цикле.
![](https://habrastorage.org/files/866/b6a/5a0/866b6a5a00514cb1ae24630b5954bb31.png)
По результатам анализа покрытия обычно пишут новые тесты, которые увеличивают процент покрытия. Следует помнить, что 100% покрытие кода тестами не гарантирует отсутствие проблем в нем. Например, этот фрагмент кода имеет высокий процент покрытия.
![](https://habrastorage.org/files/ae2/6ad/80a/ae26ad80a3f74b3f94a2f6a8c961c5a0.png)
Но среди тестов нет такого, который проверяет условное ветвление, когда срабатывает условие
if(_domain == null) return;
И если бы покрытие считали не по операторам, а по ветвлениям условных операторов, то цифра была бы другой.
CodeRush for Roslyn — новый удобный инструмент, который помогает писать правильный код и исправлять проблемы в существующем. Скачать попробовать можно в Visual Studio Gallery .
Поделиться с друзьями
Комментарии (4)
redmanmale
16.06.2016 16:40<зануда mode>
'Initialise' это не ошибка, это британский английский.
</зануда mode>
test1111
Было бы круто увидеть подобное для VS Code
xtraroman
Пока ничего не планируем делать для VS Code, но зарекаться не будем :)