Cut out all the sugar from pretty much any unit testing framework and you have yourself the situation where the users have marked their test classes to signify that they contain test methods and have marked the test methods themselves to tell the framework to actually run them.
So really on the base level (cutting out assertions and such) you need to somehow figure out which methods in which classes should be run by your tester. In managed languages this becomes a lot simpler through the use of reflection. We can simply ‘reflect’ on each of the classes/methods and decide if they should be run or not.
Here is some short C# code that demonstrates this idea through attributes and reflection. Classes which contain test methods are marked with the TestClass attribute and the test methods themselves which will be run later on are marked with the TestMethod attribute. The code uses LINQ to first get all the types in the currently executing assembly which include the TestClass attribute. Then all the methods are found in each of those classes which are marked with the TestMethod attribute. Finally each of those test methods are invoked using a new instance of the test class itself. The code is all commented so it should all be self-explanatory.
This simple idea can then be added onto in a load of different ways. For example some methods are expected to throw certain exceptions. The TestMethod attribute could therefore be modified to allow that exception through. The unit tester itself could then be adapted to catch that exception and still pass.
In a recent post I showed how it is possible to write all your C# code indirectly through reflection. Here is the same example in Java. The process itself is very much the same - retrieve meta information about the classes/methods we are interested in and then invoke them passing in the object it would normally be called from. The classes themselves are all very similar through C# to Java. Type becomes Class, MethodInfo becomes Method etc.
A more interesting difference is how the Java version uses variable length parameters in the .invoke calls on Method objects as a way of passing parameters to the particular method. In the C# version you have to explicitly pass a Type or object array. I think the Java version is slightly more user friendly in that quite small regard even though the actual parameter itself is an array in both circumstances.
Its also interesting to see just how many exceptions the Java version can throw in the process. Because they are all checked you are forced to deal with them whereas C# does not have this feature. Its probably likely then that you would have to catch a more generic exception in the C# version.
Here is the code for the Java version. The result is the same as the C# version.
You can use the reflection features in C# to write your normal code in an indirect manner. No idea why you would want to do something like this, but it gives an idea of the control you get when using reflection.
In this example we have a small class wrapping two integers inside their own properties. First of all an object is created, the properties set, and the .ToString() method result passed into a Console.WriteLine using the conventional way. The exact same thing happens again but now indirectly through the use of reflection. As you can see it takes up nearly three times more code to to the exact same thing using reflection but you at least get the same result.
Numerical Methods Helper is a learning tool for numerical algorithms in AS and A2 Mathematics modules. The program supports methods of numerical integration, root finding through iteration, local extrema, and tangents and normal lines to functions.
The progress of each algorithm is drawn onto a freely movable and interactive graph to allow students the most engaging learning experience. All parameters for each algorithm are completely customisable, and the results and graphs will be re drawn to accommodate the new values.
Not only does Numerical Methods Helper give a final result to an algorithm, but it also gives the calculations needed for students to get the final answer for themselves. For example, all integration algorithms are accompanied with list of ordinates used in the algorithm, along with a final formula that can be typed into any calculator to yield the final same final result.
Functions for use in any of the algorithms can be freely customised and changed using a number of built operators including trigonometry and logarithms. Not only can the program be used for the tuition of numerical methods, but the graphs can also be utilised for other topics such as transformations of graphs.
Main Features -
Freely scrollable and zoomable graphing view
Worked examples of all numerical algorithms and AS and A2 Maths including -
The Trapezium rule
The Mid - Ordinate Rule
Root Finding by iteration
Teaching aids for other topics such as local extrema and tangents and normal lines to functions
Every parameter for each algorithm is fully customisable to meet a wide range of questions
Functions for use in any algorithm can be changed using a wide range of built in operators
Graphing views can be copied to the clipboard to paste into other applications for annotation and printing
Main parameters for algorithms can be modified by dragging points on the graph itself. This allows for a more interactive and visual approach to the progress and inaccuracies of the algorithm
Numerical data used in the calculations of the results of the algorithm is also provided to allow students themselves to reach a solution
This screenshot shows the integration tab of the program. The user is able to enter a custom function along with the upper and lower bounds of the integration, the numerical algorithm to use and the number of iterations. The results are then shown to the user, with a formula of the chosen algorithm and the ordinates used. Te application of the algorithm to the equation is also shown graphically on an interactive plotting view.