走进 UITest for Xamarin.Forms

时间:2022-09-16 04:05:58

上一篇  走进 Prism for Xamarin.Forms 讲了简单的创建一个项目,然后添加了几个页面来回切换,这篇想先搞下 UITest

官方详细地址:https://developer.xamarin.com/guides/testcloud/uitest/intro-to-uitest/

一、首先在项目上右键添加一个 UITest 项目,我命名为 SD.Xamarin.UITest ,因为 项目叫 SD.Xamarin

走进 UITest for Xamarin.Forms

建完的项目引用的 NUnit 的引用包千万别升级,官方说了,3.X的是不兼容的,所以你就用2.6.X的好了,官方文档很重要有木有,不然像我总喜欢升级到最新版的人,就会悲剧的

IOS项目需要添加 Nuget 包 Xamarin.TestCloud.Agent(官网说的,没有 Mac 没法测试)

同时要添加 Android 和 IOS 项目的引用

摘自官方的说明

  • NUnit 2.6.x – Xamarin.UITest is not compatible with NUnit 3.x.
  • A Test Runner for Visual Studio – A 3rd party test runner, such as the NUnit Test Adapter for NUnit 2 or Resharper from Jetbrains, is required for Visual Studio to be able to run the NUnit tests. The NUnit3TestAdapter is not compatible with Xamarin.UITest.
  • Android SDK – Only if testing Android apps. Windows requires that the ANDROID_HOME environment variable is set with the path to the Android SDK.
  • Java Developers Kit – Only if testing Android apps.

二、执行 Test

  • REPL

建完项目会有2个文件,其中一个叫 AppInitializer.cs 的文件就是配置路径的文件,也就是让项目知道去哪里找到生成的包文件,Android 的是 apk 文件,IOS 的是 app 文件

public class AppInitializer
{
public static IApp StartApp(Platform platform)
{
if (platform == Platform.Android)
{
return ConfigureApp
.Android
.ApkFile("../../../SD.Xamarin/SD.Xamarin.Droid/bin/Release/SD.Xamarin.Droid.apk")
.StartApp();
} return ConfigureApp
.iOS
.AppBundle("../../../SD.Xamarin/SD.Xamarin.iOS/bin/iPhoneSimulator/Release/SD.Xamarin.iOS.app")
.StartApp();
}
}

红色的部分就是需要自己加的,因为在一个项目文件夹下,所以前边的 ../../../ 就是往上找目录(C# 的人都懂的),然后是 项目名 / 测试平台的项目名 / 生成包的路径,Debug 还是 Release 随你喜欢了(Debug 的包名称要适当修改,见下边),这里要说明下,千万不要把项目放到VS 的默认目录下,因为 WIN 10 的权限关系,它只让你搞 AppData 文件夹,而 VS 默认目录是 Document 文件夹,所以你根本找不到。

Android:  Debug 目录下生成的是 SD.Xamarin.Droid-Signed.apk ,Release 目录下会生成 SD.Xamarin.Droid-Signed.apk 和 SD.Xamarin.Droid.apk 两个

IOS: 由于没有Mac 无法验证,但是看到生成 的是 SD.Xamarin.IOS.exe ,不是 app ,不知道是否没有连接 Mac 的事情

当然跑之前要先 Build 好 apk 包,因为用 Android 跑的, IOS 需要连接 Mac 所以没法测试

这是 Test 方法

 [Test]
public void TestLogin()
{
_app.EnterText(n => n.Marked("Username"), "Name");
_app.EnterText(n => n.Marked("Password"), "Password");
_app.Tap(c => c.Button("LoginButtons")); _app.Repl(); AppResult[] result = _app.Query();
            Assert.IsTrue(result.Any(), "Login");
}

先运行下试试

走进 UITest for Xamarin.Forms

失败了,不过没关系,说明配置都是对的,只是没有设备而已。

启动 Visual Studio Emulator for Android

走进 UITest for Xamarin.Forms

嗯,还是配置的问题

官方说要这样配置,https://developer.xamarin.com/guides/testcloud/uitest/working-with/running-tests-in-ide/

TARGET ARCHITECTURE
iOS Simulator x86
iOS device x86_64
Android Device Typically armeabi-v7a
Google Emulator Depends on the Android Virtual Device

改到 Release 和 ARM 后,再来,弹出了一个窗体,输入 tree 回车

走进 UITest for Xamarin.Forms

成功了,页面里内容都显示出来了,而且因为我写了 Button 的触发,还列出了跳转后的页面的内容

同时模拟器也会有跑 Test

走进 UITest for Xamarin.Forms

  • 真机调试

1.手机启用开发者模式,USB 调试打开

2.电脑上安装 Google USB Driver(Android SDK Manager 里最下边那里有)

3.把手机连接到电脑上,如果一切正常,启动那里就可以选 Device 了(手机的名字,比如我的 Letv X800+)

如果你现在直接启动测试,会发现报错

走进 UITest for Xamarin.Forms

那就指定一下设备吧,打开 ADB 控制台

走进 UITest for Xamarin.Forms

输入 adb device

走进 UITest for Xamarin.Forms

很明显的错误,是说2个设备,因为还有个 Emulator ,所以你需要指定设备,设备号码在错误里会有,修改启动方法如下

public static IApp StartApp(Platform platform)
{
if (platform == Platform.Android)
{
return ConfigureApp
.Android
.ApkFile("../../../SD.Xamarin/SD.Xamarin.Droid/bin/Release/SD.Xamarin.Droid.apk")
.DeviceSerial("96e5b85b")
.StartApp();
} return ConfigureApp
.iOS
.AppBundle("../../../SD.Xamarin/SD.Xamarin.iOS/bin/iPhoneSimulator/Release/SD.Xamarin.iOS.app")
.StartApp();
}

  

当你再次启动测试时,会发现还是会报错,超时的错误,这点和 Emulator 很不一样,所以需要修改测试方法

[Test]
public void TestLogin()
{
_app.Tap(c => c.TextField("Username"));
_app.EnterText(n => n.Marked("Username"), "Name");
_app.WaitForElement(n => n.Marked("Username").Text("Name")); _app.Tap(c => c.TextField("Password"));
_app.EnterText(n => n.Marked("Password"), "Password");
_app.WaitForElement(n => n.Marked("Password").Text("Password"), ""); _app.Tap(c => c.Button("LoginButton")); AppResult[] result = _app.Query();
Assert.IsTrue(result.Any(), "Login");
}

在我看来这样应该是对的了,但是不知道是我的环境问题还是怎样,在想把焦点跳到 Password 的时候,手机的虚拟键盘收起又弹出,但是焦点没有跳过去,所以我手点了一下,运行到点击 Button 的时候又跳不过去焦点,于是我又点了一下,但是没有在登录按钮上抬起,于是焦点跳过去了,然后就触发了 Button 的点击,但是不写 Tap 第一个 Username 的焦点也不会进,所以我觉的焦点是这么跳的,我想不可能是只需要 WaitForElement 方法,然后都需要手动输入吧,掐断点的时候你会发现到 WaitForElement 方法的时候是会停住的,直到符合条件才会继续,但是如果你一直不符合条件,还是会报超时的错误。

Tips:1. 如果这里是我理解的错误,还请赐教

2. 如果跑 test 时遇到 refused to install the app by The ADB command ! 错误,去任务管理器里结束 adb.exe 进程

  • Xamarin Test Cloud

首先需要注册试用,https://testcloud.xamarin.com/register

进去后右上角点击 头像下的 Account Setting ,左边选 Teams & Apps,show API Key 会出来一个 key 留着一会上传用

SD.Xamarin\packages\Xamarin.UITest.2.1.2\tools 下会有一个 test-cloud.exe (VS 2017 没有右键上传,VS 2015 有)

如果账号确认后,就可以创建新的 Test 了

走进 UITest for Xamarin.Forms

点击 New Test Run,选择 Android

走进 UITest for Xamarin.Forms

选择想测试的设备

走进 UITest for Xamarin.Forms

选择分支和语言

走进 UITest for Xamarin.Forms

最终生成了脚本的模板

走进 UITest for Xamarin.Forms

复制脚本,修改你的真实参数

打开 cmd 窗体,把位置改到项目的地址

比如代码放在了E盘

  1. E:
  2. cd E:\Code\SD.Xamarin
  3. 粘贴修改过的命令

走进 UITest for Xamarin.Forms

回车后会看到上传过程和结果

走进 UITest for Xamarin.Forms

走进 UITest for Xamarin.Forms

失败了,没关系,先继续看同时网页那边的情况,回头再改

当再次刷新网站时,页面变成下边这样

走进 UITest for Xamarin.Forms

点进去看看详情

走进 UITest for Xamarin.Forms

可以看到正在跑 Test

走进 UITest for Xamarin.Forms

点进去看下

走进 UITest for Xamarin.Forms

这就是大概的详情,下边还有一些内容,请自己试验时看吧

点击失败的 Test 可以看到截图

走进 UITest for Xamarin.Forms

具体错误的原因可以查看 Log 修改,直到 可以测试成功。

补充成功的截图

走进 UITest for Xamarin.Forms

走进 UITest for Xamarin.Forms

虽然成功了,但还是很奇怪,焦点跳不过去,所以没有跳转页面,但是模拟器却始终好使。

这里就是模拟器和真机的区别了,模拟器没有显示键盘,真机需要手动关闭一下键盘,不然焦点就会不跳转

修改后的代码如下

        [Test]
public void TestLogin()
{
_app.WaitForElement(x => x.Marked("Username"));
_app.Tap(x => x.Marked("Username"));
_app.EnterText(x => x.Marked("Username"), "Name");
_app.Screenshot("Fill Name Finished"); _app.DismissKeyboard();
_app.WaitForElement(x => x.Marked("Password"));
_app.Tap(x => x.Marked("Password"));
_app.EnterText(x => x.Marked("Password"), "Password"); _app.DismissKeyboard();
_app.Tap(x => x.Marked("LoginButton"));
_app.Screenshot("Login"); AppResult[] result = _app.Query();
Assert.IsTrue(result.Any(), "Login");
}

脚本生成过程 https://developer.xamarin.com/guides/testcloud/organizations-and-teams/creating-a-test-run/

脚本参数 https://developer.xamarin.com/guides/testcloud/uitest/working-with/submitting-tests-at-command-line/

四、几个 Test 方法

方法 描述
Button 在屏幕上定位一个或多个按钮
Class 定位指定类的视图
Id 用指定的Id定位视图
Index 从集合中返回匹配的视图。通常和其他方法结合使用。接受从0开始的索引
Marked 根据之前提到的启发返回视图
Text 匹配包含提供文本的视图
TextField         匹配 Android EditText 或者 iOS UITextField.

更多内容请参考官方文档,如有错误以官方为准,有些地方翻译和理解的可能有误差