Archive for the ‘methodology’ Category
Branching build scripts for production branches
At work we recently switched to using Team Foundation Server with a ‘proper’ branch/merge strategy. We also have improved our build process so that although it’s still a partly manual process, a document leads you through the process, and the process is repeatable as all the build scripts are source controlled and each build starts from a know starting point (VM with pre-reqs and build software).
Until very recently the builds were always run against ‘Main’, but we’ve now got a production branch, and I’ve been asked to modify the build scripts to get the source from the production branch rather than Main. To do this properly I think I need to do the following:
- In the production branch modify the source controlled build scripts to point to the correct source location.
- Create a copy of the build instructions specifically for this branch that say where to get the build scripts from (production branch)
To allow builds from Main and any Production branches both the document and the build scripts need to be branched.
Translation Tester, Part 2 – Approach
In part 1 of this series I described the problem I’m trying to solve. Before I delve into solving the problem I’d like to take a quick moment to reflect on the development approach I plan to take for this project.
This is the first time I’ve tried to do any development outside of work, so I’m going to acknowledge from the outset that I don’t have a very detailed approach in mind, and I’m more than likely to change it as I go along. This fits quite well with my experience of agile development methodologies, so I’m going to try and put as many of the agile techniques into practice that I can. I’m pretty much development centric, so I’d also like to have a look at some of the related skills relating to requirements analyis and project management.
So as I see it the stages that I’ll need to go through in approximate order are:
- Initial requirements
- Iteration 0 – Get a skeleton solution with Continuous Integration etc
- High Level Design – I don’t want to get into too much detail at this stage, but just taking a moment to think of a broad design might help
- Find a suitable requirement/use case and implement it using Test Driven Development
- Analyse what comes out of the implementation and update requirements etc as needed. Lessons learned etc.
- Repeat steps 4 and 5 until all the requirements have been met.
So that’s my very rough approach, I’m sure I’ve missed oodles, so please drop a comment to suggest any pit-falls etc.
Code review, before or after check-in?
Recently I’ve been thinking about our code review process, and how it could be improved. We’ve recently moved from a simple VSS based source control to a more feature rich TFS based approach.
We now have the majority of feature development occurring in several development branches, at the end of each development iteration we get all the changes reviewed and then merge the changes into our Main (or trunk); a build from Main will then be passed to test.
Problems we’re finding with this approach are:
Development Code Freeze
Whilst code is being reviewed (and review actions being actioned) we pretty much freeze feature development in the branch, the code review can often take a long time, so people often start doing further development off-line, ready to check-in once the freeze is lifted.
How can we make sure that what is eventually merged into Main is what was reviewed?
If the review is done against the changes between Dev and Main then you miss reviewing any merge conflict resolutions (unless you do a 2nd review). If you review the ‘pending merge’ (where someone does all the merge process apart from the final check-in to Main), you risk the merge no longer being valid (someone else checks into Main between pending merge and review complete).
Seeing very little benefit from the review
Our process of reviewing all code going into Main is giving us a false sense of confidence, as we think Main has top-quality code in it; in fact this is not the case, often it seems the only review comments that are actioned are fairly trivial changes that wont take very long. Any fairly major changes are often deferred to a future ‘Change Request’, with the merge going ahead anyway, as the feature is required.
We do want to prevent breaking changes going into production or even to test, but this should probably be caught by testing (automated) and Continuous Integration.
Code review is inconsistent
Code reviews are processed in a fairly inconsistent out-of-band way, with very little formal process around it. Review comments can sometimes be lost, and tracking whether the review was fully actioned etc is not 100% possible.
Suggestion: Do the code review after the check-in to main
So the suggestion I’ve been making is that instead of holding up the check-in to main with the code review we do the code review afterwards. The process would be something like this:
- Feature development is done in a development branch
- Towards the end of the iteration the code is prepared for check-in to main
- The code is merged into main
- The check-in to main causes a code review task to be created for the changeset
- Code review actions are done directly against main.
- Once the code review has all been resolved (actioned, further tasks raised etc). It is marked as closed.
- Before main is pushed to production all feature development code reviews must have been completed.
- Development Freeze – by decoupling review from development the two activities could run in parallel, as soon as the merge is complete development could resume. If merging up to a label you wouldn’t even have to freeze whilst the merge is done.
- Review exactly what was merged – by definition we would be reviewing what was merged. We could even say that review actions should be reviewed so no changes to main go unreviewed.
- Review benefit – by decoupling review from development and making the review process more traceable I think we will be able to add review actions to the product back-log and then even the big changes will be done. Review actions should be treated in a very similar way as feature development with priority dictating what is actually done.
- Review inconsistency – having a proper review process that is tracked with tasks will means a more consistent approach and a reliable process. Any unresolved review comments will be searchable/reportable just like any other tasks.
- I think we would risk checking in bad code to main, and although we could use our source control system to roll these back etc, we might not catch them in time – I don’t think, however, that our current process really stops this happening.
- Reviewing could be neglected in favour of feature development, but this just means that project management needs to see the importance of the review process and prioritise the tasks appropriately.
Accepted Best Practice
Before writing this post I tried to search for the best practice in this area and couldn’t really find any. I guess one answer is that instead of code reviewing paired programming could be more effective. Does any one have any suggestions as to what others are doing?
When to use constants, settings.settings and Resources.resx
When developing in Visual Studio (2005 upwards I think), you have several options when it comes to referencing strings in your code (and other types, but I’ll restrict to strings for the sake of conciseness). I think it is safe to say that usually you do not want to hard-code the string directly in the code, but should you create a constant ‘at the top’ of the class? or should you create a class for constants to use throughout the project/solution? or should you use the project settings (settings.settings)? or should you reference it as a resource? Whew, that’s a lot of options!
As I see it my guidelines would be:
- If the string will never need to be changed and is only relevant to the class in question just reference it as a constant within the class. This will keep it proximal to the code using it, whilst concentrating all the class constants in one place.
- If the string will never need to be changed and is relevant to multiple classes define it in a single class at a scope that makes sense (project/solution wide)
- If the string needs to be changeable by the end user at configuration time then settings.settings should be used.
- If the string needs to be changed based on the locale the application is running in (e.g. It contains text displayed to the user) then it should be put in the resources.resx file.
- If the string sensibly fits within a grouping of configurable items that could be applied to the application (e.g. you want to be able to ’skin’ your application so that multiple configurations can be chosen) then it should be put in a resources.resx file.
I think the question of settings vs Resources can be a little tricky, as far as I am aware the differences are:
- Resources.resx file are only modifiable pre-build, the end-user will not be able to change the contents; Settings.settings files are rolled up into the application’s configuration and are therefore customizable by the end user.
- Settings.settings files are not localization aware, they should not be used to make your app localizable. Resources should be used for this.
TALC Driven Development
Recently I’ve been reading several blog posts about the effectiveness of Test Driven Development. Of particular interest is Jacob Proffit’s TDD or POUT
It seems to me that there is Plain Old Unit Testing, which I would argue implies “test at the end” unit testing at one of the spectrum, and then pure TDD at the other end. I see myself being near the TDD side, but not all the way; in fact I would categorise my approach as “Test After Little Code” Driven Development, or Pragmatic Unit Testing. What I tend to do is write a little bit of code first then write a test that exercises the code. From that point I’ll do one of two things, either write another little bit code and then test it, or sometimes write another test which deals with a slightly different case and then write the code to make it pass. Often different situations seem to lend themselves to a different approach.
I’m not sure exactly how Jacob does POUTing, but I’d imagine he doesn’t leave all the unit testing to the end. I think this is the real ‘enemy’ of unit testing, as by the end you are facing all the issues that TDD addresses such as code that isn’t testable, or no time left to test. These issues aren’t only solved by TDD, they can also be solved by incremental unit testing.
How does Silverlight fit into a ‘proper’ UI architecture such as MVC?
With Microsoft releasing a whole caboodle of new tools as part of VS2008 and .net 3.5 I thought it would be fun sensible to spend some time trying to figure them out and having a play. I also thought that I would spend some time playing about with some UI tools/best practices that I had heard about but never used (such as MVC and Monorail).
My grand idea is to create a system to act as a Video File Organiser, I have some initial thoughts about what I want it to do, but the main reason to do it is to play with the tools.
I want to create a Silverlight UI, working in a proper MVC architecture that uses an Astoria web data service to query the library. At some point I’ll also think about how I would like to populate the library with video files on the server.
Problem 1 - Silverlight with MVC
Granted, Silverlight looks fantastic, but I haven’t been able to find much about how to combine it with proper architectural best practice. What I would like to do is figure out MVC and Silverlight at the same time, and see if it makes sense to use Silverlight as the View. This is all just guesswork at the moment, and my first task is to try and familiarise myself with the basics of these technologies before I start trying to combine them in weird and wonderful ways.
I assume I could ‘do’ MVC from scratch, but I wonder if it would be possible to use a framework such as Monorail? Monorail doesn’t seem to have any mentions of Silverlight, so might have to figure this one out by myself. It seems that Silverlight would make sense in one of two places -
- Create a new Monorail view engine for silverlight - this would somehow create the silverlight markup…
- Use an existing view engine – not sure what view engines really are, but could NVelocity create Silverlight already if you specify the appropriate template?
Either way, how do you connect the controller to the silverlight generated…. hmmm
Dear reader, I will report back once I have investigated.
Mocking without a mocking framework
I have not yet had the opportunity to use a proper mocking framework. My project has a future investigation into them, but it’s a low priority. However we are using Test Driven Development, so we have started using mocks (with dependency injection), so far the mocks have been statically defined and we are ‘learning as we go’ in the sense that the quality of the mock is changing as is our technique for creating them. We started off with a mock of a database with hard coded data in it, if you like we were replicating a simple set of data that the mock would interrogate. Over time this became very messy and was difficult to change for a specific test as you could break an existing test. The next approach was to remove all hard coded data and provide a mock that could be dynamically loaded with data by the test. This seems better (and more like how mocking frameworks work I believe). However recently I realised the method for loading data was flawed as if a class called the same method twice, but required different output on each call then the mock would not be able to provide this. The following shows my current thinking for how to define a bespoke mock with dynamically loaded data. Using a queue to load the data for each call.
- Create your mock implementing the mocked object(s) interface(s)
- Create a field/property of type queue<type> for each type of data that needs to be returned
- Create a constructor for the mock that news all the queues
- For each method on the interface(s) take the appropriate queue and Dequeue() an item from it
public class MockDB:ICustomerDataAccess
{
#region Dynamically loaded results
private Queue<List<Customer>> loadedCustomerListQueue;
public Queue<List<Customer>> LoadedCustomerListQueue
{
get { return loadedCustomerListQueue; }
set { loadedCustomerListQueue = value;}
}
private Queue<Customer> loadedCustomerQueue;
public Queue<Customer> LoadedCustomerQueue
{
get { return loadedCustomerQueue; }
set { loadedCustomerQueue = value; }
}
#endregion
public MockDB2()
{
LoadedCustomerListQueue = new Queue<List<Customer>>();
LoadedCustomerQueue = new Queue<Customer>();
}
#region ICustomerDataAccess Members
public List<Customer> GetCustomerByForeignKey(long ID)
{
return LoadedCustomerListQueue.Dequeue();
}
public Customer GetCustomerById(long id)
{
return LoadedCustomerQueue.Dequeue();
}
#endregion }
To use the mock in a test:
- Create an instance of the mock
- Enqueue items into the appropriate queue in the order that they should be returned in the tested class.
[TestMethod()]
[ExpectedException(typeof(CustomerMaintenanceException))]
public void UpdateCustomer_DoesntExist_Fail()
{
MockDB Mock= new MockDB();
UpdateCustomer target = new UpdateCustomer(Mock);
Customer NonExistant=new Customer();
Mock.LoadedCustomerQueue.Enqueue(null);
target.Execute(NonExistant);
}
Some points to note:
- You can enqueue null values onto a queue
- You can have a queue of lists
- This only works if the tested class has a predictable logic flow, but for a proper unit test this should always(?) be the case
- This is not meant to be better or even anywhere near as good as a mocking framework, but where you can’t use a framework this approach seems sensible
Update: As my knowledge of mocking has improved I have realised that this is not really mocking, rather a sort of dynamic stubbing (see this post)
How to handle dependency injection with nested dependencies
Recently I managed to get myself rather confused trying to use Test Driven Development to test a specific business logic class (Class A). Part of the business logic had been refactored into a seperate business logic class (Class B), this class had a set of dependencies that were properly coded to allow for dependency injection. The problem was that Class A also included all the dependencies of Class B, and when the class B was called the dependencies were setup based on the dependencies of Class A. This all seemed ‘ok’ until I decided that a unit test of Class A should not really test Class B. (This is obvious when you think about it, but because Class B had originally been part of Class A it hadn’t clicked straight away). Having never worked with dependency injection where there are nested dependencies I had a little trouble refactoring to allow class B to be mocked.
Following are the guidelines I reached for working with nested dependencies:
- The dependencies of Class B should not be included in the dependencies of Class A
- The operations in Class B need to be extracted into an interface (IClassB)
- Class B should implement interface IClassB
- Class A should operate on an instance of this interface
- A Mock of Class B is created that also implements IClassB
- When setting up Class A (e.g. from a unit test) the dependency on IClassB needs to be initialised using the MockClassB
If using default constructors to setup the ‘default’ dependencies (I believe this is known as “poor man’s dependency injection”) then the default constructor for Class A should simply create a default instance of ClassB (allowing Class B to setup its own default dependencies)
Is consistency of method within a solution essential?
As a developer I find that I am constantly finding out about new development methods, constructs and techniques. I don’t know if this is because I am relatively ‘fresh out of uni’ or that I am working in a ‘new’ technology area (e.g. .net3.0) << how many dots?!>> Or whether this is just how development is.
When I find a new method I tend to implement my current task using the new method leaving existing parts of a solution using the ‘old’ method. This can result in a somewhat inconsistent solution, with different areas of the solution using different methods.
Is this a ‘bad’ thing? probably, ideally you would have implemented the whole system using the ‘better’ method from day 1. But is it better to re-do areas of a solution that are working fine as they are? this will take extra effort, and could introduce bugs unneccessarily. So if you don’t re-work all areas of the solution should you resist using new methods within a solution thereby keeping consistency, but not taking advantage of better techniques. Also introducing new methods can be irritating for other members of a development team as they also must understand the new method to be able to work effectively with the solution.
Is it ok for a single solution to use many different building blocks? lots of different methods all working together? It is probably not ideal and I guess this is the purpose of having lead developers and architects who are aware of the general development community and make educated decisions as to which methods will be used and which will be vetoed. But does this mean that non-lead developers should just be code-monkeys? should they not be interested in promoting techniques and methods that aren’t in the existing architecture?
So what do I think? Hmm well I’m not sure, to be honest I liberally go through existing solutions and use new techniques freely with little consideration for the rest of the solution (of course I check everything still works and I haven’t broken existing tests/functionality). However I think that developers should be encouraged to investigate new techniques, but they should not be introduced to production code without discussing the technique with the lead developer or the rest of the team. I do not think that mixing and matching within a solution is definately bad, and in some ways it is a demonstration of decoupling in a solution. The total number of methods in a solution should be managed so as to maintain the maintainability of the solution, so each new method should be judged and a decision made to do one of the following options:
- Not use the method at all
- Not use the method in existing solutions but use in new solutions
- Use the method in all solutions, without reworking existing areas
- Use the method in all solutions reworking solutions completely to the new method
Whatever choice is made effective communication to the whole development team is essential.
Leave a Comment
Leave a Comment
Comments (5)