That time's come again - another project's come along (actually an oooollld project from 6 years back has come around again), and I'm about to fire up Windows Explorer and Visual Studio ready to start dev.
I've done this dozens of times over the last couple of years, but I still remember back in the early days struggling to get to grips with where to put what, where to put my DLLs, my unit tests, etc. So I thought some folks might benefit if I jot down some notes as I go along. This post will detail exactly how I get started with a new Visual Studio project, in this case looking at an MVC project, and all of the things I do before I start cutting code.
By the way, this is the same project structure I use for most of my enterprise level work. I'm going to document this for Subversion users, as I still feel like they're in the majority (and I still suck at Git), so Git or Mercurial users will possibly want to ignore me when I talk about branches and trunks!
Getting Started - My Visual Studio Project Template
First things first, we need to do some work in Windows Explorer. Straight away, I'll create the following folders, and download a few DLLs along the way:
- \ProjectName - Obvious enough, we need a folder for the project.
- \trunk - This is the mainline where all the major dev will take place, I'll be using branching by abstraction and release branches, so no need for any branches or tags yet.
- \database - If I'm doing Database versioning, my delta scripts will live in here along with the scripts to run them in
- \deploy - Automated deployment scripts live in here, these are currently NAnt scripts, maybe old skool, but they work.
- \libs - This is where I'll keep all my DLLs that are required by my application. As well as the ones listed below, in larger projects I may have DLLs in here that are the output of other smaller projects, for example to abstract away any complex URL rewriting logic, ,
- \src - This is where all my production code lives, my non-testing Visual Studio projects will live here.
- \tests - And this is where my test code lives. All my unit test and integration test projects will live here.
- \tools - Tools are distinct from libs in that they're not required by my application to function, instead they're required by things like build and deploy processes, test coverage reports, etc.
- \NUnit (http://www.nunit.org/) - I do normally have two instances of NUnit in my project - this one's the full blown app for actually running my tests from my automated build scripts.
- \NAnt (http://nant.sourceforge.net/) - Required to run my build and deploy scripts, firing off MSBuild, NUnit, maybe test coverage analysis, positioning files, etc.
If anyone's questioning at this point why I'm bundling up my tools into my repository, I always like people to be able to check out what's in my repository, and for it all to just "work". The tests should all just work, the scripts should all do their jobs. Of course, this is a big part of why I prefer free tools such as NUnit or OpenCover, over their commercial counterparts such as MSTest or DotCover.
As well as the above, depending on the project I may add some of the following additional libraries:
Creating The Solution
Now that the folders are fleshed out, let's get the solution created. Spin up Visual Studio, and I'll start by creating my application project (in this case an MVC 3 Web Application), which I'll save to the following location:
Depending on the type of solution, I'll now move and rename the ".sln" file that's been created from the "src\" or "src\ProjectName.WebUI" folder down into the "trunk" folder. I'll do this outside of VS by moving the .sln file in Windows Explorer, and then modify the pathname in the .sln file point to my project so it all still works. Also, don't forget to move or delete the .suo file as well!
Create Your First Test Projects
Back in Visual Studio, after re-opening the moved and modified solution file, all still looks good, the solution still builds. But before we can start any work, of course we're going to use some variant of test-driven development, so let's create our test project(s). I like to implement two forms of testing now - an outer ring of BDD-style integration or acceptance tests, in addition to my standard layer of unit tests. So we'll need two test projects.
First let's create our standard unit test project in Visual Studio:
- From the File Menu, choose "New > Project".
- We want a C# Class Library, which we'll call "ProjectName.WebUI.Tests", and we'll save at the following location: \trunk\tests\ProjectName.WebUI.Tests
- Finally we need to add references to our two testing DLLs in our "libs" folder, NUnit.Framework.dll and Moq.dll
And now let's create our specification test project:
- From the File Menu, choose "New > Project".
- Another C# Class Library, this time we'll call it "ProjectName.WebUI.Specs", and we'll save at the following location: \trunk\tests\ProjectName.WebUI.Specs
- Finally we need to add references to our specification testing DLLs, NUnit.Framework.dll and TechTalk.SpecFlow.dll
So there you have it - the critical first steps in creating and organising the solution. In part 2, I'll be looking at the version control side of things, part 3 should be the first phase of automation, and in part 4(ish) the first unit and SpecFlow tests, before getting into the actual development cycle, showing how I use the inner and outer test loops, where I use automation, when and how I start bringing external entities such as databases into the mix, and what I'll do when the app spreads from the desktop to the mobile platform.
Who knows, I may even reveal all about the project itself!