Google Website Translator Gadget

Showing posts with label TeamWork. Show all posts
Showing posts with label TeamWork. Show all posts

Monday, 04 April 2011

Pragma Software Development: Check-in Procedure

When working together in a software development team it is important to have a common definition for when something is DONE.  An important aspect of getting things DONE is a well-defined check-in procedure that all developers follow to commit something into the source control repository.  Here is the procedure that we use at Pragma for committing changes into our Team Foundation Source Control repository:

  1. Code has been integrated with a recent version of the code in the TFS repository – at least a version of the TFS repository on the same day.
  2. Code has been formatted according to our ReSharper Pragma Full Cleanup profile.  This automatically formats all code to follow the same formatting and layout standards.
  3. Code compiles without any compiler warnings.
  4. Code adheres to our coding standards - I’ll write more about this in a future post.  We try to automate the application of our coding standards (where possible) using tools like ReSharper.  Alternatively, use a code review checklist to quickly identify areas of concern. 
  5. No ReSharper code analysis Error or Warning violations (i.e. green square in scrollbar). Any violation needs to be identified and agreed upon. Suggestions and Hints can be ignored if deemed unnecessary.
  6. No FxCop violations. Any violation needs to be identified, agreed upon and justified using the in-code SuppressMessage attribute.
  7. New functionality has been covered by tests and the code coverage has been verified using NCover.
  8. Bugs have been covered by tests and verified using NCover.
  9. Code adherers to the Logging strategy and the developer has inspected the usefulness of the log statements using Log4View.
  10. Code adheres to the Exception handling strategy for managing exceptions.
  11. Error Messages and translations have been added to the resource files.
  12. The associated TFS work item (development ticket/task) has been updated to reflect the effort involved (actual hours, comments etc.)

Once the code satisfies the above mentioned criteria, the developer runs a gated check-in using the TeamCity Visual Studio Plug-in.  This ensures that all the unit and integration tests are executed by the TeamCity build server after integrating the local changes with the latest TFS repository changeset.  Only if all the tests pass will TeamCity commit the changes onto the Mainline.   The observant reader may have noticed that we don’t do an upfront code review.  As we work from home for 2-3 days a week, we conduct our code reviews on the checked-in artefacts.  I’ll write more about the code review procedure in a future blog posting. 

Lastly, for service pack development, the developer needs to consider whether the change needs to be merged across to the Mainline for the next major version and merge the changes across if required.

Thursday, 20 January 2011

Pragma Software Development Team

20012011Following on my intention to blog a bit about our internal development environment here at PRAGMA, let’s start with a look at the software development team, how we communicate, where we work and what Software Development Lifecycle we follow.

 

Team

The software development team has grown quite a bit during the past 2 years.  Currently we have a Software Development Manager who takes the responsibility of managing the project, prioritizing the feature set, interacting with clients, ensuring the product vision etc.  Reporting directly to the Software Development Manager is a Development, Test and Analyst lead. They are responsible for managing the 13 developers, 3 testers and 1 analyst that compromise the rest of the team.   The management function forms only a small part of their responsibility as they are all hands-on, doing full-time development, testing and analysis together with the rest of the team.  We believe in a flat structure and in the team taking collective ownership for the solution.  As Development Lead, I share the overall responsibility for the architecture with another senior developer in the team.  We also have a Project Manager/Assistant who helps with administrating the project plan and also currently plays the role of SCRUM Master.

Communication

One of the benefits of working at PRAGMA is that we get to work from home for 2 days a week.  Initially I found it very hard to adapt to not having the whole team co-located.  Especially in the early stages of the project, where I had to do a lot of mentoring, I missed the simple “luxury” of pairing with a developer to illustrate some concepts or to fledge out a design on a whiteboard or through some code.  As the project progressed and things settled in terms of architecture and skills the issue became less of a problem.  I still feel a co-located team is the most productive setup, but there is also a lot of merit in allowing people to work remotely for a day or two in the week by giving them the flexibility of not having to commute into office every day.

When working remotely keeping in touch is obviously very important.  We use Skype for IM and VOIP calls to interact between individuals and small groups of people.  I specifically mention small groups as we struggled to use Skype for calls that involved the whole team.  The call quality was not good and people would frequently drop and had to reconnect to the conference call. This might be due to bad connections from the different ISP’s that the remote workers are using so your own mileage might differ.  Fortunately for us PRAGMA makes use of Interwise Participant for web conferencing so our daily feedback session currently involves a combination of using Interwise for visuals and PRAGMA’s normal teleconference facilities for audio.  This obviously incurs a bit of cost for the remote workers but it doesn’t nearly weigh up against the other benefits like not having to commute.  As the broadband scenario in South Africa is getting better and better we re-evaluate this setup every now and then to see whether we can’t get away with only using Skype.  For simple remote pairing/debugging sessions we find Microsoft SharedView to be an excellent solution.

Office Space

Our offices are located in the Bellville Business Park in the Northern Suburbs of Cape Town so fortunately we miss out on all city traffic.  We moved into our current premises end of November 2009 and the new, modern offices are equipped with a very nice canteen and other facilities that make working at the office a pleasure.  Of course there is some good, free coffee as well Smile  The seating inside the building is based on an open plan setup.  The software development team sit together in what is refer to as the Lab with each person having his/her own small cubicle.  This is a picture of my cubicle in the Lab.

18012011

The cubicle barriers are about 1.6 m high and allow you to work without being distracted when somebody walks by your desk.  This setup works quite nicely although there are some days that I feel the cubicle barriers should rather be taken down to create a feeling of more openness and to “increase communication” in the team. 

We have whiteboards against all the walls for design discussions and two small adjacent meeting rooms to the Lab for ad-hoc design discussions and meetings.  We also have our build monitors setup against a wall in the Lab that shows our TeamCity builds and other dashboard related statistics relevant to our ongoing development efforts. 

 18012011(001)

We will hopefully be replacing the two smallish monitors with one big monitor during this year to make it easier to read as we also use these monitors as an electronic SCRUM task board during our daily at-the-office SCRUM stand-up sessions.

SDLC

Talking about SCRUM, one of my first responsibilities when I joined the team way back in July 2008 was to look at adopting a more formal software development lifecycle.  I’m a firm believer in an agile development methodology and all the disciplines involved with doing agile development so we adopted SCRUM.  We went through quite a few Sprints trying out the different aspects of SCRUM to find out what works best in our environment.  After starting with 2 week Sprints we eventually settled on 3 weeks as our ideal Sprint length.  We tried Planning Poker for a few Sprints but eventually dropped this in favour of just estimating the tasks for a Sprint in Ideal hours.   We had some big debates about using Story Points versus Ideal Hours and how we should track our Velocity.  We took quite a long time to get a Prioritized Product Backlog in place and also struggled to map the backlog back into a project plan that was required due to immense pressure from a big international client.   We eventually got into some kind of SCRUM rhythm, but we still have quite a few areas where we want to improve on going forward. 

For a start I think we need to break the team into smaller groups that focus on specific functional areas of On Key.  We can then use a Scrum of Scrums meeting to discuss the areas of overlap and integration.  We also need to get better at breaking down the functionality in coarser tasks (or work items).  I feel we are breaking down our tasks into too fine grained work items and this causes unnecessary management overhead and also totally clutters the task board with too much detail.   I think a lot of this is as a result of us rewriting and expanding on an existing system, i.e. we have a very good idea of what is required, but I think we must still try and manage the work at a higher level.   This might ease the pain of integrating back into the project plan as well.   Having said all of this, we have mastered a lot of the technical disciplines (like continuous integration, TDD, automated acceptance testing etc.) required for agile development in place and we do succeed at delivering small increments of working functionality in our 3 week Sprint cycle.

Sprint

So how does a typical 3-week Sprint look taking into account that we work remotely for about half of the time?  The following 3 week roster gives a quick summary of the high-level activities involved:

Mon Tue Wed Thu Fri
At the office
Individual Planning and Design Discussions
At the office
Daily Scrum @ 10:00
Daily Build @ 22:00
Working remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
At the office
Daily Scrum @ 10:00
Daily Build @ 22:00
Working remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
Working Remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
At the office
Daily Scrum @ 10:00
Daily Build @ 22:00
Working remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
At the office
Daily Scrum @ 10:00
Daily Build @ 22:00
Working remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
Working Remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
At the office
Daily Scrum @ 10:00
Daily Build @ 22:00
Working remotely
Daily Scrum @ 10:00
Daily Build @ 22:00
At the office
Daily Scrum @ 10:00
Sprint Build @ 22:00
At the office
Retrospective @ 09:00
High level Planning @ 10:00
Demo @ 13:00
Design, Training @ 14:00
Drinks @ 16:00

Well, I think that’s enough for now about the overall work environment.  In my next post I’ll look at the Development Tools that we are using.

Tuesday, 01 June 2010

C# Coding Standards Using ReSharper

I found the following great blog post by Tim Lloyd on how to setup coding standards for your development environment using ReSharper 5.0.  We’ve done pretty much the same thing in our environment although I wasn’t aware of the ReSharper Settings Manager which I will test drive soon as I have found sharing settings between team members to be a real pain.  Seems like JetBrains will look at this for v6 though.  Things we are doing in addition to the content mentioned by Tim are:

  1. Using Agent Smith to ensure the correctness of the spelling for our resource files etc.
  2. Created a more advanced layout template to order all our code using the same structure when doing Code Cleanup

It works great if everybody in the team follows the agreed upon procedure.  I find that this makes code reviews focus on the right things – the actual business logic!

Sunday, 01 November 2009

Code Metrics

NOTE: This is a repost of on old post as I am moving onto the Blogger platform


I've been wanting to do a post about code metrics for quite a while now - mostly to organize my thoughts on the topic as it is something that I want to introduce at work, but also to get some feedback from other people as to if and how they are using metrics to assist them in crafting quality code.  After reading Jeremy Miller's post on the topic, I thought I might as well take the plunge.   I'll start by musing over what metrics I found to be useful, then continue with looking at tool support for generating these metrics and finish off with considering when to use these metrics.

Metrics

I am not going to cover all the different metrics in detail but instead highlight what seems to me to be the most useful metrics and refer to articles/links where other people who have done an excellent job on covering these metrics in detail.  Here are the reference articles that I used:
  1. Robert C. Martin's article on OO design quality metrics [1]
  2. Wikipedia's summary of these package metrics [2]
  3. Kirk Knoernschild's excellent introductory article on metrics with sample refactorings included [3]
  4. Patrick Smacchia's (developer of NDepend software) excellent coverage on all the types of metrics supported by NDepend [4]
  5. Write up on the software metrics supported by the Software Design Metrics software [5]

Size metrics

Size metrics are consistently good indicators of fault-proneness: large methods/classes/packages contain more faults [5].
  • Source Lines Of Code (SLOC) measures the amount of lines of code.  To be really useful comment lines and lines that have been broken into multiple lines need to be factored out.  Some people refer to this as the logical LOC vs. the physical LOC. 
"2 significant advantages of logical LOC over physical LOC are:
  • Coding style doesn’t interfere with logical LOC. For example the LOC won’t change because a method call is spawn on several lines because of a high number of argument.
  • logical LOC is independent from the language. Values obtained from assemblies written with different languages are comparable and can be summed." [4]

Complexity metrics

There is a direct correlation between complexity and the defect rate of software, so keeping code simple is a solid first step toward lowering the defect rate of software [3].
  • Cyclomatic Complexity (CC) measures code complexity by counting the number of linearly independent paths through code. Complex conditionals and boolean operators increase the number of linear paths, resulting in a higher CCN. Methods with a CCN of five or higher are good refactoring candidates to help ensure code remains easy to understand [3]

Package metrics

Coupling/Dependency metrics
Excessive dependencies between packages compromise architecture and design. Complex dependencies inhibit the testability of your system and presents numerous other challenges as presented in [1] and [3].
  • Afferent Coupling (Ca) measures the number of types outside a package that depend on types within the package (incoming dependencies). High afferent coupling indicates that the concerned packages have many responsibilities. [1]
  • Efferent Coupling (Ce) measures the number of types inside a package that depends on types outside of the package (outgoing dependencies). High efferent coupling indicates that the concerned package is dependant. [1]
It goes to reason that:
"...afferent and efferent coupling allows you to more effectively evaluate the cost of change and the likelihood of reuse. For instance, maintaining a module with many incoming dependencies is more costly and risky since there is greater risk of impacting other modules, requiring more thorough integration testing. Conversely, a module with many outgoing dependencies is more difficult to test and reuse since all dependent modules are required ... Concrete modules with high afferent coupling will be difficult to change because of the high number of incoming dependencies. Modules with many abstractions are typically more extensible, so long as the dependencies are on the abstract portion of a module." [3]
  • Instability (I) measures the ratio of efferent coupling (Ce) to total coupling. I = Ce / (Ce + Ca). This metric is an indicator of the package's resilience to change. The range for this metric is 0 to 1, with I=0 indicating a completely stable package and I=1 indicating a completely instable package. [1]
  • Abstractness (A) measures the ratio of the number of internal abstract types (i.e abstract classes and interfaces) to the number of internal types. The range for this metric is 0 to 1, with A=0 indicating a completely concrete package and A=1 indicating a completely abstract package. [1]
  • Distance from main sequence (D) measures the perpendicular normalized distance of a package from the idealized line A + I = 1 (called main sequence). This metric is an indicator of the package's balance between abstractness and stability. A package squarely on the main sequence is optimally balanced with respect to its abstractness and stability. Ideal packages are either completely abstract and stable (I=0, A=1) or completely concrete and instable (I=1, A=0). The range for this metric is 0 to 1. [1][4]
"A value approaching zero indicates a module is abstract is relation to its incoming dependencies. As distance approaches one, a module is either concrete with many incoming dependencies or abstract with many outgoing dependencies. The first case represents a lack of design integrity, while the second is useless design." [3]
Cohesion metrics
"A low cohesive design element has been assigned many unrelated responsibilities. Consequently, the design element is more difficult to understand and therefore also harder to maintain and reuse. Design elements with low cohesion should be considered for refactoring, for instance, by extracting parts of the functionality to separate classes with clearly defined responsibilities." [5]
  • Relational Cohesion (H) measures the average number of internal relationships per type. Let R be the number of type relationships that are internal to this package (i.e that do not connect to types outside the package). Let N be the number of types within the package. H = (R + 1)/ N. The extra 1 in the formula prevents H=0 when N=1. The relational cohesion represents the relationship that this package has to all its types.  As classes inside an package should be strongly related, the cohesion should be high. On the other hand, too high values may indicate over-coupling. A good range for RelationalCohesion is 1.5 to 4.0. Packages where RelationalCohesion < 1.5 or RelationalCohesion > 4.0 might be problematic. [4]
  • Lack of Cohesion of Methods (LCOM) The single responsibility principle states that a class should not have more than one reason to change. Such a class is said to be cohesive. A high LCOM value generally pinpoints a poorly cohesive class [4]
Inheritance metrics
"Deep inheritance structures are hypothesized to be more fault-prone. The information needed to fully understand a class situated deep in the inheritance tree is spread over several ancestor classes, thus more difficult to overview.  Similar to high export coupling, a modification to a design element with a large number of descendents can have a large effect on the system." [5]
  • Depth of Inheritance Tree (DIT) measures the number of base classes for a class or structure.  Types where DIT is higher than 6 might be hard to maintain. However it is not a rule since sometime your classes might inherit from tier classes which have a high value for depth of inheritance. [4]

Tools

When it comes to tools, the Mercedes Benz of .NET code metrics tools from my point of view has to be NDepend 2.0.  NDepend 2 provides more than 60 metrics (including all of the metrics listed above) and includes integration into your automated build via support for MSBuild, NAnt and CruiseControl.NET.  Browse to here for a sample report and here for a demo on how to integrate it into your build. 
There is a visual GUI (VisualNDepend) that allows you to browse your code structure and evaluate the metrics as well as a console application that you can generate the metrics with.  Patrick has also created a CQL (Code Query Language) which allows NDepend to consider your code as a database with CQL being the query language with which you can check some assertions on this database. As a consequence, CQL is similar to SQL and supports the typical SELECT TOP FROM WHERE ORDER BY patterns. Here is an example of a CQL query:

WARN IF Count > 0 IN SELECT METHODS WHERE NbILInstructions > 200 ORDER BY NbILInstructions DESC // METHODS WHERE NbILInstructions > 200 are extremely complex and // should be split in smaller methods.
How cool is this! To quote:
"CQL constraints are customisable and typically tied with a particular application. For example, they can allow the specification of customized encapsulation constraints, such as, I want to ensure that this layer will never use this other layer or I want to ensure that this class will never be instantiated outside this particular namespace."
VisualNDepend also provides a CQL editor which supports intellisense and verbose compile error descriptions to make writing CQL queries a lot easier.  Enough said!  Browse to here for a complete overview of the NDepend 2 features.
Other tools that that you can have a look at include SourceMonitor, DevMetrics, Software Design Metrics and vil to name a few. vil does not support .NET 2.0 and does not seem to be under active development. DevMetrics, after being open-sourced, seemed to have stagnated with no visible activity on SourceForge. SourceMonitor is actively under development and supports a variety of programming languages. However, it supports only a small subset of the metrics mentioned which does not include support for important metrics like efferent and afferent coupling etc. Software Design Metrics takes a novel approach in that it measures the complexity based on the UML models for the software. This has the advantage of being language independent, but you obviously need to have UML models to run
the analysis.

When to use

When should one use these metrics? I agree with Jeremy Miller in his post that the metrics should not replace the visual inspection/QA process and be performed in addition to it. It would be nice to have these metrics at hand to assist in the QA process though. I also agree with Frank Kelly in his post that a working system with no severity 1/2 errors and happy end users are more important than getting the right balance of Ca/Ce or whatever metric you are interested in.
I think I will stick with an approach of identifying a subset of useful metrics and using these as part of an overall process of static code analysis on a regular basis. When I say regular basis I feel it should be part of your continuous build process to prevent people from committing code into your repository that does not satisfy your constraints. With a tool like NDepend you can create your own custom level of acceptance criteria by which the build will fail/succeed and exclude metrics that you feel should not apply to your code base.
As mentioned, the code metrics should form part of a bigger quality process that includes:
  • Visual inspection/QA via peer code reviews (as mentioned having the metrics via a tool like VisualNDepend can greatly assist in the QA)
  • Automated code standards check (I prefer FxCop)
  • Automated code metric check (NDepend seems like the tool to use here)
  • Automated code coverage statistics (I prefer NCover and NCoverExplorer)
Well, that basically covers my thoughts on the topic for now. I'm interested to know how many people are actively using metrics and what metrics they are using. I'd also like to know what processes or tools people are using to generate these metrics on their code. Let me know what's working for you in your environment.

Code Reviews

NOTE: This is a repost of on old post as I am moving onto the Blogger platform

Code reviews are a proven, effective way to minimize defects, improve code quality and keep code more maintainable.  It encourages team collaboration and assists with mentoring developers. Yet, not many projects employ code reviews as a regular part of their development process. Why is this?  Programmer egos and the hassles of packaging source code for review are often sited as some reasons for not doing code reviews.

I felt that code reviews should form part of a good code quality control process that includes:

  • Visual inspection/QA via peer code reviews
  • Automated code standards check (I prefer FxCop)
  • Automated code metrics check (I prefer NDepend)
  • Automated code coverage statistics (I prefer NCover and NCoverExplorer)

In this post I will spend some time looking at code reviews.  I'll start by considering different styles of code review and some code review metrics. I'll then move on to some thoughts on review frequencies and best practices for peer code review.  I'll finish off by considering some tools that can assist with the code review process itself.