diff --git a/.reviewmark.yaml b/.reviewmark.yaml index 6835c54..4aff849 100644 --- a/.reviewmark.yaml +++ b/.reviewmark.yaml @@ -20,15 +20,17 @@ reviews: - id: TestResults-Model title: Review of TestResults Model paths: + - "docs/reqstream/model.yaml" + - "docs/design/model.md" - "src/DemaConsulting.TestResults/*.cs" + - "test/DemaConsulting.TestResults.Tests/*.cs" - "!**/obj/**" - - "docs/design/model.md" - - "docs/reqstream/model.yaml" - id: TestResults-Serialization title: Review of TestResults Serialization paths: + - "docs/reqstream/serialization.yaml" + - "docs/design/serialization.md" - "src/DemaConsulting.TestResults/IO/**/*.cs" + - "test/DemaConsulting.TestResults.Tests/IO/**/*.cs" - "!**/obj/**" - - "docs/design/serialization.md" - - "docs/reqstream/serialization.yaml" diff --git a/docs/design/model.md b/docs/design/model.md index 293f3a2..ac1e892 100644 --- a/docs/design/model.md +++ b/docs/design/model.md @@ -7,9 +7,10 @@ It is deliberately free of serialization concerns — it knows nothing about TRX XML — so that it can serve as a neutral interchange format between different serializers and consumers. -The model consists of three types: +The model consists of four types: - `TestOutcome` — an enumeration of all possible test execution outcomes +- `TestOutcomeExtensions` — extension methods that classify a `TestOutcome` into logical categories - `TestResult` — a single test case result, including timing, output, and error information - `TestResults` — a collection of `TestResult` objects representing a complete test run diff --git a/docs/reqstream/model.yaml b/docs/reqstream/model.yaml index 5dbea55..bc5cd10 100644 --- a/docs/reqstream/model.yaml +++ b/docs/reqstream/model.yaml @@ -63,7 +63,7 @@ sections: pass or fail result. This status is important for test frameworks that support inconclusive results and helps distinguish ambiguous test executions from failures. tests: - - TestOutcome_IsExecuted_InconclusiveOutcome_ReturnsTrue + - TestOutcome_IsExecuted_AllOutcomes_ReturnsExpectedResult - TrxExampleTests_Deserialize_Example1Trx_ReturnsAllTestResults - id: TestResults-Mdl-AbortedOutcome @@ -82,7 +82,7 @@ sections: started. This status is important for test frameworks that support asynchronous or deferred test execution and helps track test execution state. tests: - - TestOutcome_IsExecuted_InconclusiveOutcome_ReturnsTrue + - TestOutcome_IsExecuted_AllOutcomes_ReturnsExpectedResult - TestOutcome_IsPassed_PassedOutcome_ReturnsTrue - TrxExampleTests_Deserialize_Example1Trx_ReturnsAllTestResults diff --git a/src/DemaConsulting.TestResults/TestOutcome.cs b/src/DemaConsulting.TestResults/TestOutcome.cs index 7bd8b64..e041fc9 100644 --- a/src/DemaConsulting.TestResults/TestOutcome.cs +++ b/src/DemaConsulting.TestResults/TestOutcome.cs @@ -21,7 +21,7 @@ namespace DemaConsulting.TestResults; /// -/// TestOutcome enum +/// Defines the possible outcomes for a test case execution. /// public enum TestOutcome { diff --git a/src/DemaConsulting.TestResults/TestResult.cs b/src/DemaConsulting.TestResults/TestResult.cs index 9b48932..a2de702 100644 --- a/src/DemaConsulting.TestResults/TestResult.cs +++ b/src/DemaConsulting.TestResults/TestResult.cs @@ -21,7 +21,7 @@ namespace DemaConsulting.TestResults; /// -/// TestResult class +/// Represents the result of a single test case execution. /// public sealed class TestResult { diff --git a/src/DemaConsulting.TestResults/TestResults.cs b/src/DemaConsulting.TestResults/TestResults.cs index bec33be..5323c0b 100644 --- a/src/DemaConsulting.TestResults/TestResults.cs +++ b/src/DemaConsulting.TestResults/TestResults.cs @@ -21,7 +21,7 @@ namespace DemaConsulting.TestResults; /// -/// TestResults class +/// Represents a collection of test results for a complete test run. /// public sealed class TestResults { diff --git a/test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs b/test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs index 4286a2e..ea63099 100644 --- a/test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs +++ b/test/DemaConsulting.TestResults.Tests/TestOutcomeTests.cs @@ -76,7 +76,7 @@ public void TestOutcome_IsFailed_FailedOutcome_ReturnsTrue() /// Test the IsExecuted method for all outcomes /// [TestMethod] - public void TestOutcome_IsExecuted_InconclusiveOutcome_ReturnsTrue() + public void TestOutcome_IsExecuted_AllOutcomes_ReturnsExpectedResult() { Assert.IsTrue(TestOutcome.Error.IsExecuted()); Assert.IsTrue(TestOutcome.Failed.IsExecuted()); diff --git a/test/DemaConsulting.TestResults.Tests/TestResultTests.cs b/test/DemaConsulting.TestResults.Tests/TestResultTests.cs new file mode 100644 index 0000000..b9aa4e7 --- /dev/null +++ b/test/DemaConsulting.TestResults.Tests/TestResultTests.cs @@ -0,0 +1,245 @@ +// Copyright(c) 2025 DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DemaConsulting.TestResults.Tests; + +/// +/// Tests for the default property values of +/// +[TestClass] +public class TestResultTests +{ + /// + /// Tests that defaults to a non-empty GUID + /// + [TestMethod] + public void TestResult_TestId_Default_IsNotEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - TestId should be auto-generated and not the empty GUID + Assert.AreNotEqual(Guid.Empty, result.TestId); + } + + /// + /// Tests that two separate instances have different values, + /// proving that each instance generates its own unique identifier + /// + [TestMethod] + public void TestResult_TestId_TwoInstances_AreUnique() + { + // Arrange - create two independent TestResult instances + + // Act + var result1 = new TestResult(); + var result2 = new TestResult(); + + // Assert - each instance should have a distinct TestId + Assert.AreNotEqual(result1.TestId, result2.TestId); + } + + /// + /// Tests that defaults to a non-empty GUID + /// + [TestMethod] + public void TestResult_ExecutionId_Default_IsNotEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - ExecutionId should be auto-generated and not the empty GUID + Assert.AreNotEqual(Guid.Empty, result.ExecutionId); + } + + /// + /// Tests that two separate instances have different + /// values, proving that each instance generates its own unique identifier + /// + [TestMethod] + public void TestResult_ExecutionId_TwoInstances_AreUnique() + { + // Arrange - create two independent TestResult instances + + // Act + var result1 = new TestResult(); + var result2 = new TestResult(); + + // Assert - each instance should have a distinct ExecutionId + Assert.AreNotEqual(result1.ExecutionId, result2.ExecutionId); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_Name_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - Name should default to string.Empty + Assert.AreEqual(string.Empty, result.Name); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_CodeBase_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - CodeBase should default to string.Empty + Assert.AreEqual(string.Empty, result.CodeBase); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_ClassName_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - ClassName should default to string.Empty + Assert.AreEqual(string.Empty, result.ClassName); + } + + /// + /// Tests that defaults to the current machine name + /// + [TestMethod] + public void TestResult_ComputerName_Default_IsEnvironmentMachineName() + { + // Arrange - record the expected machine name before construction + var expectedComputerName = Environment.MachineName; + + // Act + var result = new TestResult(); + + // Assert - ComputerName should match the environment's machine name + Assert.AreEqual(expectedComputerName, result.ComputerName); + } + + /// + /// Tests that defaults to + /// + [TestMethod] + public void TestResult_Duration_Default_IsZero() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - Duration should default to TimeSpan.Zero + Assert.AreEqual(TimeSpan.Zero, result.Duration); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_SystemOutput_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - SystemOutput should default to string.Empty + Assert.AreEqual(string.Empty, result.SystemOutput); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_SystemError_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - SystemError should default to string.Empty + Assert.AreEqual(string.Empty, result.SystemError); + } + + /// + /// Tests that defaults to + /// + [TestMethod] + public void TestResult_Outcome_Default_IsNotExecuted() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - Outcome should default to TestOutcome.NotExecuted + Assert.AreEqual(TestOutcome.NotExecuted, result.Outcome); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_ErrorMessage_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - ErrorMessage should default to string.Empty + Assert.AreEqual(string.Empty, result.ErrorMessage); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResult_ErrorStackTrace_Default_IsEmpty() + { + // Arrange - create a new TestResult with default property values + + // Act + var result = new TestResult(); + + // Assert - ErrorStackTrace should default to string.Empty + Assert.AreEqual(string.Empty, result.ErrorStackTrace); + } +} diff --git a/test/DemaConsulting.TestResults.Tests/TestResultsTests.cs b/test/DemaConsulting.TestResults.Tests/TestResultsTests.cs new file mode 100644 index 0000000..312c029 --- /dev/null +++ b/test/DemaConsulting.TestResults.Tests/TestResultsTests.cs @@ -0,0 +1,122 @@ +// Copyright(c) 2025 DEMA Consulting +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DemaConsulting.TestResults.Tests; + +/// +/// Tests for the default property values of +/// +[TestClass] +public class TestResultsTests +{ + /// + /// Tests that defaults to a non-empty GUID + /// + [TestMethod] + public void TestResults_Id_Default_IsNotEmpty() + { + // Arrange - create a new TestResults with default property values + + // Act + var results = new TestResults(); + + // Assert - Id should be auto-generated and not the empty GUID + Assert.AreNotEqual(Guid.Empty, results.Id); + } + + /// + /// Tests that two separate instances have different values, + /// proving that each instance generates its own unique identifier + /// + [TestMethod] + public void TestResults_Id_TwoInstances_AreUnique() + { + // Arrange - create two independent TestResults instances + + // Act + var results1 = new TestResults(); + var results2 = new TestResults(); + + // Assert - each instance should have a distinct Id + Assert.AreNotEqual(results1.Id, results2.Id); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResults_Name_Default_IsEmpty() + { + // Arrange - create a new TestResults with default property values + + // Act + var results = new TestResults(); + + // Assert - Name should default to string.Empty + Assert.AreEqual(string.Empty, results.Name); + } + + /// + /// Tests that defaults to an empty string + /// + [TestMethod] + public void TestResults_UserName_Default_IsEmpty() + { + // Arrange - create a new TestResults with default property values + + // Act + var results = new TestResults(); + + // Assert - UserName should default to string.Empty + Assert.AreEqual(string.Empty, results.UserName); + } + + /// + /// Tests that defaults to a non-null empty list + /// + [TestMethod] + public void TestResults_Results_Default_IsNotNull() + { + // Arrange - create a new TestResults with default property values + + // Act + var results = new TestResults(); + + // Assert - Results list should be initialized (not null) + Assert.IsNotNull(results.Results); + } + + /// + /// Tests that defaults to an empty list + /// + [TestMethod] + public void TestResults_Results_Default_IsEmpty() + { + // Arrange - create a new TestResults with default property values + + // Act + var results = new TestResults(); + + // Assert - Results list should contain no elements + Assert.HasCount(0, results.Results); + } +}