Showing posts with label programming tools. Show all posts
Showing posts with label programming tools. Show all posts

Thursday, 13 May 2010

Programming Tools: Versioning (and magic)

The programming tools series of articles (which, I know, I promised I had already finished) relied heavily on the version control system at its heart.

Today I want to talk about a new feature of versioning: Magic Files

Imagine, I check into the version control system my source code (or a gif), I want the facility to say to the VCS "now give me the compiled code" (or "now give me a jpeg version of the gif"). The VCS - not me - should know how to generate the file I'm asking for. Because there should be rules which tell the VCS how to generate the file

Now, because we can make a rule that any such process should be side-affect free, once the VCS has generate the file, it can keep a copy of it, at least until one of the files that were used in generating it has changed. And there is nothing to say that the VCS has to wait for someone to ask for the file before it generates it - if it sees free processor time, the VCS can spawn compilation.

We can take this further: why not just check out your test results file: that would run every test and tell you how it did. And running an individual test [by looking at the individual test results log] would just check out the files it needed to run - which means only the files needed to perform a test would be compiled - leading to the optimal code-compile-test loop.

In short, I'm talking about merging the version control system and make.

Its a different world - and one which probably requires far more storage (and a few extra VCS features such as a 'regenerate' option to regenerate a file which for some reason went awry) - but one which feels to me more inherently usable, and which provides us with more records of exactly what has and hasn't been run.

Thursday, 29 April 2010

Programming Tools: Bugtracking

My final set of requests for a development environment involve the bug tracking system.

The initial observation that I wish to make is that bugs relate to a particular version of code. And that bugs stay with code until they are fixed. This means that bugs are related to the version control system. For any branch of the code, you should find exactly which set of bugs it has, and which bugs remain open. Closing bugs tends to relate to a particular point in a version control system: either "This is the fix for the code" or "This is the point where I verified that the bug no longer exists". When you split a branch, you take the bugs from that point in time - and when you merge a branch back into the main tree - or pick up the changes from one branch into another, you should pick up the changes to the bug database too.

In an ideal system, when you check out a branch onto a local machine, you should also be able to check out a copy of the bug tracking system... which you can make changes to - changes which will be applied when you merge back later. This allows you a full dev environment when away from the corporate network.

Bugs are also related to tests. Tests should be able to generate bugs... these bugs are probably along the lines of "Test xyz fails", providing links to an overnight test failure. Bugs should also be able to say "This test will identify this bug" so that you can get the test system to help verify when a bug has gone.

Bugs form trees (or rather directed acyclic networks), in a similar way to a version control system. For example the test system might generate the bug "Test xyz fails". I might take this bug and want to split it into two bugs "On windows test xzy fails because of foo" "On Linux test xyz fails because of something else". If I were to then notice that I already have a bug about windows failures due to foo, I should be able to merge that bug with it.

Bug entry needs to be easy. Really easy. When a test fails, I need to be able to add a few notes to it and WHAM! thats the bug added. Bugs are a place to store knowledge, and to allow me to find things that are outstanding.

Bugs also need to be integrated with email. I need to be able to send people questions, directly relating to the bug (so that the question, and the response, are stored in the bug). Bugs really are a chat system. This is not a bad thing.

Finally, Bug tracking and todo lists are tightly integrated. So much so, that most developers I know use bug tracking as their todo list. So when I send another developer a question - that needs to show up in their todo list - as an uncompleted part of a bug. And users need to be able to add their own private bugs, and import their emails into bugs to let them keep track of their own tasks.

I've talked about bug tracking for non-IT businesses elsewhere. And this bug tracker needs to support all of that.

Monday, 26 April 2010

Programing Tools : The Test Farm

In my discussions about programing tools, I've talked about there being a farm of build machines, so that builds can run in the background, and so that you always have a working build environment when you need one. The same has to be true of test.

Automated test is something which is more valuable to the software industry than anybody who doesn't have experience of it can imagine. It doesn't replace the test team, but it means they can focus their energies on finding new and better bugs rather than ensuring that old favourites don't rear their ugly heads.

As a developer, there are many things that stop me working. Sometimes its a problem, somthing I have to think about, mull over and ultimately solve. But sometimes I'm blocked by the fact that in order to do something, I first have to do something which is a hassle. Every time I am asked to test on a different platform, I feel that hassle. And I put off the move... on a bad day, I go to the warm (slightly tacky, a smelling of cheap perfume) embrace of the internet.

I wan't this hassle gone.

I want to say "Run this test in this environment" to my dev suite, and tlet the software find an appropriate machine.

And for that I need a test farm - just like build farm, it needs to have a number of daemon equipped machines, which are ready to run the tests I give them (and which ideally are able to clean themselves up totally - they really need to be able to reimage back to a newly installed state if I so wish)

But I also want wrriting tests to be easy. I must be able to go to my dev environment and say "now I want to write a test". It should give me a place to write that test, and appropriate tools to help me produce a working testable system.

Early stage test development is just a matter of setting appropriate applications running, and ammassing output. But I also later need to be able to write code to verify the output is correct.

And once I have tests that work, I need to be able to run them on every platform (perhaps scheduled overnight), and I need to be able to submit them, so that my tests enter the range of tests available to everybody.

Once I have those features, writing tests will be the standard way I choose to begin to develop my software. And as a company we will end up with many many tests.

The advantage of many many tests is overnight testing runs.

Overnight testing runs are really important. And they shouldn't just run overnight. They should run whenever there is spare time available on the test farm, testing every development build the build farm has generated. And they should report to the owner of a tree whenever a test failure is found.

On identifying a test failure, I need to know the history of the issue - has this failure occured before? On my branch? On the main tree? I need the system to binary chop for me, and find the point where the failure first occured. The test system, like the buiold system, needs to be fully aware of the version control system. And these failures should find their way into the issue tracking system. Ideally without my help - because if tests are failing, there is an issue - either with the test or with the application under test.

the test system should also be able to make decisions about the meaing of test failures - if a test begins to fail, that is important. If a test regularly fails intermittantly, that is less important. Tests which always pass need to be tested less often. Tests which regularly pass, but which also regularly break are the most important - every test suite has them, those tests which you recognise are the ones which regularly fail when you change something - the tests which are like a canary in a coal mine sniffing out impending doom. A test suite should be able to identify them and run them the most often, to identify problems as soon as they hit.

Oh, and the test team? Do they all go an sun themselves on the sunny sunny beaches of Acapulco? Maybe. But they have a new role. Because now they not only have a set of tools which make writing tests easier, they also have hundreds of tests being developed for them by developers... tests which migh themselves be buggy. They have a new range of applications to QA. But as tests are simpler applications, programs which can be held in ones head all in one go, they are more able to find the hidden defects, and ensure that the tests provide the QA the main application requires.

[Incidentally, I've ignored UI testing in this article. Thats because, frankly I know nothing about it. Testing that buttons work can be scripted. Testing that an application is usable will take more work. All I can say is that there is scope for manual tests which can be run by an individual with a script and be fed back into the same system. I don't quite know how this would work... consider it a reseash problem, and if you have any ideas, do get in touch]

Monday, 19 April 2010

Programming Tools: The Build Farm

In my first essay on programming tools I suggested that you take some code, press a button and it builds.

What I didn't talk about was how it builds.

Firstly, it doesn't build on your local machine (it could, if you install the right tools, but that's an unnecessary addition. If you're working locally, you just use your version control system back to the online system to build...). Instead of local builds we have a build farm - a set of one or more machines which include all the tools for building for one or more particular environments. When you hit build, your code is shunted off to the first available machine that can build for the platform you require. The build is performed, and the results are returned.

Actually - its even better. Because this is always happening in behind the scenes, as you type. Whenever it gets a chance a new build of your code is scheduled... so usually when you press the build button the results are instantly available.

And by results I mean build errors and warnings. I mean binaries. I mean all outputs one would usually see from a build. Of course, you probably won't care about the binaries because for most of your development time you'll be using a test farm to cope with these. The errors are the important thing - and they'll be checked into the appropriate point in the version control system so that they are always instantly available

In order to make such a system work, each machine in the build farm will need to have a working build environment installed (its probably best to do this with a VM image, so that making clones is easy). They will also need a daemon process to control the build. Its probably best to think of this as being the build tool - the equivalent of make.

The build tool will advertise itself on the network (using zero-conf or rendezvous or whatever), along with advertising the systems it is capable of building for. Any machine with a tool put on the network will automatically be available to build

I've spent a lot of time thinking about what the ideal replacement for make would be like, but the long and the short of it is, the characteristics of the build system tool won't matter so long as it is possible to only need to rebuild those files which have changed... it could rely heavily on the vcs here, after all, it will know from the vcs exactly which files are different from the last build.

I do think, however, that directory structure is probably not a desirable thing to have. Rather, it should be possible to put files into groups either explicitly, or by smart groups (just as you have smart folders in itunes). A file can be in many groups. When a build tool needs an arbitrary structure, it should be possible to generate it on the fly by moving (groups of )files to the correct locations. This gets over the issues with - say - Microsoft's driver build environment, which only allows two levels of directory structure, and helps where the directory structures need to be different on different platforms. It also helps with version control: at the moment version control systems have to try to emulate every filing system their files may run on, so that permissions and so forth can be replicated correctly. Moving files around is a pain. With this system, everything can fall into build system metadata, and we can provide our own security features (such as restricting changes different code areas to different program groups) if we need them. Of course, build system metadata is stored in a file in version control - so if a file is merged or permissions need to be changed, those changes are tracked like everything else - transparently.

The end result of this complexity is simplicity. Once a build has been set up, it will 'just work' for everybody. If you suddenly need to build for another platform, its just a simple choice of a new platform to see if it works. You can test every platform quickly and easily without searching for appropriate machines and solving 101 build problems.

And because a build daemon is externally controllable - it is no effort at all to use it (and maybe a particular 'gold' machine) for scheduling nightly builds. Or rolling test builds of the code integration branch.

Programmers life is simpler. Builds are easier. Testing is easier. And everyones' lives can be made faster and easier still just by throwing on new hardware. Its a win for everybody.

Thursday, 1 April 2010

Programing Tools: New Version

Once we've asserted that your programming tools should run in a web browser, we can start deciding what back end functionality it needs. The most important is version control.

Now, there is nothing new about version control, so I won't go into it here... but I want to point out that my last article just assumed version control: I suggested you could go to the code and start to edit it. Of course, what I meant was

You log into the system

You find the code you want to edit

You pick a button marked new workspace

You enter that workspace and modify the code.

The workspace is a version controlled branch. There will be options to update your workspace, and merge your workspace into other workspaces.

But all of this is transparent - for the developer its just how you work. Each time you save, thats a revision (auto saves may or may not be revisions... I suggest not). You can tag revisions with comments when you reach points where that is useful.

One final clever bit: the version control system is one of the standard ones... or compatible with one of the standard ones. A distributed VCS, naturally - git or mercurial (I have almost no git experience, so assume I'm talking about mercurial here). So, if a developer wants to work outside of the online toolchain, they can simply download a brnach to their own machine and work from there. When they are done (or just want to compile - they can push their branch back to their online workspace, and take advantage of the compilation and test features provided.

But the compilation and test features are other articles...

Monday, 29 March 2010

Programming Tools: Getting Started

I'm a programmer. Not just for my job, but in my heart. Programming is one of the things I think about when I have nothing better to do. The other night I dreamed that I was multi-threaded (seriously - from now on I will blame all my problems on race conditions).

But this means I identify problems with programming tools quite frequently. Because these problems annoy me on a day to day basis, and I believe there is always a better Way to do things. But I have lots of ideas in this space, and they overlap quite a bit. So I'm going to try to break them down into a number of posts, each getting across a salient point.

Start up time is everything:

I have, several times in my life, started at a new company. The first day tends to involve getting your computer working the way you like. The second day involves learning how to build their code. Then the next year involves gradually picking up the accumulated knowledge of the test environments they have built, the build system, all that jazz.

IDEs make things so much easier. But are also so limited and constraining. I've never worked for a company where the IDE is the way we actually develop things.

But what I want is a quick start way to do development. Don't make me do it on my own PC. Give me a web page I can point at: a local intranet web page which I can edit code on (we have ajax now: why do I need to install a dev system on my personal PC... sure make it a possibility, but don't make it a requirement). Now let my press a button and get my code to compile (Or don't. Maybe the code compiles in the background while I'm working. That's even more useful). Let me press another button to run a test from the test suite (with a GUI app, this might be a problem... but int he future all GUI apps are web pages too, no?)... and let me edit the code for the test suite in place too.

I should be able to get going straight away. Get into the system straight away.

And while I might be able to work in a more powerful manner on my own PC (and it should be a possibility - make sure I can check out a local version of the code, and give me some way I can try to build it - or schedule a build of it) from my local box - these are power features which I can worry about later, when I need them. Not on day one, when I ought to be getting to know the new territory.