Maybe I’m going about this all the wrong way, but what would be the preferred way of defining properties on a test step that are made of more complex types?
The type I would like to use for this property is something like this struct:
public readonly struct MySettingAsStruct
{
public int Id { get; }
public string Name { get; }
public string Checksum{ get; }
public MySettingAsStruct(int id, string name, string checksum)
{
Id = id;
Name = name;
Checksum = checksum;
}
public override string ToString()
{
return $"{Id} - {Name} - {Checksum}";
}
}
Or possibly this class:
public class MySettingAsClass
{
public int Id { get; }
public string Name { get; }
public string Checksum{ get; }
public MySettingAsClass(int id, string name, string checksum)
{
Id = id;
Name = name;
Checksum = checksum;
}
public override string ToString()
{
return $"{Id} - {Name} - {Checksum}";
}
}
Then I attempt to use those types as a setting of a TestStep, like so:
[Display("MyTestStep")]
public class MyTestStep : TestStep
{
[Display("MySettingAsClass")]
[AvailableValues(nameof(classSettings))]
public MySettingAsClass? MySettingAsClass { get; set; }
public MySettingAsClass[] classSettings => new MySettingAsClass[]
{
new MySettingAsClass(1,"One","One"),
new MySettingAsClass(2,"Two", "Two"),
new MySettingAsClass(3, "Three", "Three")
};
[Display("MySettingAsStruct")]
[AvailableValues(nameof(structSettings))]
public MySettingAsStruct MySettingAsStruct { get; set; }
public MySettingAsStruct[] structSettings => new MySettingAsStruct[]
{
new MySettingAsStruct(1,"One","One"),
new MySettingAsStruct(2,"Two", "Two"),
new MySettingAsStruct(3, "Three", "Three")
};
public override void Run()
{
Log.Info($"Running {Name}...");
Log.Info($"Struct ID = {MySettingAsStruct.Id}");
Log.Info($"Struct Name = {MySettingAsStruct.Name}");
Log.Info($"Struct Checksum = {MySettingAsStruct.Checksum}");
Log.Info($"Class ID = {MySettingAsClass?.Id}");
Log.Info($"Class Name = {MySettingAsClass?.Name}");
Log.Info($"Class Checksum = {MySettingAsClass?.Checksum}");
}
}
The behavior that I am seeing is that this works fine when I setup and run a test plan in TUI. I’m able to select from my list of settings, and I see the expected output when I run the test plan.
The issue that I am running into is that the plan cannot be saved. When it gets serialized to XML, this is the output I end up with:
<TestStep type="TestLibrary1.MyTestStep" Id="fe7adbaf-7abd-4f7b-b189-d6293384e203">
<MySettingAsClass></MySettingAsClass>
<MySettingAsStruct>3 - Three - Three</MySettingAsStruct>
<Name Metadata="Step Name">MyTestStep</Name>
</TestStep>
The class version has no value and throws an error on load, while the struct stores the ToString()
representation that does not get deserialized properly and results in the test step loading with defaulted values.
I tried using the [EmbedProperties]
attribute, but that doesn’t seem to quite do what I want. Applying that attribute causes the property not to appear in the settings panel at all, unless I provide setters for all of the properties. However, that allows the user to modify each individually, which is not the behavior I want.
Am I missing something simple that would allow this to work properly?