上一篇  走进 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盘

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

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

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

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

点进去看看详情

可以看到正在跑 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.

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

最新文章

  1. 面向初学者之烦人的mainactivity启动前的actionBAR
  2. [转]DAO层,Service层,Controller层、View层
  3. Emmet (Zen Coding) HTML基本语法
  4. kuangbin_SegTree B (HDU 1754)
  5. Visual Studio 发布新版API智能提示
  6. template_1
  7. 避免SWF被内存提取工具提取的方法
  8. Android源码是这样搞到的(图解)
  9. catkin_simple 的使用
  10. leetcode第一刷_Binary Tree Inorder Traversal
  11. UVA434 - Matty's Blocks
  12. tophat安装
  13. dokcer自动化构建部署java web 基于jenkins+maven+nuxus容器
  14. Maven构建Struts2项目
  15. C++一种高精度计时器
  16. Linux从入门到进阶全集——【第十四集:Shell基础命令】
  17. ajax csrf
  18. Window.sessionStorage
  19. SQL之group by
  20. window,centos双系统坏了

热门文章

  1. 201521123037 《Java程序设计》第2周学习总结
  2. 201621123067《JAVA程序设计》第一周学习总结
  3. delphi cxrid设置column靠左显示
  4. MyBatis学习(一)简介及入门案例
  5. springboot+swagger2
  6. 去掉 Warning:$HADOOP_HOME is deprecated
  7. DeepLearning.ai学习笔记(二)改善深层神经网络:超参数调试、正则化以及优化--Week2优化算法
  8. SQL性能优化十条经验(转)
  9. String类的一些转换功能(6)
  10. PYTHON 函数局部变量和全局变量