In my career, I have had privilege to work with very different teams on projects with various complexities. Different situations require different approaches and methodologies to perform with maximum in a given situation. But in every situation there is one common denominator: code and process quality. There are no compromises when quality is in question. From my experiences, if quality is taken seriously into account, project performs well and output is generally positive. And vice versa: If project or project members put a little emphasis on a quality, the project commonly fails or there are a lot of problems.
You can read my thinking about code quality here: https://www.jenx.si/2019/06/07/is-high-quality-software-worth-the-cost
In my opinion, the most important factor to a good code quality is developer attitude toward the quality. If developer follows clean code approaches, best practices and if he/she adopts the quality (and overall) rules, then this is the best “quality system”. But reality is different. Even the best developers sometimes produce not-perfect and smelly code. In this case – or to enforce quality mechanism into development process – good “quality tools” comes very handy.
Static code analysis tools are one of those tools which can greatly improve the quality.
I had opportunity to test NDepend. Before I really dig in, I would like to say that in this blog post I will not go into technical details describing NDepend features or some deep technical internals. Here, I would like to say that NDepend documentation is super awesome, and if you want to go deeper you have everything on NDepend official documentation at https://www.ndepend.com/docs/getting-started-with-ndepend.
Today, I will put NDepend extension for Azure DevOps on pedestal and try to say few words about this tool.
NDepend for Azure DevOps extension
For me, good software development process consist of (among others) good source code and Continues Integration (CI) which continuously checks for build and integration problems.
While NDepend Visual Studio extension enables ad-hoc control over source code at coding-time, NDepend Azure DevOps extension enables developers to have source code covered also under CI.
NDepend for Azure DevOps – how to get it working?
So, let’s take a look what is needed to start with this tool. First, I need to install NDepend Azure DevOps extension on my Azure DevOps portal. I find it in a Visual Studio Marketplace here: https://marketplace.visualstudio.com/items?itemName=PatrickSmacchia.NDepend. Azure DevOps extension management is under Organization Settings/Extension sub menu.
After successful installation, NDepend plugin is available on every project inside my Azure DevOps organization.
Once this is done, I basically get two things: NDepend Build Task and NDepend Dashboard. Now, I can put NDepend build task in my build pipeline and integrate my build definition with NDepend dashboard.
Of course, If I want to extend my build pipeline with NDepend task I need NDepend project in my solution. Next picture shows how this can be done.
When I queue the build, NDepend task will perform analysis on my source code. All I need now is to link my build pipeline in my NDepend dashboard.
NDepend Azure DevOps extension features
Let’s quickly take an overview of the features included in NDepend extension for Azure DevOps. NDepend Azure DevOps main view consists of these tabs:
- Quality gates
This view provides top-view of source code analysis. If I have green flags here, I am OK. If red – I will need to do something in order to put my processes back on track!
In general, when I am overall satisfied with my project and I just want a quick overview on how my development process is performing this dashboard is a perfect screen. It contains all the basic information I need to know when I check how my team or project is progressing. Image below is my NDepend Summary dashboard in action!
I will not go deeper on the Summary features (you can check awesome official documentation here). I like this view, because all relevant information about my standings are presented in succinct form.
Quality gate is a code quality goal. This goals must be achieved in order to conform to the rules enforced by the quality system. This is basically PASS/FAIL test on the code.
NDepend use CQlinq language to define custom quality gates. Quality gates are LINQ statements which result in either PASS or FAIL. CQling is really very powerful feature of NDepend.
NDepend build task also enables of stopping of the build if one of the quality gates PASS is not achieved, e.g.:
Technical debt incurs interest payments, which come in the form of the extra effort that I have to do in the future development because of my quick and dirty design choices. And yes, in real environments this happen due to various factors, e.g.: bad decisions, time pressure, lack of knowledge, management pressure to put app in production ASAP and similar. One thing to remember, more debts in my code, more error-prone my code is. Technical debt is just like financial debt: the more dept I have, more interest I have to pay later on. So, sooner I start working on my debt the less interests I have; more comfortable I feel with my (money)code. Handling technical debt is like handling financial debt – it’s good to have some strategy to address the most problematic or “expensive” issues first. The whole point is to reduce software entropy!
Rules list all the problems with my code. It displays type of problem, debt, severity and other characteristics. Based on rules violated I can do some strategies on how to improve my code.
I find Trends view a very, very useful feature, because here I can see how my overall process (parameters) is standing over time. Several parameters can be observed here. Because I am more visual guy, I like this view very much!
Trend charts are very useful feature because I can easy – visually – check how my development process is trending. I can observer several indicators over time, like:
- Lines of code,
- Lines of code covered by tests,
- No of comments (lines),
- Percentage of code coverage,
- Debt percentage,
- New issues since baseline,
- Issues fixed since baseline,
- Blocker, critical and high issues,
- Rules violated,
- Critical rules violated,
Did I mention already 😀 : All this indicators are presented visually and time dependent. Super awesome, right!?
Metrics view shows different matrices based on selected code elements, i.e. assemblies, namespaces, types or methods. It shows very condensed information per selected code element.
For me, this view is useful because I can quickly sort and filter out the most crucial issues and address them. Usage is very intuitive, it’s like sorting the table and filter out the most interesting parts or problems. Based on this view, I can prepare strategy how to deal with my problems.
What’s next? How can I improve my code.
As you can see from my initial dashboard, my demo code is rather shitty. I have only 30% code coverage, my debt is D-rated, and my trends are all red. Yes, I am doing something wrong.
I have several options:
A: Ignore all
This is the easiest option – I can ignoring code smells, bad code and all bad practices. I just disable or ignore NDepend all the way. In some scenarios this is legit option. I have seen many (especially large complex legacy projects) where introducing static analysis could present many problems. For some awkward reasons, sometimes bad practices are also deliberate introduced into the code (don’t ask me why and how, but world of software development is diverse and very colorful 🙂 ).
Every pragmatic (senior) software engineer knows that legacy and complex (especially enterprise-grade) software is sometimes hard to adopt to reflect all the best (trendy) code practices.
In this case, I would recommend to apply static code analysis and at least observe the trends- just to have some overview information about the code.
B: Let NDepend help me
This is option where I systematically address all the problems presented by NDepend. In general, this is preferred way. By this approach I will end up with much better code. When I am satisfied with my indicators, I just need to follow Trends and Quality gates to be inside tolerance interval. In my opinion, every new or green-field project MUST adopt all the best practices and follow quality guidelines. By using NDepend this is very easy. And what is even more important, it’s integral part of the software development process, not some one-time ad-hoc action. This is very important factor, because in general, some local, ad-hoc, it-works-on-my-machine, one-time checks are not the best solution!
In the case of my super awesome example, I can – based on NDepend suggestion – adopt my code. In my demo example I managed to improve my code from this to this:
The difference is obvious. The code is cleaner, fully covered, with debt under acceptable tolerance.
Every (serious) software development team or company must have source code under CI. Furthermore, CI should be equipped with some some kind of static code analyzer and/or some quality watchdog tool. The whole purpose of this is to have quality under control and to have some alerting system on place when negative trends starts to emerge. For that purpose, I highly recommend NDepend Azure DevOps extension. Furthermore, If you address issues reported by NDepend, your code and software development process will improve drastically, I am sure.
But there is one drawback to all of this – once you get used to all these fancy features you can’t live without them anymore. And of course, in return you get cleaner code and much better sleep at the end of the day.
Always, when I get new toy in my hands I first play around on some “big-button-project” as I did here with NDepend. I played on some demo/fake source code – turning smelly code into almost perfect A-rated code. This way I get to know core features of the tool. Then, I start applying this on real-world projects – here all the fun begins.
NDepend is awesome tool, therefore, in one of the next blog posts I will dig deeper and see how NDepend performs and behaves on some more realistic projects. In this blog post I addressed only a tip of the NDepend iceberg, there is a lot more to this awesome tool.
Furthermore, maybe in one of the next blog post I will also address NDepend for Visual Studio. This flavor of NDepend is really a sledge hammer for fixing the code issues, code smells and all negatives in the source code. It is also more developer-oriented in contrasts to NDepend for Azure DevOps extension – which is more extension tool in DevOps Engineer arsenal.