Most programmers probably know, but even if you don't know, is good to notice: great bulk of time in development of a software is bug fixing and maintainance. They can take from 55% in most lucky projects, to around 95%. The development time in bug fixing relies mostly on how much you invest in them also. So, having 95% of time means that this software product focuses on bug fixing greatly. Consider, for example, a real-time device programming or an air traffic control software. The platform needs to be stable in years or having minimal downtime.
In desktop programming around 75% of time is bug fixing. Why does software spend between two thirds to three quarters doing bug fixing instead adding features? Developers are humans and they can keep only some ideas in parallel, but they have to focus to memory management, performance, writing useful codes, interaction between components, specifications, etc. This will overwhelm really easy even the best developer.
Test Driven Development (TDD) is a software methodology created to reduce the time of staying in bug fixing. The best qualities of it are:
- detect bugs as early as possible
- have at least for your batteries of tests in place of their inputs, to provide the expected output
- make the code to feedback developer before a QA or in a much worse way, a user to notice.
What is the best way to do TDD?
- makes your tests pass with minimal code
- refactors your code to be as good as you want but doesn't break the tests
NaroCAD uses nUnit framework to do unit tests which are small programs that define a battery of tests.
using System;
using NUnit.Framework;
using TreeData.AttributeInterpreter;
using TreeData.NaroData;
namespace NaroTestSuite.TreeData
{
[TestFixture]
public class UndoRedoTests
{
[Test]
public void UndoAppliedEmpty()
{
DefaultInterpreters.Setup();
Document doc = new Document();
Assert.AreEqual(0, doc.Root.
doc.Transact();
doc.Root.Update<
Assert.AreEqual(1, doc.Root.
doc.Commit();
Assert.AreEqual(1, doc.Root.
doc.Undo();
Assert.AreEqual(0, doc.Root.
}
}
}
Check the feature you want to make working.
Define your expectancies (or assertions). Here are the normal expectations for a class that store a document in a doc.Root tree data.
- after I will try to save the status of the document (after a "transact") the document should not change the attribute count
- after I will add an integer attribute the attribute count should increase with 1
- after I do an Undo, the document will decrease to original document count, so it will be zero.
A great thing also is that tests are often much smaller than the entire application. So debugging it will reduce to debugging of the latest usage of the document, is not the entire NaroCAD that may not work with Undo function.
How about regression testing?
Regression Testing (RT) is almost the same as TDD but when application crashes (for instance to an user), there is a test written "to not happen again". RT has some downsides:
- the developer (or QA) who writes the test can get the application architecture. This may mean that we can create a test to pass our code, instead our code to pass our tests
- in development time, there are no tests to check if a component is working (excluding the developer will debug the program again and again)Should you use RT? Yes, definetly! RT appears in ways that application you have never expected to crash or to run, does so, and where you don't want it. Also, the user bugs are great to be tracked. A flawed component will most probably crash again. There is a QA 80/20 theory which says: 80% of errors are in 20% of code. TDD will say that for your cases your code will work correctly. But still there are your tests, which may not reflect the real life cases.
As in our example: who creates a single document to store only one integer in it?
No comments:
Post a Comment