Ferramentas de análise estática para C# e .NET, NDepend em Profundidade

Como um arquiteto de software, muitas vezes eu tenho que analisar muitos código de aplicações, a fim de executar uma verificação de qualidade.

É um código de boa aparência? Qual a sua complexidade e cobertura de teste? Posso considerar o código como sustentável e com uma boa escalabilidade?

É claro que eu não vou gastar todo o meu tempo lendo cada arquivo-fonte, seria muito demorado e com certeza nada produtivo. Para isso, existem as ferramentas de análise estática de código fonte."Lire la suite…"

Para quem usa .NET como a sua tecnologia principal, você deve verificar cada uma das seguintes ferramentas e ver como eles podem melhorar a sua experiência de trabalho:

  1. Sonar é um analisador de débito de código e suporta mais de 25 linguagens
  2. ReSharper é um potenciador de produtividade que oferece análise de código e muitos outros recursos
  3. JustCode é também um potenciador de produtividade
  4. FxCop realiza análise estática seguindo as melhores práticas e recomendações
  5. NDepend oferece análise estática de código para .Net e se concentra sobre as relações entre os objetos

Cada um deles tem seus prós e contras e tem o seu campo específico de uso, portanto, em alguns casos Sonar pode ser uma escolha melhor do que NDepend ou ReSharper e vice-versa!

Neste artigo vou me concentrar no NDepend.

O que é o NDepend?

NDepend é uma ferramenta comercial de análise estática de código para .NET, e você pode experimentá-lo por 14 dias livremente.

Patrick Smacchia criou o NDepend em 2004.

psmacchia

O NDepend pode ser usado autônomo ou em modo integrado ao Visual Studio.

Pessoalmente eu prefiro o modo integrado, uma vez que tem todas as características padrões, juntamente com os recursos da IDE Microsoft.

O NDepend oferece um acesso rápido a muitas métricas do seu código e ilustra cada aspecto das métricas, ou seja, a dependência de montagem, através de representações gráficas (Este é seu ponto forte!)

Para mim, sua principal característica é a linguagem de consulta, construída em cima de: CQLinq.

CQLinq , ou seja, código de consulta LINQ , é uma linguagem de consulta que você pode executar em um modelo abstraído do seu código. Basicamente, você pode consultar o seu código da mesma forma que você consulta visões ou tabelas de um banco de dados. Por exemplo, para obter todos os métodos com mais de 30 linhas de código que eu poderia simplesmente abrir o editor CQLinq e escrever:

from m in Methods where m.NbLinesOfCode > 30 select m

No Visual Studio você vai ter essa visão lado a lado, a consulta e sua representação gráfica no chamado Code Metrics view:

NDepend_query_metric

Graças a CQLinq não há muito a fazer, todas as métricas podem ser traduzidas em simples consultas CQLinq, e é isso que torna o NDepend tão poderoso!

Importante notar que o NDepend oferece toda a sua lógica em uma API que você pode encontrar no lib da pasta de sua instalação:  NDepend.API.dll

Você pode usar NDepend API para construir sua própria ferramenta de análise do projeto. Para isso, tudo que você precisa é incluir o arquivo NDepend.API.dll  no seu projeto e, em seguida fazer uma referência aos namespaces necessários. veja abaixo um trecho de código que mostra o que você pode fazer com esta API.

from m in Methods
where m.NbLinesOfCode > 30
orderby m.ILCyclomaticComplexity descending
select new { m }

Que pode ser facilmente adaptados em uma função C# no seu projeto:

using NDepend.CodeModel;
using NDepend.CodeQuery;

public List GetComplexMethods(ICodeBase codeBase)
{
var complexMethods = (from m in codeBase.Application.Methods 
                      where m.NbLinesOfCode > 30
                      orderby m.ILCyclomaticComplexity descending
                      select m).ToList();

return complexMethods;
}

Documentação da API NDepend está disponível online.

Agora tudo o que você precisa é de um pouco de imaginação para construir a ferramenta de análise perfeita que se adapta às suas necessidades.

Integrando mátricas NDepend

NDepend vem com muitas consultas pré-configuradas para corresponder a maioria das regras métricas comuns. Para explorar as regras predefinidas abrir o "rules explorer view":

NDepend_menu

E então você verá este painel aberto:

NDepend_q&rexplorer

Na verdade, cerca de 240 regras ficam prontas para utilização.

No entanto, você tem total liberdade para modificar ou criar suas próprias regras.

from m in  JustMyCode.Methods
           where m.NbLinesOfCode > 30 ||
                 m.CyclomaticComplexity > 20 ||
                 m.ILCyclomaticComplexity > 50 ||
                 m.ILNestingDepth > 5 ||
                 m.NbParameters > 5 ||
                 m.NbVariables > 8 ||
                 m.NbOverloads > 6
select new { m }

Mesmo as regras NDepend sendobastante próximas ao que poderíamos considerar como regras de linha de base, eu recomendo fortemente que você gaste um pouco de tempo definindo as regras pré-construídas ou escrever suas próprias consultas! Você apenas pode criar o seu grupo de regras personalizado e, em seguida, criar suas consultas.

NDepend_createcustomeq

Agora você deve estar se perguntando o que diabos é JustMyCode?

Não entre em pânico você está fazendo uma boa pergunta! JustMyCode é apenas um filtro que elimina o código inútil gerado ao usar frameworks como "Entity" por exemplo.

Uma vez que não faz nenhum sentido real verificar a qualidade do código gerado por outras ferramentas, JustMyCode deve sempre ser usado em cada uma das suas consultas.

Você pode estender a definição de JustMyCode ao aplicar:

notmycode
from m in Application.Namespaces.WithNameLike("NameSpace.Of.GeneratedCode").ChildMethods() select m

Desta forma, eu digo que todo o código dentro do namespace "NameSpace.Of.GeneratedCode" é considerar como código gerado. Você também pode filtrar por atributos, nomes de arquivos, convenção de nomenclatura, heranças ou o que você precisar, muito fácil! Por padrão NDepend considera como código gerado os códigos contidos em arquivos Designer.cs, no método InitializeComponent e alguns outros do tipo.

Visualizações Gráficas

Você tem quatro visualizações gráficas no NDepend. Duas delas realmente focam no aspecto da dependência. A terceira é a exibição de métrica de código(como citado no inicio do artigo). E a quarta é simplesmente o recurso que ajuda a exportar o resultado de sua consulta CQLinq em um gráfico.

Lado a lado matriz de dependência e gráfico de visualização:

NDepend_matrix_graph

Se você não estiver familiarizado com estes gráficos, não se frustre, geralmente ninguém é! Exatamente por isso o NDepend tem dicas para ajudar você a entender os vários valores. Basicamente, a matriz e o gráfico irão ajudá-lo a descobrir como assemblies, namespaces, classes e métodos dependem uns dos outros.

A visualização gráfica é mais útil para mostrar um "código espaguete" e a visualização da matriz é mais adequado para verificar se há ou não o código segue o princípio de baixo acoplamento e alta coesão. Assim, na maioria das vezes, é melhor analisar tanto o gráfico quanto a matriz.

Eu não entendi por que as linhas eram tão cheias de curvas no gráfico de dependência, por vezes até contornando objetos, mesmo para pequena quantidade de nós. Eu não acho que isso vai fazer uma enorme diferença na sua vida diária, mas não vejo vantagens com todas essas curvas, para mim, acrescenta confusão desnecessária. Eu preferiria ver linhas retas ligando os itens. Veja por si mesmo:

NDepend_curves

Aqui está o que a equipe de desenvolvedores NDepend, disse sobre isso:

The graph algorithm comes from an older version of MsAgl. Actually we don't find the result that over-curly, but anyway, Graph is an important feature that will face major enhancements in the mid-term

"O algoritmo gráfico vem de uma versão mais antiga do MsAgl. Na verdade, nós não achamos o resultado tão encaracolado, mas de qualquer forma, esse Gráfico é uma característica importante que terá de enfrentar grandes melhorias no médio prazo"

Em seguida, o "metrics view" exibe blocos proporcionais de tamanho diferente de acordo com a métrica que você selecionou. Ele pode ser definido por número de linhas de código, número de instruções IL ou qualquer opção no menu suspenso:

NDepend_metricchange

o "metric view" costumou me dar dores de cabeça porque ao mudar para # linhas de código, eu recebi esta mensagem muitas vezes:

NDepend_errormessage

Então, como você pode ver, mesmo que a mensagem seja muito clara, não é útil uma vez que não lhe diz  nada sobre o que realmente está faltando!

Caso se depare com essa mesma situação, verifique manualmente se cada projeto está configurado para gerar os arquivos .pdb no diretório da assembly.

Integração Contínua

Você pode facilmente configurar NDepend para fazer parte do seu servidor de compilação em seu processo de integração contínua. Por que pode configurar na linha de comando uma tarefa de compilação ou obter a extensão: NDepend TFS 2010 integration on Codeplex

O NDepend é compatível com CCNet, TFS, FinalBuilder, Team City e provavelmente, muitos outros, leia sobre isso aqui .

Open Source

Eu apresentei NDepend, dizendo que ele é uma ferramenta comercial. Não é mentira, mas o NDepend API é completamente livre para usar em qualquer um dos seus projetos. Na verdade NDepend vem com uma ferramenta de linha de comando chamado "NDepend.PowerTools" e seu código fonte:

NDepend_powertools_opensource

Como se diz na documentação:

NDepend.PowerTools são um conjunto de analisadores estáticos de código aberto curtos, embalados na IDE Visual Studio.

Então, você está livre para estender o código para o seu próprio uso.

Uma característica muito legal dos PowerTools é o detector de código duplicado.

NDepend_powertools

Eu acho que esse recurso deveria ser totalmente integrado em NDepend UI. Veja o que o time NDepend disse sobre isso:

"Certamente a detecção de clonagem de código é uma característica emblemática que será adicionada no futuro."

Documentação

A Documentação do NDepend está completa e atualizada. Abrange todas as características das ferramentas e têm muitas telas e exemplos. Ela também vem com um vídeo de introdução de 3 minutos. Mas, infelizmente, o vídeo é gravado para a versão 4 do NDepend e a versão atual é a versão 5 Também acho que Patrick Smacchia poderia ter feito melhor, gravando mais videos. E como a equipe de desenvolvedores disse:

"Mais vídeos é definitivamente algo que iremos oferecer"

Outras Características

Além de todas essas boas características já mencionadas, o NDepend também oferece:

  1. Relatório HTML estático
  2. Analisador de cobertura de teste
  3. Análise contínua
  4. Regras de construção de  falhas criticas

O que está faltando no NDepend?

Para mim NDepend é uma ótima ferramenta, mas ainda precisa de algumas melhorias.

Na verdade, você não pode esquecer que hoje em dia os aplicativos combinam diferentes linguagens. Na maioria das vezes o seu aplicativo .Net será como um conjunto de C# (ou qualquer outra linguagem), e as linhas de JavaScript de código e por esta razão a sua análise de código com certeza vai ter que ser poliglota ou pelo menos bilíngue. E sabendo que o NDepend não entende JavaScript, você terá que obter outras ferramentas para analisar todo o seu código por completo.

Isso pode ser um ponto de fundamental para alguns usuários preferiram uma ferramenta como o Sonar que suportam diferentes linguagens.

Por exemplo, em um aplicativo C# ASP.NET SPA, a maioria do código provavelmente será escrito em JavaScript e por isso vou ter de concluir relatório NDepend C# usando outra ferramenta.

A segunda característica que falta, seria o relatório analisador de dívida técnica_._ Patrick Smacchia optou por concentrar o NDepend em fatos e métricas de código-fonte, o que é bom e uma visão objetiva ponto. Mas eu acho que uma interpretação mais inteligente da análise através de um relatório da dívida técnica seria muito apreciada por muitos desenvolvedores. Podemos esperar algumas melhorias no futuro de acordo com Patrick Smacchia:

"Igual a detecção de clonagem de código, a análise da dívida técnica é uma característica emblemática futura."

Palavra Final

Como um usuário .Net, Achei NDepend muito poderoso e muito fácil de usar. Eu realmente acho que a linguagem CQLinq e a biblioteca NDepend são realmente os melhores recursos da ferramenta, já que não havia nenhuma equivalente.

A equipe NDepend é muito ativa e podemos esperar muitas características boas nos próximos lançamentos.

Agora é só experimentá-lo aqui.