Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Tuesday, February 15, 2011

Test Driven Development

It has been some time since my last post, work has been rather hectic of late.  My downtime has been just that, downtime.  However when I finally got back to my Java oData Consumer I ended up having a good experience in Test Driven Development that I thought I would share.

The next small chunk that I wanted to complete was the XML namespace to package name piece, and then applying that package in my code when trying to get a type of node from a known namespace.  The first part was easy, I wrote my test, got the code working, and vola, I had my XML namespace to package converter.  Not the best work, has hardcoded parts that I would love to remove, but it does the job.  It is something I can refactor later once I have a complete oData consumer.  (A side note, I can add various namespaces and XML definitions easily, so am thinking of also expanding this to allow for a simple RSS consumer in Java, but that is way down the track and I digress.)

The next part I thought was simple. Combine the package name with the expected class name and end up with a complete class name that I can reference in my code when I am trying to create a new node in my tree.  I wrote my test, got it working, then because I had tests that checked the rest of the code I ran those and lo and behold they broke.  So, I fixed them up making sure that I was not breaking anything else, and my code went back to being robust.

The reason why I am saying that this is a good experience in Test Driven Development (TDD) is that if I did this the way I am used to, just manually tested my code, there is almost no chance that I would have picked up the bugs that I created.  By using TDD I had a repository of tests that I have coded against to meet the requirements (each in and of itself a small requirement).  Now I might not have hundreds and thousands of tests to run against my code, but as my codebase grows, the number of tests expands as well to cater for the new code.  No new code should be written where it isn’t to make a test pass.

However, proceed with caution here.  Tests need to be useful and meaningful.  Make sure that you are testing what you think your testing.  Your tests form part of your codebase, make sure you check that they pass regularly, and also make sure that you know what they are testing.  Having heaps of tests that are checking the same thing is pointless. If you have one test to check that your function is working in a set scenario, then move on.  You should write a new test for each scenario.  Also you when you get a bug you should be able to write a test to show that the bug is in the code, then you can debug your code to make sure that the fix is working, and that it hasn't accidently broken anything else.

A tip on testing that I got from Tatham Oddie (@tathamoddie on twitter) is to use the following template for writing a test.  It works in any language.  First create the test (the name and container in code).  Then add 3 comments: Arrange; Act; Assert.  The first part of your test should be to Arrange the objects that your testing, with mocks, creating the object that you want to test.  The second should be the Act part, this is where you perform the function or method that you want to test.  The third is the Assert part, where you check that what you wanted to be the result was indeed the result.

Saturday, January 22, 2011

Agile vs Waterfall

Recently I found myself coding less and “planning” more. It took me a while to work out why, and when I did I thought I would write this so that others may avoid the trap I was in.

Firstly, some background. As you may or may not be aware, I am writing an API in java for read an OData source.  Now, I am using TDD principals to code the API (basically write a test case and then write the code that makes this test pass).  This means that I need to think in small increments, write a test for the small increment, then write a small increment that satisfies that test, then write another test for another small increment, then write that small increment and so on,  you get the idea.

Now back to the present.  I encountered the next part of my code requirements, implementing XML namespaces within my code.  This is where my problems started.  I did the right thing by researching some things on XML namespaces, to make sure that I understood how they were implemented and make sure my code didn’t vastly differ what it should be.  Then I did the wrong thing, I tried to plan the entire implementation of the XML Namespace component, rather than looking at the small piece I was dealing with (in this case pulling the namespace and storing it in the required format).

I was planning the reading dtd and metafiles and how that would work.  Looking at the manner that dtd’s could be delivered.  How would I know which was an internal namespace and which was an external? How would I register the external namespace in my code (for example the $metadata of an OData source)? And so on and so forth.  That is not how I am wanting to write my code.  I want to write a test for a small part, then write that small part.  In this case the small part was identifying the namespaces and putting them into a useful format.

This got me thinking about agile and waterfall practices.  Agile methodologies would say that you get the requirement and break it down into smaller pieces, and those into smaller pieces until you have something that can be done in a defined period of time (for example, in scrum you would break it down into smaller pieces that would be done within an iteration).  Whilst you know what the requirements are, you don’t design the entire solution for what may or may not happen, nor do you plan everything out at the start.  You break the requirement into smaller chunks and that into smaller chunks into a requirement that you can complete within a week or 2.

Waterfall is very different to this.  In the waterfall approach, you define every requirement that you can think of, plan the end result to the finest detail, then you start coding to the fine details that you have planned to deliver.  You don't start coding until you have the UX defined, the web services documented and the classes worked out and what each class properties and methods are.

Now, without going into a discussion about waterfall vs agile development practices, I will say my thoughts.  While there are parts of one in the other and vice versa, the two can not coexist.  For example, when your doing agile you need to know the end result, what is the stakeholder asking for.  That you can break down into smaller requirements and so on until it is small enough to complete in iteration or sprint.  And conversely in waterfall development, you can not say “deliver the whole project at once”, you need to break it down into smaller chunks that a developer can work on.

The main point of difference for me is that in my opinion, agile is about meeting the requirements that you have been asked to deliver.  No more no less.  You cant tell the stake holder what they want, you can only guide them along as you code and as they see the work.  This doesn't mean that if they say they want a field you don't do any error checking on it, or that you just make it work and not deliver a quality product.  What it does mean is that you don't enlarge the requirements to what you can see being needed down the track.  You meet the current need. If the database table needs a title, description and timestamp, don't add a link to a status that is then part of a different requirement.  By the same token you can guide the requirements along by asking questions like “where is this going to be reported?”, “Is there a need to report on this?”, “ Who should be able to edit this?”

Waterfall projects on the other hand you can vastly change the requirements because you are part of the planning process.  Nothing gets done until everything is defined and some form of specification documented.  You research to make sure that it is future proof, so that you can work on another project and this one wont need any attention.  You tend to guide the requirements and specifications, rather than the development.  But, once it is locked in, it takes a lot to change one line of the specifications that your working to.

Personally, I prefer agile development processes over waterfall process because you can be flexible, if you code something that the user changes their mind on you can adapt. (Hence, why it is called agile.)  You also only deliver what is needed, not what you think is best.  The issue with stakeholders is that they don’t always communicate it well to developers, project managers or product owners.  Hence the need to ask questions and listen to the answers.  You also end up with leaner code (it does what is needed, and nothing it doesn't) rather than bloated code with parts that are rarely, if ever, used.

Saturday, January 8, 2011

Running a single test with JUnit and Eclipse

So, I had a slight problem with using TDD in Eclipse.  Not a problem as such, more an obstacle that I needed to overcome.  What I wanted to do was to write a test, get that working, then re-run all the tests, check that the changes to the code hadn’t caused another error to correct, then move on to the next test.  I found a few odds and ends about how this could be done, but nothing seemed to work.

After some looking and seeing I was able to get this working.  Here’s how I did it.  For this example, I am using JUnit 4 and Eclipse 3.6.1 (Helios).  Please note, to see the images more clearly just click on the image.

Firstly, go to Run –> Run Configurations

Then, right click the JUnit node in the tree and select New

Enter the name for the run configuration (I have called mine XMLSourceRepository_GetTokensTest)

Select the Method that you would like to test (default is all methods).

Now, I have Android JUnit and Eclipse JUnit launchers, so down the bottom I need to press the hyperlink and the following dialogue box appears. Select the Use Configuration specific settings and then Eclipse JUnit Launcher.

And your done.  Press the run button to run the test, and now it is in your run and debug button menus

So there you have it.  Using JUnit and Eclipse Helios (3.6.1) I have been able to select a single test to run without the overhead of other tests being run as well.

Now, to me, this is rather complex and time consuming if you write a test, change the run configurations to add or alter an existing configuration, make a few changes to change the code, then have to do the whole process again.  It would be easier be able to do this via the source or a test list of some kind.  I am not saying that this isn’t possible, but I couldn’t get it to work.  If you know how to do that, please let me know so that I can correct this post with the easier way of managing tests!