Skip to content

Commit

Permalink
Improve attachment handling
Browse files Browse the repository at this point in the history
  • Loading branch information
dotMorten committed Nov 6, 2023
1 parent f7e0931 commit 701160f
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 14 deletions.
1 change: 1 addition & 0 deletions src/MSTestX.Adapter/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Resource = Microsoft.VisualStudio.TestTools.UnitTesting.Resource;
9 changes: 7 additions & 2 deletions src/MSTestX.Adapter/MSTestX.Adapter.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
<AssemblyName>Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter</AssemblyName>
<RootNamespace>Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter</RootNamespace>
<PackageId>MSTestX.TestAdapter</PackageId>
Expand All @@ -15,10 +15,11 @@
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<PackageTags>Unit Test, Xamarin, Android, iOS, MSTest, VSTest, TestFX, MSTest.TestAdapter</PackageTags>
<Version>2.2.10.1</Version>
<Version>2.2.10.2</Version>
<GeneratePackageOnBuild Condition="'$(Configuration)'=='Release'">true</GeneratePackageOnBuild>
<PackageOutputPath>./../../nupkg</PackageOutputPath>
<Description>The cross-platform adapter to discover and execute MSTest Framework based tests. This is a .NET Standard 2.0 compilation of the MSTest.TestAdapter for reusing the test adapter on other platforms, like Xamarin Android and iOS.</Description>
<LangVersion>10</LangVersion>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -51,6 +52,10 @@
<Compile Include="..\..\testfx\src\Adapter\PlatformServices.Shared\netstandard1.0\**\*.cs">
<Link>PlatformServices\%(RecursiveDir)%(Filename)%(Extension)</Link>
</Compile>
<Compile Remove="..\..\testfx\src\Adapter\PlatformServices.Shared\netstandard1.0\Services\ns10TestContextImplementation.cs" Condition="'$(TargetFramework)'=='net6.0'" />
<Compile Include="..\..\testfx\src\Adapter\PlatformServices.NetCore\Services\NetCoreTestContextImplementation.cs" Condition="'$(TargetFramework)'=='net6.0'">
<Link>PlatformServices\Services\%(Filename)%(Extension)</Link>
</Compile>

</ItemGroup>

Expand Down
4 changes: 2 additions & 2 deletions src/TestAppRunner/TestAppRunner.Maui/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected override void OnSettingsMenuLoaded(List<Tuple<string, Action>> menuIte
menuItems.Add(new Tuple<string, Action>("Custom action", () => Current.MainPage.DisplayAlert("Hello!", "You clicked a custom action", "OK")));
menuItems.Add(new Tuple<string, Action>("Run two specific tests", async () =>
{
var tests= TestCases?.Where(t => t.DisplayName == "TestOK" || t.DisplayName == "MoreTests_1");
var tests= TestCases?.Where(t => t.DisplayName == "TestOK" || t.DisplayName == "TestAttachments");
try
{
var results = await RunTestsAsync(tests);
Expand All @@ -32,7 +32,7 @@ protected override void OnSettingsMenuLoaded(List<Tuple<string, Action>> menuIte
}));
menuItems.Add(new Tuple<string, Action>("Custom test list", () =>
{
var tests = TestCases?.Where(t => t.DisplayName == "TestOK" || t.DisplayName == "MoreTests_1");
var tests = TestCases?.Where(t => t.DisplayName == "TestOK" || t.DisplayName == "TestAttachments");
NavigateToTestList("Custom Test List", tests);
}));
base.OnSettingsMenuLoaded(menuItems);
Expand Down
12 changes: 12 additions & 0 deletions src/TestAppRunner/TestAppRunner.Maui/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ public static MauiApp CreateMauiApp()
builder
.UseTestApp<App>((testOptions) =>
{
#if __IOS__
var logsdir = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "UnitTests");
#elif __ANDROID__
var logsdir = System.IO.Path.Combine(Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.ApplicationContext.FilesDir.Path, "UnitTests");
#elif WINDOWS
var logsdir = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UnitTests");
#endif
testOptions.TestAssemblies = new System.Reflection.Assembly[] { typeof(UnitTests.AttachmentTests).Assembly };
// configure default timeout
testOptions.SettingsXml = @"<?xml version=""1.0"" encoding=""utf-8""?>" +
Expand All @@ -19,6 +26,11 @@ public static MauiApp CreateMauiApp()
"<TestTimeout>30000</TestTimeout>" +
"</MSTestV2>" +
"</RunSettings>";
if (!System.IO.Directory.Exists(logsdir))
System.IO.Directory.CreateDirectory(logsdir);
testOptions.TrxOutputPath = System.IO.Path.Combine(logsdir, $"UnitTests.trx");
testOptions.ProgressLogPath = System.IO.Path.Combine(logsdir, $"UnitTest.log");
return testOptions;
})
.ConfigureFonts(fonts =>
Expand Down
4 changes: 3 additions & 1 deletion src/TestAppRunner/TestAppRunner/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using TestAppRunner.Views;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.Xaml;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;

[assembly: XamlCompilation (XamlCompilationOptions.Compile)]
namespace MSTestX
Expand Down Expand Up @@ -64,6 +65,7 @@ public void Initialize(TestOptions settings = null)
TestRunnerVM.Instance.Initialize();
}
#endif
public IRunSettings TestRunSettings => TestRunnerVM.Instance.Settings;

/// <summary>
/// Navigate to a page with a custom set of tests.
Expand Down Expand Up @@ -110,7 +112,7 @@ protected override void OnResume()
/// <returns></returns>
public System.Threading.Tasks.Task<IEnumerable<TestResult>> RunTestsAsync(IEnumerable<TestCase> testCases, Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IRunSettings settings = null)
{
return TestRunnerVM.Instance.Run(testCases, settings);
return TestRunnerVM.Instance.Run(testCases, settings ?? TestRunnerVM.Instance.Settings);
}

/// <summary>
Expand Down
3 changes: 2 additions & 1 deletion src/TestAppRunner/TestAppRunner/TrxWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ internal class TrxWriter : TestLoggerEvents, ITestLogger, ITestLoggerWithParamet
public TrxWriter(string trxOutputPath)
{
logger = new Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.TrxLogger();
var parameters = new Dictionary<string, string>() { { "TestRunDirectory", "." } };
var testRunDirectory = new FileInfo(trxOutputPath).Directory.FullName;
var parameters = new Dictionary<string, string>() { { "TestRunDirectory", testRunDirectory } };
if (!string.IsNullOrEmpty(trxOutputPath))
parameters.Add("LogFileName", trxOutputPath);
logger.Initialize(this, parameters);
Expand Down
6 changes: 3 additions & 3 deletions src/TestAppRunner/TestAppRunner/ViewModels/TestResultVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public IEnumerable<UriDataAttachment> Attachments
{
get
{
if(result != null && result.Attachments != null && result.Attachments.Any())
return result.Attachments.SelectMany(t => t.Attachments);
return null;
if (result != null && result.Attachments != null && result.Attachments.Any())
return result.Attachments.Where(t => t.Attachments is not null).SelectMany(t => t.Attachments).Where(a => a is not null);
return Enumerable.Empty<UriDataAttachment>();
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/TestAppRunner/TestAppRunner/ViewModels/TestRunnerVM.cs
Original file line number Diff line number Diff line change
Expand Up @@ -379,11 +379,22 @@ private async Task<IEnumerable<TestResult>> Run_Internal(IEnumerable<TestCase> t
{
try
{
#if DEBUG
File.Delete(Settings.TrxOutputPath);
#endif
trxWriter?.OnTestRunComplete(new Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestRunCompleteEventArgs(null, false, false, null, null, TimeSpan.Zero));
#if DEBUG
var trx = File.ReadAllText(Settings.TrxOutputPath);
System.Diagnostics.Debug.WriteLine(trx);
#endif
}
catch(PlatformNotSupportedException) // Throws due to https://github.com/microsoft/vstest/issues/4736. However it's thrown after TRX is written
catch (PlatformNotSupportedException) // Throws due to https://github.com/microsoft/vstest/issues/4736. However it's thrown after TRX is written
{
Debug.Assert(File.Exists(Settings.TrxOutputPath));
#if DEBUG
var trx = File.ReadAllText(Settings.TrxOutputPath);
System.Diagnostics.Debug.WriteLine(trx);
#endif
}
trxWriter = null;
Logger.Log($"TRXREPORT LOCATION: {Settings.TrxOutputPath}");
Expand Down Expand Up @@ -492,6 +503,14 @@ private static string ComputerName
#endif
void ITestExecutionRecorder.RecordResult(TestResult testResult)
{
var execId = GetProperty<Guid>("ExecutionId", testResult, Guid.Empty);
if (execId == Guid.Empty)
{
var prop = testResult.Properties.Where(p => p.Id == "ExecutionId").FirstOrDefault();
if (prop != null)
testResult.SetPropertyValue(prop, Guid.NewGuid());
}

results?.Add(testResult);
var innerResultsCount = GetProperty<int>("InnerResultsCount", testResult, 0);
var parentExecId = GetProperty<Guid>("ParentExecId", testResult, Guid.Empty);
Expand Down
63 changes: 59 additions & 4 deletions src/TestAppRunner/TestAppRunner/Views/AllTestsPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TestAppRunner.ViewModels;
using System.IO.Compression;
using TestAppRunner.ViewModels;

namespace TestAppRunner.Views
{
Expand Down Expand Up @@ -110,17 +111,71 @@ private void RunFailed_Clicked()

private void Save_Report_Clicked()
{
string path = Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".trx");
string filename = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string path = Path.Combine(Path.GetTempPath(), filename);
bool hasAttachments = false;
var tests = TestRunnerVM.Instance.Tests.Select(t => t.Result).Where(r => r is not null);
try
{
TrxWriter.GenerateReport(path, TestRunnerVM.Instance.Tests.Select(t => t.Result).Where(r => r is not null));
if (!string.IsNullOrEmpty(TestRunnerVM.Instance.Settings.TestRunResultsDirectory) &&
Path.Exists(TestRunnerVM.Instance.Settings.TestRunResultsDirectory))
{
var folders = new DirectoryInfo(TestRunnerVM.Instance.Settings.TestRunResultsDirectory);
foreach (var test in tests.Where(t => t.Attachments is not null))
{
foreach (var a in test.Attachments.Where(a => a is not null))
{
foreach (var a2 in a.Attachments.Where(a2 => a2 is not null))
{
if (File.Exists(a2.Uri.OriginalString))
{
hasAttachments = true;
goto exit_loop;
}
}
}
}
}
exit_loop:
TrxWriter.GenerateReport(path + ".trx", tests);
}
catch (PlatformNotSupportedException) // Throws due to https://github.com/microsoft/vstest/issues/4736. However it's thrown after TRX is written
{
System.Diagnostics.Debug.Assert(File.Exists(path));
}
if(hasAttachments)
{
// Create zip instead
if (Directory.Exists(TestRunnerVM.Instance.Settings.TestRunResultsDirectory))
{
using (ZipArchive archive = ZipFile.Open(path + ".zip", ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(path + ".trx", filename + ".trx");
foreach (var test in tests.Where(t => t.Attachments is not null))
{
foreach (var a in test.Attachments.Where(a => a is not null))
{
foreach (var a2 in a.Attachments.Where(a2 => a2 is not null))
{
string file = a2.Uri.OriginalString;
if (file.StartsWith(TestRunnerVM.Instance.Settings.TestRunResultsDirectory))
{
var entryName = file.Substring(TestRunnerVM.Instance.Settings.TestRunResultsDirectory.Length).TrimStart('/');
var executionId = test.GetPropertyValue(test.Properties.FirstOrDefault(t=>t.Id == "ExecutionId"))?.ToString();
var entrypath = Path.Combine("In", executionId, Environment.MachineName, entryName);
archive.CreateEntryFromFile(file, entrypath);
}
}
}
}
}
Microsoft.Maui.ApplicationModel.DataTransfer.Share.RequestAsync(
new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFileRequest("TRX Test Report", new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFile(path + ".zip")));
return;
}
}
Microsoft.Maui.ApplicationModel.DataTransfer.Share.RequestAsync(
new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFileRequest("TRX Test Report", new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFile(path)));
new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFileRequest("TRX Test Report", new Microsoft.Maui.ApplicationModel.DataTransfer.ShareFile(path + ".trx")));
}
private void StopRun_Clicked()
{
Expand Down

0 comments on commit 701160f

Please sign in to comment.