【发布时间】:2020-04-08 00:08:54
【问题描述】:
我为 Android 应用程序编写 Xamarin UITest。在应用程序中使用谷歌地图。请帮帮我,如何点击地图上的标记?
【问题讨论】:
-
您是否在询问如何以编程方式模拟标记点击、响应标记点击事件或其他?
标签: google-maps user-interface testing xamarin
我为 Android 应用程序编写 Xamarin UITest。在应用程序中使用谷歌地图。请帮帮我,如何点击地图上的标记?
【问题讨论】:
标签: google-maps user-interface testing xamarin
标记没有显示在视图树中,我猜它们是在地图框架布局内的屏幕上绘制的。
鉴于标记位于地图的中心,您可以使用以下方式点击它:
(带有 id 为“map”的地图片段)
var map = app.Query("map")
var middleX = (map.First().Rect.Width + map.First().Rect.X) / 2
var middleY = (map.First().Rect.Height + map.First().Rect.Y) / 2
app.TapCoordinates(middleX, middleY)
但我认为这就是地图本身所能做的一切。
【讨论】:
如果您自己构建应用程序,我建议您检查后门方法。这些方法可以构建到应用程序中,然后从测试中调用。
有很多关于 Obj-C 和 Java 应用程序的示例。这是 C# 后门方法的示例,您可以将其放入 MainActivity 或 AppDelegate 类中:http://danatxamarin.com/2015/05/07/configuring-backdoor-methods-in-c-for-xamarin-test-cloud/
我会创建一个后门来返回您需要的有关地图的任何数据,然后使用app.Invoke("myNewMethod"); 返回一个字符串(可能是 json)。该字符串可以包含屏幕坐标,然后您可以将其传递给app.TapCoordinates(x, y);。
简短的回答是,Android 上的 Google 地图并没有真正以自动方式公开对象,因此第二好的选择是后门。
【讨论】:
如果你有一个自定义的android渲染器,你可以在里面模拟点击,主要的技巧是访问渲染器内部的标记:
var field = this.GetType().BaseType.GetField("_markers", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var markers = (List<Marker>)field.GetValue(this);
现在对于markers 中的任何元素,因为您无法发送真正的点击,您可以模拟它。从我的实时项目中粘贴代码:
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == "ExternalClickedPin")
{
if (FormsControl.ExternalClickedPin != null)
{
var pin = Map.Pins.FirstOrDefault(x => x.MarkerId == FormsControl.ExternalClickedPin.MarkerId);
if (pin != null)
{
var field = this.GetType().BaseType.GetField("_markers", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var hiddenMarkers = (List<Marker>)field.GetValue(this);
var marker = hiddenMarkers.FirstOrDefault(x => x.Id == pin.MarkerId.ToString());
if (marker != null)
{
//simulating click
//1 invoke clicked event
// pin.SendMarkerClick(); // <- if needed for tests
//2 show info on map
marker.ShowInfoWindow(); //just what i was needing
//3 center pin on map
//Map.MoveToRegion(...); <- not here, im calling this from Forms subclassed control
}
}
FormsControl.ExternalClickedPin = null;
}
}
}
【讨论】: