This tool is plain and small, as I designed to be.
The reason behind the design is to put emphasis on the software being designed with the tool, not the tool itself. That is, the tool automates some repetitive tasks and leaves room for what the humans do best, think.
The tool does some tedious tasks for the software designer, but by no means has the tool tried to easy the thinking process of crafting a design.
In the words of Professor Edsger Wybe Dijkstra:
“…tools have the unfortunate tendency to backfire (Easing the correction of errors immediately leads to more errors being made)”
Can computing science save the computer industry?, Edsger W. Dijkstra
Just copy AutoTest.dll to one of the following locations:
· Your working folder
· A subfolder named AutoTest within your working folder
The simplistic case: If you are designing a simple calculator class, convey your usage intentions starting as the following:
AutoTest will execute all the public methods of CalcTest class which first characters are “test”, each such a method is a test case. AutoTest will report results of executing each test case.
Compiling CalcTest.cs now will result with several errors about not knowing AutoTestSuite class type, Calc class type and missing entry point for program. Let’s do the simplest thing that make these errors disappear:
Let’s compiling again:
csc /r:AutoTest.dll CalcTest.cs
Execution reports the following:
Often, we want more information about the failing test case, that information could be specified in the test case:
Now execution reports:
By now, we have been using a test runner for console mode, if we want our test runner on windows mode, then we need to change the line:
TestRunner runner = new TextConsoleTestRunner(Console.Out);
With this line:
TestRunner runner = new WinFormTestRunner();
Now, the execution shows the following window:
Selecting the root in the tree view control and clicking on Run button will execute our test cases and report results:
A red box tells us that our current detailed design (source code) is not fulfilling our usage intentions of Calc class type, let’s fix that:
Let’s go back to our console mode test runner and see execution results:
Ok, 100% test cases passed! This means our detailed design (source code) fulfill the functional requirements (by now) of our Calc class type.
Our sample testSimpleAdd test case method above creates an instance of Calc class type for exercising the projected functionality, as the test case methods on this test class grow in number, will be annoying to create instances within each test case method. It may be handy to locate a single point to setting up the instances for all test case methods to use, and another single point to release the resources used by the test case methods.
There are a couple of methods from base class AutoTestSuite that can be overridden for such a purpose, like this:
SetUp and ShutDown methods will be executed once each for the entire AutoTestSuite-derived class type, at the beginning and at the end respectively. That is, each test case method is able to use the instance itsCalc, without creating or destroying an instance per test case method.
As development team members work on different functions of the software being designed, they can group their test cases, making up a hierarchy of test cases as deep and broad as they choose.
Setting the test case hierarchy as:
Using the WinFormTestRunner looks like:
If there are AutoTestSuite-derived class types defined in your testing assembly, certainly you want them to be executed; if the test case hierarchy configuration is conveyed by static methods like advancedTest above, then it may be handy to say that kind of decisions in just one place and saying something like “setup test case hierarchy from class types defined in calling assembly”; avoiding to configure the hierarchy at the program entry point.
If this is the case, then you may use the static method SuiteFromCallingAssembly from AutoTestSuite class type like this:
All the AutoTestSuite-derived class types will be included in your test case hierarchy. For grouping define a TestSuite-derived class type that group the test suites as needed in a TestSuite instance which must be returned from a public static ‘Suite’ method, like the following:
Now, the execution inspects the calling assembly and configures the test case hierarchy from the class types defined within.
Just as Mr. Churchill said: “…this is not the end, this is not even the beginning of the end…; perhaps this is the end of the beginning”
It is up to you; give an honorable try to test-first design techniques using supporting tools like this one. It could make a big difference in the quality of your software designs.
Several unit testing frameworks designs http://www.xprogramming.com/software.htm
Code Complete http://www.stevemcconnell.com/cc.htm
Is design dead? http://martinfowler.com/articles/designDead.html
Continuous Integration http://martinfowler.com/articles/continuousIntegration.html
Avoiding Repetition http://martinfowler.com/articles/repetition.pdf