This post will give an example on how to add support for a custom test parameter type. The basic idea of test parameter value handling could be summarized as such:
- A parameter of a certain type is declared in a test case. In this example, the test case parameter could look like:
class MyTest { // ..skipped private byte[] buffer; public byte[] Buffer { get {return buffer;} set {buffer = value;} }
- Somewhere within Yats DLLs a class implementing AbstractParameterValue is written. It handles (generates, loads, stores etc.) one or more parameter types.
- During program start, all assemblies (DLLs) are searched for classes implementing AbstractParameterValue.
- Objects of all such classes are instantiated automatically and their InitType() method is called. In this method, the parameter value type should be associated with a parameter type.
- Similar to classes handling parameter values, GUI value editors are declared and associated with the parameter value types they support.
- When a the user is about to edit a parameter (i.e. byte[]), the possible parameter value handler classes (classes implementing AbstractParameterValue) are chosen. Parameter editors supporting the value handlers (classes implementing IEditor interface) are found and shown in tabs.
This creates a mapping of 1 parameter type -> N value handlers -> N editors.
This post will show an example of implementing a value handler that generates a random byte buffer (random size array filled with random bytes). It will be associated with byte[] and List<byte> test case parameters.
Source code:
public class RandomByteArrayValue : AbstractParameterValue { // Minimum size of the generated buffer int minSize; public int MinSize { [DebuggerStepThrough] get { return minSize; } [DebuggerStepThrough] set { minSize = value; } } // Maximum size of the generated buffer int maxSize; public int MaxSize { [DebuggerStepThrough] get { return maxSize; } [DebuggerStepThrough] set { maxSize = value; } } // parameterless constructor is needed for serialization public RandomByteArrayValue() { } public RandomByteArrayValue(int minSize, int maxSize):this() { this.minSize = minSize; this.maxSize = maxSize; } public override AbstractParameterValue Clone() { return new RandomByteArrayValue(minSize, maxSize); } public override void InitType() { // a delegate is used to determine that RandomByteArrayValue is suitable for byte[] or List<byte> ParameterTypeCollection.AddEntry(this.GetType(), "random buffer", delegate(IParameter parameterInfo, ref int valueTypePriority) { if ((parameterInfo.IsArray || parameterInfo.IsList) && parameterInfo.ParamType == typeof(byte).AssemblyQualifiedName) { valueTypePriority = 30; // low priority - should put the editor tab towards the end return new RandomByteArrayValue(); } return null; }); } // User-friendly summary for GUI public override string GetDisplayValue() { return string.Format("Random buffer [{0}..{1}]B", minSize, maxSize); } // Returns the actual parameter value, to be assigned before running a test case public override object GetValue(IParameter format) { var rnd = new Random(); byte [] result = new byte[rnd.Next(minSize, maxSize)]; rnd.NextBytes(result); return result; } // Used to detect when parameter implementation has been changed between program runs public override int GetParamValueTypeHash() { return this.GetType().Name.GetHashCode(); } }
The parameter value handler is associated with parameter type. Unfortunately, there are no parameter editor components that could be used to edit the Min/Max values. Editing a byte array parameter will still not suggest a random option yet. A separate post will show how to implement and associate an editor.