Input Properties

Hello,

I have a test step with Input property that accepts a double value as shown below. The issue is the selected input property has to be selected every time the tap plan is reopened . I think the initialization of the input property resets the previous value that was selected. So, what would be the right way to bring back the selected property.

[Display(“Parameter Value”, Order: 1)]
public Input ParameterValue { get; set; }

Thank you,
Priya

1 Like

Hi @priram, is that code missing the “double” type?

[Display(“Parameter Value”, Order: 1)]
public Input<double> ParameterValue { get; set; }

Also, where are you initializing ParameterValue?

1 Like

Hi @david-wsd ,

I just realized that the issue is when a Embedded property is assigned to the input parameter. Not sure if I am missing anything.

Thanks!

2 Likes

Hi @priram,

I am unable to reproduce your issue. Are you doing like this?

        public class StepSetting
        {
            public Input<Verdict> Input { get; set; } = new Input<Verdict>();
        }

        public class StepWithInputFromSetting : TestStep
        {
            [EmbedProperties]
            public StepSetting Settings { get; set; } = new StepSetting();
            public override void Run()
            {
                var x = Settings.Input.Value;
                Log.Info("Verdict was {0}", x);
            }
        }

Maybe you are forgetting to initialize one of your properties?

Hi,

I created a sample plugin to describe the issue.

AddNumbersStep has the embedded properties which is used as Input property in IFConditionStep.
The saved plan when opened does not have the input property selected in the IFConditionStep.
I investigated the tapplan in notepad and it seems to have the propertyname set correctly.

I appreciate your guidance in this. Did I miss any initialization or is this a bug with Embedded Properties?

AddNumberStep.cs

public class AddNumberStep : TestStep
{
#region Settings
// ToDo: Add property here for each parameter the end user should be able to change.
[EmbedProperties]
[Display(Name: “Add Numbers”, Order: 1)]
public MyNumbers Numbers { get; set; }
#endregion

    public AddNumberStep()
    {
        // ToDo: Set default values for properties / settings.
        Numbers = new MyNumbers();
    }

    public override void Run()
    {
        // ToDo: Add test case code.
        Numbers.ResultValue = Numbers.Number1 + Numbers.Number2;
        RunChildSteps(); //If the step supports child steps.

        // If no verdict is used, the verdict will default to NotSet.
        // You can change the verdict using UpgradeVerdict() as shown below.
        // UpgradeVerdict(Verdict.Pass);
    }
}

IFConditionStep.cs
public class IfCondition : TestStep
{
public enum CompareOperator
{
[Display(“!=”)]
NotEqual = 1,
[Display(“>=”)]
GreaterThanOrEqual = 2,
[Display(“<=”)]
LessThanOrEqual = 3,
[Display(“=”)]
Equal = 4
}
public enum LogicalOperator
{
[Display(“AND”)]
ANDOPER = 1,
[Display(“OR”)]
OROPER = 2
}
#region Settings
// ToDo: Add property here for each parameter the end user should be able to change
[Display(“Parameter Value”, Order: 1)]
// Properties defined using the Input generic class will accept value from other
// test steps with properties that have been marked with the Output attribute.
public Input ParameterValue { get; set; }

    [Display("Condition", Group: "Condition 1", Order: 2)]
    public CompareOperator SelectedCondition { get; set; }

    [Display("User Value", Group: "Condition 1", Order: 3)]
    public double UserValue { get; set; }

    [Display("Add Condition", Order: 4)]
    public bool IsConditionAdded { get; set; }

    [Display("AND / OR", Order: 5)]
    [EnabledIf("IsConditionAdded", true, HideIfDisabled = true)]
    public LogicalOperator AndOrCondition { get; set; }

    [Display("Condition", Group: "Condition 2", Order: 6)]
    [EnabledIf("IsConditionAdded", true, HideIfDisabled = true)]
    public CompareOperator SecondCondition { get; set; }

    [Display("User Value", Group: "Condition 2", Order: 7)]
    [EnabledIf("IsConditionAdded", true, HideIfDisabled = true)]
    public double UserValue2 { get; set; }

    [Display("Set Verdict", Group: "Verdict", Order: 8)]
    public Verdict SetVerdict { get; set; }

    [Display("Verdict if condition not met", Group: "Verdict", Order: 9)]
    public Verdict DefaultVerdict { get; set; }
    #endregion

    public IfCondition()
    {
        // ToDo: Set default values for properties / settings.
        ParameterValue = new Input<double>();
        UserValue = 0;
        DefaultVerdict = Verdict.NotSet;
        Rules.Add(() => ParameterValue.Step != null, "Parameter Value must be selected.", nameof(ParameterValue));
    }
    public override void Run()
    {
  
        ThrowOnValidationError(true);
        Log.Info($"Parameter Value: {this.ParameterValue}");
        bool conditionResult = GetConditionResult(ParameterValue.Value, SelectedCondition, UserValue);
        Log.Debug($"conditionResult: {conditionResult}");
        bool finalVerdictResult = conditionResult;
        if (IsConditionAdded)
        {

            bool condition2Result = GetConditionResult(ParameterValue.Value, SecondCondition, UserValue2);
            Log.Debug($"Second condition: {condition2Result}");
            if (AndOrCondition == LogicalOperator.ANDOPER && (conditionResult && condition2Result))
                finalVerdictResult = true;
            else if (AndOrCondition == LogicalOperator.OROPER && (conditionResult || condition2Result))
                finalVerdictResult = true;
            else
                finalVerdictResult = false;

        }
        Log.Debug($"finalVerdictResult: {finalVerdictResult}");
        if (finalVerdictResult)
            UpgradeVerdict(this.SetVerdict);
        else
            UpgradeVerdict(DefaultVerdict);
        RunChildSteps(); //If the step supports child steps.

    }

    private bool GetConditionResult(double value, CompareOperator conditionSelected, double userValue)
    {
        bool result = false;
        if (conditionSelected == CompareOperator.Equal && value == userValue)
            result = true;
        else if (conditionSelected == CompareOperator.NotEqual && value != userValue)
            result = true;
        else if (conditionSelected == CompareOperator.GreaterThanOrEqual && value >= userValue)
            result = true;
        else if (conditionSelected == CompareOperator.LessThanOrEqual && value <= userValue)
            result = true;
        return result;
    }

   
}

MyNumbers.cs
public class MyNumbers
{
[Display(“Number 1”, Order: 1)]
[Output(OutputAvailability.BeforeRun)]
public double Number1 { get; set; }

    [Display("Number 2", Order: 2)]
    [Output(OutputAvailability.BeforeRun)]
    public double Number2 { get; set; }

    [Display("Result", Order: 3)]
    [Output(OutputAvailability.BeforeRun)]
    public double ResultValue { get; set; }
}
1 Like

I am not 100% sure, but I expect the deserializer to be a bit confused about the type of ParameterValue.

Maybe you can try changing this:

public Input ParameterValue { get; set; }

to:

public Input<double> ParameterValue { get; set; }

Thanks @rolf_madsen . I have it as Input when I tested it. I think somehow when I copy pasted it here the double was removed.

1 Like

I tried to edit the tapplan and change the property name that is serialized. In the first image it refers to the Step name(highlighted in green) | property name (highlighted in yellow). so, after saving the tap plan without the step name as shown in image 2, the Tap GUI opens fine with the property selected.

could this be a Test Automation Editor bug?

It already knows which test step is based on what is inside the Step element.

Do you have any concrete issues with it?

The issue is every time I open a saved plan, since the Input element does not get selected, I have to go and re select the input element. If it is a simple plan with just one input selection it would have been fine. I have a tap plan with multiple Input selections.

image

1 Like

Ok, I am not sure what is going wrong here. I tried to reproduce it like this:

    public class Inputs
    {
        public Input<double> X { get; set; } = new Input<double>();
    }

    [Display("Input Output")]
    public class InputOutputStep2 : TestStep
    {
        [EmbedProperties]
        public Inputs EmbeddedInputs { get; set; } = new Inputs();
        
        [Output]
        public double Result { get; set; }

        public override void Run()
        {
            Result = EmbeddedInputs.X.Value;
        }
    }

To me it seems to work correctly:

image

Edit: This is how it looks after loading the test plan

1 Like