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
- Add a C# Script step from the step palette.
- In the editor, implement a
publicclass that derives fromScriptTestStepBasewith a parameterless constructor. - Override
Execute(AbstractTestStep testStep)and returnRunResult.SuccessorRunResult.Failure. - 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;
}
}
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 (
CodeFilewithNameandContent). 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:
| Member | Description |
|---|---|
testStep.Information | Set 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.TestCase | The owning test case (and .TestCase.TestSuite, .TestCase.TestSuite.AutomationProject). |
return RunResult.Success / RunResult.Failure | Determines the step outcome. Throwing an exception also fails the step. |
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.