Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Testing] NativeAOT: Stand up UI testing on iOS platforms #20541

Merged
merged 7 commits into from Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 27 additions & 1 deletion eng/cake/dotnet.cake
Expand Up @@ -25,6 +25,14 @@ var NuGetOnlyPackages = new string[] {
"Microsoft.Maui.Maps.*.nupkg",
"Microsoft.AspNetCore.Components.WebView.*.nupkg",
};
public enum RuntimeVariant
{
Mono,
NativeAOT
}

RuntimeVariant RUNTIME_VARIANT = Argument("runtimevariant", RuntimeVariant.Mono);
bool USE_NATIVE_AOT = RUNTIME_VARIANT == RuntimeVariant.NativeAOT ? true : false;

ProcessTFMSwitches();

Expand Down Expand Up @@ -168,7 +176,25 @@ Task("dotnet-samples")
["RestoreConfigFile"] = tempDir.CombineWithFilePath("NuGet.config").FullPath,
};
}
RunMSBuildWithDotNet("./Microsoft.Maui.Samples.slnf", properties, binlogPrefix: "sample-");

string projectsToBuild;
if (USE_NATIVE_AOT)
{
if (configuration.Equals("Debug", StringComparison.OrdinalIgnoreCase))
{
var errMsg = $"Error: Building dotnet-samples with NativeAOT is only supported in Release configuration";
Error(errMsg);
throw new Exception(errMsg);
}
projectsToBuild = "./src/Controls/samples/Controls.Sample.UITests/Controls.Sample.UITests.csproj";
properties["_UseNativeAot"] = "true";
}
else
{
projectsToBuild = "./Microsoft.Maui.Samples.slnf";
}

RunMSBuildWithDotNet(projectsToBuild, properties, binlogPrefix: "sample-");
});

Task("dotnet-legacy-controlgallery")
Expand Down
19 changes: 12 additions & 7 deletions eng/devices/ios.cake
Expand Up @@ -45,6 +45,7 @@ Information("Project File: {0}", PROJECT);
Information("Build Binary Log (binlog): {0}", BINLOG_DIR);
Information("Build Platform: {0}", PLATFORM);
Information("Build Configuration: {0}", CONFIGURATION);
Information("Runtime Variant: {0}", RUNTIME_VARIANT);

string DOTNET_TOOL_PATH = "/usr/local/share/dotnet/dotnet";

Expand Down Expand Up @@ -166,6 +167,13 @@ Task("uitest-build")
var name = System.IO.Path.GetFileNameWithoutExtension(DEFAULT_APP_PROJECT);
var binlog = $"{BINLOG_DIR}/{name}-{CONFIGURATION}-ios.binlog";

if (USE_NATIVE_AOT && CONFIGURATION.Equals("Debug", StringComparison.OrdinalIgnoreCase))
{
var errMsg = $"Error: Running UI tests with NativeAOT is only supported in Release configuration";
Error(errMsg);
throw new Exception(errMsg);
}

Information("app" +DEFAULT_APP_PROJECT);
DotNetBuild(DEFAULT_APP_PROJECT, new DotNetBuildSettings {
Configuration = CONFIGURATION,
Expand All @@ -175,14 +183,10 @@ Task("uitest-build")
{
args
.Append("/p:BuildIpa=true")
.Append($"/p:_UseNativeAot={USE_NATIVE_AOT}")
.Append("/bl:" + binlog)
.Append("/tl");

// if we building for a device
if(TEST_DEVICE.ToLower().Contains("device"))
{
args.Append("/p:RuntimeIdentifier=ios-arm64");
}
.Append("/tl")
.Append($"/p:RuntimeIdentifier={DOTNET_PLATFORM}");

return args;
}
Expand Down Expand Up @@ -311,6 +315,7 @@ Task("uitest")
Configuration = CONFIGURATION,
ArgumentCustomization = args => args
.Append("/p:ExtraDefineConstants=IOSUITEST")
.Append($"/p:_UseNativeAot={USE_NATIVE_AOT}")
.Append("/bl:" + binlog)
.Append("/tl")

Expand Down
5 changes: 3 additions & 2 deletions eng/pipelines/common/ui-tests-steps.yml
Expand Up @@ -8,6 +8,7 @@ parameters:
provisionatorChannel: 'latest'
agentPoolAccessToken: ''
configuration : "Release"
runtimeVariant : "Mono"

steps:
- ${{ if eq(parameters.platform, 'ios')}}:
Expand Down Expand Up @@ -103,7 +104,7 @@ steps:
- pwsh: ./build.ps1 --target=dotnet-buildtasks --configuration="${{ parameters.configuration }}"
displayName: 'Build the MSBuild Tasks'

- pwsh: ./build.ps1 --target=dotnet-samples --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false
- pwsh: ./build.ps1 --target=dotnet-samples --configuration="${{ parameters.configuration }}" --${{ parameters.platform }} --verbosity=diagnostic --usenuget=false --runtimevariant="${{ parameters.runtimeVariant }}"
displayName: 'Build the samples'

- bash: |
Expand All @@ -113,7 +114,7 @@ steps:
condition: ${{ eq(parameters.platform, 'ios') }}
continueOnError: true

- pwsh: ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --target=uitest --project="${{ parameters.path }}" --appproject="${{ parameters.app }}" --device="${{ parameters.device }}" --apiversion="${{ parameters.version }}" --configuration="${{ parameters.configuration }}" --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }} --verbosity=diagnostic
- pwsh: ./build.ps1 -Script eng/devices/${{ parameters.platform }}.cake --target=uitest --project="${{ parameters.path }}" --appproject="${{ parameters.app }}" --device="${{ parameters.device }}" --apiversion="${{ parameters.version }}" --configuration="${{ parameters.configuration }}" --results="$(TestResultsDirectory)" --binlog="$(LogDirectory)" ${{ parameters.cakeArgs }} --verbosity=diagnostic --runtimevariant="${{ parameters.runtimeVariant }}"
displayName: $(Agent.JobName)
retryCountOnTaskFailure: 1

Expand Down
41 changes: 38 additions & 3 deletions eng/pipelines/common/ui-tests.yml
Expand Up @@ -55,15 +55,15 @@ stages:
provisionatorChannel: ${{ parameters.provisionatorChannel }}
agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}

- stage: ios_ui_tests
displayName: iOS UITests
- stage: ios_ui_tests_mono
displayName: iOS UITests Mono
dependsOn: []
jobs:
- ${{ each project in parameters.projects }}:
- ${{ if ne(project.ios, '') }}:
- ${{ each version in parameters.iosVersions }}:
- ${{ if not(containsValue(project.iosVersionsExclude, version)) }}:
- job: ios_ui_tests_${{ project.name }}_${{ replace(version, '.', '_') }}
- job: ios_ui_tests_mono_${{ project.name }}_${{ replace(version, '.', '_') }}
timeoutInMinutes: 240 # how long to run the job before automatically cancelling
workspace:
clean: all
Expand All @@ -87,6 +87,41 @@ stages:
device: ios-simulator-64_${{ version }}
provisionatorChannel: ${{ parameters.provisionatorChannel }}
agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
runtimeVariant : "Mono"

- stage: ios_ui_tests_nativeaot
displayName: iOS UITests NativeAOT
dependsOn: []
jobs:
- ${{ each project in parameters.projects }}:
- ${{ if ne(project.ios, '') }}:
- ${{ each version in parameters.iosVersions }}:
- ${{ if not(containsValue(project.iosVersionsExclude, version)) }}:
- job: ios_ui_tests_nativeaot_${{ project.name }}_${{ replace(version, '.', '_') }}
timeoutInMinutes: 240 # how long to run the job before automatically cancelling
workspace:
clean: all
displayName: ${{ coalesce(project.desc, project.name) }} (v${{ version }})
pool: ${{ parameters.iosPool }}
variables:
REQUIRED_XCODE: $(DEVICETESTS_REQUIRED_XCODE)
steps:
- template: ui-tests-steps.yml
parameters:
platform: ios
${{ if eq(version, 'latest') }}:
version: 16.4
${{ if ne(version, 'latest') }}:
version: ${{ version }}
path: ${{ project.ios }}
app: ${{ project.app }}
${{ if eq(version, 'latest') }}:
device: ios-simulator-64
${{ if ne(version, 'latest') }}:
device: ios-simulator-64_${{ version }}
provisionatorChannel: ${{ parameters.provisionatorChannel }}
agentPoolAccessToken: ${{ parameters.agentPoolAccessToken }}
runtimeVariant : "NativeAOT"

# - stage: winui_ui_tests
# displayName: WinUI UITests
Expand Down
Expand Up @@ -19,6 +19,13 @@
<WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>

<PropertyGroup Condition=" '$(_UseNativeAot)' == 'true' ">
<PublishAot>true</PublishAot>
<_IsPublishing>true</_IsPublishing>
<IlcTreatWarningsAsErrors>false</IlcTreatWarningsAsErrors>
<DefineConstants>$(DefineConstants);NATIVE_AOT</DefineConstants>
</PropertyGroup>

<ItemGroup Condition=" '$(UseMaui)' != 'true' ">
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
</ItemGroup>
Expand Down
5 changes: 5 additions & 0 deletions src/Controls/samples/Controls.Sample.UITests/TestCases.cs
Expand Up @@ -168,6 +168,10 @@ public TestCaseScreen()

var assembly = typeof(TestCases).Assembly;

#if NATIVE_AOT
// Issues tests are disabled with NativeAOT (see https://github.com/dotnet/maui/issues/20553)
_issues = new();
#else
_issues =
(from type in assembly.GetTypes()
let attribute = type.GetCustomAttribute<IssueAttribute>()
Expand All @@ -181,6 +185,7 @@ public TestCaseScreen()
Description = attribute.Description,
Action = ActivatePageAndNavigate(attribute, type)
}).ToList();
#endif

VerifyNoDuplicates();

Expand Down
2 changes: 2 additions & 0 deletions src/Controls/tests/UITests/Controls.AppiumTests.csproj
Expand Up @@ -23,6 +23,8 @@

<ItemGroup>
<Compile Include="..\..\samples\Controls.Sample.UITests\Test.cs" Link="Test.cs" />
<!-- Issues tests are disabled with NativeAOT (see https://github.com/dotnet/maui/issues/20553) -->
<Compile Condition=" '$(_UseNativeAot)' == 'true' " Remove="Tests/Issues/**/*.*" />
</ItemGroup>

<ItemGroup>
Expand Down