diff --git a/RPCTest/RPCTest.csproj b/RPCTest/RPCTest.csproj
new file mode 100644
index 000000000..8638c026d
--- /dev/null
+++ b/RPCTest/RPCTest.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net8.0
+ latest
+ enable
+ enable
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/RPCTest/Registry/StrategyExecutorTests.cs b/RPCTest/Registry/StrategyExecutorTests.cs
new file mode 100644
index 000000000..da723f646
--- /dev/null
+++ b/RPCTest/Registry/StrategyExecutorTests.cs
@@ -0,0 +1,130 @@
+using SharpHoundRPC.Registry;
+using Xunit;
+
+namespace RPCTest.Registry;
+
+public class StrategyExecutorTests {
+ private readonly StrategyExecutor _strategyExecutor = new();
+
+ [Fact]
+ public async Task CollectAsync_NoStrategies_ReturnsFailure_WithNoAttempts() {
+ // Act
+ var result = await _strategyExecutor.CollectAsync("target machine", [], []);
+
+ // Assert
+ Assert.NotNull(result);
+ Assert.False(result.WasSuccessful);
+ Assert.Empty(result.FailureAttempts!);
+ Assert.Null(result.Results);
+ Assert.Null(result.SuccessfulStrategy);
+ }
+
+ [Fact]
+ public async Task CollectAsync_CanExecuteIsFalse_ReturnsFailure_WithAttempt() {
+ //Arrange
+ var strategy = new FakeCollectionStrategy(false, "well now I am not doing it");
+
+ // Act
+ var result = await _strategyExecutor.CollectAsync("target machine", [], [strategy]);
+
+ // Assert
+ Assert.False(result.WasSuccessful);
+ Assert.Null(result.Results);
+ Assert.Null(result.SuccessfulStrategy);
+
+ var attempt = result.FailureAttempts?.Single();
+ Assert.Equal("well now I am not doing it", attempt?.FailureReason);
+ Assert.Equal(strategy.GetType(), attempt?.StrategyType);
+ }
+
+ [Theory]
+ [MemberData(nameof(StrategyExceptions))]
+ public async Task CollectAsync_ThrowsException_ReturnsFailure_WithExceptionMessage(Exception strategyException) {
+ //Arrange
+ var strategy = new FakeCollectionStrategy(
+ canExecute: true,
+ exception: strategyException
+ );
+
+ // Act
+ var result = await _strategyExecutor.CollectAsync("target machine", [], [strategy]);
+
+ // Assert
+ Assert.False(result.WasSuccessful);
+ Assert.Null(result.Results);
+ Assert.Null(result.SuccessfulStrategy);
+
+ var attempt = result.FailureAttempts?.Single();
+ Assert.Contains($"Collector failed: {strategyException.Message}.", attempt!.FailureReason!);
+
+ if (strategyException.InnerException is not null)
+ Assert.Contains($"\nInner Exception: {strategyException.InnerException}", attempt!.FailureReason!);
+ else
+ Assert.DoesNotContain("Inner Exception:", attempt!.FailureReason!);
+ }
+
+ public static IEnumerable