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

[Mobile] Add BrowserStack Android MAUI Test #23383

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

carzh
Copy link
Contributor

@carzh carzh commented Jan 15, 2025

Description

Add test project that will perform an automated UI test that runs the unit tests on Android.

Motivation

  • Enables end-to-end on-device MAUI unit testing which we want to add to the packaging pipelines

Context

Microsoft.ML.OnnxRuntime.Tests.MAUI uses DeviceRunners.VisualRunners to allow running the unit tests (found in Microsoft.ML.OnnxRuntime.Tests.Common) across multiple devices. DeviceRunners.VisualRunners provides a simple UI with a button that will run the unit tests and a panel with the unit test results.

In order to automate the process of running the unit tests across mobile devices, Appium is used for UI testing orchestration (it provides a way to interact with the UI), and BrowserStack automatically runs these Appium tests across different mobile devices.

This project does not include the capability to start an Appium server locally or attach to a local emulator or device.

Build & run instructions

Requirements

  • A BrowserStack account with access to App Automate
    • You can set BrowserStack credentials as environment variables as shown here
  • ONNXRuntime NuGet package
    1. You can either download the stable NuGet package then follow the instructions from NativeLibraryInclude.props file to use the downloaded .nupkg file
    2. Or follow the build instructions to build the Android package locally
  • The dotnet workloads for maui and maui-android, which will not always automatically install correctly
    1. dotnet workload install maui
    2. dotnet workload install maui-android
  • Appium and the UiAutomator2 driver

Run instructions

  1. Build the Microsoft.ML.OnnxRuntime.Tests.MAUI project into a signed APK.
    1. Run the following: dotnet publish -c Release -f net8.0-android in the Microsoft.ML.OnnxRuntime.Tests.MAUI directory.
    2. Search for the APK files generated. They should be located in bin\Release\net8.0-android\publish.
    3. If they're in a different location, edit the browserstack.yml file to target the path to the signed APK.
  2. Ensure you've set the BrowserStack credentials as environment variables.
  3. Run the following in the Microsoft.ML.OnnxRuntime.Tests.Android.BrowserStack directory: dotnet test
  4. Navigate to the BrowserStack App Automate dashboard to see your test running!

@carzh carzh requested review from skottmckay and edgchen1 January 15, 2025 21:21
/// </summary>
/// <param name="text">Log text to send.</param>
/// <param name="logLevel">Log level -- choose between info, debug, warning, and error</param>
public void browserStackLog(String text, String logLevel = "info")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not used anywhere at the moment, but I thought that I would leave the function in in case anybody wanted to write logs to send to BrowserStack for debugging purposes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add it back later if we want to use it. in general, I'd prefer to not have unused code checked in. it may potentially be useful but also adds complexity.


if (element.Text.Equals("✔"))
{
i++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to increment i in these two if conditions or can we just let the loop run?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the number of tests that passed is stored as a separate text element from the "✔", so I increment to make sure that the element directly after the indicator is parsed as the number passed.

@carzh
Copy link
Contributor Author

carzh commented Jan 16, 2025

Comment on lines 96 to 97
Assert.Pass();
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.Pass() throws so we can just return.

Suggested change
Assert.Pass();
return;
return;


// click into test results if tests have failed
FindAppiumElementThenClick("//android.widget.TextView", "⛔");
await Task.Delay(500);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how reliable is this delay? would the test be less prone to flakiness if we explicitly wait for an expected UI element to become available?

public async Task ClickRunAllTest()
{
// XAML for the main page:
// https://github.com/mattleibow/DeviceRunners/blob/main/src/DeviceRunners.VisualRunners.Maui/App/Pages/HomePage.xaml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also use a permalink here

Suggested change
// https://github.com/mattleibow/DeviceRunners/blob/main/src/DeviceRunners.VisualRunners.Maui/App/Pages/HomePage.xaml
// https://github.com/mattleibow/DeviceRunners/blob/cba7644e07b305ba64dc930b01c3eee55ef2b93d/src/DeviceRunners.VisualRunners.Maui/App/Pages/HomePage.xaml

/// </summary>
/// <param name="text">Log text to send.</param>
/// <param name="logLevel">Log level -- choose between info, debug, warning, and error</param>
public void browserStackLog(String text, String logLevel = "info")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can add it back later if we want to use it. in general, I'd prefer to not have unused code checked in. it may potentially be useful but also adds complexity.

@edgchen1
Copy link
Contributor

will this test be run from a pipeline? will that be done in another PR?

@carzh
Copy link
Contributor Author

carzh commented Jan 17, 2025

will this test be run from a pipeline? will that be done in another PR?

Yep, the test will be run in the NuGet packaging pipeline which will be done in a follow-up PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants