上一篇 走进 Prism for Xamarin.Forms 讲了简单的创建一个项目,然后添加了几个页面来回切换,这篇想先搞下 UITest
官方详细地址:https://developer.xamarin.com/guides/testcloud/uitest/intro-to-uitest/
一、首先在项目上右键添加一个 UITest 项目,我命名为 SD.Xamarin.UITest ,因为 项目叫 SD.Xamarin
建完的项目引用的 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");
}
先运行下试试
失败了,不过没关系,说明配置都是对的,只是没有设备而已。
启动 Visual Studio Emulator for Android
嗯,还是配置的问题
官方说要这样配置,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 回车
成功了,页面里内容都显示出来了,而且因为我写了 Button 的触发,还列出了跳转后的页面的内容
同时模拟器也会有跑 Test
- 真机调试
1.手机启用开发者模式,USB 调试打开
2.电脑上安装 Google USB Driver(Android SDK Manager 里最下边那里有)
3.把手机连接到电脑上,如果一切正常,启动那里就可以选 Device 了(手机的名字,比如我的 Letv X800+)
如果你现在直接启动测试,会发现报错
那就指定一下设备吧,打开 ADB 控制台
输入 adb device
很明显的错误,是说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 了
点击 New Test Run,选择 Android
选择想测试的设备
选择分支和语言
最终生成了脚本的模板
复制脚本,修改你的真实参数
打开 cmd 窗体,把位置改到项目的地址
比如代码放在了E盘
- E:
- cd E:\Code\SD.Xamarin
- 粘贴修改过的命令
回车后会看到上传过程和结果
失败了,没关系,先继续看同时网页那边的情况,回头再改
当再次刷新网站时,页面变成下边这样
点进去看看详情
可以看到正在跑 Test
点进去看下
这就是大概的详情,下边还有一些内容,请自己试验时看吧
点击失败的 Test 可以看到截图
具体错误的原因可以查看 Log 修改,直到 可以测试成功。
补充成功的截图
虽然成功了,但还是很奇怪,焦点跳不过去,所以没有跳转页面,但是模拟器却始终好使。
这里就是模拟器和真机的区别了,模拟器没有显示键盘,真机需要手动关闭一下键盘,不然焦点就会不跳转
修改后的代码如下
[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 . |
更多内容请参考官方文档,如有错误以官方为准,有些地方翻译和理解的可能有误差