diff --git a/.github/workflows/speed-comparison.yml b/.github/workflows/speed-comparison.yml
index 6f58d3269f..8b0413f8c9 100644
--- a/.github/workflows/speed-comparison.yml
+++ b/.github/workflows/speed-comparison.yml
@@ -29,36 +29,28 @@ jobs:
dotnet-version: 9.0.x
- name: Build TUnit AOT .NET 8.0
- run: dotnet publish TUnitTimer.csproj -c Release --framework net8.0 --output aot-publish-net8 --property:Aot=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
- working-directory: "tools/speed-comparison/TUnitTimer/TUnitTimer"
+ run: dotnet publish UnifiedTests.csproj -c Release -p:TestFramework=TUNIT --framework net8.0 --output aot-publish-net8 -p:PublishAot=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
+ working-directory: "tools/speed-comparison/UnifiedTests"
- name: Build TUnit AOT .NET 9.0
- run: dotnet publish TUnitTimer.csproj -c Release --framework net9.0 --output aot-publish-net9 --property:Aot=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
- working-directory: "tools/speed-comparison/TUnitTimer/TUnitTimer"
+ run: dotnet publish UnifiedTests.csproj -c Release -p:TestFramework=TUNIT --framework net9.0 --output aot-publish-net9 -p:PublishAot=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
+ working-directory: "tools/speed-comparison/UnifiedTests"
- name: Build TUnit Single File .NET 8.0
- run: dotnet publish TUnitTimer.csproj -c Release --framework net8.0 --output singlefile-publish-net8 --property:SingleFile=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
- working-directory: "tools/speed-comparison/TUnitTimer/TUnitTimer"
+ run: dotnet publish UnifiedTests.csproj -c Release -p:TestFramework=TUNIT --framework net8.0 --output singlefile-publish-net8 -p:PublishSingleFile=true -p:SelfContained=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
+ working-directory: "tools/speed-comparison/UnifiedTests"
- name: Build TUnit Single File .NET 9.0
- run: dotnet publish TUnitTimer.csproj -c Release --framework net9.0 --output singlefile-publish-net9 --property:SingleFile=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
- working-directory: "tools/speed-comparison/TUnitTimer/TUnitTimer"
+ run: dotnet publish UnifiedTests.csproj -c Release -p:TestFramework=TUNIT --framework net9.0 --output singlefile-publish-net9 -p:PublishSingleFile=true -p:SelfContained=true --runtime ${{ matrix.os == 'windows-latest' && 'win-x64' || matrix.os == 'ubuntu-latest' && 'linux-x64' || 'osx-x64' }}
+ working-directory: "tools/speed-comparison/UnifiedTests"
- - name: Build TUnit
- run: dotnet build -c Release
- working-directory: "tools/speed-comparison/TUnitTimer"
-
- - name: Build xUnit
- run: dotnet build -c Release
- working-directory: "tools/speed-comparison/xUnitTimer"
-
- - name: Build NUnit
- run: dotnet build -c Release
- working-directory: "tools/speed-comparison/NUnitTimer"
-
- - name: Build MSTest
- run: dotnet build -c Release
- working-directory: "tools/speed-comparison/MSTestTimer"
+ - name: Build All Frameworks
+ run: |
+ dotnet build -c Release -p:TestFramework=TUNIT
+ dotnet build -c Release -p:TestFramework=XUNIT
+ dotnet build -c Release -p:TestFramework=NUNIT
+ dotnet build -c Release -p:TestFramework=MSTEST
+ working-directory: "tools/speed-comparison/UnifiedTests"
- name: Run Benchmark
run: dotnet run -c Release --framework net9.0 --allCategories=Runtime
@@ -97,6 +89,11 @@ jobs:
with:
dotnet-version: 9.0.x
+ - name: Prepare builds
+ run: |
+ dotnet restore UnifiedTests/UnifiedTests.csproj
+ working-directory: "tools/speed-comparison"
+
- name: Run Benchmark
run: dotnet run -c Release --allCategories=Build --framework net9.0
working-directory: "tools/speed-comparison/Tests.Benchmark"
diff --git a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/.gitignore b/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/.gitignore
deleted file mode 100644
index 9de94a54ad..0000000000
--- a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Rider ignored files
-/contentModel.xml
-/projectSettingsUpdater.xml
-/modules.xml
-/.idea.MSTestTimer.iml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/encodings.xml b/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/encodings.xml
deleted file mode 100644
index df87cf951f..0000000000
--- a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/material_theme_project_new.xml b/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/material_theme_project_new.xml
deleted file mode 100644
index a4167976b0..0000000000
--- a/tools/speed-comparison/MSTestTimer/.idea/.idea.MSTestTimer/.idea/material_theme_project_new.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer.sln b/tools/speed-comparison/MSTestTimer/MSTestTimer.sln
deleted file mode 100644
index cbaaa1a1da..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer.sln
+++ /dev/null
@@ -1,16 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTestTimer", "MSTestTimer\MSTestTimer.csproj", "{0D88A24E-7A58-415E-BBF5-A77904C7420B}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {0D88A24E-7A58-415E-BBF5-A77904C7420B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0D88A24E-7A58-415E-BBF5-A77904C7420B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0D88A24E-7A58-415E-BBF5-A77904C7420B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0D88A24E-7A58-415E-BBF5-A77904C7420B}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
-EndGlobal
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer/AssemblyInfo.cs b/tools/speed-comparison/MSTestTimer/MSTestTimer/AssemblyInfo.cs
deleted file mode 100644
index c3f48a1b21..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer/AssemblyInfo.cs
+++ /dev/null
@@ -1,2 +0,0 @@
- [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)]
-
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer/AssertionTests.cs b/tools/speed-comparison/MSTestTimer/MSTestTimer/AssertionTests.cs
deleted file mode 100644
index 6913712e75..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer/AssertionTests.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-namespace MSTestTimer;
-
-[TestClass]
-public class AssertionTests
-{
- [TestMethod]
- public void NumericAssertionsTest()
- {
- var value = 42;
- var pi = 3.14159;
- var negative = -10;
-
- Assert.AreEqual(42, value);
- Assert.IsTrue(value > 40);
- Assert.IsTrue(value < 50);
- Assert.IsTrue(value >= 40 && value <= 45);
-
- Assert.AreEqual(3.14159, pi);
- Assert.IsTrue(pi > 3.0);
- Assert.AreNotEqual(3.14, pi);
-
- Assert.IsTrue(negative < 0);
- Assert.IsTrue(negative < 0);
- }
-
- [TestMethod]
- public void StringAssertionsTest()
- {
- var text = "Hello, MSTest Framework!";
- var empty = "";
- var whitespace = " ";
-
- Assert.IsNotNull(text);
- Assert.IsTrue(text.Length > 0);
- Assert.IsTrue(text.Contains("MSTest"));
- Assert.IsTrue(text.StartsWith("Hello"));
- Assert.IsTrue(text.EndsWith("!"));
- Assert.AreEqual(24, text.Length);
-
- Assert.AreEqual(0, empty.Length);
- Assert.IsTrue(whitespace.Length > 0);
- Assert.IsFalse(text.Contains("xUnit"));
- }
-
- [TestMethod]
- public void CollectionAssertionsTest()
- {
- var numbers = new List { 1, 2, 3, 4, 5 };
- var empty = new List();
- var duplicates = new[] { 1, 2, 2, 3, 3, 3 };
-
- Assert.IsNotNull(numbers);
- Assert.IsTrue(numbers.Count > 0);
- Assert.AreEqual(5, numbers.Count);
- CollectionAssert.Contains(numbers, 3);
- CollectionAssert.DoesNotContain(numbers, 10);
-
- Assert.AreEqual(0, empty.Count);
-
- CollectionAssert.Contains(duplicates, 2);
- Assert.AreEqual(3, duplicates.Distinct().Count());
- }
-
- [TestMethod]
- public void BooleanAssertionsTest()
- {
- var isTrue = true;
- var isFalse = false;
- var condition = 10 > 5;
-
- Assert.IsTrue(isTrue);
- Assert.IsFalse(isFalse);
- Assert.IsTrue(condition);
- Assert.IsFalse(!condition);
-
- Assert.IsTrue(string.IsNullOrEmpty(""));
- Assert.IsFalse(string.IsNullOrEmpty("text"));
- }
-
- [TestMethod]
- public void ObjectAssertionsTest()
- {
- var obj1 = new TestObject { Id = 1, Name = "Test" };
- var obj2 = new TestObject { Id = 1, Name = "Test" };
- var obj3 = obj1;
- TestObject? nullObj = null;
-
- Assert.IsNotNull(obj1);
- Assert.IsNull(nullObj);
- Assert.AreEqual(obj1, obj2); // Equals comparison
- Assert.AreSame(obj3, obj1);
- Assert.AreNotSame(obj2, obj1);
-
- Assert.AreEqual(typeof(TestObject), obj1.GetType());
- }
-
- [TestMethod]
- public void ComplexAssertionsTest()
- {
- var data = GenerateTestData();
-
- Assert.IsNotNull(data);
- Assert.IsTrue(data.Count > 0);
-
- var firstItem = data.First();
- Assert.AreEqual(1, firstItem.Id);
- Assert.IsTrue(firstItem.Values.Length > 0);
- Assert.AreEqual(15, firstItem.Values.Sum());
-
- var allValid = data.All(x => x.IsValid);
- Assert.IsTrue(allValid);
-
- var totalSum = data.SelectMany(x => x.Values).Sum();
- Assert.AreEqual(120, totalSum);
- }
-
- [TestMethod]
- [DataRow(new[] { 1, 2, 3 }, 6)]
- [DataRow(new[] { 10, 20, 30 }, 60)]
- [DataRow(new[] { -5, 0, 5 }, 0)]
- public void ParameterizedAssertionsTest(int[] values, int expectedSum)
- {
- Assert.IsNotNull(values);
- Assert.IsTrue(values.Length > 0);
- Assert.AreEqual(expectedSum, values.Sum());
- Assert.IsTrue(values.Length > 0);
- Assert.AreEqual((double)expectedSum / values.Length, values.Average());
- }
-
- private List GenerateTestData()
- {
- return new List
- {
- new() { Id = 1, Name = "First", Values = new[] { 1, 2, 3, 4, 5 }, IsValid = true },
- new() { Id = 2, Name = "Second", Values = new[] { 6, 7, 8, 9, 10 }, IsValid = true },
- new() { Id = 3, Name = "Third", Values = new[] { 11, 12, 13, 14, 15 }, IsValid = true }
- };
- }
-
- private class TestObject : IEquatable
- {
- public int Id { get; set; }
- public string Name { get; set; } = "";
-
- public bool Equals(TestObject? other)
- {
- if (other is null) return false;
- return Id == other.Id && Name == other.Name;
- }
-
- public override bool Equals(object? obj) => Equals(obj as TestObject);
- public override int GetHashCode() => HashCode.Combine(Id, Name);
- }
-
- private class ComplexTestObject
- {
- public int Id { get; set; }
- public string Name { get; set; } = "";
- public int[] Values { get; set; } = Array.Empty();
- public bool IsValid { get; set; }
- }
-}
\ No newline at end of file
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer/AsyncTests.cs b/tools/speed-comparison/MSTestTimer/MSTestTimer/AsyncTests.cs
deleted file mode 100644
index 96ae5fdb63..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer/AsyncTests.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-namespace MSTestTimer;
-
-[TestClass]
-public class AsyncTests
-{
- [TestMethod]
- public async Task SimpleAsyncTest()
- {
- var result = await ComputeAsync(10);
- Assert.AreEqual(100, result);
-
- var text = await ProcessTextAsync("hello");
- Assert.AreEqual("HELLO", text);
- }
-
- [TestMethod]
- public async Task AsyncStreamOperationsTest()
- {
- using var stream = new MemoryStream();
- using var writer = new StreamWriter(stream);
- using var reader = new StreamReader(stream);
-
- await writer.WriteLineAsync("Line 1");
- await writer.WriteLineAsync("Line 2");
- await writer.WriteLineAsync("Line 3");
- await writer.FlushAsync();
-
- stream.Position = 0;
-
- var lines = new List();
- string? line;
- while ((line = await reader.ReadLineAsync()) != null)
- {
- lines.Add(line);
- }
-
- Assert.AreEqual(3, lines.Count);
- Assert.AreEqual("Line 1", lines[0]);
- Assert.AreEqual("Line 3", lines[2]);
- }
-
- [TestMethod]
- public async Task ConcurrentTasksTest()
- {
- var tasks = new[]
- {
- ComputeAsync(5),
- ComputeAsync(10),
- ComputeAsync(15),
- ComputeAsync(20)
- };
-
- var results = await Task.WhenAll(tasks);
-
- Assert.AreEqual(4, results.Length);
- Assert.AreEqual(25, results[0]);
- Assert.AreEqual(100, results[1]);
- Assert.AreEqual(225, results[2]);
- Assert.AreEqual(400, results[3]);
- Assert.AreEqual(750, results.Sum());
- }
-
- [TestMethod]
- public async Task AsyncEnumerableTest()
- {
- var sum = 0;
- var count = 0;
-
- await foreach (var value in GenerateValuesAsync())
- {
- sum += value;
- count++;
- }
-
- Assert.AreEqual(10, count);
- Assert.AreEqual(55, sum);
- }
-
- [TestMethod]
- public async Task AsyncFileSimulationTest()
- {
- var data = await SimulateFileReadAsync("test.txt");
- var lines = data.Split('\n');
-
- Assert.AreEqual(5, lines.Length);
- Assert.AreEqual("Header: Test File", lines[0]);
- Assert.AreEqual("Footer: End of File", lines[4]);
-
- var processed = await SimulateFileProcessAsync(data);
- Assert.IsTrue(processed.Contains("PROCESSED"));
- }
-
- [TestMethod]
- [DataRow(10)]
- [DataRow(20)]
- [DataRow(30)]
- public async Task ParameterizedAsyncTest(int input)
- {
- var result = await ComputeAsync(input);
- Assert.AreEqual(input * input, result);
-
- var delayed = await DelayedComputeAsync(input, 10);
- Assert.AreEqual(input + 10, delayed);
- }
-
- [TestMethod]
- public async Task AsyncExceptionHandlingTest()
- {
- try
- {
- var result = await SafeComputeAsync(10);
- Assert.AreEqual(100, result);
-
- result = await SafeComputeAsync(-1);
- Assert.AreEqual(0, result);
- }
- catch
- {
- Assert.Fail("Should not throw");
- }
- }
-
- private async Task ComputeAsync(int value)
- {
- await Task.Yield();
- return value * value;
- }
-
- private async Task ProcessTextAsync(string text)
- {
- await Task.Yield();
- return text.ToUpper();
- }
-
- private async IAsyncEnumerable GenerateValuesAsync()
- {
- for (var i = 1; i <= 10; i++)
- {
- await Task.Yield();
- yield return i;
- }
- }
-
- private async Task SimulateFileReadAsync(string filename)
- {
- await Task.Yield();
- return $"Header: Test File\nLine 1: Data\nLine 2: More Data\nLine 3: Even More Data\nFooter: End of File";
- }
-
- private async Task SimulateFileProcessAsync(string content)
- {
- await Task.Yield();
- return $"PROCESSED: {content.Length} characters";
- }
-
- private async Task DelayedComputeAsync(int value, int delay)
- {
- await Task.Delay(1);
- return value + delay;
- }
-
- private async Task SafeComputeAsync(int value)
- {
- await Task.Yield();
- if (value < 0) return 0;
- return value * value;
- }
-}
\ No newline at end of file
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer/BasicTests.cs b/tools/speed-comparison/MSTestTimer/MSTestTimer/BasicTests.cs
deleted file mode 100644
index 1b8492d05f..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer/BasicTests.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-namespace MSTestTimer;
-
-[TestClass]
-public class BasicTests
-{
- [TestMethod]
- public void SimpleTest()
- {
- var result = CalculateSum(5, 10);
- Assert.AreEqual(15, result);
- }
-
- [TestMethod]
- public void MultipleAssertionsTest()
- {
- var text = "Hello, World!";
- var numbers = new[] { 1, 2, 3, 4, 5 };
-
- Assert.IsNotNull(text);
- Assert.AreEqual(13, text.Length);
- Assert.IsTrue(text.Contains("World"));
-
- Assert.AreEqual(5, numbers.Length);
- Assert.AreEqual(15, numbers.Sum());
- CollectionAssert.Contains(numbers, 3);
- }
-
- [TestMethod]
- public void CollectionOperationsTest()
- {
- var items = Enumerable.Range(1, 100).ToList();
- var filtered = items.Where(x => x % 2 == 0).ToList();
- var sum = filtered.Sum();
-
- Assert.AreEqual(50, filtered.Count);
- Assert.AreEqual(2550, sum);
- Assert.AreEqual(2, filtered.First());
- Assert.AreEqual(100, filtered.Last());
- }
-
- [TestMethod]
- public void StringManipulationTest()
- {
- var input = " Hello, MSTest Testing Framework! ";
- var trimmed = input.Trim();
- var upper = trimmed.ToUpper();
- var words = trimmed.Split(' ');
-
- Assert.AreEqual("Hello, MSTest Testing Framework!", trimmed);
- Assert.AreEqual("HELLO, MSTEST TESTING FRAMEWORK!", upper);
- Assert.AreEqual(4, words.Length);
- Assert.AreEqual("MSTest", words[1]);
- }
-
- [TestMethod]
- public void DictionaryOperationsTest()
- {
- var dictionary = new Dictionary();
- for (var i = 0; i < 50; i++)
- {
- dictionary[$"key{i}"] = i * i;
- }
-
- Assert.AreEqual(50, dictionary.Count);
- Assert.AreEqual(100, dictionary["key10"]);
- Assert.IsTrue(dictionary.ContainsKey("key25"));
- Assert.AreEqual(40425, dictionary.Values.Sum());
- }
-
- private int CalculateSum(int a, int b) => a + b;
-}
\ No newline at end of file
diff --git a/tools/speed-comparison/MSTestTimer/MSTestTimer/DataDrivenTests.cs b/tools/speed-comparison/MSTestTimer/MSTestTimer/DataDrivenTests.cs
deleted file mode 100644
index 4b301e3fca..0000000000
--- a/tools/speed-comparison/MSTestTimer/MSTestTimer/DataDrivenTests.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-namespace MSTestTimer;
-
-[TestClass]
-public class DataDrivenTests
-{
- [TestMethod]
- [DataRow(1, 2, 3)]
- [DataRow(10, 20, 30)]
- [DataRow(-5, 5, 0)]
- [DataRow(100, 200, 300)]
- public void ParameterizedAdditionTest(int a, int b, int expected)
- {
- var result = a + b;
- Assert.AreEqual(expected, result);
- }
-
- [TestMethod]
- [DataRow("hello", "HELLO")]
- [DataRow("world", "WORLD")]
- [DataRow("MSTest", "MSTEST")]
- [DataRow("Testing", "TESTING")]
- [DataRow("Framework", "FRAMEWORK")]
- public void ParameterizedStringTest(string input, string expected)
- {
- var result = input.ToUpper();
- Assert.AreEqual(expected, result);
- Assert.AreEqual(input.Length, result.Length);
- }
-
- [TestMethod]
- [DynamicData(nameof(ComplexTestData), DynamicDataSourceType.Method)]
- public void DynamicDataSourceTest(TestData data)
- {
- var result = ProcessTestData(data);
-
- Assert.AreEqual(data.Id, result.Id);
- Assert.AreEqual(data.Value * 2, result.ProcessedValue);
- Assert.IsTrue(result.IsValid);
- }
-
- [TestMethod]
- [DynamicData(nameof(GetTestCases), DynamicDataSourceType.Method)]
- public void ClassDataSourceTest(int value, string text, bool flag)
- {
- Assert.IsTrue(value > 0);
- Assert.IsNotNull(text);
- Assert.IsTrue(text.Length > 0);
- Assert.IsTrue(flag);
- }
-
- [TestMethod]
- [DataRow(new int[] { 1, 2, 3, 4, 5 }, 15)]
- [DataRow(new int[] { 10, 20, 30 }, 60)]
- [DataRow(new int[] { -5, 0, 5 }, 0)]
- [DataRow(new int[] { 100 }, 100)]
- public void ArrayParameterTest(int[] numbers, int expectedSum)
- {
- var sum = numbers.Sum();
- var average = numbers.Average();
-
- Assert.AreEqual(expectedSum, sum);
- Assert.AreEqual((double)expectedSum / numbers.Length, average);
- Assert.IsTrue(numbers.Length > 0);
- }
-
- public static IEnumerable