diff --git a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs index 26011945cd..c7802c2cde 100644 --- a/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs +++ b/src/Adapter/PlatformServices.NetCore/Services/NetCoreTestContextImplementation.cs @@ -10,6 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; + using System.Linq; using System.Threading; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; @@ -31,7 +32,7 @@ public class TestContextImplementation : UTF.TestContext, ITestContext /// /// List of result files associated with the test /// - private IList testResultFiles; + private readonly IList testResultFiles; /// /// Properties @@ -213,6 +214,22 @@ public UTF.TestContext Context } } + /// + /// Adds a file name to the list in TestResult.ResultFileNames + /// + /// + /// The file Name. + /// + public override void AddResultFile(string fileName) + { + if (string.IsNullOrEmpty(fileName)) + { + throw new ArgumentException(Resource.Common_CannotBeNullOrEmpty, "fileName"); + } + + this.testResultFiles.Add(Path.GetFullPath(fileName)); + } + /// /// Set the unit-test outcome /// @@ -255,12 +272,21 @@ public void AddProperty(string propertyName, string propertyValue) } /// - /// Returning null as this feature is not supported in ASP .net and UWP + /// Result files attached /// - /// List of result files. Null presently. + /// List of result files generated in run. public IList GetResultFiles() { - return null; + if (this.testResultFiles.Count == 0) + { + return null; + } + + IList results = this.testResultFiles.ToList(); + + this.testResultFiles.Clear(); + + return results; } /// diff --git a/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs index b0b090992c..7442e7301d 100644 --- a/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs +++ b/src/Adapter/PlatformServices.Shared/netstandard1.0/Services/ns10TestContextImplementation.cs @@ -133,6 +133,19 @@ public UTF.TestContext Context } } + /// + /// Adds a file name to the list in TestResult.ResultFileNames + /// + /// + /// The file Name. + /// + public override void AddResultFile(string fileName) + { + // No-op function + // will be replaced at runtime time by PlatformServices Desktop/NetCore + // depending the target framework + } + /// /// Set the unit-test outcome /// @@ -174,15 +187,6 @@ public void AddProperty(string propertyName, string propertyValue) this.properties.Add(propertyName, propertyValue); } - /// - /// Returning null as this feature is not supported in ASP .net and UWP - /// - /// List of result files. Null presently. - public IList GetResultFiles() - { - return null; - } - /// /// When overridden in a derived class, used to write trace messages while the /// test is running. @@ -230,6 +234,15 @@ public override void WriteLine(string format, params object[] args) } } + /// + /// Returns null as this feature is not supported in ASP .net and UWP + /// + /// List of result files. Null presently. + public IList GetResultFiles() + { + return null; + } + /// /// Gets messages from the testContext writeLines /// diff --git a/src/TestFramework/Extension.Core/NetCoreTestContext.cs b/src/TestFramework/Extension.Core/NetCoreTestContext.cs index 644d75ce01..ed503ae80d 100644 --- a/src/TestFramework/Extension.Core/NetCoreTestContext.cs +++ b/src/TestFramework/Extension.Core/NetCoreTestContext.cs @@ -97,6 +97,14 @@ public abstract class TestContext /// public virtual UnitTestOutcome CurrentTestOutcome => UnitTestOutcome.Unknown; + /// + /// Adds a file name to the list in TestResult.ResultFileNames + /// + /// + /// The file Name. + /// + public abstract void AddResultFile(string fileName); + /// /// Used to write trace messages while the test is running /// diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj index fd9d5671fc..8d199cbd96 100644 --- a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj +++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/PlatformServices.NetCore.Unit.Tests.csproj @@ -19,7 +19,6 @@ - diff --git a/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs new file mode 100644 index 0000000000..b375b9470c --- /dev/null +++ b/test/UnitTests/PlatformServices.NetCore.Unit.Tests/Services/NetCoreTestContextImplementationTests.cs @@ -0,0 +1,340 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestAdapter.PlatformServices.Tests.Services +{ +#if NETCOREAPP1_1 + using Microsoft.VisualStudio.TestTools.UnitTesting; +#else + extern alias FrameworkV1; + extern alias FrameworkV2; + + using Assert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.Assert; + using CollectionAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert; + using StringAssert = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert; + using TestClass = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute; + using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute; + using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute; + using UnitTestOutcome = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome; +#endif + + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + + using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + using Moq; + using MSTestAdapter.TestUtilities; + using ITestMethod = Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod; + + [TestClass] + public class TestContextImplementationTests + { + private Mock testMethod; + + private IDictionary properties; + + private TestContextImplementation testContextImplementation; + + [TestInitialize] + public void TestInit() + { + this.testMethod = new Mock(); + this.properties = new Dictionary(); + } + + [TestMethod] + public void TestContextConstructorShouldInitializeProperties() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.IsNotNull(this.testContextImplementation.Properties); + } + + [TestMethod] + public void TestContextConstructorShouldInitializeDefaultProperties() + { + this.testMethod.Setup(tm => tm.FullClassName).Returns("A.C.M"); + this.testMethod.Setup(tm => tm.Name).Returns("M"); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.IsNotNull(this.testContextImplementation.Properties); + + CollectionAssert.Contains( + this.testContextImplementation.Properties, + new KeyValuePair("FullyQualifiedTestClassName", "A.C.M")); + CollectionAssert.Contains( + this.testContextImplementation.Properties, + new KeyValuePair("TestName", "M")); + } + + [TestMethod] + public void CurrentTestOutcomeShouldReturnDefaultOutcome() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.AreEqual(UnitTestOutcome.Failed, this.testContextImplementation.CurrentTestOutcome); + } + + [TestMethod] + public void CurrentTestOutcomeShouldReturnOutcomeSet() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.SetOutcome(UnitTestOutcome.InProgress); + + Assert.AreEqual(UnitTestOutcome.InProgress, this.testContextImplementation.CurrentTestOutcome); + } + + [TestMethod] + public void FullyQualifiedTestClassNameShouldReturnTestMethodsFullClassName() + { + this.testMethod.Setup(tm => tm.FullClassName).Returns("A.C.M"); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.AreEqual("A.C.M", this.testContextImplementation.FullyQualifiedTestClassName); + } + + [TestMethod] + public void TestNameShouldReturnTestMethodsName() + { + this.testMethod.Setup(tm => tm.Name).Returns("M"); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.AreEqual("M", this.testContextImplementation.TestName); + } + + [TestMethod] + public void PropertiesShouldReturnPropertiesPassedToTestContext() + { + var property1 = new KeyValuePair("IntProperty", 1); + var property2 = new KeyValuePair("DoubleProperty", 2.023); + + this.properties.Add(property1); + this.properties.Add(property2); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + CollectionAssert.Contains(this.testContextImplementation.Properties, property1); + CollectionAssert.Contains(this.testContextImplementation.Properties, property2); + } + + [TestMethod] + public void ContextShouldReturnTestContextObject() + { + this.testMethod.Setup(tm => tm.Name).Returns("M"); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + Assert.IsNotNull(this.testContextImplementation.Context); + Assert.AreEqual("M", this.testContextImplementation.Context.TestName); + } + + [TestMethod] + public void TryGetPropertyValueShouldReturnTrueIfPropertyIsPresent() + { + this.testMethod.Setup(tm => tm.Name).Returns("M"); + + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + Assert.IsTrue(this.testContextImplementation.TryGetPropertyValue("TestName", out object propValue)); + Assert.AreEqual("M", propValue); + } + + [TestMethod] + public void TryGetPropertyValueShouldReturnFalseIfPropertyIsNotPresent() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + Assert.IsFalse(this.testContextImplementation.TryGetPropertyValue("Random", out object propValue)); + Assert.IsNull(propValue); + } + + [TestMethod] + public void AddPropertyShouldAddPropertiesToThePropertyBag() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.AddProperty("SomeNewProperty", "SomeValue"); + + CollectionAssert.Contains( + this.testContextImplementation.Properties, + new KeyValuePair("SomeNewProperty", "SomeValue")); + } + + [TestMethod] + public void WriteLineShouldWriteToStringWriter() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("{0} Testing write", 1); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing write"); + } + + [TestMethod] + public void WriteLineShouldWriteToStringWriterForNullCharacters() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("{0} Testing \0 write \0", 1); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0"); + } + + [TestMethod] + public void WriteLineShouldNotThrowIfStringWriterIsDisposed() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + stringWriter.Dispose(); + + this.testContextImplementation.WriteLine("{0} Testing write", 1); + + // Calling it twice to cover the direct return when we know the object has been disposed. + this.testContextImplementation.WriteLine("{0} Testing write", 1); + } + + [TestMethod] + public void WriteLineWithMessageShouldWriteToStringWriter() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("1 Testing write"); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing write"); + } + + [TestMethod] + public void WriteLineWithMessageShouldWriteToStringWriterForNullCharacters() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("1 Testing \0 write \0"); + + StringAssert.Contains(stringWriter.ToString(), "1 Testing \\0 write \\0"); + } + + [TestMethod] + public void WriteLineWithMessageShouldNotThrowIfStringWriterIsDisposed() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + stringWriter.Dispose(); + + this.testContextImplementation.WriteLine("1 Testing write"); + + // Calling it twice to cover the direct return when we know the object has been disposed. + this.testContextImplementation.WriteLine("1 Testing write"); + } + + [TestMethod] + public void GetDiagnosticMessagesShouldReturnMessagesFromWriteLine() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.WriteLine("1 Testing write"); + this.testContextImplementation.WriteLine("2 Its a happy day"); + + StringAssert.Contains(this.testContextImplementation.GetDiagnosticMessages(), "1 Testing write"); + StringAssert.Contains(this.testContextImplementation.GetDiagnosticMessages(), "2 Its a happy day"); + } + + [TestMethod] + public void ClearDiagnosticMessagesShouldClearMessagesFromWriteLine() + { + var stringWriter = new StringWriter(); + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, stringWriter, this.properties); + + this.testContextImplementation.WriteLine("1 Testing write"); + this.testContextImplementation.WriteLine("2 Its a happy day"); + + this.testContextImplementation.ClearDiagnosticMessages(); + + Assert.AreEqual(string.Empty, stringWriter.ToString()); + } + + [TestMethod] + public void AddResultFileShouldAddFiletoResultsFiles() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.AddResultFile("C:\\files\\myfile.txt"); + var resultFile = this.testContextImplementation.GetResultFiles(); + + CollectionAssert.Contains(resultFile.ToList(), "C:\\files\\myfile.txt"); + } + + [TestMethod] + public void AddResultFileShouldThrowIfFileNameIsNull() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + var exception = ActionUtility.PerformActionAndReturnException(() => this.testContextImplementation.AddResultFile(null)); + + Assert.AreEqual(typeof(ArgumentException), exception.GetType()); + StringAssert.Contains(exception.Message, Resource.Common_CannotBeNullOrEmpty); + } + + [TestMethod] + public void AddResultFileShouldThrowIfFileNameIsEmpty() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + var exception = ActionUtility.PerformActionAndReturnException(() => this.testContextImplementation.AddResultFile(string.Empty)); + + Assert.AreEqual(typeof(ArgumentException), exception.GetType()); + StringAssert.Contains(exception.Message, Resource.Common_CannotBeNullOrEmpty); + } + + [TestMethod] + public void AddResultFileShouldAddMultipleFilestoResultsFiles() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.AddResultFile("C:\\files\\file1.txt"); + this.testContextImplementation.AddResultFile("C:\\files\\files2.html"); + + var resultsFiles = this.testContextImplementation.GetResultFiles(); + + CollectionAssert.Contains(resultsFiles.ToList(), "C:\\files\\file1.txt"); + CollectionAssert.Contains(resultsFiles.ToList(), "C:\\files\\files2.html"); + } + + [TestMethod] + public void GetResultFilesShouldReturnNullIfNoAddedResultFiles() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + var resultFile = this.testContextImplementation.GetResultFiles(); + + Assert.IsNull(resultFile, "No added result files"); + } + + [TestMethod] + public void GetResultFilesShouldReturnListOfAddedResultFiles() + { + this.testContextImplementation = new TestContextImplementation(this.testMethod.Object, new StringWriter(), this.properties); + + this.testContextImplementation.AddResultFile("C:\\files\\myfile.txt"); + this.testContextImplementation.AddResultFile("C:\\files\\myfile2.txt"); + + var resultFiles = this.testContextImplementation.GetResultFiles(); + + Assert.IsTrue(resultFiles.Count > 0, "GetResultFiles returned added elements"); + CollectionAssert.Contains(resultFiles.ToList(), "C:\\files\\myfile.txt"); + CollectionAssert.Contains(resultFiles.ToList(), "C:\\files\\myfile2.txt"); + } + } + +#pragma warning restore SA1649 // SA1649FileNameMustMatchTypeName + +} diff --git a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs index c063c1f42e..e0c26889da 100644 --- a/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs +++ b/test/UnitTests/PlatformServices.Shared.Unit.Tests/netstandard1.0/ns10TestContextImplementationTests.cs @@ -20,7 +20,6 @@ namespace MSTestAdapter.PlatformServices.Tests.Services using System.Collections.Generic; using System.IO; - using System.Linq; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Moq;