Skip to main content

C# Script Step

The C# Script step lets you run arbitrary C# code as part of a test case. Code is compiled with the Roslyn compiler and can use the full .NET API plus the Aethrix Core libraries. Use it for custom logic, complex assertions, data transformation, or integration with .NET libraries.

When to Use​

  • Performing calculations or data transformations that built-in steps cannot express
  • Calling .NET libraries not directly supported by other step types
  • Implementing complex conditional logic or custom control flow
  • Generating dynamic test data
  • Logging custom diagnostics to the test report

Quickest Scenario​

  1. Add a C# Script step from the step palette.
  2. In the editor, implement a public class that derives from ScriptTestStepBase with a parameterless constructor.
  3. Override Execute(AbstractTestStep testStep) and return RunResult.Success or RunResult.Failure.
  4. Click Compile to verify, then run the test case.
using Aethrix.Automation;

public class MyStep : ScriptTestStepBase
{
public override RunResult Execute(AbstractTestStep testStep)
{
testStep.Diagnostics.Add("Running C# script");

// access the test case and suite if needed
var suite = testStep.TestCase.TestSuite;

testStep.Diagnostics.Add("Validation passed");
return RunResult.Success;
}
}
note

The automation engine searches for the first public class that inherits from ScriptTestStepBase. That class must have a default (parameterless) constructor. You may define additional helper classes in the same file.

Editor​

The C# Script editor (CSharpScriptPanel.axaml) provides:

  • A multi-file tab strip — a step owns one or more code files (CodeFile with Name and Content). Project-level code files are compiled first so their types are available to the step's files.
  • Toolbar buttons: Compile, Format Document, Format Selection, Comment Selection, Uncomment Selection, and Debug.
  • The Debug session exposes Continue, Step Into, Step Over, Step Out, and Stop, plus a locals panel and breakpoint support.
  • Compilation errors are surfaced through Compile Diagnostics.

Script API​

Inside Execute, the testStep parameter exposes:

MemberDescription
testStep.InformationSet a human-readable status message for the step.
testStep.Diagnostics.Add(string)Append a line to the step's diagnostic log (shown in the report).
testStep.GetVariable(name)Read a variable by name. Returns the Variable (use .Value); throws if the variable does not exist in local or upper-level scopes.
testStep.TestCaseThe owning test case (and .TestCase.TestSuite, .TestCase.TestSuite.AutomationProject).
return RunResult.Success / RunResult.FailureDetermines the step outcome. Throwing an exception also fails the step.
tip

Add using Aethrix.Automation;, using Aethrix.Core;, and using Aethrix.Core.Util; to reach Aethrix Core helpers. You may also reference installed extensions for additional libraries.

Common Patterns​

Generate Test Data​

public override RunResult Execute(AbstractTestStep testStep)
{
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
testStep.TestCase.LocalVariables.AddRuntimeItem("UniqueUsername", $"test-user-{timestamp}");
testStep.TestCase.LocalVariables.AddRuntimeItem("OrderReference", Guid.NewGuid().ToString("N")[..12]);
return RunResult.Success;
}

Complex Assertion Logic​

public override RunResult Execute(AbstractTestStep testStep)
{
var status = testStep.GetVariable("LastStatusCode").Value;
var body = testStep.GetVariable("LastResponseBody").Value;

if (status != "200")
{
testStep.Diagnostics.Add($"Expected 200 but got {status}");
return RunResult.Failure;
}
if (!body.Contains("success"))
{
testStep.Diagnostics.Add("Response body does not contain 'success'");
return RunResult.Failure;
}
return RunResult.Success;
}

Companion Files​

Each code file's Content is stored on disk as code/<Name>.cs next to the project (never embedded in the .aprj file), keeping the project file small.

Limitations​

  • Scripts run in-process with the test engine — long-running operations block other parallel tests.
  • External NuGet packages are not directly available; use installed extensions for additional libraries.
  • File system access is allowed but is sandboxed to the project directory.

See Also​