Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Friday, November 18, 2011

Duplicate MEF Exports When Export Has Metadata

I just discovered that the Managed Extensibility Framework will produce duplicate exports for parts that are exported with custom metadata. My scenario is pretty simple. I have created an Entity Framework DbContext subclass that is marked up with both [Export] and [DbContextMetadata] attributes. DbContextMetadataAttribute is my own custom metadata attribute.

   1: [Export(typeof(IDbContext))]
   2: [DbContextMetadata(ContextType = "Person")]
   3: public class PersonContext : DbContext, IDbContext
   4: {

The result is shown here:


image


I have verified that this is true by simply commenting out the custom metadata attribute. Interestingly, this behavior is not present when using the MEF ExportMetadataAttribute. I’m planning to dig into this a little more to see why it’s happening, but it certainly was unexpected.


 


Blogger Labels: Duplicate,Exports,Export,Metadata,Framework,custom,scenario,DbContext,DbContextMetadata,DbContextMetadataAttribute,IDbContext,ContextType,Person,PersonContext,behavior,ExportMetadataAttribute

Tuesday, August 9, 2011

Visual Studio 2010 Error–The Project File Could Not Be Loaded. Root Element is Missing.

I happened upon this gem of an error today. It is totally a red herring. I was expecting to find some kind of corruption in the XML like a missing <Project> tag or something similar; however, when I compared the .csproj file between revisions in Subversion, I found no substantial differences, only some additional files added to the project. So what gives?

Turns out that this error is caused by a problem with the .user file associated with the project. Delete the .user file and voila! it works. I can’t take credit for figuring it out. Thanks goes to the BizTalk Tips and Tricks blog here.

Thursday, July 28, 2011

Entity Framework 4.1 Primary Key Convention

I’m very pleased with the move to EF 4.1. Using a code first approach to implement my Repository pattern has reduced complexity and given me additional control over my code base and that makes me very happy. I want to point out one area that is a potential sticking point when implementing your entities.

In our system we have a number of entities whose tables have primary keys that are not identities. These entities have their IDs set via initial load scripts at the time the database is deployed using initialization scripts. As a result, the ID fields are simply INTs. The repository for these entities supports adding new entities and require the caller to set the IDs on their entities prior to calling save.

The point of contention comes from the fact that Entity Framework, by default, considers properties marked as [Key] to be identities. You must supply an additional data annotation attribute to override this behavior. The attribute you must apply to your key field is:

[DatabaseGenerated(DatabaseGeneratedOption.None)]

Forgetting to apply this attribute will cause Entity Framework to generate SQL statements on insert that attempt to rely on the key being auto-generated by the identity. The result is a error when you attempt to insert new data that your ID field cannot be NULL.

Using data annotations on your entities allows you to customize numerous behaviors that Entity Framework provides as well other consumers of your entities include data binding for your UI.

Thursday, June 2, 2011

Reflecting on a Successful Software Release

What goes into a successful software release? I think to really answer that, it would boil down to a really abstract answer – “It depends.” In this blog post, I’ll give you a quick look at what went into making our most recent release a success.

First a little background …

The project that was just delivered was several years in the making. From concept to delivery took a LONG time. The reasons behind this were numerous; some were technical, but the majority were business-related.

The team members that worked on the project in the early days were not the same members that ended up delivering the solution. A couple of hangers-on were there for the whole duration, but largely it was a new team. Even the product owner from the client side was a new person. The team was also a geographically-dispersed multi-national team with language and time zone challenges.

The project’s development methodology changed over time. The process that persisted the longest and the one that was in place at the time of its delivery was a Scrum-hybrid that was chiefly centered on daily stand-ups. It lacked some of the important best practices that successful Scrum practitioners rely on. For example, it wasn’t until the last few weeks that the team had a well-defined and prioritized backlog.

Key Drivers for Success? I’ll give you the top 3 reasons – at least from my point of view, which was as a latecomer to the project.

The background of the project paints a pretty challenging picture for any team that finds itself facing the pressure to deliver a product. And this is certainly true for the team that delivered our product. So what made it possible to pull this off?

#1 Reason – Commitment

The team that delivered the project to the satisfaction of the client was determined to make it happen. Everyone involved knew the stakes and knew that success depended on each of their individual contributions to pull it off. I’ve been involved with projects in the past and almost without exception those that failed to deliver, or at least to deliver on time, were a direct result of a lack of personal commitment from the entire team.

#2 Reason – A Spirited Team Leader

I’m convinced that what brought the team’s commitment into focus and pulled things together at the end was the efforts of a new Scrum master. The team’s newest business analyst was a success catalyst. Her efforts to wrestle the last set of features and defects into a manageable backlog and focus the team’s efforts onto the right areas was a critical piece of the puzzle that helped the team cross the finish line.

#3 Reason – A Little Bit of Luck

Let’s face it, the project background that I gave at the beginning set the stage for another disastrous failure. However, as luck would have it, a number of events came about near the end that made success possible. For example, a new product owner became more engaged near the end and helped to focus the attention on must-haves. The team gained some new members that had experience with delivering results. They pulled together with the original team members and raised the bar for everyone. And lastly, the work of the team was largely usable and had relatively few “big ticket” issues. Had there been some time bombs that were unrealized by the new team, it could have been a very different result.

What was missing that would have made things better?

My top two things on this list are pretty solid in my mind: First – A well-groomed product backlog with priorities set by the product owner. Having that view gives the team a picture of what defines success. Anything short of that and it’s like shooting at a moving target. Second – Team continuity. Churn on a team can be a killer. When people leave they take with them something that can’t be underestimated – knowledge. If that person is a pivotal person on the team it can spell doom. Sometimes that knowledge can be rebuilt – other times not. Reduce your churn to improve your team’s velocity.

So what now? Well our team held a retrospective where a lot of great feedback was gathered and plans were made to put things into place to fix things. We’ll be relying on Scrum best practices to help guide our new process and hopefully will help reduce or eliminate some of the challenges earlier in the cycle.

Good luck on your next project!

Friday, April 29, 2011

Importing DBF Files Into SQL Server 2008

I’m currently working on a new solution to allow geocoding and data augmentation with demographic data. The demographic data set that we are working with is provided to us as several gigabytes of data separated into logical groupings of .DBF files each with 200+ columns of data and an accompanying data dictionary document in Word format.

I needed to upload all of this data into a new SQL Server 2008 R2 database so that we can do some aggregation and other processing against the data. Unfortunately, SQL Server 2008 R2 does not support a direct import of the data found in the .DBF files. One option is to convert the .DBF files into Excel files. Excel handles the conversion easily. Unfortunately, in my case, the width of the tables is simply too wide for the Microsoft Office Data Access Engine to handle properly. When I attempt to import the resulting Excel files into the database I am greeted with a crash error dialog after a lengthy wait.

The second option, which is the one that I had to go with is to use Microsoft Access to do the conversion. Fortunately, Access will open the .DBF files with no problem. I chose to use the import approach as opposed to the linked tables approach. Due to the size of data that I was dealing with, it was actually faster to load the respective tables into Access, and then use the SQL Server upsizing wizard in Access to push the data into a local SQLExpress instance. Once that had completed, I then detached the database, copied the .MDF and .LDF files to the server and reattached.

The only glitch I’ve had with this process is that for some reason Access will fail to copy data into the SQL Server tables. It’s erratic and I’ve not determined why it does this. There are no errors produced during the export process. It creates the table structure with no problem, but occasionally it will fail to copy the data – even though it runs for several minutes. That’s a battle for another time.

Now I’m off to resume my work on the geocoding functionality that will ultimately pull in this data.

Tuesday, April 26, 2011

Quick Tip on SQL Server 2008 Database Projects

I just imported the scripts from an existing SQL Server 2008 database. All went well, except that some of the stored procedures made reference to objects from system databases, which the newly imported scripts couldn’t resolve.

Database projects support making references to other databases in a few different ways. One way is via .dbschema files that you can generate from your projects. This approach is a loosely-coupled approach and improves reuse across your projects.

In the case of the master or msdb databases, Microsoft ships .dbschema files for these for this exact purpose. Simply add a database reference to your project and browse to the directory where Microsoft ships these files: [Program Files]\Microsoft Visual Studio 10.0\VSTSDB\Extensions\SqlServer\Version\DBSchemas, where Version is the version of SQL Server that you are using (such as 2005 or 2008).

For more info on using database references, here’s the link to MSDN:

http://msdn.microsoft.com/en-us/library/bb386242.aspx

Thursday, February 10, 2011

On the Path to Continuous Delivery–Part 1

In this post, I’m going to begin describing the way that I’ve been addressing our pain points associated with delivery of our software. This will be the first of a number of posts that delve into the specific ways that we are altering our methodology to be able to build and deploy our software faster and better each iteration.

First, a bit of background…

When you look at the process that was in place when I joined the company, it was somewhat disjointed. Some parts of it were working pretty well, while other parts were a complete mess (like the deployment process). That’s probably not all that different from what the situation is at many companies (assuming they have a process at all). But considering our company uses Scrum and considers itself Agile, it seemed the process wasn’t allowing us to realize the full benefits of our methodology.

The phrase “Continuous Delivery” was new to me until I attended Agile2010 in Orlando last year; however, “continuous integration” was old news. I’d been using CI for quite some time and found it to be an invaluable part of the software development process. I attended Jez Humble’s session on Continuous Delivery. This practice focuses on making your entire product continuously ready for deployment at any time, all the time. That means all parts of your application – application code, database schema, and any data needed by the app to function. A quick poll of the session’s attendees showed a wide variance in their delivery iteration lengths. The least frequent was once a year and the most frequent was once every six hours. Both were extreme, but it made me realize that if you can deliver your working software every six hours, you could certainly do it once a sprint, once a week, or even daily if needed.

Jez’s talk started me thinking more deeply about how continuous integration represents only the first step in the overall process. What we needed was to apply some of the same principles from CI into how we package and deploy our software as well. What we needed was a way to go from requirements to delivery as continuously and quickly as possible. What we needed was more automation and more repeatability.

Martin Fowler also attended Jez’s session and added some commentary. One of the tenets that he spoke of was about bringing pain points forward in your process and doing them often. The idea being that it would force you to address them and smooth them out. For us, that significant pain was in our deployments.So I began from the backend of the process (deployments) and worked my way backward into the development build/test/stage process. This allowed me to tackle our biggest pain first, look for ways to improve it, and from that learn what our earlier parts of the process needed to produce in order to make deployments easier.

We are faced with a number of complications that make our transition difficult. What fun would there be if it was simple? In particular, we have six development teams (not counting the database development group) and two sets of development tools/environments (Visual Studio 2008/2010 and TFS 2008/2010). Up until this point, the database developer group did not use version control and had their own set of tools, so you could really say we had three sets.

Each team has a slightly different methodology, only one using CI, with the others having some similarities in their TFS build project structure. These six teams are building numerous applications on differing sprint schedules with varying degrees of cross-team integration. They are also responsible for maintenance of their applications as well, which the business expects to be delivered intra-sprint, particularly for more critical bug fixes.

As each team completes their various updates, including testing, they funnel all of their deployment requests to a single team (of two people right now) that review, accept, and perform the request to push the update into the production environment. Today, those steps look very different from team to team and from request to request. And to make it worse, a significant portion of it is manual – from file copies to individual SQL script executions one-by-one. This team is on the verge of burn-out as you can imagine.

That pretty well sums up the current state of affairs. In my next post, I’ll describe the automation pieces that have been built and are now beginning to be put in place by the teams to ease the deployment burden.

Tuesday, January 25, 2011

Unable to Add Entity Model to Silverlight 4 Business Application

I decided to try out the Silverlight 4 Business Application template in VS2010. I just wanted to see what the template produced out of the box. When I created the “BusinessApplication1” project it created both the Silverlight and host web projects for me which I expected.

Next, I wanted to add an entity model to the web project to support a new domain service. However, when I went to add the new item to the project, I received the following error: “"The project's target framework does not contain Entity Framework runtime assemblies..". That’s interesting since out of the box the template targeted the .NET 4 framework.

I found that that only way to clear up this error was to do the following:

  1. Change the target framework for the web project to .NET 3.5 and rebuild. The compile fails because the new code requires features from .NET 4.0.
  2. Change the target framework back to .NET 4.0 and rebuild. The compile now succeeds.
  3. Now I can add the entity model to the project.

Looks like there’s a small problem in the business application template in terms of the web application project file.

Monday, January 17, 2011

CAB Event Publishers and Subscribers

CAB Event publishers and subscribers allow your application to be designed in a very modular and decoupled way. That’s a good thing, but it can bite you if you’re unprepared. In this post, I want to describe a situation that recently snagged me while working on a CAB-based application project.

One of the advantages of using CAB, or other composite application frameworks for that matter, is the fact that your code becomes much more loosely coupled. It helps to isolate your classes allowing you to better unit test. It makes it possible to organize the development of your application functionality into discreet units. In order to support this modularization, CAB brings a number of important features to the table that allows your loosely coupled code to share information.

While this modularization and loose coupling is a big benefit in the big scheme of things, it also puts a burden on you to design your application modules with certain things in mind. In particular, each module will not have direct knowledge of other modules loaded at runtime. In our case, modules are organized into their own projects and do not have any references to one another. At most, they will share some references to common projects that provide some base functionality. If your modules are interested in sending or receiving information from each other, there are a number of possible ways to approach this. The most common way and the way that leverages the publish/subscribe pattern is the use of CAB events.

Using CAB events is very straightforward. In your publisher, simply declare the event that your class will raise. You add the CAB EventPublicationAttribute to the event. The constructor for this attribute takes two parameters: a topic string and an enum for the publication scope.

   1: [EventPublication(ConstantsEvent.CurrentLeadSummaryChanged, PublicationScope.Global)]



   2: public event EventHandler<LeadSummaryEventArgs> CurrentLeadSummaryChanged;




We define a set of string constants for our event topics. In the case above, the publication scope is defined as Global so that CAB notifies everyone that the selection of a lead has changed.



The subscribers to the event simply declare their event handler and apply the EventSubscriptionAttribute. This attribute has a couple of different constructors. One simply takes the string topic ID and the other takes the topic ID and a ThreadOption enum, which allows you to control marshaling of the event data. This is useful when your publisher raises their events from a different thread and you need to marshal it to the UI thread for instance.





   1: [EventSubscription(ConstantsEvent.CurrentLeadSummaryChanged)]



   2: public void CurrentLeadChanged(object sender, LeadSummaryEventArgs e)




At development time, you must take the initiative to make sure that the signatures of the two (publisher and subscriber) match. Your code will happily compile, even if the two have differing EventArg types. If you fail to make them match, you will be presented with an ArgumentException at runtime indicating that one cannot be converted to the other.



Admittedly, the fix for the situation that I just ran into is pretty straightforward, but I think it bears pointing out that your development methodology should take this into consideration. If you miss one, probably the easiest way to locate all of the places where the event is used is to simply search the solution by the topic ID. This will allow you to verify that the signatures match.



Long term, add tests to your integration tests to validate that both publisher and subscribers work together. This will help prevent future mismatches and validate that the communication between the two is working well.



Hope this helps if you find yourself in this situation…

Thursday, January 13, 2011

Troubleshooting “Exception has been thrown by the target of an invocation”

You’ve probably run across this Exception in a number of different situations. In my case, I ran into it most recently while doing some plumbing changes on our application, which is a composite application built using CAB (Composite UI Application Block). One of the most common failures we run into when wiring up new views or controllers is when an Exception occurs within the initialization logic of one or both of these.

CAB utilizes ObjectBuilder2  for dependencies. You will most often get the above exception when construction of your object occurs because ObjectBuilder2 is going through Activator to instantiate the object you asked for.

The problem with this Exception is that it masks the actual problem that is occurring. In my most recent case, it was caused by a null reference that wasn’t being checked. Unit testing and checking for a null reference would have solved this problem prior to doing the wiring (obviously); however, lacking those in the code base I’m working in currently, the best option was to break on the Exception in the debugger and see what was up.

It’s somewhat annoying that the InnerException is null in this case. The stack trace did however yield some insight into the problem and helped to solve the problem.

In my case, starting at the top of the chain with the constructor of the new object helped to ferret out the problem. From there, I was able to go back and properly check my state and handle the null situation without it being a problem.

Hope this helps…

Thursday, December 30, 2010

Just Read “Making Too Much of TDD”

As I read Michael Feather’s points in this blog post, I found myself agreeing so many times that I felt I had to link to this.

http://www.typepad.com/services/trackback/6a00d8341d798c53ef0147e1235b4c970b

I work in a company where the “scientist” in me is constantly challenged and where most in the developer group fall into the engineer group. I think it’s an excellent example of a polarity that exists (strongly) in our company. The business puts extraordinary pressure on the developers to deliver a working solution in the shortest time possible. The natural response is to forego practices that many in the Agile community consider “best practice” in order to just keep up with the pace of change and new features.

I personally get the same sense of satisfaction when patterns just emerge from the iterative process I follow, which is not strictly TDD, but is more or less a hybrid of it. It bothers me that refactoring is not given much attention in our daily development activities, but I am finding myself now questioning many of the beliefs which I held to be incontrovertible (am I being dogmatic?).

I think my most important takeaway from Michael’s post is the unmistakable position that we MUST question our approaches regularly to improve and to seek new approaches that make us better. Out with the old, in with the new. Constantly focus on pragmatism. If doing something doesn’t improve your product or your time to market, drop it.

I also want to better understand his concept “language granularity”. I believe it has an important impact on how we do development here. It touches on a very important business pattern here. Namely, the constant churn our teams find themselves in and the costs associated with the changes that are required in order to satisfy the latest/greatest requirements.

Great read Michael …

Tuesday, November 16, 2010

When Team Velocity is King

Our team met yesterday to do a walk-through on a project that was developed by a group of contractors for a high-priority project. A significant portion of the project architecture relied on patterns like dependency injection, factories, and the like to gain a high degree of loose coupling. This was motivated by the ever changing requirements for the product owner and the demands that the system be easily extensible.

At various points during the review, some of the team members that had the longest time on the team made comments that the design was too abstract, that “we’d never do a system this way.” When we came across a set of tests that had been commented out, the response was, “Good, we didn’t want to maintain tests anyway.”

Being the new guy on the team, I wanted to understand why they felt that way. The general opinion of the team was that abstraction and unit tests were simply too time consuming to implement and yielded too little value to consider for their applications. This position intrigued me – considering how much adoption and support Agile practices for software engineering have across the industry.

I believe this opinion is rooted in the business’s belief that “better is the enemy of ‘good enough’”. They are more interested in getting applications out quickly, with as few bugs as possible, but when bugs do occur, they are VERY tolerant of them. The cost associated with fixing the bugs, even if they are found in the field by end users, is not seen as a significant reason for being more strict in the development methodologies to prevent them.

Instead, they rely heavily on business analysts acting as QA and end users to ferret out the defects that are most critical and fix them then and there. More esoteric bugs that don’t dramatically affect the usability of the applications are glossed over and may be fixed in the future when time allows (or may not).

All of this is motivated by the belief that “going fast is the single most important requirement for our development teams.”

Velocity is King here – and it’s good to be the King.

Friday, March 5, 2010

Starting Down the Path of Android Development

Awhile back I decided to begin doing some Windows Mobile development. Overall, it’s been a good experience and the tool support from VS2008 is excellent. The ability to debug your mobile app in a virtual device emulator is extremely helpful to visualize how your app will run on the target device platform.

However, now that I’ve had the chance to begin using the Motorola Droid and seeing their marketplace application, which gives access to scores of free and pay apps, it has convinced me that I need to begin looking at developing for this platform as well. In the short time that I’ve used this new phone, it’s clear that the user experience is far superior to WM6. Not having seen the new Windows Mobile 7 platform more than a couple of screenshots, it does look like it WM7 could be a strong competitor though.

My next posts will be about ramping up and getting started with a basic application for this platform. It should be exciting and hopefully I can help share some of the stumbling blocks that I run across to save you a bit of your own frustration.

del.icio.us Tags: ,,

Friday, February 19, 2010

Exporting Table Definitions from SQL Compact Edition Database Files

While working on a mobile app that uses SQLCE, I was unpleasantly surprised to find that there was no built-in capability for the SQL Server 2008 Management Studio to export table definitions into a script file. So when I found that @ErikEJ on the CodePlex site had written this little plug-in I was quite happy.

Thanks Erik For a very useful little utility :)

del.icio.us Tags: ,,

Friday, February 12, 2010

Writing Stored Procedures for SQL Server 2008 in C#

This is my first foray into writing stored procedures for SQL Server in managed code. I decided to check it out since I was already doing some other SQL Server work in support of a WPF-based Agile project management application and thought this would be a good opportunity to explore a little and see how it might apply.

Let me be clear, this is a post really to capture my thoughts and experience along the way. I’ll include links and quotes where it seems applicable.

Decision Points

From “Overview of CLR Integration” - http://msdn.microsoft.com/en-us/library/ms131045.aspx

Choosing Between Transact-SQL and Managed Code

When writing stored procedures, triggers, and user-defined functions, one decision you must make is whether to use traditional Transact-SQL, or a .NET Framework language such as Visual Basic .NET or Visual C#. Use Transact-SQL when the code will mostly perform data access with little or no procedural logic. Use managed code for CPU-intensive functions and procedures that feature complex logic, or when you want to make use of the BCL of the .NET Framework.

Choosing Between Execution in the Server and Execution in the Client

Another factor in your decision about whether to use Transact-SQL or managed code is where you would like your code to reside, the server computer or the client computer. Both Transact-SQL and managed code can be run on the server. This places code and data close together, and allows you to take advantage of the processing power of the server. On the other hand, you may wish to avoid placing processor intensive tasks on your database server. Most client computers today are very powerful, and you may wish to take advantage of this processing power by placing as much code as possible on the client. Managed code can run on a client computer, while Transact-SQL cannot.

* Note: I have some reservations about the suggestions made in the last section. While many business-class PCs today have more processing power, and while scenarios may exist where it would be nice to distribute the computational work to the client, it is likely unreasonable to place the burden of processing on the client PC due to the need to transfer the required data to the client. This seems like a corner case, which probably doesn’t happen often.

Advantages

While reading through the various articles, I came across this list of advantages for using managed code instead of Transact-SQL.

  • Enhanced programming model
  • Enhanced Safety and Security
  • User-Defined Types and Aggregates
  • Common Development Environment
  • Better Performance (for computational sorts of logic; see the point above regarding straight data access)
  • Language richness
  • Reusability of code
  • Extensibility
  • Leverage existing skills
  • Richer development experience
  • Stability and reliability

Step-by-Step

1) Create the database project in your solution. Click the database category and choose the “SQL Server Project”. Give it a name and choose the directory where you want it created.

The wizard will create a .SQL script from which you can test the database objects that you create.

2) I decided to create a subfolder in which I’ll place my new stored procedures

3) After that, right-click the new folder and add a new stored procedure; give it a descriptive name. Use a naming convention that lets you know what the stored procedure does. I prefer to prefix my stored procedures with the name of the module of the app that it applies to; e.g., Products_InsertNewProduct or Products_SelectProductById


4) The stored procedure template will give you a basic outline for a stored procedure. The first thing you’ll notice is that it creates a static method on a partial class. Also, the method is marked up with the Microsoft.SqlServer.Server.SqlProcedure attribute.

5) Modify the signature of the method to include the parameters that you want

6) The implementation of this is pretty much plain vanilla ADO.NET; There are a couple of minor differences to make note of:

a. The connection string for the SqlConnection is based on the current context that the stored procedure is running under:
”context connection = true”

b. When returning data, you use the SqlPipe, which is accessible from the SqlContext

7) Next, compile and deploy the project. Both of these commands are available from the “Build” menu.

That’s about it for now. You can use the Test.Sql script that is generated in the project in order to test your procedures. Going forward, I see lots of potential for code reuse. My next post on managed code for SQL Server will focus on triggers and user defined types.

Have fun!

Related Links

Introduction to SQL Server CLR Integration (ADO.NET)

Overview of CLR Integration

Creating SQL Server Objects in Managed Code

del.icio.us Tags: ,,,

Sunday, January 31, 2010

BDD Tooling

In my previous post on BDD, I alluded to tools that would come along to help with bridging the gap between specifications and test code.

"...new advances in DSLs would provide a potential bridge to generate
functional code to validate the requirements have been met. It seems to
me this would provide a much higher value from a testing and code
quality perspective as you are now writing tests that are 1) driven
directly by the requirements; 2) oriented at a piece of functionality
that directly affects the user."


A tweet from @ryanlanciaux today pointed me to SpecFlow. This tool looks to have a lot of promise in doing just what I described above.

You can read more about SpecFlow and download it from here: http://specflow.org/home.aspx

I plan on downloading SpecFlow this week and giving it a look. I'll post more on my experiences and thoughts regarding this tool after had some time with it.

Wednesday, November 18, 2009

Behavior Driven Development

After my last post on metrics, I came to the realization that what would be a much better approach to testing would be to focus on Behavior Driven Development. This methodology focuses on the use of scenarios to describe a small piece of functionality. Given its natural language approach to describing things, it provides an easily understood description of the requirements. For example:

Scenario 1: Refunded items should be returned to stock

  • Given a customer buys a black jumper
  • and I have three black jumpers left in stock
  • when he returns the jumper for a refund
  • then I should have four black jumpers in stock
From this, new advances in DSLs would provide a potential bridge to generate functional code to validate the requirements have been met. It seems to me this would provide a much higher value from a testing and code quality perspective as you are now writing tests that are 1) driven directly by the requirements; 2) oriented at a piece of functionality that directly affects the user.

Of course, some situations make this a difficult approach to use. For example, in my team's case, framework and API development would be somewhat more challenging to apply this approach. In order to overcome the lack of user-oriented scenarios, it may be necessary to approach it from an API-consumer perspective. A DSL here would perhaps help to bridge this gap, but still doesn't quite give the same clean application. Still, it seems like the benefits are there.

Something for us to consider as we move forward with our next release starting in January...

Tuesday, November 17, 2009

Metrics - Are they useless?

In the early stages of our project, we set a goal for ourselves of 70% code coverage. Besides not being reasonable or attainable given our deadlines, in the end, what did it really do for us?

Is pure code coverage effective at eliminating defects? In my opinion, the clear answer is 'No'. Though admittedly our code coverage in our last release was significantly higher than the release before, and our defect rate was significantly lower, I'd suggest that improved quality was due to other factors including a much cleaner and less-complex design.

In the end, I'd say that code coverage like other metrics are just a glance at the quality of your code. Use it for what it is - a tool and don't lean too heavily on it, otherwise you just might fall :)