Enforcing Quality with Tools – Artur Dorochowicz



Enforcing Quality with Tools – Artur Dorochowicz

0 0


presentation-enforcing-quality-with-tools

Presentation: Enforcing Quality with Tools

On Github ArturDorochowicz / presentation-enforcing-quality-with-tools

Enforcing Quality with Tools

Artur Dorochowicz

https://github.com/ArturDorochowicz/

Agenda

Visual Studio Code Analysis StyleCop JSHint

Principles

Automation - tool is part of the build Enforcement - violations fail the build Available in Visual Studio Per project settings, with shared defaults

Visual Studio Code Analysis

What's wrong with this code?

using (var smtp = new SmtpClient { Host = "smtp.gmail.com" })
{
    smtp.Send("from@from.com", "to@to.com", "subject", "body");
}

Code Analysis

  • Static analysis tool of managed assemblies - analyses binaries
  • Validates against .NET Framework Design Guidelines
  • Integrated into Visual Studio and the build system
  • In VS2010 available only in Premium and Ultimate
  • In VS2012 available in all paid editions as well as in Express with limited number of rules
  • FxCop - standalone analysis tool (fxcopcmd.exe) with somewhat different set of rules; Available in Microsoft Download Center and in Windows SDK; Microsoft is phasing it out

Installation

  • Nothing to install - Code Analysis is part of the build out of the box
  • Integration with the build is governed by an MSBuild project file
  • Available configuration options can be discovered from here
$(MSBuildExtensionPath)\Microsoft\VisualStudio\v11.0\CodeAnalysis\Microsoft.CodeAnalysis.Targets

StyleCop

StyleCop

  • Source code style verification tool - for C# code only
  • Validates against .NET Framework Design Guidelines and formatting style recommended by Microsoft
  • Originally an internal Microsoft tool, later released to the public
  • Now it's an open source project - stylecop.codeplex.com

Installation

Install StyleCop.MSBuild NuGet package into each project where the analysis is desired

PM> Install-Package StyleCop.MSBuild

MSBuild Properties

  • StyleCopEnabled - enables the analysis, true by default which makes the analysis run on each build
  • StyleCopTreatErrorsAsWarnings - report issues as warnings, true by default

Recommended settings should be added to each project file manually

<PropertyGroup>
    <StyleCopEnabled>false</StyleCopEnabled>
    <StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
</PropertyGroup>
StyleCopEnabled = false - it's probably a bit too cumbersome to have StyleCop run on each build. StyleCopTreatErrorsAsWarnings = false - since we want to enforce the quality and break the build when violations are found.

Visual Studio integration

Integration makes it easier to configure StyleCop, but is irrelevant for the analysis during the build.

Installer at stylecop.codeplex.com includes Visual Studio extension, JetBrains ReSharper plugin as well as StyleCop MSBuild targets.

Installed StyleCop MSBuild targets are irrelevant here due to the use of NuGet package for analysis during the build.

Configuration

By default StyleCop searches for configuration files — Settings.StyleCop — from the project directory up.

Multiple files are merged from top to bottom allowing for the recommended setup:

  • common settings file for the solution in the solution directory
  • project specific overrides in each individual project directory
By default the configuration file search really ends with the default settings file (here: settings file in the tools directory of the StyleCop NuGet package.) Default settings of automatically searching in parent directories may potentially result in including unrelated configuration files placed above the solution level and result in different build output depending on build location. This is build nondeterminism and It's a Bad Thing (TM). In reality it's probably not an issue. A settings file can be easily created with StyleCop Visual Studio extension - from project context menu in VS. To manage a configuration file without the VS extension: create Settings.StyleCop file with just the root configuration element - <StyleCopSettings/>. Next, run the settings editor on it (it's in the tools directory of the StyleCop NuGet package): > StyleCopSettingsEditor.exe path/to/created/settings/file

Rules

The default rule set includes all of the rules

Consider disabling some of them:

  • Documentation rules
  • UsingDirectivesMustBePlacedWithinNamespace
  • AccessModifierMustBeDeclared
  • PrefixLocalCallsWithThis, PrefixCallsCorrectly, FieldNamesMustNotBeginWithUnderscore
UsingDirectivesMustBePlacedWithinNamespace - even VS templates don't follow this rule AccessModifierMustBeDeclared - less code ceremony PrefixLocalCallsWithThis, PrefixCallsCorrectly, FieldNamesMustNotBeginWithUnderscore - no need for this. or base. unless really required

Suppressing violations

Selectively suppress violations with Code Analysis' SuppressMessage attribute

[System.Diagnostics.CodeAnalysis.SuppressMessage(
    "StyleCop.CSharp.OrderingRules",
    "SA1202:ElementsMustBeOrderedByAccess",
    Justification = "Optional, but you should always provide one.")]
public class MyClass
{
    static void PrivateBeforePublic()
    {
    }

    public static void Public()
    {
    }
}

Introducing to legacy projects

StyleCop Visual Studio extension allows to exclude individual files from the analysis

<Compile Include="ThisFileIsExludedFromStyleCop.cs">
    <ExcludeFromStyleCop>True</ExcludeFromStyleCop>
</Compile>

Use ExcludeFromStyleCop tool for mass exclusion

ExcludeFromStyleCop tool needs to be compiled - it's made available in source code form only.

ReSharper integration

The plugin does not use Settings.StyleCop files — matching configuration needs to be established again in ReSharper options.

The division of StyleCop settings into solution and project level settings files can be matched with ReSharper team-shared solution level and project level settings and committing them to source control.

ReSharper Settings - JetBrains blog Share StyleCop compatible ReSharper settings between different machines - József Kanczler

Execution

Example command line

msbuild MySolution.sln
    /target:Build
    /property:Configuration=Release
    /property:StyleCopEnabled=true

JSHint

What's wrong with this code?

function calculateCost(order) {
    return
        order.getProductsTotal() +
        order.getShippingCost();
}

JSHint

  • JSHint, a JavaScript Code Quality Tool - www.jshint.com
  • JavaScript analysis tool, detects errors and potential problems
  • Little code style verification, will be removed in a future version
  • Community fork of Douglas Crockford's JSLint

Installation

mkdir node_modules
npm install grunt
npm install grunt-cli
npm install grunt-contrib-jshint
copy path\to\node.exe node_modules\.bin\
JSHint npm package contains the analysis library as well as a node command line interface. However, we choose to use JSHint via Grunt - a popular "JavaScript Task Runner". 1. Create node_modules directory in the solution directory. When npm is run somewhere inside the solution directory, it will search up for existing node_modules directory and install the package there. 2. Need to have npm (and of course node) installed on the developer's machine for the installation of the packages. 3. Grunt packages 0.4.1 and earlier don't have a patch for a longstanding issue with redirected output in node on Windows. We want version 0.4.2+. See: https://github.com/gruntjs/grunt/issues/921 4. Normally grunt-cli would be installed as a global module (npm install grunt-cli -g). Here it's needed on the build server, therefore it's installed locally and committed to the source control. Commit node_modules to source control.

Configuration: .jshintrc

{
// Enforcing
 "newcap"   : true,  // Require capitalization of all constructor functions e.g. `new F()`
 "undef"    : true,  // Require all non-global variables to be declared (prevents global leaks)
 "strict"   : true,  // Requires all functions run in ES5 Strict Mode
  /* ... */
// Relaxing
 "asi"      : false, // Tolerate Automatic Semicolon Insertion (no semicolons)
 "debug"    : false, // Allow debugger statements e.g. browser breakpoints.
 "evil"     : false, // Tolerate use of `eval` and `new Function()`
  /* ... */
// Environments
 "browser"  : true,  // Web Browser (window, document, etc)
// Custom Globals
 "globals" : {}      // additional predefined global variables
}

http://www.jshint.com/docs/options Defaults: https://github.com/jshint/jshint/blob/master/examples/.jshintrc

JSHint picks up .jshintrc files for configuration options. In general, start with enabling all enforcing options and disabling all relaxing options, then adjust to the needs of the project. Multiple .jshintrc files may exist in different directories. JSHint picks the nearest one (traversing directories up) relative to the file being linted. (Does it merge .jshintrc files???)

Configuration: .jshintignore

# Exclude libraries, third party code
# and other files that shouldn't be checked
Scripts/lib/**

# Prevent checking VS compilation output directories
bin/**
obj/**
JSHint picks up .jshintignore for files to exclude from the analysis. This is similar to .gitignore.

Configuration: Gruntfile.js

module.exports = function (grunt) {
    grunt.initConfig({
        jshint: {
            all: ['**/*.js'],
            options: {
                jshintrc: true
            }
        }
    });
    grunt.loadTasks('../../node_modules/grunt-contrib-jshint/tasks');
};

https://github.com/gruntjs/grunt-contrib-jshint

Gruntfile.js is specific to the web project. Paths are relative to the project directory.

Suppressing violations

Inline configuration in script file — override has function scope

/* jshint undef: true, unused: true */
/* global MY_GLOBAL */

Ignore a piece of code altogether

// Code here will be linted with JSHint.
/* jshint ignore:start */
// Code here will be ignored by JSHint.
/* jshint ignore:end */

How to marry Grunt with MSBuild?

Create a custom JSHint reporter which outputs notifications in a format recognized by MSBuild and Visual Studio Create MSBuild targets file that executes Grunt Import the targets into the web project

See the accompanying JSHint sample for details

Visual Studio integration

Extensions for JSHint/JSLint analysis

Only Web Essentials 2013 uses .jshintrc and .jshintignore files. In other cases settings will need to be established again in the extension.

Execution

Example command line

msbuild MySolution.sln
    /target:Build
    /property:Configuration=Release
    /property:JSHintEnabled=true

Enforcing Quality with Tools

Artur Dorochowicz

https://github.com/ArturDorochowicz/presentation-enforcing-quality-with-tools