Skip to content

Add Android device tests with bundled ICU 70 - #230

Merged
hahn-kev merged 27 commits into
masterfrom
feature/android-device-tests
Sep 23, 2026
Merged

hahn-kev merged 27 commits into
masterfrom
feature/android-device-tests

Conversation

@hahn-kev

@hahn-kev hahn-kev commented Jul 3, 2026 •

Copy link
Copy Markdown
Collaborator

Most of this work was done by Cursor.

Runs the icu.net test suite on a physical Android device or emulator via DeviceRunners, using bundled ICU 70 instead of system ICU. All tests use NUnit — the full icu.net.tests suite plus a small android.tests assembly for platform smoke and ICU load diagnostics.

  • MAUI test app (icu.net.android.tests) — NUnit smoke tests (platform check, ICU load diagnostics) and the full NUnit suite from icu.net.tests via project reference
  • Bundled ICU loading — APK native libs, dlopen with RTLD_GLOBAL, soname symlinks, external icudt72l.dat; bootstrap lives in icu.net and runs from Wrapper.Init() on Android
  • Optional net10.0-android TFM on icu.net via IcuDotNetIncludeAndroid (off by default for the NuGet package)
  • DeviceRunners workarounds — default TRX logger for dotnet test summary; TRX rebuild from JSONL when failure output contains XML-invalid control characters

Status: Smoke/diagnostic tests pass. Full NUnit run discovers ~458 tests; many failures are expected Android/ICU gaps (BiDi, locale, Windows-only cases), not runner wiring.

Test plan:

$env:ANDROID_HOME = 'C:\path\to\android-sdk'
.\scripts\run-android-tests.ps1 -Configuration Release

hahn-kev and others added 10 commits July 2, 2026 15:31
Introduce a MAUI-based test host for on-device xUnit runs on Android,
with a dotnet test script and xharness tool manifest for CI/local use.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove default shell, sample UI, and non-Android targets so the
device runner project is a minimal starting point for on-device tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reference icu.net from the device test project and add RuleBasedCollator Compare coverage on Android. Map Android to Unix in Platform so native ICU loading follows the Unix path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add cross-compile scripts, APK-native-library wiring, and Android-specific
loading so soname dependencies and external icudt72l.dat work under FastDev.

Co-authored-by: Cursor <cursoragent@cursor.com>
Multi-target the test project for net10.0-android, wire AddNUnit in the MAUI
host, and delegate ICU setup through Wrapper.AndroidTestConfigure.

Co-authored-by: Cursor <cursoragent@cursor.com>
DeviceRunners only writes TRX when a logger is configured; default VSTestLogger
in the test project produces the documented test summary line.

Co-authored-by: Cursor <cursoragent@cursor.com>
DeviceRunners can truncate TRX when messages contain control characters; regenerate
a sanitized test-results.trx from tcp-test-events.jsonl before dotnet test reports.

Co-authored-by: Cursor <cursoragent@cursor.com>
… TFM.

Wrapper.Init() now configures bundled ICU on Android automatically, removing the test-app setup hook.
Convert smoke and diagnostics tests to NUnit and remove duplicate collation coverage already in icu.net.tests.
Run bundled ICU build and NUnit tests on an emulator; include TRX in the test-results workflow alongside desktop NUnit XML.
@github-actions

github-actions Bot commented Jul 3, 2026 •

Copy link
Copy Markdown

Test Results

       9 files  ±    0     754 suites  +27   11s ⏱️ -2s
   455 tests +  14     451 ✔️ +  14      4 💤 ±0  0 ❌ ±0 
4 177 runs  +126  3 955 ✔️ +120  222 💤 +6  0 ❌ ±0 

Results for commit 4f56a6b. ± Comparison against base commit 2bb57eb.

♻️ This comment has been updated with latest results.

hahn-kev and others added 9 commits July 3, 2026 13:18
Use valid action SHAs, gate net10.0-android on IcuDotNetIncludeAndroid in icu.net.tests, and skip building icu.net.android.tests from the main solution so desktop jobs do not require MAUI workloads.
Only collation and Android-specific tests are expected to pass on Android for now.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the in-repo NDK cross-compile with a local NuGet feed package, and make bootstrap extract APK natives plus resolve symbols via NativeLibrary/libdl so collation tests pass on emulator.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hahn-kev hahn-kev changed the title Add Android device tests with bundled ICU 72 Add Android device tests with bundled ICU 70 Aug 13, 2026
Drop the local-packages feed now that the Android ICU natives package is published.

Co-authored-by: Cursor <cursoragent@cursor.com>
@hahn-kev
hahn-kev marked this pull request as ready for review August 14, 2026 07:11
hahn-kev and others added 2 commits August 14, 2026 14:49
Avoid hardcoding 70 so a native package bump does not require rebuilding icu.net. Drop unused NDK/probe scripts from this branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
Path.GetFileName only treats backslash as a separator on Windows, which failed the assets\\icudt70l.dat case on Linux CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
imnasnainaec

This comment was marked as low quality.

@hahn-kev

Copy link
Copy Markdown
Collaborator Author

@imnasnainaec you say that it doesn't compile when it does in CI. Why?

@imnasnainaec

Copy link
Copy Markdown
Contributor

@imnasnainaec you say that it doesn't compile when it does in CI. Why?

@hahn-kev I assumed it was a gap in the CI coverage, but hadn't checked myself. Sorry for any contained hallucination or slop.

Co-authored-by: Cursor <cursoragent@cursor.com>
NUnit 4 (used by the net10.0-android target) removed the
Assert.That(actual, constraint, string, params object[]) overload, so
the IsBoundary assertion failed to compile there. Use an interpolated
message string, which binds to Assert.That(actual, constraint, string)
on both NUnit 3 and 4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread source/icu.net/NativeMethods/NativeMethods.cs Outdated
hahn-kev and others added 3 commits September 17, 2026 09:48
Resolve conflicts with the net40/net451 -> net462 retarget and the XML
docs packaging change: keep the Android TFM additions, take net462, and
drop the dead NET40 branch in GetMethod<T> while keeping the
MissingMethodException fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hahn-kev
hahn-kev merged commit 864ac70 into master Sep 23, 2026
8 checks passed
@hahn-kev
hahn-kev deleted the feature/android-device-tests branch September 23, 2026 02:22
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.

3 participants