Verify.Xamarin
February 8, 2022 ยท View on GitHub
Extends Verify to allow verification of Xamarin UIs.
Leverages Xamarin.UITest to capture the state of an app.
NuGet package
https://nuget.org/packages/Verify.Xamarin/
Usage
App
Main content
Given an app with a text control:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/theText"
android:text="Hello World!" />
</RelativeLayout>
Make Fullscreen
To prevent the tool bar header (that contains a clock) from making the snapshots unreliable, it is necessary to make the app full screen when running tests.
Add the following to the main activity:
protected override void OnCreate(Bundle bundle)
{
#if DEBUG
Window.AddFlags(WindowManagerFlags.Fullscreen);
Window.ClearFlags(WindowManagerFlags.ForceNotFullscreen);
#endif
Testing
Setup
Enable VerifyXamarin once at assembly load time:
VerifyXamarin.Enable();
Setup the app
app = ConfigureApp
.Android
.EnableLocalScreenshots()
.ApkFile(apkPath)
.StartApp();
App test
The current app state can then be verified as follows:
[Test]
public async Task AppUsage()
{
await Verify(app);
}
With the state of the control being rendered as:
[
{
Class: 'DecorView',
Rect: 'w:1080 h:1920 x:0 y:0'
},
{
Class: 'LinearLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'FrameLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Id: 'action_bar_root',
Class: 'FitWindowsLinearLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Id: 'content',
Class: 'ContentFrameLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'CoordinatorLayout',
Rect: 'w:1080 h:1794 x:0 y:0'
},
{
Class: 'AppBarLayout',
Rect: 'w:1080 h:147 x:0 y:0'
},
{
Id: 'toolbar',
Class: 'Toolbar',
Rect: 'w:1080 h:147 x:0 y:0'
},
{
Text: 'SampleXamarin',
Class: 'AppCompatTextView',
Rect: 'w:379 h:71 x:42 y:38'
},
{
Class: 'ActionMenuView',
Rect: 'w:105 h:147 x:975 y:0'
},
{
Label: 'More options',
Class: 'ActionMenuPresenter$OverflowMenuButton',
Rect: 'w:105 h:126 x:975 y:10'
},
{
Class: 'RelativeLayout',
Rect: 'w:1080 h:1647 x:0 y:147'
},
{
Id: 'theText',
Text: 'Hello World!',
Class: 'AppCompatTextView',
Rect: 'w:200 h:51 x:440 y:945'
},
{
Id: 'fab',
Class: 'FloatingActionButton',
Rect: 'w:147 h:147 x:891 y:1605'
},
{
Id: 'navigationBarBackground',
Class: 'View',
Rect: 'w:1080 h:126 x:0 y:1794'
}
]
Control test
A control can be verified as follows:
[Test]
public async Task ControlUsage()
{
var appResult = app.Query(x => x.Id("theText"))
.Single();
var data = new ControlData(app, appResult);
await Verify(data);
}
With the state of the control being rendered as:
{
Id: 'theText',
Text: 'Hello World!',
Class: 'AppCompatTextView',
Rect: 'w:200 h:51 x:440 y:945'
}
OS specific rendering
The rendering of Form elements can very slightly between different OS versions. This can make verification on different machines (eg CI) problematic. There are several approaches to mitigate this:
- Using a custom comparer
Icon
Monkey designed by Maxim Kulikov from The Noun Project.