移动端-DevOps-全-
移动端 DevOps(全)
原文:
annas-archive.org/md5/d0acd7b3595ec41ccc59782fbc8c5ba9译者:飞龙
前言
移动 DevOps 是移动应用开发中持续集成和持续交付的未来,也是当今快节奏开发文化中的一个非常重要的需求。尽管 DevOps 已被大多数快速发展的开发团队实施并采纳,但移动 DevOps 仍未被大多数移动开发领域广泛使用。它能够改善集成和交付,并提供更强大的反馈机制和早期缺陷捕捉工具。
移动 DevOps 具有自身的实施挑战,而随着数百万设备上存在各种移动平台,以及不同的屏幕比例,使用能够简化物理设备测试和交付给客户的工具变得越来越重要,同时为开发者提供快速反馈机制。
在本书中,我们将使用 Xamarin 探索移动应用开发的基础知识和工具。Xamarin 是微软推出的一个跨平台移动应用开发框架,可以使用共享的代码库和设计来创建 iOS、Android 和 Windows 应用程序。除了 Xamarin,我们还将使用微软工具集中的其他工具,如 Xamarin Test Cloud 和 Visual Studio Team Services,深入研究移动 DevOps 的不同阶段。
使用 Xamarin 的主要动机是它能够开发跨平台应用程序,并且与微软的其他广泛使用的工具在应用程序开发周期的不同阶段具有极好的集成性。
本书结束时,你不仅应该熟悉移动 DevOps 和移动应用开发,而且应该能够在你的新应用或现有的移动应用项目中,使用现有的流行工具,实施、配置和排除移动 DevOps 生命周期中的每一个步骤。
本书读者对象
本书主要面向移动应用开发者、DevOps 工程师和愿意将 DevOps 应用于其移动应用开发生命周期的小团队。已经使用 Visual Studio 和/或 C# 作为编程语言的开发者,鼓励使用本书开始跨平台移动应用开发,并理解持续交付和持续集成的工作原理。
如果你已经是 Xamarin 开发者,那么本书将帮助你通过在项目中实施移动 DevOps 来简化快速开发、持续测试和频繁交付管理过程。
本书内容
第一章,简介,将带你进入 DevOps 和移动 DevOps 的世界,并解释它们之间的差异。本章还将描述在将 DevOps 应用于移动开发时,你可能会遇到的各种挑战。
第二章,使用代码仓库系统,探讨了代码仓库系统,并讨论了各种版本控制工具。本章主要关注 Git,深入探讨了源代码版本控制的细节。
第三章,使用 Xamarin 进行跨平台移动应用开发,介绍了 Xamarin 和跨平台移动应用开发。本章还解释了在 Windows 机器上设置 Xamarin 和 Visual Studio 的步骤。
第四章,使用 Xamarin 编写您的第一个 Android 应用程序,解释了 Android 应用程序的基本概念。内容还描述了使用 Xamarin 创建 Android 应用程序项目的步骤,并讨论了如何在移动设备上部署应用程序的 UI。
第五章,使用 Xamarin 实现自动化测试,讨论了在 DevOps 循环中自动化测试的重要性,并深入讲解了为 Xamarin.Android 应用项目编写自动化测试用例的方法。此外,您还将学习如何设置 Xamarin Test Cloud 并在其上运行 Android 应用的自动化测试。
第六章,使用 Xamarin 配置 TeamCity 进行 CI/CD,介绍了持续集成的概念,并讨论了可用于持续集成的各种工具。本章让您深入了解如何使用 TeamCity 进行持续集成,详细解释了使用 TeamCity 作为 CI 工具时涉及的各种配置和设置步骤。
第七章,使用 Visual Studio Team Services 进行 Android 的 CI/CD,讲解了如何使用 Visual Studio Team Service 实现持续集成和持续交付。内容涵盖了从在 Visual Studio 中创建帐户到配置和排队构建的连续构建过程的各个步骤。
第八章,在 AWS 上部署应用程序,描述了如何将应用程序部署和迁移到云端。本章详细解释了从创建实例到创建 ELB 并使用 Terraform、AWS CLI 和 LightSail 配置终节点的各种步骤。
第九章,监控和优化应用程序,带您深入了解不同级别的监控,从 API 级别监控开始,逐步介绍如何使用 Android 监控工具进行监控。内容还包括针对 Test Cloud 的监控步骤。
第十章,调试应用程序,解释了在 Xamarin 中排查故障是一个常见问题,并涵盖了各种部署生命周期。内容包括调试 Xamarin 代码、故障排除 Android 模拟器、调试 Mono 类库,最后是调试 Git 连接。
第十一章,案例研究,详细讲解了移动 DevOps 的整个过程,从移动应用开发和集成到通过两个案例研究进行的持续测试和部署。
为了最大限度地利用本书
本书假设你具备中级的 Windows 操作系统知识,具备云计算和应用开发生命周期的基本知识,同时具备面向对象编程语言(如 Java 或 C#)的初学者级别知识。本书将通过移动 DevOps 生命周期的各个阶段,讲解应用开发基础和应用交付的基本概念。如果你有使用 Visual Studio 的经验,并且熟悉 C#编程,那将是一个很大的优势。
安装 Visual Studio 和 Xamarin 的最低要求如下:
-
Windows 要求:Windows 7
-
Android 6.0/API 级别 23
以下是 Android 模拟器的硬件要求:
-
支持 Hyper-V
-
4GB 或更高内存
-
64 位版本的 Windows 操作系统
请注意,由于没有硬件加速时,Android SDK 模拟器的速度非常慢,因此推荐使用英特尔的硬件加速执行管理器(HAXM)来大幅提升 Android 模拟器的性能。
安装必要的 Visual Studio 和 Xamarin.Android 包、Git,并连接到 Xamarin Test Cloud 时,需要联网。
下载示例代码文件
你可以通过你的账户在 www.packtpub.com 下载本书的示例代码文件。如果你是在其他地方购买的本书,可以访问 www.packtpub.com/support,注册后我们会将文件直接发送到你的邮箱。
你可以按照以下步骤下载代码文件:
-
请登录或注册 www.packtpub.com。
-
选择“支持”标签。
-
点击“代码下载与勘误”。
-
在搜索框中输入书名,并按照屏幕上的指示操作。
下载文件后,请确保使用以下最新版本的工具解压或提取文件夹:
-
WinRAR/7-Zip for Windows
-
Zipeg/iZip/UnRarX for Mac
-
7-Zip/PeaZip for Linux
本书的代码包也托管在 GitHub 上,地址为 github.com/PacktPublishing/Mobile-DevOps。如果代码有更新,它将在现有的 GitHub 仓库中更新。
我们还提供了其他代码包,这些代码包来自我们丰富的图书和视频目录,可以在github.com/PacktPublishing/找到。快来看看吧!
下载彩色图像
我们还提供了一个 PDF 文件,包含本书中使用的截图/图表的彩色图像。你可以在这里下载:www.packtpub.com/sites/default/files/downloads/MobileDevOps_ColorImages.pdf。
使用的约定
本书中使用了多种文本约定。
CodeInText:表示文本中的代码词语、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟网址、用户输入和 Twitter 账号。例如:“MainActivity.cs文件包含了我们用于处理事件和其他功能的 C#代码,位于主屏幕中。”
一段代码如下所示:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
},
任何命令行输入或输出都按如下方式书写:
$ mkdir terraform
$ cd terraform
$ terraform workspace new MyTestMachine
粗体:表示一个新术语、一个重要的词语或您在屏幕上看到的词语。例如,菜单或对话框中的词语会以这样的方式显示在文本中。以下是一个例子:“点击 Visual Studio Community 2017 下提供的免费下载。”
警告或重要提示会这样出现。
小贴士和技巧会这样出现。
联系我们
我们始终欢迎读者的反馈。
一般反馈:请发送电子邮件到feedback@packtpub.com,并在邮件主题中注明书名。如果您对本书的任何部分有问题,请通过questions@packtpub.com联系我们。
勘误:虽然我们已尽最大努力确保内容的准确性,但难免会出现错误。如果您在本书中发现了错误,我们将不胜感激您向我们报告。请访问www.packtpub.com/submit-errata,选择您的书籍,点击“勘误提交表单”链接,并输入相关信息。
盗版:如果您在互联网上发现我们作品的任何非法版本,我们将非常感激您提供相关的网址或网站名称。请通过copyright@packtpub.com联系我们,并附上相关材料的链接。
如果你有兴趣成为作者:如果您在某个领域有专长并且有意写书或为书籍做贡献,请访问authors.packtpub.com。
评价
请留下您的评价。在阅读并使用本书后,为什么不在您购买它的网站上留下评价呢?潜在的读者可以查看并参考您的公正意见来做出购买决策,我们在 Packt 可以了解您对我们产品的看法,而我们的作者也可以看到您对他们书籍的反馈。谢谢!
欲了解更多有关 Packt 的信息,请访问packtpub.com。
第一章:介绍
DevOps 作为一个术语,有着广泛的含义,涵盖了软件开发生命周期中的不同阶段。在本章中,我们将讨论 DevOps 是什么,它在软件开发过程中的含义,以及在软件维护过程中扮演的角色。我们将在本章中通过以下主题讨论关于 DevOps 和移动 DevOps 的各种细节:
-
DevOps 介绍
-
移动 DevOps 介绍
-
DevOps 与移动 DevOps 的比较
-
将 DevOps 应用于移动端的挑战
DevOps 介绍
DevOps 来源于两个不同的词:开发(development)和运维(operations)。因此,正如这个词所暗示的,它描述了在开发软件和管理运维任务的过程中所采用的一套实践。
DevOps 这个术语最早由 Andrew Shafer 和 Patrick Debois 于 2008 年提出,他们成为了这一理念的两位主要倡导者,自 2009 年以来,该术语已被广泛使用并推广,旨在统一软件开发和运维的过程。
DevOps 不仅是一套实践,它还是软件开发行业的一种工作方式;它是开发与运维合作方式上的一种文化变革。
以更快的速度向客户交付技术,并与他们的需求对接,是未来增长的关键;这是一种实践,可以通过 DevOps 来实现。采用 DevOps 可以创建一个持续交付的生态系统,提高交付质量和速度,并带来所有相关的好处。

在传统方法中,开发人员按照需求在任何本地环境中编写代码。一旦应用程序准备好,QA 团队会在一个类似生产环境的环境中测试该应用程序。
一旦测试成功并且满足需求,产品就会被交给运维团队进行部署。由于两个团队是独立工作的,因此应用程序版本的部署可能会花费很长时间,且可能无法按预期进行。
然而,在 DevOps 中,过程是完全不同的。在这里,开发人员、QA 和运维合作,使用各种工具进行持续开发、集成、交付和监控,这有助于填补一个巨大的空白并加速过程。
从某种意义上讲,每个工具都独立工作,但又紧密集成。快速和自动的发布到运维能够让相关方迅速响应变化并满足需求。
过去,软件开发与运维是完全分开的过程。发布往往与实际开发过程松散集成,因此有时会在开发环境与发布或生产环境之间产生差异。
开发人员过去常常独立完成开发工作,而运维则负责项目的发布和发布后的任务。
这种工作方式曾在瀑布式软件开发模型流行时表现得非常出色,那时每个步骤都是顺序进行的,发布往往是一个漫长的过程。
在今天,敏捷已成为新的流行软件开发方法,更频繁的发布成为交付目标,只有集成化环境才能提供所需的灵活性和稳定性及服务质量。
DevOps 的文化方面
DevOps 带来的最大文化差异是将不同角色/人员聚集到一个具有相同交付目标的特定团队中。
人们可以做自己擅长的事情并得到即时反馈。DevOps 能够在技术故障的情况下提供快速解决方案,并有助于团队健康、个人满意度以及时间效率和管理。
例如,过去需要几个月的过程现在可以在几分钟内完成。它将环境配置从一个新问题转变为按下按钮即可解决的愉快体验。
DevOps 为我们提供了发明和专注于实际业务需求的能力和灵活性,而不是管理数小时、数周或数月的运维任务。
像 Amazon、Facebook、LinkedIn 和 Twitter 这样的站点众所周知,每天会进行多次部署(有时每分钟一次)。为了如此频繁地进行部署,他们不能破坏已经运行的系统;必须在现有系统的基础上进行补充。
DevOps 帮助你专注于行业逻辑和实际需求,而不是维护、扩展、集群、部署等繁琐工作。
DevOps 在某种程度上代表并推动了 IT 文化的变化,专注于通过采纳敏捷开发来实现快速和频繁的交付,在软件开发生命周期的背景下简化实践,包括开发和运维。
DevOps 关注人和文化,致力于改善开发团队和运维团队之间的协作与整合。DevOps 的实施利用了能够确保集成和快速反馈的技术,从而确保质量,特别是通过使用可以利用日益可编程且高度动态的基础设施的自动化软件工具,从开发和运维生命周期的角度来看。
DevOps 之前
为了真正理解使用 DevOps 的好处和差异,我们必须了解 DevOps 出现之前的工作方式。如图所示,运维曾经并未与开发周期的其他部分集成:

DevOps 之后
在 DevOps 工作方式中,运维从最初阶段就参与到开发过程中。他们更好地理解可能在后期出现的问题,并能在早期采取措施,避免它们在生产阶段发生。开发人员得到快速反馈,能够根据运维提出的问题进行调整,反之亦然。

移动 DevOps 介绍
移动 DevOps 与 DevOps 非常相似,只不过它应用于移动端。尽管如此,它仍然带来了新的挑战,这些挑战与移动应用的部署和维护相关。在讨论移动应用开发时,部署和反馈方面有许多新因素需要考虑。
一个 Web 应用只需要在有限的浏览器上进行测试和质量检查,但对于移动应用来说,测试的范围非常广泛,并不限于一组特定的移动设备或操作系统版本。一旦应用上线,市场上众多操作系统版本需要进行测试和追踪。
DevOps 和移动 DevOps 之间的主要区别在于实现过程所需的工具。在移动 DevOps 中,必须将 SDK 集成到应用代码中,以便在生产环境中跟踪错误报告和崩溃报告。
反馈机制变得更加重要,因为移动应用具有更强的个人化特点,用户提供的反馈非常重要,可以用于进一步改进应用。
持续反馈和持续发展
持续反馈和持续发展已经成为移动应用开发中最重要的内容。开发者必须不断根据客户的反馈进行调整,并且必须使用工具确保能够及时收到正确的客户反馈并付诸行动。在开发和生产发布的每个阶段,必须监控渠道并使用监控工具,以确保用户的意见能够被理解和照顾。开发者需要了解哪些场景可能导致用户的应用在手机上崩溃,例如用户在哪个页面停留时间最长,用户在哪些功能上没有进行操作。所有这些反馈对于移动应用开发至关重要;为了能够获得这些反馈,必须配备能够实现持续反馈的工具,帮助开发者更好地了解用户体验。

移动 DevOps 中的待办事项重要性
当谈到移动应用时,应用崩溃并不是唯一的反馈机制。用户可以直接从移动应用中提交反馈给开发者。一些工具还提供用户指标和自定义事件,帮助开发者了解应用的接受度和使用情况。所有这些信息都应被用来改进待办事项列表,开发者应该始终根据数据对投资方向充满信心。

DevOps 与移动 DevOps
DevOps 和移动 DevOps 相似,但它们在实现相同目标时使用的工具集有所不同。为了更好地理解 DevOps 和移动 DevOps 之间的区别,让我们逐步了解应用开发和运维生命周期中的每个阶段,并讨论两者方法的差异。
开发
开发阶段对于 Web 和移动应用程序开发几乎相同,但在移动应用程序开发中,开发者需要包含 SDK 和工具,帮助他们跟踪应用崩溃和用户反馈,并更好地监控用户活动。移动应用开发者可以在应用程序中构建反馈机制,借此他们可以要求用户提交反馈,甚至是 bug 报告,这些通常由移动操作系统提供。甚至一些 SDK 可以嵌入到移动应用程序代码中,帮助反馈跟踪和改善最终用户的互动。
HockeyApp等工具直接将用户交互和反馈整合到开发者手中。
测试
在测试方面,Web 应用程序测试和移动应用程序测试使用的工具差异很大。在 Web 应用程序中,测试应用程序所需的资源仅限于一组浏览器和有限的操作系统版本。
手动测试有时足以确保高质量的产品。但在移动应用程序测试中,有数百种不同的硬件依赖设备组合需要进行测试,以确保应用程序上线时能够正常运行。Android 崛起后,出现了各种硬件配置和不同操作系统的设备。为了确保广泛的用户群体,开发者需要确保他们的应用程序与所有不同版本以及低端设备兼容。
为了保证质量,仅在模拟器上测试是不够的,尤其对于高质量的应用程序;它们需要在真实设备上进行测试,但这对于许多组织来说有时既困难又超预算。这时,像 Xamarin Test Cloud 这样的云测试环境便应运而生,能够自动化该过程,并以低成本在真实设备上进行测试。
部署
在 Web 应用程序部署中,环境可以根据我们的需求进行控制和定制,但在移动应用程序部署中,应用程序需要通过某种操作系统应用商店发布,之后该商店会验证并发布应用程序供用户在其设备上使用。
监控
为了监控 Web 应用程序,开发者使用日志、服务器端的一些工具和客户端的其他工具来帮助他们识别由于网络或代码质量引发的问题。但在移动应用程序中,由于可能出现的问题,范围相当广泛。各种硬件依赖、设备权限和其他因素可能会出现,如果没有合适的工具,难以监控到这些问题,这就是移动 DevOps 与 DevOps 的区别所在。
持续交付
持续交付听起来非常简单,如果正确实施,确实是这样。在 DevOps 中,获取反馈并进行处理、修复 bug,然后重新部署,比移动应用程序要简单且节省时间得多。从用户那里获取崩溃报告,然后找出问题,再重新进入测试阶段,如果没有自动化,这个过程可能非常耗时。
自动化开发过程、在真实设备上进行测试、签署应用并发布到商店,再次跟踪用户反馈——如果没有使用正确的工具,整个过程变得非常复杂。
将 DevOps 应用于移动设备的挑战
由于快速和持续交付的思维方式,DevOps 面临许多挑战,尤其是在将 DevOps 应用于移动应用程序开发生命周期时。
以下是将 DevOps 应用于移动时出现的一些挑战。
快速的技术适应
移动技术每天都在快速发展和改进,随着每天发布的新设备和硬件支持,DevOps 工具很难跟上它们的步伐。
跨平台支持
大多数移动应用程序有多个平台目标;操作系统有不同的版本,应用程序需要支持其中的大部分,以确保拥有广泛的用户基础。例如,Android 系统中,许多设备安装的是旧版本,因硬件限制而无法更新到新版本,且制造商不更新其设备。同时,拥有不同设备意味着要定制 Android 以适应个人喜好并更改用户界面,因此应用程序必须与所有不同的设备形式和 UI 更改兼容。
跟上移动开发的步伐
移动应用程序现在已成为许多组织前端的不可或缺的一部分,并显然推动了后端开发的变化。组织使用服务层和数据层来进行后端操作,但由于与移动开发的集成,它们需要更好地适应并与移动和 Web 开发协作。
发布
由于在移动平台上发布和更新的方式与 Web 完全不同,因此确保更新并关注旧版本变得更加困难。在移动设备上,用户必须下载更新;而不像 Web 一样,用户每次访问 URL 时,应用程序会自动更新。大多数时候,用户选择不下载更新,有时他们的存储空间有限。因此,应用程序开发者必须不断确保旧版和新版都能正常运行。
向后兼容性
如前所述,移动应用需要在新旧版本的操作系统上都能正常运行。仅仅因为你开发了新版本,并不意味着旧版本用户就不再是你的责任。事实证明,大多数使用旧版本操作系统的用户并不会下载最新更新。应用开发者必须在新版本操作系统中使用最新功能,同时确保应用在旧版本上也能完美运行。
应用商店
这是一种新的应用分发方式,主要出现在移动应用行业。在网页应用中,你只需将应用部署到网页服务器上,用户可以通过 URL 访问你的应用。
修复问题和部署补丁变得非常简单,因为你只需将其部署到服务器上,访问你网页应用程序的人就会立即收到更新。
在移动应用中,应用程序必须通过所有不同操作系统的应用商店。
它们必须在发布前经过验证,即使是更新和小补丁也需要通过相同的流程,因此修复不会立即提供给最终用户。这在将 DevOps 应用到移动端时增加了额外的复杂性。
反馈机制
在网站和其他平台中,由于应用程序不是通过应用商店提供给用户的,反馈仅限于应用团队。用户的反馈对其他用户不可见,他们可以根据自己的判断来评估和使用它。
在移动设备中,用户可以在应用商店中给予反馈,如果应用程序未能满足用户的期望,它会收到差评,这对应用程序的影响很大。这种快速且显而易见的反馈可以帮助应用程序迅速起飞,或者如果用户不喜欢它,它将惨败。根据这些反馈采取行动在移动 DevOps 中变得尤为重要。
总结
在本章中,我们讨论了 DevOps 和移动 DevOps,实施 DevOps 的含义,以及它如何改变不同团队的协作方式。我们还描述了 DevOps 和移动 DevOps 在不同开发和运营阶段的主要区别。在下一章中,你将学习 DevOps 最重要的一个方面,即源代码管理。
第二章:使用代码库系统
在上一章中,我们了解了 DevOps 在应用开发生命周期中的意义,DevOps 与移动 DevOps 之间的关键区别,同时探讨了将 DevOps 应用于移动应用开发周期所面临的挑战。
在本章中,正如章节标题所示,我们将探讨代码库系统。我们将讨论各种可用的版本控制工具,并主要关注 Git,以便详细了解源代码版本管理步骤,我们将在全书示例中使用 Git 作为代码库。
本章涵盖的一些主题如下:
-
版本控制的种类
-
源代码管理
-
使用 Git 为项目创建一个代码库
-
在 GitHub 上创建一个帐户
-
管理用户和组
-
配置 SSH 密钥
源代码管理
在移动 DevOps 生命周期中,应用开发是其中的第一阶段。编码是开发生命周期中最重要的部分,而长期来看,管理这些代码更为重要。
当开发者持续编写应用程序时,如果管理不当,代码的管理会变得麻烦。随着开发的进展,代码合并的频率越来越高,随着时间推移,开发团队迅速扩大,更多的人需要与其他开发者整合代码。
源代码管理变得复杂,成为必须重点关注的一个重要部分,以确保无缝的开发和代码集成。
需要进行源代码管理
让我们以一个小公司的应用开发为实际例子。团队最初有两个人。团队开始编写应用程序,并将代码保存在本地机器上。
在一天结束时,两位开发者分享他们的更改并整合代码。
此时一切顺利,因为两位开发者很容易检查文件、合并代码和复制文件。过了一段时间,另外两个人加入了开发团队,现在他们需要管理和合并代码,并每天进行更改。
这是团队当前面临的挑战:
-
代码合并问题:每当新开发者对代码文件进行更改时,他们必须将自己的文件与五个不同的开发者共享。这可能会产生大量未管理的代码更改,导致无法正确同步。在这种手动合并代码的过程中,可能会错过一些更改。
-
手动检查中浪费的时间:在手动检查代码更改并确保所有更改都已合并、手动复制粘贴,再次验证一切是否正确集成,确保没有遗漏更改,然后再次手动构建以确保更改不会导致构建失败的过程中,会浪费大量时间。
-
没有代码更改记录:在手动代码合并过程中,开发人员的更改没有记录。代码更改可能会破坏某些功能,但直到开发过程的后期才会被发现。没有记录谁做了哪些更改,这使得故障排除变得更加耗时且困难。
-
没有统一的最新代码位置:因为代码没有定期提交到任何中央代码库,所以它依赖于开发人员,并且使得将代码库迁移到新的系统和团队变得困难。
-
分布式开发:当团队扩展并成为一个分布在不同地点的分布式团队时,这在今天的世界中非常普遍,如果没有源代码管理解决方案,代码合并和更改跟踪将变得非常具有挑战性。开发人员从不同地方进行代码更改并需要合并这些更改;这会变得具有挑战性,因为他们现在需要每天与所有团队成员合并代码,而这不能通过简单的文件共享系统完成。在这种过程中需要大量的跟踪和合并工作。
-
源版本控制:源版本控制是谈论源代码管理时的另一个问题。如果没有源代码管理工具,开发人员必须手动维护不同版本的代码文件夹,并确保每个人使用相同的结构,且集成必须以相同的方式进行。源代码管理工具通过提供创建分支和标签的选项来解决这个问题,这样可以对不同版本和特性进行管理,从而使源版本控制过程变得简单、易于跟随且无缝。
存在许多此类问题,要求使用代码库系统来确保代码质量,跟踪更改,顺利地合并代码,并促进开发人员之间的集成。这就是源代码管理和代码库系统发挥作用的地方。
源代码管理和版本控制中常用的术语
以下是一些在源代码管理和版本控制系统中常用的术语。它们通常是广泛使用的标准术语,几乎所有的控制系统都使用这些术语:
-
分支:分支是主代码的一个修订版本,开发人员可以在其上进行更改,然后再将其与主代码合并。分支可用于维护不同的特性,并保持不同的发布和版本。标签也属于同一类别,并具有类似的用途。
-
更改:更改代表源代码文件中的修改,并通过源版本控制系统进行跟踪。
-
检出:检出源代码意味着在你的机器上创建一个代码库的本地副本。它也可以表示获取最新的代码。
-
克隆:克隆类似于检出,区别在于它通常用于将远程代码库克隆到一个空的本地代码库中。
-
提交:提交与其他系统中的提交相同;它基本上是将你的本地副本或工作副本的更改推送到远程代码库。
-
冲突:冲突发生在不同的开发人员对同一个源文件进行修改,且通常是在文件的同一部分。可以使用一些差异检查工具,如 KDiff,来比较文档并确保冲突不会被覆盖。
-
合并:当开发人员对一个文件进行修改,而这个文件也被其他开发人员修改过,并且他需要将自己的代码提交到代码库时,通常会进行合并。在这种情况下,源代码管理工具通常会给出警告,指出该文件已经有其他开发人员的更改,你的更改将与他们的更改合并。另一些时候,类似的情况可以通过手动合并来解决,以避免冲突,或者先从代码库获取最新的更改,然后在本地合并,再提交代码。
各种源代码管理工具
由于不同的项目有不同的需求,而且根据你的项目是集中式还是分布式,团队和组织可能需要不同类型的源代码管理。有些组织可能要求将代码集中存放,而其他组织则希望代码库分散,不在单一位置维护。
考虑到所有这些场景,有两种类型的源代码管理工具:
-
集中式版本控制
-
分布式版本控制
集中式版本控制
正如名字所示,集中式版本控制意味着我们的项目代码在服务器上有一个单一的中央副本,开发人员将他们的更改提交到这个中央代码库。在这种版本控制系统中,开发人员可以签出所需的源代码文件,但不能拥有整个本地副本。最常见且知名的例子之一是 SVN。
分布式版本控制
分布式版本控制与集中式版本控制系统正好相反。在分布式版本控制系统中,开发人员不依赖于中央代码库服务器来存储所有与版本相关的信息和项目文件。他们将代码库克隆到本地计算机上,本地计算机包含项目源代码的所有版本和分支信息。最常用的分布式系统之一是 Git,我们将在本章深入学习如何使用 Git 作为源代码版本控制工具。
在 GitHub 上创建账户并使用 Git 创建一个代码库
正如我们之前所描述的,代码库是用来管理和分享项目代码的地方。Git 允许你创建公共或私人代码库。公共代码库对所有人开放,但你可以包含一个许可证文件,说明你希望如何与他人共享项目。
按照以下步骤在 GitHub 上创建一个代码库:
- 打开一个网页浏览器,访问
github.com/,并通过提供用户名、电子邮件和密码注册一个新账户。如果你已经在 GitHub 上有账户,可以跳过这一步:

- 注册完成后,前往
github.com/login并登录你的新创建的 GitHub 账户:

- 登录后,在页面右上角点击“+”按钮,然后点击“新建仓库”,如下图所示:

- 在下一个页面,为你的仓库命名并可选择性地添加描述。然后,勾选“初始化仓库并添加 README”,接着点击“创建仓库”按钮:

就这么简单,你可以为你的项目创建一个新仓库,现在可以推送代码并与团队中的其他人管理和共享它。
管理组织用户和团队
组织是多个共享账户和私有仓库的组合。拥有者或管理员可以管理对组织数据和项目的访问权限。
创建一个组织并邀请用户加入
按照以下步骤在 GitHub 上创建你的组织账户,并邀请用户加入你的 GitHub 组织:
-
登录到你的 GitHub 账户,访问
github.com/login。 -
登录后,点击你的个人资料照片,然后点击“你的个人资料”,如下图所示:

- 在下一个页面,点击“编辑个人资料”按钮:

- 在页面左侧,点击“个人设置”下的“组织”。然后,点击“新建组织”按钮以添加一个新组织:

- 在下一页面,提供组织的名称和电子邮件,并选择一个计划来创建组织账户:

- 点击“创建组织”按钮:

- 组织创建完成后,你现在可以通过搜索用户名、全名或电子邮件来邀请 GitHub 用户加入你的组织。你也可以选择稍后邀请他们。点击“完成”来完成组织创建过程:

- 被邀请的人会收到一封电子邮件,邀请他们加入该组织。他们需要接受邀请才能成为组织的成员。
通过遵循之前的步骤,你应该能够在 GitHub 上创建组织账户并邀请成员加入该组织。此外,你还可以像为个人账户一样,为组织创建仓库。
创建团队并添加成员到团队
按照以下步骤在 GitHub 上创建团队并添加成员:
- 进入组织页面,点击“团队”标签页,再点击“新建团队”按钮:

- 提供要创建的团队的详细信息,然后点击“创建团队”按钮:

- 团队创建完成后,进入“成员”标签页,添加成员到团队:

- 点击“添加成员”按钮,向团队中添加新成员:

按照上述步骤,你将能够在 GitHub 上创建一个新团队并添加成员。
在不同服务器上安装 Git
本主题将讨论如何在不同操作系统(包括 Windows、Linux 和 Ubuntu)上安装 Git。
在 Windows 上安装 Git
在 Windows 上安装 Git 就像安装任何基于 GUI 的应用程序一样简单。按照步骤在 Windows 上安装 Git:
- 要下载最新版本的 Git for Windows 安装程序,请访问
git-scm.com/downloads。选择 Windows,下载将自动开始:

-
下载完成后,启动安装程序文件。
-
下一屏幕会要求你接受许可协议。点击“下一步”。
-
提供 Git 安装路径;如果你愿意,可以保持默认路径不变,然后点击“下一步”。
-
下一屏幕是选择你希望在系统上如何使用 Git。有多个选项可供选择。第一个选项让你通过 Git Bash 使用 Git,这是 Git 的命令行工具。第二个选项允许你在 Git Bash 和 Windows 命令提示符中都使用 Git 命令,这样非常灵活,能提高使用 Git 的便捷性。建议选择第二个选项,然后点击“下一步”:

- 接下来,我们将选择用于远程连接的 OpenSSH 客户端,这是 Git 的默认选项:

- 选择用于 HTTPS 连接的 SSL 库。你可以保持默认设置,或根据需要进行更改;点击“下一步”:

- 选择 Git 在检出代码和提交时使用的行结束符样式。你需要做出选择,因为不同开发者可能使用不同的系统,如 Windows 和 Linux,行结束符样式在不同系统中有所不同。因此,始终建议保持提交时使用相同的行结束符样式:

- 选择用于 Git Bash 执行命令的终端仿真器;MinTTY 更加灵活,并且是默认选项:

- 在最后一步,选择你希望启用的所有功能,然后点击“安装”:

-
一旦文件提取到
path文件夹并完成安装,点击“完成”: -
现在,打开命令提示符或 Git Bash,运行以下命令来配置你的用户名和电子邮件:

Git 安装已完成,且用户身份已配置为用于提交。
在 CentOS/RHEL 服务器上安装 Git
要在 CentOS 或 RHEL 服务器上安装 Git,请按照以下步骤操作:
- 从你的 shell 中,使用
yum(或旧版 Fedora 上的dnf)安装 Git:
$ sudo yum install git
或者:
$ sudo dnf install git
- 通过输入以下命令验证安装是否成功:
$ git --version
- 配置所有仓库的用户名和电子邮件地址:
$ git config --global user.name "firstname lastname"
$ git config --global user.email "email@gmail.com"
- 使用
dnf(或旧版 Fedora 上的yum)安装必要的构建依赖:
$ sudo dnf install curl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel asciidoc xmlto docbook2X
或使用 yum-Epel 仓库:
$ sudo yum install epel-release
$ sudo yum install curl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel asciidoc xmlto docbook2X
- 将
docbook2x创建为 Git 构建期望的文件名符号链接:
$ sudo ln -s /usr/bin/db2x_docbook2texi /usr/bin/docbook2x-texi
- 克隆 Git 源代码(如果你还没有安装 Git 版本,请下载并解压):
$ git clone https://github.com/git/git
- 要构建 Git 源代码并将其安装到
/usr目录下,请运行make:
$ make all doc prefix=/usr
$ sudo make install install-doc install-html install-man prefix=/usr
按照之前的步骤将在 CentOS/RHEL 服务器上安装并配置 Git。
在 Ubuntu/Debian 系统上安装 Git
在 Ubuntu 系统上安装 Git,请按照以下步骤操作:
- 从你的 shell 中,使用
apt-get命令安装 Git:
$ sudo apt-get update
$ sudo apt-get install git
- 通过输入
git --version验证安装是否成功:
$ git --version
git version 2.9.2
- 为单个仓库配置 Git 用户名和电子邮件:
$ git config --global user.name "firstname lastname"
$ git config --global user.email "email@gmail.com"
- 使用
apt-get命令安装必要的依赖:
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev asciidoc xmlto docbook2x
- 克隆 Git 源代码(如果你还没有安装 Git 版本,请下载并解压):
$ git clone https://git.kernel.org/pub/scm/git/git.git
- 要构建 Git 源代码并将其安装到
/usr目录下,请运行make:
$ make all doc info prefix=/usr
$ sudo make install install-doc install-html install-info install-man prefix=/usr
至此,我们已经讨论了在不同平台上安装和配置 Git,包括 Windows、CentOS 和 Linux 系统。
配置 SSH 密钥
要为你的 GitHub 账户配置和设置 SSH 密钥,请按照以下步骤操作:
-
检查是否已经有
ssh密钥对。 -
打开 Git Bash,输入
ls -al ~/.ssh查看是否已存在 SSH 密钥:
$ ls -al ~/.ssh

-
公钥的扩展名是
.pub。创建一个新的密钥对(如果你已经有密钥对,可以跳过此步骤)。 -
打开 Git Bash 并粘贴以下文本,替换为你的 GitHub 电子邮件地址:
$ ssh-keygen -t rsa -b 4096 -C your_email@example.com

- 当系统提示你
Enter a file in which to save the key时,按 Enter 键接受默认的文件位置:

- 当系统提示时,输入一个安全的密码短语(推荐),或者按 Enter 继续而不设置密码短语:

- 整个设置过程将在以下截图中显示:

- 将新创建的 SSH 密钥添加到
ssh-agent中;为此,请确保ssh-agent正在运行:
$ eval $(ssh-agent -s)

-
将新创建的私钥添加到
ssh-agent。 -
如果你使用不同的名称创建了密钥,或者你要添加的现有密钥使用不同的名称,请将命令中的
id_rsa替换为你的私钥文件名:

- 要将 SSH 密钥添加到 GitHub 账户中,请下载/复制
~/.ssh/id_rsa.pub中的公钥。
你也可以手动复制公钥,或者使用以下工具:
Windows:
**$ clip < ~/.ssh/id_rsa.pub** Linux:
**$ sudo apt-get install xclip**
**$ xclip -sel clip < ~/.ssh/id_rsa.pub**
Mac:
**$ pbcopy < ~/.ssh/id_rsa.pub**
- 在 GitHub 页面的右上角,点击你的个人头像,然后点击设置:

- 在个人设置侧边栏中,点击 SSH 和 GPG 密钥,然后选择新建 SSH 密钥:

- 在标题栏输入一个有意义的名称,并将你的密钥粘贴到密钥栏中。点击添加 SSH 密钥:

-
当提示时,输入你的 GitHub 密码。
-
新添加的 SSH 密钥将如下所示:

很好,现在你已经成功将 SSH 密钥添加到你的 GitHub 账户了!
总结
在本章中,我们详细了解了不同的版本控制系统和源代码管理。我们还深入探讨了如何使用 Git 创建仓库并管理团队和组织。在下一章,你将学习使用 Xamarin 进行跨平台应用开发,并使用 Visual Studio 进行开发。
第三章:使用 Xamarin 进行跨平台移动应用开发
Xamarin 是一个平台,允许开发者通过使用相同的源代码和相同的集成开发环境(IDE),在 Android、iOS、Windows 及其他平台上创建跨平台应用程序。
Xamarin 的历史
Xamarin 最初是作为一个实验开始的,旨在为 Linux 开发一个版本的.NET,始于 2000 年初,最初被称为一个名为Mono的开源项目。
后来,同一个项目由一个名为Xamarin的新公司开发和支持,该公司由 Mono 的最初开发者创建,也被称为MonoTouch和 Mono for Android。
Mono 的开发持续进行,后来更名为 Xamarin,支持 Android 和 iOS 应用程序开发。
Xamarin 现在已被微软收购,并作为微软提供的产品之一进行开发和支持,与现有的 IDE——Visual Studio 有很好的集成,甚至还有自己独立的 IDE,叫做 Xamarin Studio,适用于 Mac 和 Windows。
为什么你应该学习 Xamarin
事实上,Xamarin 可以在许多场景中拯救你的项目,在某些情况下,甚至可以节省数月的时间。
假设你有一个想要开发的移动应用的创意。当然,你希望尽快开发出来并推向市场。但在开始开发过程之前,有一些小挑战和决策你需要克服或决定。
让我们来看看这些挑战:
-
选择目标移动平台:这是我们应用程序规划阶段中非常重要的一部分。移动平台市场由主要玩家组成,如 Android、iOS 和 Windows。为了最大限度地发挥我们的应用程序的作用,我们希望它能够被大多数用户访问和使用。
-
学习一个特定平台的编程语言,或让团队中有平台特定的开发者:现在,假设你决定将目标定位于所有三个主要的移动平台。我们清楚地知道,我们需要为三个移动平台开发应用程序。在这种情况下,如果你是单独开发,那么你需要学习三种不同平台特定的语言。Android 有自己的官方 IDE,同样,苹果也有自己的 IDE 和编程语言来构建 iOS 应用程序,而 Windows 也有自己的开发工具。
-
为每个平台花费时间和资源进行开发:三个不同的平台,三种不同的语言,以及三种不同的 IDE。这将非常耗时,并且学习曲线将成为一个主要问题。或者,你有三个不同的开发团队来负责每个平台;那么,你将在开发上投入更多的资源。
-
尽量保持每个平台上的应用一致的行为:现在,假设你已经决定为应用程序开发使用多个资源。现在,所有不同的移动平台都有各种不同的用户交互方式,以及不同的用户界面设计方式。使用不同的团队开发不同平台的应用程序,有时会使同一个应用在这些平台上的用户体验大相径庭。
-
为同一个应用维护所有平台特定的代码库:一旦应用的初步开发完成,开发挑战就永远不会结束。每当你向应用添加新功能时,你将不得不将相同的更改和功能应用到所有三个平台特定的代码库,重复相同的业务逻辑,并在不同的 IDE 上以不同的方式开发相同的功能。
从前面的情境中,你可以看到,如今开发一个移动应用并不是那么简单直接的事,如果我们必须通过不同的编程语言和 IDE 来完成。
这大大增加了我们的交付时间,并且在时间、资源以及当然还有金钱上都非常昂贵。
为了解决所有这些挑战,Xamarin 来拯救我们。Xamarin 使开发者无需学习不同的编程语言和不同的 IDE。
不仅如此,我们还可以享受一次编写应用程序代码,构建到不同移动平台的好处。如果你已经是一个在.NET 框架上使用 Visual Studio 的 C#开发者,那么你简直是中了头奖。因为猜猜看,语言和 IDE 方面,这就是你开始使用 Xamarin 开发所需要的一切。

没有 Xamarin 的开发周期

使用 Xamarin 的开发周期
使用 Xamarin 进行跨平台开发的好处
使用 Xamarin,开发者在移动应用开发的许多方面都变得更加轻松:
-
语言:最耗时的过程是不断学习新语言;Xamarin 让开发者摆脱了这个问题。你只需要有 C#经验,就能同时为 Android、iOS 和 Windows 开发——呼!
-
IDE: 学习新语言时会带来另一个额外负担:每次都需要适应一个新的 IDE。每当我们为不同的平台获取一个新的 IDE 时,我们旧的快捷键就不再有效,文件位置也发生变化,调试方式完全不同。所有这些问题都会增加开发时间。使用 Xamarin,你只需使用一个我们已经喜爱的 IDE——Visual Studio。
-
一致的 UI 设计:通常,我们希望我们的应用在所有移动设备上都看起来一样。我们不希望用户购买新手机后,发现同样用途的应用程序在用户互动上完全不同。为了实现这一点,Xamarin 提供了 Xamarin.Forms,以便在所有移动平台上开发一致的 UI 元素,为用户提供无缝的体验。
-
代码复用:Xamarin 允许我们在所有平台上共享业务逻辑代码。对于任何业务逻辑代码,我们只需要编写一次。
移动应用程序开发简介
在当今市场中,移动应用程序开发是任何产品开发的重要组成部分。本地移动应用程序将用户与应用程序的互动提升到了一个新的水平:
-
始终触手可及:本地移动应用程序与网页和桌面应用程序不同,始终存在于用户的手机中。用户可以随时选择不访问网页应用程序,这可能导致互动减少,但移动应用程序是由用户安装在手机上的,每当用户与手机互动时,开发者可以利用用户的活动,在多方面提升互动体验。可能性是无限的。
-
了解用户行为:移动应用程序可以利用用户在手机上的行为。我们可以监控用户的活动,例如走路、跑步、睡觉等,以获取个人用户分析和反馈。
-
始终在线:移动数据使用户能够在旅途中保持连接互联网,从而增加用户与应用程序互动的次数。移动数据为用户与互联网连接的应用程序提供了更高的连接性。
-
利用尖端硬件传感器:移动应用程序能够利用用户移动设备上可用的传感器,如 GPS、指纹识别、陀螺仪等等。
-
个人互动:移动设备对每个用户来说都是非常个人化的,与桌面和笔记本电脑设备不同。如今,个人助手和语音合成技术的世界正在使用户互动变得更加个性化和人性化,例如语音输入和语音操作。
移动应用程序开发的过程
和其他平台一样,移动应用程序开发包括几个关键步骤,这些步骤是创建完整且稳定的移动应用程序的过程,用户可以使用并喜爱:
-
构思:每个应用程序都是从一个小点子或一个待解决的问题开始的。一个能够解决用户问题的强大且有影响力的想法,最终会导致一个成功的应用程序。现在,比以往任何时候都更容易想到一个伟大的想法。我们使用移动设备并面临许多日常使用中的问题,或者有时会希望某个应用程序能够解决这些问题。正是这些,成为了伟大应用程序创意的源泉。
-
规划:规划是过程中的一个非常重要的部分。一个创意只有在执行得当的情况下,才算是好创意:
-
上市所需的时间应该是多少?
-
该应用应该是付费的还是免费的?
-
我们应该针对哪个移动平台进行开发?
-
应该使用哪些技术和工具?
-
所有这些问题的答案必须在规划阶段确定。
-
设计:这是应用程序开发的阶段,在这一阶段,我们的想法开始成型,能够看到应用完成后的样子。在开始编码之前,设计应用的线框图和布局是非常重要的。
-
编码:当我们进入编码阶段时,我们已经对目标方向和应用程序要实现的功能有了清晰的了解。因此,这使得编码阶段可以集中在实际的代码开发上。
-
测试:在各种移动设备上测试应用程序对于应用程序的稳定性至关重要。
-
部署和持续反馈:在将应用提交到商店后,持续监控用户反馈和报告,并根据反馈采取行动是非常重要的。
Xamarin 支持的平台
正如本章前面提到的,Xamarin 允许开发者通过共享相同的代码为多个移动操作系统创建应用程序。以下是 Xamarin 支持的平台:
-
Xamarin.Android:Xamarin.Android 使我们能够使用 C# 构建原生 Android 应用程序。它使用 即时编译(JIT)编译器来优化应用程序的性能,并且包括所有可以在 Xamarin C# 代码中使用的 Android API。它适用于从 Android 手机到平板电脑,甚至是可穿戴设备。
-
Xamarin.iOS:与 Xamarin.Android 类似,Xamarin.iOS 提供了所有现有的 API,正如你猜到的,它们是 Apple's iOS SDK 中的 C# 版本。此外,Xamarin.iOS 使用 预编译(AOT)编译器将你的 C# 代码编译为本地 ARM 汇编代码。
-
Xamarin.Mac:Xamarin 不仅仅局限于移动平台;你还可以使用相同的代码库开发 Mac 应用程序。
-
Xamarin for Windows:由于 C# 是编写 Windows 手机和 Windows 桌面应用程序的默认语言,你甚至可以在移动应用和 通用 Windows 平台(UWP)应用之间共享代码。
Xamarin 在 Visual Studio 中
Visual Studio 是编写 C# 代码的默认 IDE,尽管在使用 Xamarin 编写应用程序时,其他选项也可以选择。
还有其他选项,例如适用于 Windows 的 Xamarin Studio 和适用于 Mac 的 Xamarin Studio,如果你使用的是 Mac。不过,Xamarin Studio for Windows 已不再由微软支持,微软鼓励开发者改用 Visual Studio。对于 Mac 开发,你可以使用 Xamarin Studio for Mac。
本书将介绍在 Windows 上使用 Visual Studio 进行 Xamarin 开发,因为它是用于 C# 代码开发的最佳 IDE,并且提供了出色的 IntelliSense 支持。
扩展和插件
Visual Studio 支持使用 NuGet 包管理器的第三方库和本地库。它提供了从 Visual Studio 内部添加新插件和附加组件的功能。
Xamarin 是 Visual Studio 的扩展。你可以在安装 Visual Studio 时安装 Xamarin 组件,如下文所示。
在 Windows 上安装 Visual Studio 和 Xamarin
在 Windows 机器上安装 Visual Studio 和 Xamarin,请按照以下步骤操作:
-
当你在浏览器中打开前述网址时,你会看到如下画面:

-
你会看到有多个 Visual Studio 版本供开发者选择。
-
你可以选择最适合你需求的版本。如果你只是想使用 Visual Studio 学习 Xamarin,或者你是一个寻求免费版本的个人开发者,那么 Visual Studio Community Edition 是最适合你的版本。
-
点击在 Visual Studio Community 2017 下提供的“免费下载安装”按钮。
-
你应该会在计算机上下载到一个 Visual Studio 安装程序文件。
-
打开安装程序文件后,你应该会看到如下画面:

-
点击“继续”按钮开始安装过程。
-
加载可用安装程序可能需要一些时间,你可能会看到以下屏幕:

- 下一个屏幕会让你选择工作负载:

现在,如果你是 Visual Studio 2017 的新手,你可能会发现安装过程与之前的版本有所不同。工作负载是 2017 新增的,它们代表了用于不同开发目的的不同包。例如,如果你计划仅为 .NET 桌面应用程序编写代码,那么你只需选择该工作负载并跳过其他工作负载。
Visual Studio 2017 安装程序中的这种变化是一个很好的方式,可以避免安装我们在开发中可能不会用到的组件,只选择需要的工作负载来安装必要的组件。这为我们的笔记本节省了大量的时间和空间。
- 在我们的 Xamarin 开发中,我们需要一个工作负载来安装移动开发所需的 Xamarin 工具和语言。如果你在这个菜单中稍微向下滚动,你会找到一个名为“移动与游戏”的部分:

-
在“移动与游戏”类别下,第一个选项也是我们教程中唯一需要的选项是 Xamarin 移动开发与 .NET。
-
选择第一个选项,在右侧面板中你会看到此工作负载中包含的所有包。Visual Studio 安装程序还会在右下角显示工作负载的大小。选择后,点击“安装”按钮开始安装过程。
-
这将开始下载所有列出的包,然后将它们安装到你的计算机上。Xamarin 包的大小超过 30 GB,下载和安装这些包可能需要一些时间,具体取决于你的互联网速度。
-
一旦安装程序完成所有必需包的下载和安装,你将看到如下界面:

-
就这样,恭喜你成功安装了 Visual Studio 和 Xamarin。现在,选择开发设置中的 Visual C# 和你喜欢的 Visual Studio IDE 主题颜色,点击 Start Visual Studio 按钮。
-
安装完成后,让我们验证 Xamarin 是否与 Visual Studio 一起安装。
-
点击 Tools 菜单并选择 Extensions and Updates。
-
在 Installed 部分,向下滚动以查找已安装的 Xamarin for Visual Studio、Xamarin.Android SDK 和 Xamarin.Apple SDK:

-
现在我们已经验证了安装,接下来在开始编码之前,我们还有一些最后的步骤。本书将聚焦于 Android 应用开发过程,以帮助你更好地了解 Xamarin 的工作原理。
-
让我们利用已经与 Xamarin 一起安装的 Android SDK 管理器来更新所有 Android 包。
-
打开 Tools | Android | Android SDK Manager:

- 这将打开 Android SDK 管理器的新窗口:

这里我们可以看到已安装基本包的可用更新。
-
让我们点击安装 11 个包。
-
这将为你提供一个新窗口,你需要接受要下载的包的许可协议。根据不同的包,某些许可可能需要单独选择。一旦所有包上都有绿色勾选,点击安装。根据你的网速,更新所有包可能需要一些时间:

一旦一切都更新完毕,我们将继续设置我们的 Android Virtual Device(AVD)以便在开发环境中测试我们的应用。
设置我们的 Android 虚拟设备进行开发
Android 模拟器将使我们能够在计算机上测试 Android 应用,我们无需实际设备进行测试。
- 让我们点击 Tools | Android | Android Emulator Manager:

-
为了简化这个过程,我们将从现有的适用于 Android 模拟器的移动模板开始。
-
转到以下屏幕中显示的设备定义选项卡。进入设备定义屏幕后,向下滚动直到你看到 Nexus 设备:

-
选择你喜欢的 Nexus 设备,并点击右侧的 Create AVD 按钮。
-
接下来,你应该会看到如下窗口,在这里你可以根据自己的需求自定义 Android 模拟器:

-
填写所有必需的详细信息。你可以参考前面的截图帮助你。一旦点击 OK,AVD 管理器将为你创建一个新的 Android 模拟器。
-
为了验证我们的模拟器是否已创建,让我们回到 Android 虚拟设备(AVD)管理器中的 Android 虚拟设备选项卡,我们可以在列表中找到新创建的 AVD:

-
您一定迫不及待想要启动这个 AVD,看看它的外观和表现如何。那么,让我们不再等待,选择 AVD 并点击启动按钮。
-
在 AVD 管理器启动 AVD 之前,它会给我们一些启动选项,类似于以下截图所示的内容:

- 在这里,您可以将显示大小调整为我们之前选择的模板的实际手机大小(本例中为 Nexus 6);完成后,点击启动。模拟器可能不会启动。看到这个错误非常重要,它有助于我们理解 AVD 需要在 x86 环境中运行的要求。
现在,在 x86 环境中启动 Android 模拟器有一些先决条件;其中一个主要要求是必须启用虚拟化技术(Intel VT-x)。
-
在运行模拟器之前,我们需要检查机器的 BIOS 是否启用了 VT-x。我们的机器必须启用 Intel VT-x,如果机器上安装了 Hyper-V,也需要将其卸载。
-
否则,您将看到类似这样的屏幕,说明在启动模拟器时出现了问题:

在前面的截图中,我们可以看到 VT 功能在 BIOS/UEFI 中被禁用。
-
要启用 VT/VT-x,请进入 BIOS,您应该会看到一个选项来启用虚拟化技术(VT-x)。我们不会详细讲解如何操作,因为不同的机器设置方法不同。
-
除了启用 VT,我们还需要检查 Hyper-V 是否已安装在机器上。为此,请按照以下步骤操作:
-
打开控制面板。
-
点击“程序”:
-

-
- 点击“打开或关闭 Windows 功能”:

-
- 向下滚动查看是否能在程序列表中找到 Hyper-V:

-
-
如果 Hyper-V 已选择,请取消选择它。点击确定。
-
这可能会重启您的系统。
-

-
- 这应该会移除 Hyper-V,最后一切准备就绪。
-
让我们回到 Visual Studio 启动我们的 AVD。这次,模拟器成功启动,界面如下:

- 如果您的 AVD 看起来与前面的截图不一样,请返回并编辑 AVD,将皮肤更改为“无皮肤”。
太棒了!现在我们有了正在运行的 Android 虚拟设备,可以开始使用 Xamarin 编写我们的新 Android 应用程序了。
总结
在这一章中,我们了解了 Xamarin 的简短历史,并探讨了为什么它是开发人员进行跨平台移动应用开发的绝佳工具。
我们还了解了如何在 Windows 机器上安装 Visual Studio 和 Xamarin,以及如何创建 AVD 来测试我们的应用。
在下一章,我们将学习基本的应用程序基础知识,并使用 Xamarin 创建我们的第一个 Android 应用程序。
第四章:使用 Xamarin 编写您的第一个 Android 应用
现在,Visual Studio 已经安装在你的 Windows 机器上,开发环境已经准备好,Android 虚拟设备(AVD)也已经就绪,我们可以开始第一个 Android 应用的开发了。
在本章中,我们将使用 Xamarin 在 Visual Studio 中构建我们的第一个 Android 应用,同时学习 Android 应用开发的一些基础知识。
创建你的第一个 Android 项目
在 Visual Studio 中创建一个新的 Android 项目,按照以下步骤操作:
- 点击 文件 | 新建 | 项目:

- 从左侧面板中点击 Android,然后选择空白应用(Android):

- 在名称部分,为项目命名,选择项目的首选位置,然后点击 OK 按钮。你将看到如下截图:

恭喜,你已经在 Visual Studio 中创建了第一个 Android 项目。
Xamarin 解决方案结构
一旦项目创建完成,你将看到如下截图所示的解决方案结构:

目前我们需要理解的解决方案的主要部分如下:
-
引用:此部分列出了项目所需的所有库。正如我们在前面的截图中看到的,它引用了
Mono.Android,这是Xamarin.Android的库。 -
资源:它包含所有的资源,例如图片、布局等等。
-
MainActivity.cs文件包含了我们用于处理事件和其他事项的 C# 代码。
为应用程序创建 UI
- 让我们展开在前一截图中看到的
Resources文件夹,然后展开解决方案资源管理器中的layout文件夹。双击Main.axml以打开它。这是应用程序屏幕的布局文件。默认情况下,它会在 Android 设计器中打开;你也可以点击底部的 Source 标签查看其 XML 代码。这个布局文件是我们将添加 UI 控件的主要文件,也是我们运行应用程序时看到的界面:

现在,让我们添加一个输入框来输入电话号码。从工具箱(左侧面板)中拖动“Phone”字段到 Main.axml 文件的设计视图中:

拥有电话号码文本框的好处是可以限制用户只输入电话号码。同时,当用户点击输入框时,他们只会看到数字键盘,而不是完整的文字键盘。
现在,我们已经为用户添加了一个输入框,用来输入电话号码,以便拨打电话。
为了从 C# 代码中识别这个字段并插入一个值,我们需要为它指定一个唯一的 ID。
- 在设计表面上选择电话文本字段时,使用右侧的属性面板将电话号码输入字段的 ID 属性更改为 @+id/PhoneNumber,如下图所示:

现在,我们已经添加了输入字段,用户可以在其中输入电话号码,接下来我们需要一个按钮来执行拨打电话的操作。
- 从工具箱左侧窗格中的表单小部件拖动一个按钮到
Main.axml的设计视图中:

与输入字段类似,我们需要给按钮赋予一个唯一的 ID,这样我们的 C# 代码才能识别按钮何时被点击,并采取适当的行动;即拨打用户输入的号码。
此外,按钮上的文本应该写成 Do you want to call,对吧?那么我们在下一步中也要做这个修改。
- 在设计器中选择按钮,进入右侧的属性窗口,向下滚动并将 ID 更改为 @+id/CallButton,文本更改为 CALL,如下图所示:

现在,我们的应用程序的基本 UI 已经准备就绪,所有字段和按钮都有了适当的 ID。
现在是时候转到我们的 C# 代码,将 UI 与后端代码连接起来,以执行某些操作。
当用户打开应用程序时,MainActivity 会被打开,并且与之关联的是 Main.axml 文件。
我们稍后将详细了解 Activities;现在,让我们编写代码来处理 MainActivity 中的交互。
处理用户交互
用户交互是开发移动应用程序最重要的方面。一个移动应用程序应该是互动的且易于使用的。
在这个基本应用程序中,我们将用 C# 编写用户交互代码,并将其作为 MainActivity.cs 文件的一部分:
- 让我们点击左侧解决方案资源管理器中的
MainActivity.cs文件并打开它:

它有一些自动生成的代码,我们将修改这些代码,以便使我们的应用程序正常工作。
- 我们需要在
MainActivity.cs文件的OnCreate()方法中编写代码:

在我们开始编写用户交互代码之前,先理解一下自动生成的代码:
base.OnCreate(savedInstanceState);
这段代码调用了 MainActivity.cs 的父类/基类 Activity.cs 的 OnCreate() 方法。
SetContentView(Resource.Layout.Main);
正如注释所说,它设置了来自我们布局资源文件 Main.axml 的视图。
我们需要编写 SetContentView(Resource.Layout.Mai) 代码。
- 首先,通过 Android Designer 获取在
layout文件中创建的控件引用,也就是电话号码输入框和拨打电话的按钮。
在 OnCreate() 方法中添加以下代码:
EditText phoneNumberInput = FindViewById<EditText>(Resource.Id.PhoneNumber); Button callButton = FindViewById<Button>(Resource.Id.CallButton);
-
现在,我们已经获得了控件的引用,可以编写事件来在点击 CALL 按钮时执行操作。让我们为 CALL 按钮的点击编写一个事件:
-
输入
callButton.Click +=(IntelliSense 将为您提供一个建议,按Tab键即可)。 -
按下Tab键以自动完成。
-
这将创建一个名为
CallButton_Click的方法。 -
我们将使用这个新创建的方法来编写按钮点击的代码,代码如下:
-

-
因为我们将
Click事件写在了一个单独的方法中,接下来让我们在类的全局作用域中声明按钮和输入框变量,这样类中的所有方法都可以访问它们的引用。请在类级别声明以下变量:-
EditText phoneNumberInput; -
Button callButton;
-
-
OnCreate()方法现在应该如以下截图所示:

-
- 在
CallButton_Click方法中,我们获取用户在输入框中插入的值:
- 在
var phoneNumber = phoneNumberInput.Text;
-
- 接下来,我们创建一个警告对话框,在实际拨打电话之前请求用户确认。要创建该对话框,请编写以下代码:
var callDialog = new AlertDialog.Builder(this);
-
-
我们需要在此对话框中设置两件事:
- 显示给用户的消息:
-
callDialog.SetMessage("Do you want to call " + phoneNumber + "?");
-
-
- 对话框的 OK 和 Cancel 按钮的事件:
-
callDialog.SetMessage("Do you want to call " + phoneNumber + "?"); callDialog.SetNeutralButton("Call", delegate {
var callIntent = new Intent(Intent.ActionCall);
callIntent.SetData(Android.Net.Uri.Parse("tel:" + phoneNumber));
StartActivity(callIntent);
});
callDialog.SetNegativeButton("Cancel", delegate { });
-
- 进行一些修改,使代码看起来像下面的截图:

- 处理用户交互的代码现在已经完成;让我们从顶部选择模拟器并运行应用程序:

第一次运行项目并在模拟器上部署可能需要一些时间,请耐心等待并让它完成部署。
- 一旦应用程序部署完成,您应该能够在模拟器上看到应用程序正在运行:

正如我们在前面的截图中看到的,用户界面是我们在Main.axml布局文件中创建的。
让我们测试我们编写的处理用户交互的代码。
- 点击 CALL 按钮时不输入任何号码:

我们将看到一个toast,如前面的截图所示,因为我们写了一个条件来检查输入号码字段中的空值或空格。
对于没有输入的情况,我们编写了以下代码来显示一个toast:
var toast = Toast.MakeText(this, "Please provide number", new ToastLength());
toast.Show();
- 让我们在文本输入框中输入一个电话号码,然后按 CALL:

根据我们的代码,应该会弹出一个对话框,显示“是否要拨打 9980020860?”。
- 点击 Cancel 按钮应该仅关闭对话框。现在点击 CALL:

如果一切顺利,应该会拨打前面的号码。但一旦我们点击 CALL 按钮,这并不是发生的事情。
- 会抛出一个
java.Lang.SecurityException异常:

我们遇到这个异常的原因是因为 Android 应用程序需要权限才能执行某些操作和任务。
这些权限应该在 Android 应用程序代码中列出,以便系统在安装前知道应用程序所需的所有权限。
这些权限会在安装时显示给用户;如果用户允许该应用程序执行这些操作,则应用程序才可以执行这些操作。因此,接下来我们需要做的是为 Android 应用程序添加权限。
向 Android Manifest 添加权限
目前我们的应用程序只需要一个权限,那就是拨打电话。要修改或添加应用程序权限,我们需要编辑 Android Manifest。
-
要编辑 Android Manifest 并授予权限,请按照以下步骤操作:
-
打开解决方案资源管理器。
-
双击项目下的属性。
-
这将打开一个用于编辑项目属性的界面。
-
现在,从左侧菜单中点击 Android Manifest 以打开它:
-

- 在“所需权限”部分,向下滚动,找到 CALL_PHONE 权限,并选择该选项:

-
-
按Ctrl + Shift + S保存项目的所有更改。
-
关闭属性窗口。
-
我们已经完成了应用程序权限的添加。
-
现在我们需要构建解决方案,以便生成的安装文件包含我们所做的所有更改。
-
-
重新构建项目;右键单击解决方案 | 重新构建解决方案:

- 如果一切正常,我们应该能够在输出窗口看到重建成功;如果遇到错误,请返回到前面的步骤,比较代码并重新构建:

为 Android 应用添加图标
应用程序权限已设置完毕,准备运行,现在让我们为应用程序添加一个图标:
-
下载一个你喜欢且最适合你的电话应用程序的图标文件。
-
转到解决方案资源管理器,将下载的文件添加到
Resources下的drawable文件夹中。 -
右键单击
drawable| 添加 | 现有项,如下图所示:

- 将打开文件资源管理器窗口。导航到图标文件的位置,选择图标文件,然后点击添加:

- 图标现在应该已经添加到项目的
drawable文件夹中了:

- 右键单击文件并点击重命名,将图标文件重命名为
icon.png:


-
重命名文件后,像之前一样重新构建项目。
-
一旦重建成功完成,我们来为应用程序的 Manifest 文件添加图标。
-
从解决方案资源管理器中双击属性并打开 Android Manifest。
-
从应用程序图标下拉菜单中选择 @drawable/icon:

-
按 Ctrl + Shift + S 来保存所有内容并重建解决方案,以确保一切正常运行。
-
现在,让我们在模拟器中运行该应用。
-
如果我们进入应用抽屉并向下滚动至应用名称,我们可以看到我们刚刚添加的应用图标,现在显示在那里:

-
恭喜你,已经成功为新的 Android 应用添加了图标。
-
现在我们已经在清单文件中添加了权限和图标,是时候测试应用的主要功能——拨打电话了。
测试用户交互
在 Android 模拟器中点击应用并运行它。重复之前测试应用的步骤,最后按下 CALL 按钮拨打电话:

这次,应用已经具有了所需的权限,我们已编写代码来处理 CALL 按钮的交互,并且我们在 MainActivity.cs 中创建了一个 callIntent 来拨打电话。
因此,应该通过点击 CALL 按钮来拨打电话,我们应该看到如下截图所示的屏幕:

太棒了!你刚刚使用 Xamarin 和 C# 在 Visual Studio 中创建了你的第一个 Android 应用。
既然我们已经完成了困难的部分,接下来让我们了解一下我们刚刚开发的 Android 应用的基础知识,看看它是如何结合在一起的。
应用基础知识
在解释 Android 应用基础知识时可以涉及许多主题。但是对于本书的范围,我们将尝试了解我们在开发 PhoneCallApp 时使用的最重要的一些主题:
- Android API:Android 为不同版本的 Android 提供了不同的 API 级别。这些 API 级别基本上说明了我们的代码使用了哪个版本的 Android 库,并且我们的应用与哪些版本的 Android 操作系统兼容。
开发 Android 应用时需要指定不同的配置。这些配置包括:
-
-
目标框架
-
最低 Android 版本
-
目标 Android 版本
-
你将更详细地了解这些配置。
-
资源:资源封装了许多在 Android 中用于构建更好 Android 应用的特性。一个 Android 应用使用许多资源,例如:
-
我们使用的图标
-
用于为用户创建 UI 的布局文件
-
用于存储应用本地化/国际化字符串的字符串文件,等等
-
-
活动:活动是 Android 应用的主要构建模块。每个 UI 元素及其交互都与一个活动关联。每当我们点击一个按钮并打开新页面时,都会调用一个新的活动,控制权也随之转移。
一个 Android 活动可以有不同的状态,取决于当前正在执行的操作。我们将在未来的主题中更详细地学习活动。
Android API
Android API 以 API 级别来标识,例如 API 级别 23。
API 等级代表特定的 Android 版本。如果您在 Visual Studio 中打开 Android SDK 管理器,您将看到如下界面:


每个 API 等级特定于一个 Android 发布版本。一个 Android 版本通常有多个名称:
-
API 等级,例如 API 等级 23
-
Android 版本,例如 Android 6.0
-
代号,例如 Marshmallow
因此,我们可以说 API 具有整数值,用于标识版本发布,因为每次发布时此 API 等级都会发生变化,而用户会在发布新版本时更新他们的 Android 版本。
一个 Android 应用程序应该能够在不同的 API 上运行,并与之前的版本兼容,以便旧设备也能运行应用程序,且当用户将操作系统版本更新到新版本时,现有应用不会在他们的手机上崩溃。
为了支持多个 API 等级,Android 项目属性有配置项来定义:
- 目标框架:此设置可以在属性中的应用菜单下找到。此设置告诉
Xamarin.Android使用特定的 API 等级库来编译项目。在编译/构建应用程序时,Xamarin.Android使用此设置中指定的 API 等级来加载库并构建应用程序:

- 最低 Android 版本/API 等级:这是应用程序能够运行的最低 Android 版本;它告诉 Android 系统该应用程序是否支持特定的操作系统版本。指定较低的最低版本意味着您的应用程序可以安装在介于最低和目标版本之间的所有版本上。但要小心,因为即使应用程序已经编译并安装在较低版本的 Android 上,也不一定意味着它会成功运行。
可能有一些您的应用程序正在使用的高级 API,无法在较旧的版本上运行。此设置可以在属性中的 Android Manifest 下找到:

- 目标 Android 版本/API 等级:这是应用程序开发时所需运行的操作系统版本。Android 使用此配置来检查是否需要在运行应用程序时启用任何兼容性行为。此配置也可以在项目的属性中的 Android Manifest 下找到:

资源
当我们创建一个新的Xamarin.Android应用程序项目时,解决方案资源管理器中会创建一个名为Resources的文件夹:

让我们详细分析一下Resources文件夹的结构。
对于一个 Android 应用程序的结构,除了实际的代码之外,几乎所有内容都是资源。
资源可以是以下任何一种,但不限于以下内容:
-
图片
-
应用程序中使用的任何图片或图标
-
它们位于
drawable文件夹中
-
-
应用视图
-
应用程序的视图文件,也就是我们创建的
Main.axml文件 -
放在
layout文件夹中
-
-
字符串
-
这些是应用程序中使用的文本字符串
-
例如,文本按钮上的 CALL 文本
-
它有助于保持应用程序的一致性
-
放在
values文件夹中
-
我们在应用程序中使用的资源
我们在Resources文件夹中使用的主要文件如下:
-
Icon.png:我们下载并添加的应用程序图标。 -
Main.axml:我们应用程序的默认用户界面布局文件。我们只在设计器中编辑了这个文件,但你也可以打开该文件的 XML 视图,尝试理解 UI 元素使用的 XML 标签。 -
Resource.designer.cs:这个文件是由Xamarin.Android自动生成和维护的,包含分配给每个资源的唯一 ID。它是由Xamarin.Android工具自动创建的,并且会不定期重新生成。
这就是为什么我们要访问某些资源时,在 C#代码中使用以下代码的原因:
phoneNumberInput = FindViewById<EditText>(Resource.Id.PhoneNumber);
请注意Resource.Id.PhoneNumber;这个信息基本上存储在Resource.designer.cs文件中,所有分配给资源的唯一 ID 都存储在这里。
理解活动(Activities)
活动(Activities)是 Android 应用开发中特有的概念。通常,在其他应用程序中,我们有一个入口点或一个主方法作为应用程序启动的入口。
但是在 Android 中,同样的目的由活动(Activities)来实现。Android 应用程序可以从任何指定为启动活动的活动开始,使用MainLauncher:

活动类
Activity类包含控制用户界面的代码。Activity类基本上负责创建 UI 并处理用户交互,例如按钮点击或触摸。
现在,让我们以我们的PhoneCallApp应用程序为例。我们在项目中只有一个Activity,那就是MainActivity.cs类。它是操作系统进入此应用程序的主要入口点,因为我们已经将其设置为MainLauncher:

如果我们仔细看,MainActivity类继承了Activity类,也就是说它是Activity类的子类。那意味着现在MainActivity也是一个Activity。
此外,值得注意的是,在MainActivity类上方定义了一个Activity属性,它指定了Label和MainLauncher属性。这个属性告诉 Android,MainActivity类是应用程序的一部分,并且由其 Manifest 进行管理。
通过继承Activity类,MainActivity可以访问Activity类中的方法,这些方法为开发者提供了在MainActivity不同状态下执行特定操作的能力,例如:
-
当一个活动被创建时
-
当一个活动被暂停时
-
当一个活动恢复时
在开发应用程序并编写Activity的代码时,如前所述,Activity类提供了一些方法,我们可以根据Activity的不同状态使用这些方法来执行操作。
Activity类中的方法
OnCreate():当用户点击应用图标启动应用程序时,调用此方法。此方法用于执行一些可能需要的初始设置,例如创建视图、初始化变量等:

让我们看看我们的应用程序代码,在这里我们使用OnCreate()方法进行了一些初始化和设置:

我们在OnCreate()方法中所做的事情包括:
-
-
设置视图的布局
-
初始化变量以获取对
TextInput和CallButton的引用 -
将
Click事件绑定到CallButton
-
-
OnStart():系统会在OnCreate()方法之后立即调用此方法。 -
OnResume():当应用程序重新启动并准备与用户交互时,系统会调用此方法。OnResume()很重要,因为在OnPause()中执行的任何操作应该在OnResume()中撤销,因为它是唯一一个在OnPause()之后执行并将Activity恢复到前台的生命周期方法。 -
OnPause():当系统即将将Activity放入后台时,会调用此方法。它也是一个重要的方法,因为Activity应该执行某些任务,例如:-
保存未保存的更改
-
释放资源,例如相机或其他资源
-

-
OnStop():当Activity不再对用户可见时,会调用此方法。发生以下情况之一时,会调用该方法:-
按下返回按钮
-
打开并将现有的
Activity带到前台 -
启动一个新的
Activity,并覆盖当前的Activity
-

-
OnRestart():如果一个Activity被停止然后再次启动,系统会调用此方法。 -
OnDestroy():这是在Activity被销毁并完全从内存中移除之前调用的最终方法。它用于清理可能导致内存误用的资源。
为了更好地理解不同的Activity状态,让我们深入了解Activity生命周期。
Activity生命周期
Activity生命周期通常通过Activity类中的一系列方法来定义,这些方法为我们提供了控制Activity状态的方式。这使得开发人员能够在 Android 应用程序中处理Activity。
让我们来看看Activity的不同状态:

这些状态可以分为以下四个主要组:
-
运行:如果某个活动位于前台,即位于活动堆栈的顶部,我们称其为活跃或运行活动。这被认为是 Android 中优先级最高的活动,只有在极端情况下,如活动尝试使用超过设备可用内存的情况下,操作系统才会将其终止,因为这可能导致应用程序界面变得无响应。
-
暂停:当一个部分活动位于当前运行活动之上时,它被视为暂停。暂停的活动仍然处于活动状态,即它们保持所有状态和成员信息,并保持在活动堆栈中。这被认为是 Android 中第二高优先级的活动,只有当终止该活动能满足保持活跃/运行活动稳定和响应所需的资源时,操作系统才会将其终止。
-
停止/后台:如果一个活动完全停止或被另一个活动接管,则该活动被视为停止或处于后台。停止的活动仍尽可能保留其状态和成员信息,但停止的活动在这三种状态中优先级最低。
-
重启/恢复:如果用户从另一个活动中返回到当前活动,或者通过点击应用切换器图标返回,它必须在暂停时恢复,或在停止时恢复到先前保存的状态,然后显示给用户。
这些类别是活动生命周期中不同状态的基本解释。
在移动设备上部署应用程序
到目前为止,我们已经在 Android 虚拟设备(Android 模拟器)上测试了我们的应用程序。但最好还是在物理设备上测试应用程序。因此,让我们学习如何设置一个真实的 Android 设备来进行应用程序测试。
本主题中显示的截图是在运行 Lollipop 版本的 Android 设备上拍摄的;您的设备设置可能会根据设备版本的不同而有所不同。
以下是设置设备进行调试的步骤:
-
启用设备调试:我们需要在设备上启用调试。默认情况下,无法在 Android 设备上调试应用程序。
-
安装 USB 驱动程序:在我们的 Windows 计算机上,我们需要为设备安装 USB 驱动程序。
-
连接设备到计算机:最后一步是通过 USB 数据线将设备连接到计算机。
启用设备调试
要在设备上启用调试,我们需要执行以下步骤:
- 点击通知栏中的设置图标:

-
打开设置。
-
向下滚动到底部并点击“关于手机”:

-
向下滚动至“版本号”。
-
连续点击“版本号”七次,直到看到“您现在是开发者!”:

-
返回设置菜单,向下滚动到最底部:
-
你现在应该能够看到“开发者选项”菜单条目,位于“关于手机”之前:
-
点击开发者选项:

- 查找启用 USB 调试的选项并启用它:

安装 USB 驱动程序
对于不同的设备,可能需要安装不同的驱动程序才能使计算机识别设备。请确保所有设备驱动程序已正确安装,并且计算机可以正确识别你的设备。
如果你正在下载设备驱动程序并希望手动安装到计算机上,请按照以下步骤在 Windows 7 上执行:
-
使用 USB 数据线将设备连接到计算机。
-
右键点击桌面或 Windows 资源管理器中的计算机并选择“管理”。
-
在左侧窗格中选择设备。
-
在右侧窗格中定位并展开其他设备。
-
右键点击设备名称并选择更新驱动程序软件。
-
这将启动硬件更新向导。
-
选择“浏览我的计算机以查找驱动程序软件”并点击“下一步”。
-
点击浏览,定位到 USB 驱动程序文件夹。
-
点击“下一步”以安装驱动程序。
将设备连接到计算机
如果你通过 USB 数据线将设备连接到计算机,Android 调试桥(adb)应该能够与设备通信,并且你应该在设备上看到“USB 调试已连接”的通知,如下图所示:

现在,你可以打开 Visual Studio,选择设备列表中的设备,并运行应用程序。这将把应用程序安装到你的设备并运行。
推送代码到 Git 仓库
应用开发完成。让我们将代码保存到 Git 仓库中,这样我们就可以从任何地方访问代码:
- 在 Visual Studio 中,点击右下角的“添加到源代码控制”并选择 Git:

- 点击连接 | 设置:

- 点击全局设置:

-
输入你的 GitHub 账户用户名和电子邮件,并点击更新:
-
点击 Team Explorer 底部的上箭头图标(推送图标)。
-
然后,点击“发布 Git 仓库”以推送到远程仓库。
-
请注意,它说本地仓库没有配置远程仓库。这是因为我们还没有将远程 GitHub 仓库连接到本地项目:

登录你的 GitHub 账户并为你的项目创建一个空的 Git 仓库,正如我们在第二章《与代码仓库系统的工作》中所学,并将该 URL 复制到以下截图中的文本框:

- 点击发布后,将打开一个新窗口,要求输入你的 GitHub 凭证:

-
输入你的 GitHub 凭据进行认证,然后点击登录:
-
登录成功后,代码将被推送到远程 Git 仓库,你应该会看到如下成功信息:

恭喜,你的代码已经成功推送到远程仓库,可以通过登录 GitHub 并访问仓库 URL 来查看。
总结
在本章中,我们学习了如何使用 Xamarin 和 Visual Studio 开发 Android 应用程序。我们还了解了一些 Android 应用的基本概念、Activity 及其生命周期。我们在模拟器上运行了应用程序,并设置了一个实际的物理设备来运行应用;最后,我们将代码推送到了 Git 仓库。
在下一章,我们将学习如何使用 Xamarin Test Cloud 实现持续测试。
第五章:使用 Xamarin 实现自动化测试
在今天这个快速发展的世界里,应用程序需要尽可能快地交付,开发生命周期必须缩短以达到这一快速交付的目标。测试是软件开发中最重要的方面之一。
对于移动应用程序来说,它们需要在所有可能支持的设备上进行测试,以确保它们在所有目标设备上平稳运行。
让我们来看看本章中我们将要学习的内容:
-
自动化测试在 DevOps 循环中的重要性
-
使用 Xamarin.UITest 编写自动化 UI 测试
-
使用 Xamarin Test Cloud 在多个物理设备上测试应用程序
理解自动化测试在 DevOps 循环中的重要性
测试是应用程序开发中的一个重要因素。开发人员尽力开发一个平稳运行的复杂应用程序,但总会有一些开发人员无法预见的场景,因为只有在以最终用户的心态使用应用程序时,才可以进行测试。
尽管开发人员正在努力开发应用程序,但对应用程序进行以用户为中心的测试,并测试开发人员未曾想到的内容,至关重要。
测试人员的职责是确保应用程序按预期运行,并且一个功能不会影响应用程序中的其他功能。
虽然有人工测试员测试应用程序是件好事,而且确实能确保应用程序像真实世界中的最终用户一样被测试和使用,但仅依赖人工测试员测试应用程序并不是最好的选择。
测试移动应用程序
对于 Web 应用程序或桌面应用程序,测试的操作系统版本和设备数量非常少。
让人工测试员测试应用程序,找出应用程序中的不足和缺陷,并通知开发人员,通常是更简单的。
但是当涉及到移动应用程序时,情况完全不同。
如果我们只谈论一个 Android 应用程序,例如,来看看在测试中面临的挑战数量。
测试移动应用程序的挑战
在测试移动应用程序时面临许多挑战:
-
在真实环境中进行测试
-
经常部署和测试
-
持续反馈
在真实环境中进行测试
对于移动开发者来说,最重要的事情是确保最终的应用程序在所有目标设备上都能正常工作。在开发的最早阶段,使用模拟器或仿真器是可以的,但当应用程序变得更加复杂并且即将发布到市场时,唯一可接受的方式是通过真实设备测试移动应用程序:

经常部署和测试
移动应用程序几乎每周都会更新,或者至少每月更新两次。因此,它们需要更频繁地进行测试。
移动应用程序应该在每个夜间构建时进行测试,这样可以更早地发现缺陷并更快地修复它们。频繁而高效地测试相同的功能可能不是最佳解决方案,并且可能会拖慢交付过程。如果我们对重复任务有自动化处理,那将为我们节省大量时间,加速市场推广。持续开发和测试使得公司能够更快地向市场交付产品。
持续反馈
持续反馈与频繁部署和测试应用程序相辅相成。正如我们所学,手动完成重复任务的过程占用了大量时间,而这些时间本应节省下来以便更快地交付到市场。同样,来自测试和生产环境的持续反馈对于应用程序的质量至关重要:

为了克服移动应用测试中的所有挑战,我们需要采纳 DevOps 思维方式,将测试作为开发周期中自动化和集成的一部分,并使其在每次构建时自动执行(并向开发者反馈,以便他们在开发的早期阶段采取行动)。
使用 Xamarin.UITest 编写测试
在开始使用 Xamarin.UITest 编写 UI 测试之前,了解一下单元测试是什么,以及 Xamarin.UITest 将如何帮助我们实现移动应用程序自动化测试的目标,是很有帮助的。
Xamarin.UITest
Xamarin.UITest 是一个基于 C#中流行测试库NUnit的测试框架。如果你以前在 C#项目中使用过 NUnit 进行单元测试,那么理解 Xamarin.UITest 会更加得心应手。但如果你没有 NUnit 的经验,也完全没问题。
它基本上是 C#的一组库(类似于 Java 的 JUnit),用于帮助编写单元测试。
使用 UITest 时,我们将为移动应用编写 UI 测试。
UITest 基础知识
UITest,或者一般来说,任何基于 NUnit 的测试,都有一个明确的结构需要遵循:
-
测试夹具:测试夹具是一个包含测试的类,同时也进行任何测试执行前的初始化设置,或者任何在测试执行完毕后需要完成的任务。
-
测试:UITest 作为一种方法写在测试夹具类中
理解 AAA 模式
Arrange-Act-Assert(AAA)模式应该在编写 UITest 时遵循,以达到最佳效果并从测试中获得快速反馈。顾名思义,它包括三个步骤:
-
安排:顾名思义,这一步包含所有有助于安排测试的操作,例如初始化测试过程中后续所需的事物、设置环境等等。
-
执行:这是测试与应用程序进行期望交互的时刻,例如输入文本、点击按钮等。
-
Assert:Assert 是在我们的 UITest 中检查交互是否产生了预期结果,例如验证是否显示了错误消息。
向解决方案中添加 UITest 项目
让我们回到 Visual Studio,设置一个新的测试项目来编写 Xamarin.UITest:
- 右键点击解决方案 | 添加 | 新建项目:

- 在“添加新项目”窗口中,点击左侧的 Test,然后选择 UI Test App(Xamarin.UITest | Android),因为我们将为我们的 Android 应用程序编写测试。在名称部分给这个项目命名,然后点击 OK:

- Visual Studio 现在会创建一个新的测试项目。完成后,你应该能看到在解决方案下创建了一个新项目:

-
我们通过 Android Test Project 模板创建的这个新测试项目应该也包括运行 Xamarin.UITest 所需的 NuGet 包。这些包包括:
-
NUnit
-
NUnit 测试适配器,用于本地运行 UITests
-
Xamarin.UITest,我们将用来编写测试的框架
-
这些可以作为 NuGet 包的形式提供,但通常会随我们用来创建 UITest 项目的模板一起提供。
- 为确保这些必需的包可用并已安装,右键点击 UITest 项目,然后点击管理 NuGet 包:

- 在下一个屏幕上,你应该能看到列出的包:

-
Visual Studio 建议将 NUnit 包更新到 3.X.X 版本,但不要更新 NUnit,因为 Xamarin.UITest 与 NUnit 3.x 不兼容。撰写时,它与 2.6.x 版本兼容。此外,由于 Test Adapter 的版本与 NUnit 框架的版本相关联,因此最好也不要更新 Test Adapter。
-
接下来,我们需要添加对应用程序项目的引用,以便 UITest 项目可以构建并运行该应用程序。
-
右键点击 UITest 项目下的 References,然后点击添加引用:

- 在下一个屏幕上,选择左侧的 Projects,然后选择 PhoneCallApp(我们要测试的应用程序项目),然后点击 OK:

- 一旦你添加了应用程序项目,你应该能够在解决方案资源管理器中看到添加的引用:

-
由于应用程序项目和 UITest 项目位于同一解决方案下,因此只需像前一步那样添加对应用程序项目的引用即可。但如果你想将两个项目放在不同的解决方案中,或者如果你希望在 Android 6.0 上测试应用程序,那么 Visual Studio 会要求你提供系统中 APK 的路径。
-
要提供此路径,请打开 UITest 项目下的
Tests.cs文件:

- 在
Tests.cs中,取消注释.ApkFile()代码,如下图所示:

- 更改为
.apk文件的路径,您可以在应用程序项目的bin文件夹中找到此路径。如果您无法看到文件,请尝试先部署应用程序,之后它应该会在bin|debug或bin|release中创建,具体取决于您的构建配置。
Tests.cs
这个文件是在我们通过 Xamarin.UI Android Test Project 模板在解决方案中添加 UITest 项目时自动创建的默认文件,我们将在这个文件中编写 UI 测试。这个文件中有一些需要注意的事项:
-
[TextFixture]:这是添加到Tests类中的注解,告诉 UITest 框架此类包含要运行的测试。 -
[Setup]:每个包含测试的类都需要进行初始配置,就像前面部分中的 APK 文件路径一样。这会添加到BeforeEachTest()方法中,并告诉框架在运行测试之前运行此方法并执行初始设置。 -
[Test]:这个注解标识包含测试的方法。

回顾应用程序代码
让我们回顾一下在应用开发过程中写过的一些内容。
PhoneCallApp 中的元素
-
输入电话号码的文本框
-
点击 CALL 按钮拨打电话
-
如果用户在未输入号码的情况下点击 CALL 按钮,显示的文本
-
用户在输入号码后点击 CALL 按钮时会出现的确认对话框
PhoneCallApp 中的用户交互
-
在文本框中输入一个号码
-
点击 CALL 按钮
-
在确认对话框中点击确定或取消
打开 PhoneCallApp 项目中的 MainActivity.cs 文件,您会注意到如果输入的号码字符串为空,我们会显示一个 Toast:

测试中要包含的步骤
为了编写高效的测试,应该遵循一些步骤,基于前面讨论的 AAA 模式:
- 配置并启动应用程序(Arrange):我们不需要编写这一步,因为这部分已经在
BeforeEachTest()方法中处理了:

-
与屏幕上的某个元素进行交互(操作):我们需要编写代码来输入文本或点击 CALL 按钮
-
验证预期输出(Assert):我们需要编写代码来验证交互是否给出预期的输出
如我们所见,测试的第一步已经完成,现在我们需要编写下一步,包括与 CALL 按钮进行交互,然后验证预期的输出。
编写您的第一个 UITest
现在是时候在 Tests.cs 文件中编写我们的新 UITest,位于 UITest 项目下,用于测试前面描述的测试用例:
- 在
Tests.cs类下编写一个新方法,并加上注释[Test],如前所述:

- 编写代码,在应用加载后截取屏幕截图:

- 然后,按照 第 2 步 提到的,进行交互,即编写代码点击 CALL 按钮:

在前面的代码中,我们使用了 AndroidApp.Tap() 方法来执行点击操作,并使用 AppQuery.Id() 方法来识别 CALL 按钮,然后将该 app 查询传递给 Tap 按钮,以便它知道点击的位置。
- 再次,我们来截取按下按钮的屏幕截图:

- 下一步是验证行为是否符合预期。在 PhoneCallApp 中,验证是否出现了显示
Please provide number的 toast:

在前面的代码中,我们使用了 AndroidApp.Query() 方法查询 UI 屏幕上的元素,并传递了 AppQuery.Marked() 方法,带有我们要识别的 toast 内容。
Marked() 方法类似于 Id() 方法,但它会搜索一个元素,其 ID 或内容包含给定的字符串,在我们的案例中,它是 toast 的内容。
- 现在,我们需要验证是否找到了包含提供字符串
Please provide number的 toast;Assert.IsTrue()方法将通过检查结果数组来验证该元素已被找到:

在本地机器上运行测试
现在我们已经完成了在 Tests.cs 类文件中编写 UITest,是时候在本地机器上运行测试了:
- 使用设备或模拟器的构建配置重新构建解决方案:

- 在我们运行测试之前,让我们先部署解决方案以生成
.apk文件:

- 一旦部署成功,请点击 Test | Windows | Test Explorer,如下图所示:

- 在 Test Explorer 中,NUnit 应该能够识别我们在
Tests.cs文件中编写的测试,因为我们使用了[Test]特性:

- 如前述截图所示,在 Test Explorer 中点击 "Run All" 按钮运行所有测试。如果一切顺利,您应该在 Test Explorer 中看到 "Passed Tests" 的信息:

- 很棒,您已经成功编写并在本地机器上运行了测试。接下来,我们将学习 Xamarin Test Cloud 以及如何使用它在多个物理设备上运行我们的 UI 测试。
使用 Xamarin Test Cloud 在多个设备上进行测试
移动应用的用户对应用的质量和性能要求非常高。像应用商店这样的平台,用户可以随时给予反馈,这使得认真对待移动应用质量变得更加重要:
-
问题:我们如何有效地测试移动应用程序?
-
答案:通过在真实设备上运行应用程序,并像用户一样使用它
移动应用测试中的挑战
移动应用测试涉及许多 Web 应用程序不具备的挑战。
不同的移动操作系统版本
以 Android 为例。自从 Android 开始以来,它的发展速度非常快,每年都有一个新的重大版本发布。这使得市场上大约有 15 个主要版本,其中至少有 6 个版本在全球不同地区广泛使用,具体取决于区域和智能手机的可用性。
这些只是我们提到的主要版本,次要版本多得数不胜数。
考虑到这种情况,质量保证团队几乎不可能测试所有目标设备上的应用程序,并保证其正常运行。
不同屏幕尺寸的设备
我们都知道,设备数量每天都在增加,但旧设备仍在继续使用,屏幕尺寸从 4.0 英寸到 6.5 英寸不等(有些甚至更大)。
移动应用程序在不同的屏幕尺寸和分辨率下可能表现不同。如果开发不当,可能会导致应用程序在开发设备和真实用户使用的设备上的外观发生剧烈变化。
因此,在多个设备上进行测试,尤其是考虑到不同的屏幕尺寸,成为了移动应用测试中一个非常重要的方面。某种程度上,可以通过获取所有可能的设备尺寸来进行测试,但这会极大地增加成本,并且非常耗时。
以成本效益和质量为前提解决此类挑战,唯一的方式就是使用云测试平台,这些平台使我们能够同时在多个设备上运行测试。所有这些云平台上的设备都是物理设备,而非模拟器,它们还提供即时反馈,并支持包括 NUnit 在内的多种测试框架。
Xamarin 测试云简介
Xamarin 测试云是一个基于云的平台,提供支持在各种不同设备上进行自动化测试的工具,也被称为UI 接受测试。这使我们能够确保应用程序在多个设备上正确高效地运行,且投入的精力最小。
它还有助于将测试人员的焦点从在多个设备上重复相同的测试,转移到专注于验证应用程序在测试云上按预期工作。
Xamarin 测试云家族包括以下几个部分:
Xamarin.UITest
这是一个基于非常流行的 NUnit 测试库的测试框架。如果你之前在 C# 项目中使用过 NUnit 进行单元测试,那么了解 Xamarin.UITest 将会更加轻松。但如果你没有使用过 NUnit 也完全没有问题。
Xamarin.UITest 本质上是一组用于 C# 的库(类似于 Java 的 JUnit),帮助编写单元测试。
Xamarin 还支持 Calabash 框架来编写测试,如果您想使用 Ruby 和 Cucumber 编写测试。
我们将专注于 Xamarin.UITest,用 C# 编写测试以进行持续测试。
Test Cloud
这是一个基于云的平台,由成千上万的物理设备组成。用户可以将使用 Xamarin.UITest 编写的应用程序和测试上传到 Test Cloud;然后,它会在可用的或选择的设备上安装应用程序,并在其上运行给定的测试。测试完成后,结果将提供给用户,以便分析和验证应用程序的行为。
Xamarin Test Recorder
这是 Test Cloud 生态系统中的另一个应用程序,帮助编写 Xamarin.UITest。
它基本上允许您将设备连接上,手动在设备上运行测试,然后通过记录您在应用程序中的操作来为您编写所有测试代码。
我们不会涉及 Test Recorder,而是将学习如何使用 Xamarin 编写 UI 测试。
将 Xamarin Test Cloud 作为持续集成的一部分使用
Xamarin Test Cloud 帮助我们实现持续集成,在每个构建上执行自动化测试,在像 TeamCity 这样的构建服务器上进行测试,执行测试后,直接向开发人员提供反馈:

在 Test Cloud 上创建用户和组织
让我们从在 Xamarin Test Cloud 上创建帐户开始:
- 访问
testcloud.xamarin.com/register注册新帐户:

输入您的详细信息,然后点击继续按钮以开始流程。该过程需要使用公司邮箱进行注册;Gmail 或 Yahoo 邮箱无法使用。
- 在下一个屏幕上,输入您组织的详细信息,然后点击开始使用:

- 在下一步中,接受条款和条件以完成注册:

- 完成注册后,请确保在开始测试之前验证您的电子邮件地址。
用户和组织
Xamarin Test Cloud 作为一个持续测试的云平台,支持组织结构,通过使用访问密钥提供访问权限、创建 API 和运行测试。
这样可以更轻松地将组织中的团队应用程序进行隔离。
Test Cloud 层次结构
Test Cloud 的层次结构非常简单且易于理解:
-
组织:组织基本上是管理 Test Cloud 订阅的最高层级,当一个组织中的人员首次在 Xamarin Test Cloud 上创建帐户时,就会创建该组织。
-
管理员:每个组织将至少有一名管理员,管理员可以创建团队并管理用户。
-
团队:一个团队通常至少有一个应用和一些在该应用上工作的用户。每个团队会获得自己的 API 密钥,以访问并运行应用上的测试:

创建一个团队
在 Xamarin 测试云中创建团队,按照以下步骤操作:
- 点击你的个人资料,然后点击“帐户设置”:

- 点击“团队与应用”:

- 然后,点击“新建团队”按钮来添加新团队:

- 要编辑团队详情,比如团队名称,或添加新成员,点击如下截图中的设置(齿轮)图标:

- 在向团队添加新成员后,你可以管理用户的权限:

- 一旦团队详情、成员和权限都设置完成,点击“完成”。
为你的应用创建测试运行
现在我们已经向团队添加了成员,是时候为团队添加我们的应用测试运行了。要为 PhoneCallApp 创建测试运行,请按照以下步骤操作:
- 在 Xamarin 测试云中,点击“新建测试运行”:

-
这将打开一个自我引导的对话框,我们可以在其中选择平台并选择设备。
-
在对话框的第一步中,选择“我正在测试一个 Android 应用”,然后点击“下一步”:

- 选择适当的设备来运行应用,并进入下一步:

- 选择一个合适的测试系列,或者你可以创建一个新的,选择语言后点击“下一步”:

- 在下一屏幕选择 UITest 并点击“在 Windows 上运行”:

-
该页面根据我们在前面步骤中选择的设备,提供了带设备 ID 的命令。如页面所述,请更新目录路径至
.apk测试程序集的bin文件夹,然后在应用的root文件夹中运行该命令。 -
在将应用上传到 Xamarin 测试云之前,确保你已经在 Release 配置中构建了应用。
-
一旦你用 Release 构建了项目,就可以将应用上传到 Xamarin 并在那运行 UI 测试。使用命令并修改 Xamarin.UITest.xxx 版本和 APK 文件名,带上
apk的完整路径和UITest文件夹的相对路径,如下截图所示。然后从项目的root目录运行它:

-
恭喜,你已经成功将你的第一个应用上传到 Xamarin 测试云并进行了测试!上传应用后,Xamarin 测试云应当会运行提供的测试。
-
访问 Xamarin Test Cloud 的网页界面,你会注意到应用现在出现在仪表板上:

- 点击应用查看在步骤 4 中选择的设备上运行的测试:

你可以进一步点击测试链接,查看有关测试的更多详细信息和状态。
- 这标志着你在 Xamarin Test Cloud 上运行第一个测试的完成,你可以在云中对多个物理设备上的应用进行测试。
总结
在本章中,我们学习了持续测试在应用开发周期中的重要性。我们还了解了 Xamarin.UITest,如何编写自动化 UI 测试以进行应用的验收测试,同时熟悉了 Xamarin Test Cloud,它对于在多个物理设备上进行持续测试非常有用。
在接下来的章节中,你将学习如何使用各种工具进行持续集成和持续交付。
第六章:配置 TeamCity 进行 CI/CD 与 Xamarin
在过去,应用程序开发通常是在分离的、不太集成的团队中进行的。开发人员不习惯将自己的代码与其他开发人员的代码合并,并且这种情况往往会导致合并问题。开发人员本地副本上正常工作的内容在与其他人代码合并时常常会停止工作。这种不太集成的开发环境增加了开发时间,并延迟了问题的发现。解决这一问题的一种方法是将持续集成纳入开发周期,开发人员每天多次合并代码,并在更早阶段解决问题。
在本章中,我们将深入了解持续集成、持续交付,以及我们可以用来改善开发集成和交付流程的各种工具。
在本章中,我们将讨论以下主题:
-
持续集成简介
-
持续集成的各种工具
-
使用 TeamCity 与 Xamarin
-
为 TeamCity 准备构建服务器并安装 TeamCity
-
创建构建脚本
-
创建 TeamCity 项目
持续集成简介
持续集成(CI)是一种开发和集成实践,开发人员频繁地将代码提交到共享代码库中,最好是一天提交几次。每次代码合并后,可以通过自动构建和自动化测试(如果适用)进行验证。
遵循持续集成有许多好处,其中一个优势是帮助快速发现缺陷并尽早解决。提交的代码通常非常小,包含的是小规模的开发,因此能够迅速定位具体问题。
持续交付(CD)是集成后的一个过程,顾名思义,它确保已提交的代码库在任何时候都可以进行部署。从测试环境到生产环境的每个环境可能有不同的配置。持续交付确保所有配置始终准备好进行部署,并且代码通过发布所需的所有测试。
简而言之,持续集成通过频繁的代码合并改善了开发和测试体验,帮助快速发现错误,并在流程中包含自动化测试时运行自动化测试。持续交付确保代码库始终处于可随时部署的状态,适用于任何环境。
Web 应用程序的 CI/CD

对于 Web 应用程序,一旦从 CI 服务器准备好构建,测试应用程序在不同浏览器上的表现并不是一项艰巨的任务,因为浏览器数量有限。但对于移动应用程序,需要更多的一步来改善体验,因为市面上有成千上万的设备,且操作系统版本各异。
移动应用程序的 CI/CD

如前所示,移动应用程序需要在数百台具有不同操作系统的设备上进行测试,而购买这些不断推出的移动设备可能非常昂贵。为了确保应用程序的质量保持高水平,采用基于云的测试解决方案成为了流程中的一个重要组成部分。
选择持续集成工具
市场上有许多 CI 工具可供实施持续集成,就像市场上有许多编程语言可以用于开发应用程序一样,但选择合适的 CI 工具对于确保长期利益至关重要。
为你的项目选择 CI 工具可能取决于许多因素:
-
编程语言支持:这是选择 CI 工具时最重要的因素之一。一些 CI 工具有更好的语言特定构建和包的支持,而其他工具可能不提供语言特定的打包选项。
-
操作系统:操作系统的支持很重要,因为一些团队可能会觉得开源操作系统(如 Linux)对于所有服务器(包括 CI 服务器)来说是更好的选择,而且他们可能会觉得配置一个熟悉的操作系统更为舒适,而其他从事 .NET 应用程序开发的团队可能会觉得 Windows 在配置上更为舒适且功能丰富。这一切归根结底是不同团队的偏好和他们所开发的应用程序类型决定的。
-
与代码库的集成:不同的团队由于各种原因偏好不同的代码库。有些团队可能觉得 Git 更为功能丰富,并且在各种 IDE 中有插件支持,而另一些对微软环境更为熟悉的团队则觉得 Team Services 更易于使用且集成性更好。不同的 CI 工具对这些代码库的支持程度也不同。
-
应用平台部署支持:有些 CI 服务器更适合 Web 应用程序的部署,而其他一些则提供更多的功能并更好地支持将移动应用程序部署到应用商店。根据你的应用程序类型,选择可能会有所不同。
-
成本:成本始终是选择任何类型工具时的重要因素。中型到大型公司可以负担得起昂贵且功能丰富的 CI 工具,而较小的公司和团队可能会选择低预算,有时是开源并且免费的 CI 工具,并根据需要对其进行定制。
各种持续集成工具
让我们来看看一些市场上广泛使用的 CI 工具。
TeamCity
TeamCity 是由 JetBrains 开发的著名 CI 服务器。JetBrains 在为软件开发生命周期的不同阶段开发各种工具方面颇有名气,例如 WebStorm 和 ReSharper。TeamCity 提供有许可证的版本和一个免费版本,免费版具有有限的配置和构建代理数量。免费版本适用于计划随着时间增长的小型团队。
尽管 TeamCity 是一个基于 Java 的解决方案,但它在此列表中的工具中提供了最佳的 .NET 支持。它还有不同的企业套餐,根据所需的代理数量进行扩展。
您将在本章稍后学习更多关于 TeamCity 的内容。
其主要特点如下:
-
广泛支持基于 .NET 的应用程序和 Visual Studio
-
远程运行,可以用来测试变更是否会导致失败,而无需进行实际的提交
-
支持自动和手动触发构建,您可以为每次提交配置自动构建触发器
Jenkins
Jenkins 是最受欢迎的开源持续集成项目之一。通过数千个插件可供选择,Jenkins 可以帮助团队自动化本来会对软件团队造成时间压力的任务。常见用途包括构建项目、运行测试、错误检测、代码分析和项目部署。
其主要特点如下:
-
Jenkins 通过运行命令
java -jar jenkins.war并部署,安装过程非常简单—没有其他复杂步骤 -
Jenkins 配备了用户友好的 web 界面,您可以完全通过它来配置 Jenkins
-
Jenkins 拥有庞大的插件库,并与大多数构建工具集成
-
通过创建插件和扩展功能,Jenkins 可以非常简单地根据项目需求进行定制
-
Jenkins 支持在不同的服务器上进行分布式构建,甚至支持不同操作系统
Visual Studio Team Services
Microsoft 提供的 Visual Studio Team Services 帮助团队更好地规划、共同编写代码并加速发布。您可以在任何 IDE 或语言中进行编码,针对任何目标平台。各种工具和插件可以下载并根据项目需求进行定制。
其主要特点如下:
-
支持多种工具,包括 Visual Studio、Eclipse 或任何其他可用的工具
-
提供无限制的免费私有仓库(包括 Git 仓库)
-
提供适用于敏捷和看板项目的计划板和工具
-
自动在云中编译和测试应用程序,以避免构建失败
Bamboo
Bamboo 是全球软件团队使用的 CI 服务器,用于自动化应用程序和一般软件的发布管理过程。它允许团队建立一个简化的构建交付管道。移动开发者可以自动将他们的应用程序部署到 Apple Store 或 Google Play。作为一个 Atlassian 工具,它原生支持 Jira 和 BitBucket,您甚至可以轻松地将 Jenkins 配置导入到 Bamboo 中。
其主要特点如下:
-
与 Jenkins 不同,Bamboo 内置了 Git 分支工作流。
-
由于它是由 Atlassian 构建的,因此它内置了对 Jira 和 BitBucket 的集成。
-
Bamboo 还支持自动合并,以避免工作分支和主分支之间的冲突和差异。
-
Bamboo 中的测试自动化产生了从构建、测试,甚至到将应用程序发布给客户的持续流程。
-
内置对 Jira 的支持使得在特定发布版本中,甚至是在构建过程中,bug 跟踪实现了自动化且易于追踪。
使用 TeamCity 与 Xamarin 进行 CI/CD
如上一节所述,TeamCity 对基于 .NET 的应用程序提供了很好的支持。
虽然它可以自动从配置文件和项目文件中检测构建步骤,但它也能从 GitHub 中检测自动构建触发器。
使用 TeamCity 的要求
要使用 TeamCity,需要具备一定的硬件和技术知识,并且能够访问这些硬件和技术,以便使设置过程更加顺利:
-
为 TeamCity 安装和设置专用的构建服务器:理想情况下,构建服务器应该是独立的服务器,不应承担其他职责,如作为数据库服务器或托管服务器。
-
MSBuild 知识:掌握 MSBuild 知识可以使这个设置更加顺利,并帮助在需要时解决任何与编译相关的问题。
-
Xamarin Test Cloud 连续测试的知识:本章将使用 Xamarin Test Cloud 进行构建和应用程序包准备完毕后的连续测试。你应该已经很熟悉它,因为在上一章中已经详细描述过了。
TeamCity 设置的步骤
设置 TeamCity 时涉及以下步骤:
-
准备构建服务器:为了在构建服务器上构建我们的移动应用程序,需要在构建服务器上安装一些软件,这些软件将在构建应用程序时使用。
-
创建构建脚本:构建脚本基本上是一个包含一组命令的脚本,用于在构建过程中执行各种操作,如编译应用程序、构建 APK,然后将其提交到云端进行测试,以及更多其他操作。
-
安装 TeamCity:一旦我们在 CI 服务器上安装了所需的工具,就需要安装和配置 TeamCity,以便项目和用户能够运行构建脚本。
-
创建 TeamCity 项目:一旦我们拥有了构建项目所需的所有软件和执行构建的脚本,就应该创建一个 TeamCity 项目。
准备构建服务器
为了在服务器上编译和构建移动应用,需要安装一些软件,因为它们是构建过程的必要条件。为了在构建服务器上构建 Android 应用,必须安装 Visual Studio SDK 和 Visual Studio 构建工具等工具。同时,获取 Android Keystore 是为了签名即将发布的应用包。为了避免任何配置问题,建议将这些软件安装在与 TeamCity 相同的用户账户下。
防火墙配置
对于持续测试,我们使用 Xamarin Test Cloud,这在前一章节中已详细描述。为了让测试自动提交到 Xamarin Test Cloud 作为 CI 的一部分,CI 服务器必须配置允许网络流量进出 testcloud.xamarin.com 的端口 80 和 443。
完成这些配置并将防火墙配置为允许服务器与 Xamarin Test Cloud 之间的通信后,我们就能够在构建步骤中使用命令行工具将我们的 UITests 提交到 Xamarin Test Cloud。
安装带有 Xamarin 的 Visual Studio
要安装带有 Xamarin 的 Visual Studio,您可以按照 第三章中描述的相同步骤进行操作,使用 Xamarin 进行跨平台移动应用开发。
按照这些步骤将安装 Visual Studio 和 Xamarin,并附带所需的工具和 SDK。
Android Keystore
Android Keystore 用于在分发应用时对应用进行签名。在打包应用之前需要进行此操作,以确保我们的最终包是用它签名的。
创建自己的 Keystore
第一步是创建您自己的个人 Keystore,它将包含用于数字签名 Android 包文件的信息。您可以使用以下命令来完成此操作:
"C:Program Files (x86)Javajre1.8.0_45binkeytool.exe" -genkey -v -keystore youFileName.keystore" -alias your_alias_for_keystore -keyalg RSA -keysize 2048 -validity 30000
命令末尾的 30000 表示证书的有效期;Google 要求此值大于 2033。
在运行此命令之前,请先记下几个参数。运行命令时,它会要求您输入以下参数。这些参数稍后将在项目文件中再次使用:
Password - <yourpassword>
Name - <yourname>
OU - <organisationunit> eg: JamSoft
Orgname - <organisationame>
Local - <locality>
State - <state>
Country - <2lettercountrycode>
运行命令后应生成一个 .keystore 文件,文件名由命令提供。现在我们的构建服务器已准备就绪,接下来让我们准备在构建过程中使用的构建脚本。
创建构建脚本
构建脚本应包含以下步骤:
-
编译应用:配置应用项目文件以使用正确的 Keystore,并使用 Visual Studio SDK 工具编译应用
-
将应用提交到 Xamarin Test Cloud:一旦服务器的防火墙配置为允许与 Test Cloud 服务器通信,如前面的步骤所述,构建脚本中的这一步将运行命令,上传已签名的应用包到 Test Cloud 服务器。
编译应用
现在我们的 Android Keystore 准备好了,可以开始使用,我们可以查看 Visual Studio 项目。为了在构建系统中自动化这一过程,我们需要配置项目以使用我们的 Keystore 凭据:
- 在 Visual Studio 中,编辑 Android 应用的
.csproj文件,并添加另一个PropertyGroup元素,如以下代码所示:
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<AndroidKeyStore>True</AndroidKeyStore> <AndroidSigningKeyStore>myandroid.keystore</AndroidSigningKeyStore>
<AndroidSigningStorePass>yourpassword</AndroidSigningStorePass> <AndroidSigningKeyAlias>myaliasdroidpub</AndroidSigningKeyAlias>
<AndroidSigningKeyPass>yourpassword</AndroidSigningKeyPass>
</PropertyGroup>
- 现在,我们的
.csproj文件知道如何在无人干预的情况下使用我们的 Keystore。我们可以在自动化构建中将其与 Xamarin 构建过程集成,并生成基础的 Android 包。你可以使用以下命令来测试它是否正常工作:
msbuild.exe PhoneCallApp.csproj /p:Configuration=Release /t:Rebuild
此命令使用 MSBuild 按照给定的配置构建应用程序;在我们的案例中,它应该是发布版本。
- 现在我们有了应用程序包,可以应用签名过程。要签名在前一步中创建的包,我们需要执行以下命令:
"C:\Program Files (x86)\Java\jdk1.7.0_71\binjarsigner.exe" -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore youFileName.keystore -storepass yourpassword -keypass yourpassword -signedjar \bin\Release\packagename-signed.apk \bin\Release\packagename.apk your_alias_for_keystore
该包现在已使用我们之前制作的 Keystore 中的证书进行数字签名。
- 现在我们有了签名的包,我们可以使用 zipalign 对该包进行对齐,然后将其作为 TeamCity 构建过程的构件发布。此命令使用了 Android SDK 的
zipalign.exe程序。你需要找到该程序在你机器上的位置,因为它可能在多个位置。你需要的命令看起来可能是这样的:
"C:\Users\<name>\AppData\Local\Android\android-sdk\build-tools <version>\zipalign.exe" -f -v 4 packagename-signed.apk packagename-zipaligned.apk
-
现在是时候将我们的测试和 Android 包上传到 Xamarin Test Cloud 进行 UI 测试了。我们在前一章中创建了 Xamarin.UITest,并假设你已经了解了创建和上传测试到 Xamarin Test Cloud 的过程。
-
因此,将以下命令添加到你的构建过程中,以将测试上传到 Test Cloud:
test-cloud.exe <path-to-apk-or-ipa-file> <test-cloud-team-api-key> --devices <device-selection-id> --assembly-dir <path-to-tests-containing-test-assemblies> --nunit-xml report.xml --user <email>
当测试运行时,测试结果将以 NUnit 样式的 XML 文件 report.xml 形式返回。TeamCity 会在构建日志中显示这些信息。
安装和配置 TeamCity
在 Windows 机器上安装和配置 TeamCity,请按照以下步骤进行:
- 访问
www.jetbrains.com/teamcity/download/#section=windows,点击下载按钮从 TeamCity 网站下载 TeamCity 安装包:

- 下载完成后,打开安装包并点击下一步:

- 在下一个屏幕上,同意许可证并进入下一步:

- 选择要安装 TeamCity 的路径并点击下一步:

- 选择要安装的包;例如,如果你在不同的服务器上安装构建代理和服务器,请根据需要选择。为了学习目的,你可以选择将两者安装在同一台机器上:

- 安装完成后,选择你希望 TeamCity 服务器运行的端口。确保该端口未被机器上的其他服务占用,尽量选择一个唯一的端口号,而不是默认端口:

- 在下一个屏幕上,你将能看到为服务器配置的设置和端口,如果需要,你也可以在这里进行更改:

- 点击“确定”以保存配置。

- 选择用于运行 TeamCity 的账户:

- 启动构建服务器和构建代理:

- 勾选“设置完成后打开 TeamCity Web UI”并点击“完成”:

- 这将打开 TeamCity Web UI,在这里我们可以创建一个 TeamCity 项目。
创建 TeamCity 项目
安装完成后,TeamCity Web 用户界面将在浏览器中打开,我们可以在这里创建新的 TeamCity 项目。请按照以下步骤操作:
- 登录 TeamCity UI 后,点击“创建项目”:

- 要从 GitHub 连接到我们的项目,请在下一个屏幕上点击“从 GitHub”:

- 这将打开一个弹窗,提供将 TeamCity 应用添加到 GitHub 账户的指示:

-
点击 注册 TeamCity 链接,它会将你带到 GitHub 页面,在那里你可以注册一个新的 OAuth 应用。
-
填写应用程序的详细信息、主页 URL 和回调 URL,如下截图所示,并注册 OAuth 应用:

- 注册后,在下一个屏幕上你将看到客户端 ID 和客户端密钥;请复制这些信息,因为它们将在 TeamCity 项目中需要用到:

- 返回 TeamCity,将客户端 ID 和客户端密钥填写到相应字段,并点击“保存”:

- 接下来,你需要进行一次性登录,以允许 TeamCity 使用 GitHub 仓库。点击“登录到 GitHub”:

- 通过点击“授权应用”来授权 TeamCity 应用使用 GitHub:

- 授权后,从 TeamCity 显示的仓库列表中选择 PhoneCallApp 仓库:

- 在下一个屏幕上,TeamCity 会提供从选定的 URL 创建新项目的选项。给它命名并点击“继续”:

- 这应该会创建两件事。第一,每次你提交代码时,TeamCity 都会触发一个构建。第二,它会自动创建一个来自仓库的构建步骤:

-
我们需要手动配置构建步骤,并使用创建构建脚本部分描述的构建脚本。使用这些脚本,按照前面的步骤逐步创建 TeamCity 中的构建步骤。
-
最终,你的构建步骤应该如下图所示,包括在创建构建脚本部分提到的所有步骤:

- 现在,你的 TeamCity 持续构建已经准备好,触发器已配置好,在每次代码提交时,或者在仓库中发现任何代码变化时自动执行此构建。最终,你将获得一个准备分发的 Android 包。
总结
在本章中,我们学习了持续集成和持续交付。我们了解了各种持续集成工具。我们使用 TeamCity 在前面章节中开发的 Xamarin 项目中实现了 CI/CD,并学习了如何在 TeamCity 中创建项目来自动化构建过程,最终得到一个可以分发的 Android 包。
在下一章,你将了解如何使用 Visual Studio Team Services 进行持续分发和交付。
第七章:使用 Visual Studio Team Services 实现 Android 的 CI/CD
在上一章中,我们学习了关于持续集成的内容以及如何在开发生命周期中实现它的各种工具。我们还详细了解了使用 TeamCity 作为 CI 工具的持续集成过程。
在本章中,我们将详细介绍如何使用 Visual Studio Team Services(VSTS)作为工具来进行持续集成和持续交付。我们将讨论设置和使用 VSTS 所需的所有步骤。
VSTS 是 Microsoft 提供的另一种 DevOps 工具,几乎可以与市场上的任何第三方 DevOps 工具链配合使用。它与 GitHub、Jenkins、Azure 以及许多其他类似工具有着很好的集成,能够满足你的持续集成需求。
本章涵盖的部分内容如下:
-
在 Visual Studio 中创建账户
-
从 GitHub 获取代码
-
创建构建定义
-
配置一个代码库
-
队列构建
-
每次提交时构建
在 Visual Studio 中创建账户
要开始使用 VSTS,请打开你的网页浏览器并按照以下步骤操作:
-
打开 Microsoft 网站,访问以下 URL:
www.visualstudio.com/team-services/。 -
在网站上,你将看到一个“免费开始”按钮,如下图所示。点击该按钮:

- 点击按钮将带你到注册页面,你可以使用现有的 Microsoft 账户登录:

-
如果你还没有 Microsoft 账户,可以点击同一页面上的“创建账户”链接。
-
点击“创建账户”链接将带你到下一页,在那里你可以选择用户名和密码并点击“下一步”:

-
它可能会要求你验证你是一个真实的人在创建账户,完成该步骤后,你的账户应该就可以使用了。
-
完成注册表单后,下一步是设置用于托管你的 Team Services 项目的 URL:
www.visualstudio.com/。 -
在这里,你需要提供项目托管的 URL,并选择你将如何管理代码源版本(即,选择 TFS 或 Git):

-
我们将使用 Git 作为我们的源代码库来管理项目。
-
选择 Git 作为代码管理平台,然后点击继续按钮,注册过程就完成了。
从 GitHub 获取代码
现在你的账户已创建,接下来是将代码导入 VSTS:
-
在下一页中,你将看到不同的选项,用于从你的计算机上集成项目,包括使用命令行,甚至通过初始化新的 Git 仓库。
-
我们已经将项目同步到 Git 上,因此我们将选择从 Git 导入项目的选项,如下图所示:

-
点击导入按钮将打开一个小弹窗,你可以在其中选择 Git 或 TFS 作为你的源类型,并提供你的代码库 URL。
-
请注意,它需要你授予此应用程序使用你的 Git 凭据访问权限:

-
提供代码库 URL 和登录信息后,点击导入按钮。
-
这将把你的项目从 Git 导入到 VSTS 服务器,在这里你可以管理与 DevOps 生命周期相关的所有过程。
-
一旦代码被导入,你就能在 VSTS 的代码部分看到所有目录和代码:

- 现在你的代码也已经导入到 VSTS,是时候为项目创建构建了。
创建构建定义
在 VSTS 中创建构建定义是一个简单直接的过程。它为你提供了多种工具模板,帮助你创建构建定义。
按照以下步骤开始为你的项目创建构建定义:
- 在代码页面,点击设置构建按钮,如下图所示:

-
这将带你到下一页,在那里你可以选择一个预定义的 VSTS 模板来使用。
-
在下一页,选择 GitHub 或其他你选择的源版本作为构建的连接来源。
-
在输入框中提供一个连接名称,然后点击使用 OAuth 授权按钮:

-
一个弹窗将会打开,你可能需要从 VSTS 网站解除弹窗阻止才能看到它。
-
授权并给予 VSTS OAuth 权限访问你的 GitHub 仓库:

-
点击授权 vsonline 按钮以授权并授予访问账户的权限。
-
完成后,在下一步将要求你选择项目的代码库和分支来获取代码:

-
从提供的代码库下拉菜单中选择项目代码库,然后选择相应的分支,点击继续按钮,如前面的截图所示。
-
在这个例子中,我们跟进的是之前项目中开发和使用的同一个项目,也就是我们用 Xamarin.Android 开发的 Android 应用。
-
现在,由于 VSTS 和 Xamarin 都是微软工具,它们具有很好的兼容性和内置模板。
-
所以,在下一页,向下滚动模板列表,直到看到 Xamarin.Android 模板并应用该模板:

- 现在模板已应用,接下来是配置构建定义的步骤。
配置构建定义
VSTS 对 Xamarin 应用程序构建过程提供了很好的支持,并自动执行所有你可能需要的构建配置步骤。但是,你可能需要为某些构建步骤提供额外的信息:
- 你将在下一页的 VSTS 中看到已经设置好的构建步骤:

-
让我们暂停一下,看看 VSTS 提供的构建步骤,所有这些都已经为你自动设置好,你只需开始构建。
-
看一下涉及的步骤是个好主意,从 Nuget 包恢复,到构建包,最后到发布它们:

-
这里我们需要提供一些与 Xamarin Test Cloud 帐户相关的信息,以便 VSTS 可以在 Test Cloud 上运行测试。
-
点击屏幕左侧的测试步骤。它将在屏幕右侧突出显示所需的信息字段:

-
你将需要使用 Xamarin Test Cloud 帐户中的团队 API 密钥和你希望构建运行的用户电子邮件,还需要指定要运行测试的设备。
-
现在回到 Xamarin Test Cloud 并登录,然后转到帐户设置:

-
点击“帐户设置”,然后你需要进入“Teams & Apps”部分,获取 API 密钥和其他所需的详细信息。
-
在帐户设置中,点击左侧窗格中的“Teams & Apps”链接,这将打开“Teams & Apps”部分:

-
如前面的截图所示,我们创建的用于运行测试的团队是可见的。
-
在“Teams & Apps”部分,将有一个链接来显示 API 密钥,如前面的截图所示。
-
点击相同的链接查看团队定义的 API 密钥,并记下它:

- 然后,点击齿轮图标获取团队成员的详细信息及其电子邮件:

-
确保记录下具有运行测试所需的所有权限的用户凭证。
-
复制用户的电子邮件并记下它。
-
最后一个必需的值是设备字符串;这个字符串存储了有关要运行 Xamarin 测试的设备列表的信息。
-
设备字符串可以在之前章节中描述的 Test Cloud 测试运行的
-devices命令行参数中找到:

- 现在我们已经有了所有必需的值,让我们回到构建配置步骤并输入这些值。
排队构建
所有配置完成,现在我们可以保存配置并排队构建:
- 一旦完成上述步骤,点击构建配置页面顶部的“保存并排队”按钮:

- 给构建和提交注释命名,并点击“保存并排队”:

- 一旦构建被保存并排队,你将收到一个小的通知,如下图所示:

- 恭喜你,现在已经成功完成了构建配置并排队执行构建。
触发器 - 每次提交时构建
现在我们已经介绍了如何配置构建步骤并手动排队它们。在持续集成中,自动化构建非常重要,尤其是在开发人员提交代码时。这有助于确保最新的构建与所有更改保持同步,并让开发人员在开发的早期阶段就能发现构建中的任何问题。
现在按照这些步骤设置触发器并自动化构建:
- 点击前面步骤中配置部分的“触发器”选项卡:

-
在触发器选项卡的左侧面板中,你将看到一个“持续集成”部分,在该部分下你会找到与你的仓库相关联的信息。
-
点击该链接以打开右侧的持续集成部分:

-
勾选“启用持续集成”框。
-
你会注意到,还有一个复选框是“在构建过程中批量处理更改”。当你有许多开发者频繁地向仓库提交更改时,这个选项非常有用。勾选此选项将在构建已在进行时,将新更改批量处理,直到构建完成后,再将其他更改批量排队,并为这些更改排队一个新的构建。
-
以下是集成复选框;你将看到选择特定分支来包含在构建中的选项。你还可以根据需求排除某些分支:

-
一旦更改完成,你可以保存构建定义,现在该构建将成为我们持续集成过程的一部分,具体流程为:
-
按照你的配置设置,开始在每次检查提交时或批量构建时构建你的项目
-
在 Xamarin 测试云上运行测试
-
对项目的 APK 文件进行签名和 zipalign
-
发布你的应用
-
所有这些步骤将作为构建配置的一部分执行,所有内容都实现了自动化。
现在,所有开发者只需要关注编写高质量代码,他们可以使用微软的 CI 工具,在真实设备上实时测试代码,并在每次构建时发布它们。
这有助于提高应用开发的质量,通过更快的反馈和在开发各个阶段之间实现持续的工作流程。
总结
在本章中,我们讨论了使用 VSTS 进行持续集成。如果在开发生命周期中使用了大量微软工具,特别是 Xamarin,那么 VSTS 是一个非常适合的 CI 工具。我们学习了如何在 VSTS 中配置构建步骤,并集成 Xamarin Test Cloud Teams API 进行持续测试,最后,我们设置了持续构建的触发器。
在下一章,我们将讨论如何将应用程序部署到云端并进行迁移。
第八章:在 AWS 上部署应用程序
在本章中,我们将介绍如何将应用程序部署到云端,并探讨部署的先决条件。在继续之前,我们需要了解为什么要将应用程序部署到云端。我们在第一章中已经讲解了云计算与本地系统的区别,介绍。
到目前为止,我们已经讨论了各种 DevOps 机制,在这些机制中,你将开始编写代码并将其推送到代码仓库(GitHub),因为这些命令非常简单(例如 git add、git commit 和 git push)。
一旦 GitHub 中的新版本代码可用,它将作为新变更被拉取到 持续集成 和 持续部署(CI/CD)管道中。我们在书中展示了两个示例,说明如何部署 CI/CD 管道(Teamcity 和 VSTS)。CI 将开始构建软件的不同部分,包括代码/软件、数据库以及管道中的其他依赖组件。然后,软件脚本将被部署到环境中。
在部署代码之前,我们需要设置环境,这里所说的环境包括一组在 AWS 上运行的机器。AWS 中的虚拟机称为 弹性计算云(EC2)。由于软件运行在多台机器上,我们必须确保请求能够发送到所有机器。为此,我们将创建一个 弹性负载均衡器(ELB)。ELB 将用户请求分配到多个 EC2 节点,并为终端用户请求提供一个单一的 DNS 主机入口。在本章中,我们还将使用 自动伸缩组(ASGs),用于根据工作负载、CPU、内存消耗等各种指标来动态调整 EC2 实例的数量。你可以配置 ASG 来满足你的应用需求。
在本章中,我们将介绍如何在 AWS 上部署应用程序:
-
创建实例:
-
Lightsail
-
EC2 CLI
-
-
Terraform
-
创建弹性负载均衡器、启动配置和自动伸缩组
创建实例
现在,让我们继续创建 EC2 实例。在 AWS 中有多种方法可以创建 EC2 实例。我们将介绍以下几种方法:
-
Lightsail
-
EC2 CLI
-
Terraform
Lightsail
Lightsail 是一种一键创建实例的简便服务,非常适合用于测试应用程序和开发环境,在这些环境中你不想花时间旋转和维护节点。Lightsail 还支持使用预定义模板创建实例,这些模板包括 MEAN、LAMP、Node.js 和 LEMP(Nginx)。让我们看看如何使用 Lightsail 创建实例。
以下是在 Lightsail 中创建实例所需的步骤:
-
登录到 AWS 控制台。
-
在计算部分点击 Lightsail:

- Lightsail 的第一个界面非常简单,只需点击创建实例:

-
现在,你将被要求回答一系列基本问题:
- 选择你的实例位置:

-
- 选择你的实例镜像并选择一个蓝图:

-
- 点击“创建新实例”并为你的实例创建密钥对:

-
- 为密钥提供一个名称,并点击生成密钥对:

-
- 选择你的实例计划:

- 为实例命名。根据需要可以创建多个实例。实例将如下所示:

- 你可以通过点击实例图标右上角的三个点并点击“连接”来连接到实例:

- 将显示以下连接界面:

现在,实例已经创建。接下来,我们将使用 Terraform 创建实例。
Terraform
Terraform 为多个云提供商和现有内部系统提供简单的基础设施即服务。通过 Terraform,我们可以管理非常低级的任务,如创建实例、为实例添加 EBS 卷以及将实例注册到 Route 53。我们将把 Terraform 用作自助服务代码;例如,当我们开发了代码并希望将其部署到某个地方,进行集成测试,然后销毁机器/集群时。此设置对于软件展示/试用、多云设置以及可替换的基础设施非常有用。
安装
Terraform 安装可以通过下载单个二进制包来完成。根据你的操作系统,从www.terraform.io/downloads.html下载相应的二进制包。
安装完成后,通过运行以下命令进行验证:
$ terraform --version
配置文件
现在我们将看看如何使用 Terraform 创建 EC2 实例。
为你的配置文件创建一个目录。Terraform 会加载目录中所有的文件(*.tf),该目录称为workspace,所以请确保将必要的文件放在该目录中:
$ mkdir terraform
$ cd terraform
$ terraform workspace new MyTestMachine
$ terraform workspace select MyTestMachine
Terraform 使用*.tf格式,称为 Terraform 配置。
创建实例
- 要传递 AWS 实例类型的变量,请使用以下代码:
variable "instance_type" {
description = "the AWS instance type to use"
}
你也可以在名为terraform.tfvars或*.auto.tfvars的文件中定义secret变量。
- 在创建实例之前定义 AMI;
ami-id在不同区域会有所不同。请根据你的区域使用正确的镜像 ID。你可以使用 Packer 等工具创建自己的黄金 AMI。我也附上了 Ansible 代码,你可以使用它来创建自定义 AMI:
resource "aws_instance" "testapp" {
ami = "ami-12345t67"
instance_type = "${var.instance_type}"
}
- 使用诸如
"aws"等提供者来在 AWS 中创建实例。你还可以在配置文件中设置多个提供者,以便一次性在多个提供者中创建实例:
Provider "aws" {
access_key = "ENTER_ACCESS_KEY"
secret_key = "ENTER_SECRET_KEY"
region = "us-west-2" // you can select any region
}
如果你想使用 IAM 角色,请不要传递access_key和secret_key变量。我们将在后面的章节中创建 IAM 角色。
此外,可以使用profile选项将access_key和secret_key保存到~/.aws/credentials中:
**# aws configure --profile user1**
**AWS Access Key ID [None]: ABCDEFGHIJKLMNOPQ**
**AWS Secret Access Key [None]: wjVDFVdfdfklfF/G6vFGFGr/fsjfERDFFDGgFGDFGDF**
**Default region name [None]: us-west-2**
**Default output format [None]: json**
区域详情如下所示:
| 区域 | 区域名称 |
|---|---|
| 美国东部(俄亥俄州) | us-east-2 |
| 美国东部(弗吉尼亚北部) | us-east-1 |
| 美国西部(北加利福尼亚) | us-west-1 |
| 美国西部(俄勒冈州) | us-west-2 |
| 亚太地区(东京) | ap-northeast-1 |
| 亚太地区(首尔) | ap-northeast-2 |
| 亚太地区(大阪-本地) | ap-northeast-3 |
| 亚太地区(孟买) | ap-south-1 |
| 亚太地区(新加坡) | ap-southeast-1 |
| 亚太地区(悉尼) | ap-southeast-2 |
| 加拿大(中部) | ca-central-1 |
| 中国(北京) | cn-north-1 |
| 中国(宁夏) | cn-northwest-1 |
| 欧洲(法兰克福) | eu-central-1 |
| 欧洲(爱尔兰) | eu-west-1 |
| 欧洲(伦敦) | eu-west-2 |
| 欧洲(巴黎) | eu-west-3 |
| 南美洲(圣保罗) | sa-east-1 |
- 通过运行以下命令初始化配置文件:
$ terraform init
$ terraform plan -var 'instance_type=t2.micro'
配置完成后,AWS 插件将被设置在一个单独的目录中以供后续使用。
- 在与
main.tf文件相同的目录中运行配置。你还可以通过命令行传递多个变量:
$ terraform apply -var 'instance_type=t2.micro'
-
输出非常易于阅读,类似于 Git 输出。输出包含了详细的实现步骤。如果实现以
+(加号)开始,表示 Terraform 正在创建资源。 -
在开始创建实例之前,Terraform 会要求确认。你可以查看计划并点击
yes。如果你将 Terraform 作为自动化的一部分运行,可以添加auto-approve来自动批准所有配置:
terraform apply -auto-approve -var 'instance_type=t2.micro'
实例创建可能需要一些时间,一旦实例可用,你可以在控制台中查看它们。
- 要获取 Terraform 的当前状态,请输入以下命令:
terraform show
修改实例
- 要修改实例,你需要在
main.tf中进行更改。例如,我正在更新实例的弹性 IP。aws_eip模块用于分配弹性 IP:
resource "aws_eip" "ip" {
instance = "${aws_instance.testapp.id}"
}
- 保存文件后,再次运行以下命令以使实例更改生效:
$ terraform apply
+ aws_eip.ip
allocation_id: "<computed>"
association_id: "<computed>"
domain: "<computed>"
instance: "${aws_instance.example.id}"
network_interface: "<computed>"
private_ip: "<computed>"
public_ip: "<computed>"
输入yes以接受更改,并通过 AWS 控制台查看更改,或运行terraform show命令。
- 通过在相同目录中创建另一个
output.tf文件来获取输出。将以下配置详情添加到文件中:
output "ip" {
value = "${aws_eip.ip.public_ip}"
}
- 你可以单独查询 IP 输出:
$ terraform output ip
终止实例
实例可以通过单个命令终止。确保从与main.tf文件相同的目录中运行命令:
terraform destroy
# ...
- aws_instance.testap
如果想强制销毁实例,可以使用 "-force" 标志与命令一起使用。
使用 Terraform 创建实例的示例
- 我们有一个示例配置文件,用于创建实例并使用该实例设置 Route 53 DNS。将文件保存为
main.tf:
$ vi main.tf
variable "stack_name" { default = "MyTestMachine"}
variable "aws_region" { default = "us-east-1" }
variable "instance_type" { default = "t2.micro" }
variable "instance_count" { default = "1" }
variable "route53_zone_id"
variable "security_group_id"
provider "aws" {
region = "${var.aws_region}"
}
module "MyTestMachine" {
source = "./ec2_nodes"
instance_type = "${var.instance_type}"
stack_name = "${var.stack_name}"
role = "MyTestMachine"
count = "1"
security_group_id = "${var.security_group_id}"
}
resource "aws_route53_record" "MyTestMachine" {
zone_id = "${var.route53_zone_id}"
name = "${var.stack_name}-domainname.com"
type = "A"
ttl = "300"
records = ["${module.MyTestMachine.firstip}"]
}
- 我已经将源文件的详细信息放在另一个文件中,这样可以使用单个配置文件创建多个机器。创建一个
ec2_nodes文件夹,并在该目录中创建main.tf:
$ mkdir ec2_nodes
$ cd ec2_nodes
$ vi main.tf
variable "stack_name" {}
variable "count" {}
variable "role" {}
variable "instance_type" {}
variable "security_group_id" {}
variable "route53_zone_id" {}
resource "aws_instance" "MyTestMachine" {
ami = "ami-97785bed" # you can select any AMI instance
instance_type = "${var.instance_type}"
count = "${var.count}"
vpc_security_group_ids = [
"${var.security_group_id}"
]
associate_public_ip_address = false
iam_instance_profile = "MyTestRole"
subnet_id = "subnet-12345678"
key_name = "aws-key-1234"
user_data = <<EOF
# yum update
sudo yum update -y
EOF
tags {
Name = "${var.stack_name}"
Role = "${var.role}"
}
}
resource "aws_route53_record" "nodecname" {
zone_id = "${var.route53_zone_id}"
count = "${var.count}"
name = "${var.stack_name}-${var.role}-${count.index}.domainname.com"
type = "A"
ttl = "300"
records = ["${element(aws_instance.MyTestMachine.*.private_ip, count.index)}"]
}
- 现在,我们将在同一目录中创建另一个输出文件,
ec2_nodes:
output "first_ip" {
value = "${aws_instance.MyTestMachine.0.private_ip}"
}
- 使用以下命令运行 Terraform 安装:
$ terraform workspace new MyTestMachine
$ terraform workspace select MyTestMachine
$ terraform plan \
-var "stack_name=MyTestMachine" \
-var "instance_type=t2.micro" \
-var "route53_zone_id=123456789" \
-var "security_group_id=sg-12345678"
$ terraform apply -auto-approve \
-var "stack_name=MyTestMachine" \
-var "instance_type=t2.micro" \
-var "route53_zone_id=123456789" \
-var "security_group_id=sg-12345678"
EC2 CLI
AWS CLI 包含多个模块来管理 AWS 资源。EC2 CLI 是创建和管理实例的一种非常直接的方式。
安装 AWS CLI(命令):
**$ curl -O https://bootstrap.pypa.io/get-pip.py // 下载 pip**
**$ python get-pip.py --user // 为用户安装 pip**
**$ pip install awscli --upgrade --user // 安装 AWS CLI(如果要为所有用户安装,请删除 --user)**
格式:
$ aws ec2 run-instances <Pass parameters>
示例:
$ aws ec2 run-instances --count 1 --security-groups launch-wizard-1 --subnet-id subnet-1234rt78 --instance-type t2.micro --key-name myTestKey --image-id ami-abc123dec --associate-public-ip-address --iam-instance-profile Name=MyTestIAM-Role
输出将包含实例的所有详细信息,包括如下的实例 ID:
{
"Instances": [
{
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "",
"StateReason": {
"Message": "pending",
"Code": "pending"
},
"State": {
"Code": 0,
"Name": "pending"
},
"EbsOptimized": false,
"LaunchTime": "2018-03-10T07:55:32.000Z",
"PrivateIpAddress": "10.10.81.24",
"ProductCodes": [],
"VpcId": "vpc-123456b",
"StateTransitionReason": "",
"InstanceId": "i-1234d5r6t7y8g9aws",
"ImageId": "ami-12345678",
"PrivateDnsName": "ip-10-10-81-24.ap-southeast-1.compute.internal",
"KeyName": "MyTestKey",
"SecurityGroups": [
{
"GroupName": "launch-wizard-1",
"GroupId": "sg-12345678"
}
],
"ClientToken": "",
"SubnetId": "subnet-1234rt78",
"InstanceType": "t2.micro",
"NetworkInterfaces": [
{
"Status": "in-use",
"MacAddress": "02:d4:43:07:9c:a4",
"SourceDestCheck": true,
"VpcId": "vpc-12345678",
"Description": "",
"NetworkInterfaceId": "eni-12345678",
"PrivateIpAddresses": [
{
"Primary": true,
"PrivateIpAddress": "10.10.81.24"
}
],
"SubnetId": "subnet-1234rt78",
"Attachment": {
"Status": "attaching",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "eni-attach-c5d3e72e",
"AttachTime": "2018-03-12T07:55:32.000Z"
},
"Groups": [
{
"GroupName": "launch-wizard-1",
"GroupId": "sg-12345678"
}
],
"Ipv6Addresses": [],
"OwnerId": "1234567891011",
"PrivateIpAddress": "10.10.81.24"
}
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "us-east-1a"
},
"Hypervisor": "xen",
"BlockDeviceMappings": [],
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"IamInstanceProfile": {
"Id": "A1B2C3D4E5S6F7G8I9J1K0",
"Arn": "arn:aws:iam::1234567891011:instance-profile/MyTestIAM-Role"
},
"RootDeviceName": "/dev/xvda",
"VirtualizationType": "hvm",
"AmiLaunchIndex": 0
}
],
"ReservationId": "r-123456789101112",
"Groups": [],
"OwnerId": "1234567891011"
}
您可以获取实例 ID 的详细信息:
$ aws ec2 describe-instances --instance-id <id-awsinstanceid>
要终止实例,请使用以下命令:
$ aws ec2 terminate-instances --instance-ids "i-1234d5r6t7y8g9aws"
{
"TerminatingInstances": [
{
"InstanceId": "i-1234d5r6t7y8g9aws",
"CurrentState": {
"Code": 32,
"Name": "shutting-down"
},
"PreviousState": {
"Code": 16,
"Name": "running"
}
}
]
}
创建 Elastic Load Balancer、启动配置和自动扩展组
在本节中,我们将看到如何使用 AWS CLI 创建 ELB 和 ASG。
Elastic Load Balancer
ELB 会自动将负载/流量分配到多个实例中,这些实例可以位于不同的 可用区(AZs)。成员实例可以属于单一的 AZ 或多个 AZ。ELB 成为 DNS 和最终用户的唯一接入点。ELB 还通过健康检查监控实例;如果实例健康,才会将请求路由到该实例。
由于我们已经创建了实例,接下来将使用 CLI 创建一个 ELB。执行此操作的命令如下:
$ aws elb create-load-balancer --load-balancer-name my-test-elb --listeners "Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=80" --availability-zones us-west-2a us-west-2b
将新创建的实例添加到 ELB:
$ aws elb register-instances-with-load-balancer --load-balancer-name my-test-elb --instances i-awsinstance12fd
可以通过 CloudWatch、访问日志和 AWS CloudTrail 监控 ELB。ELB 可以是内部的或面向互联网的。面向互联网的 ELB 可以与域名关联。
自动扩展组
让我们了解基础设施扩展的基本概念:
-
扩展:通过增加 EC2 实例的数量来实现可扩展性
-
向上扩展:通过调整现有 EC2 实例的容量(计算、内存和 EBS)来实现可扩展性
-
向下扩展:减少现有 EC2 配置的 EC2 实例数量
自动扩展处理扩展和缩减。自动扩展组件被管理成组,以便它们可以作为单独的逻辑单元进行管理和扩展。自动扩展组使用 启动配置 作为模板来创建 EC2 实例
$ aws autoscaling create-launch-configuration --launch-configuration-name my-test-launch --key-name my-key-pair --image-id ami-c1wjdlakf6 --instance-type m1.small --security-groups sg-lkjl3kmm --instance-type m1.small
扩展计划将定义触发 ASG 的阈值和条件:
$ aws autoscaling create-auto-scaling-group --auto-scaling-group-name my-test-asg-group --launch-configuration-name test-launch --load-balancer-names my-test-elb --health-check-type ELB --health-check-grace-period 120 --min-size 1 --max-size 3 --desired-capacity 2 --default-cooldown 600--termination-policies "OldestInstance"
IAM 角色
AWS IAM 角色通过管理和旋转密钥本身提供了额外的安全层。密钥是加密的凭证,分别称为访问密钥和密钥。
访问密钥示例如下:
aws iam create-role --role-name myTestKey --assume-role-policy-document file://myTestKeyPolicy.json --description "Role for testing access from EC2 to S3 and Route 53"
策略是一个 JSON 文档,包含从一个 AWS 服务到另一个 AWS 服务的权限委托。IAM 角色的默认权限是全拒绝(默认情况下会阻止所有对任何服务的请求,直到明确指定)。示例策略用于创建和管理 EC2 实例、S3 存储桶和 Route 53。
示例策略(将以下文本保存为 myTestKeyPolicy.json):
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "elasticloadbalancing:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "cloudwatch:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "autoscaling:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:CreateServiceLinkedRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:AWSServiceName": [
"autoscaling.amazonaws.com",
"ec2scheduled.amazonaws.com",
"elasticloadbalancing.amazonaws.com",
"spot.amazonaws.com",
"spotfleet.amazonaws.com"
]
}
}
总结
在本章中,我们介绍了为软件部署创建 EC2 实例的各种方法。一旦实例创建完成,将软件 JAR 文件推送到实例中。使用私有实例的 IP 地址、用户名(ec2-user)和私钥(test.pem)连接到机器。一旦测试完成,确保终止测试实例,以免产生额外费用。
T2.micro EC2 实例类型对于新的 AWS 账户可以免费使用一年。
在本章的后面部分,我们通过 AWS CLI 演示了如何创建 ELB 和 ASG。
您可以将您的 ELB DNS 名称注册到您的域名服务提供商(例如,Route 53、GoDaddy 和 BigRock),以解析您的应用程序。
您还可以尝试将一些工作负载投入到您的应用程序中,查看 Auto Scaling 是否增加了实例数量,然后移除工作负载以测试终止策略。
您还可以使用分布式文件系统,如 EFS、NFS 和 GlusterFS,在所有节点之间共享工作空间。
在下一章中,我们将介绍使用 Test Cloud 和 Android 监控工具对应用程序进行优化和监控。Test Cloud 是由 Xamarin 提供支持的移动测试工具,它可以测试超过 2000 台设备的应用程序。Android Monitor 提供图形界面,用于调试和优化应用程序。
第九章:监控和优化应用程序
应用程序监控是简单地跟踪应用程序各个方面及其表现的过程。它对于持续的质量检查和改进非常重要,并且对于在应用程序到达用户之前发现问题至关重要。
应用程序监控不仅可以让我们了解应用程序的表现及其内部问题,还可以记录相关数据库和 API 的状态。
本章中,我们将讨论各种应用程序监控方法。以下是本章将涵盖的高级主题:
-
API 级别监控及各种 API 监控工具
-
使用测试云监控应用程序
-
使用 Android 监控工具监控应用程序
API 级别监控
应用程序编程接口 (APIs) 是当今集成开发环境中不可或缺的一部分。它们也可以通过客户端-服务器关系来理解,其中移动应用是请求资源的客户端,而 API 位于服务器端,并为任何想要发出请求的应用程序提供 URL。
大多数应用程序在 Web 和移动端之间共享公共 API。API 是一种提供跨不同平台一致操作行为的有效方式。它还帮助在不同的移动应用平台之间共享相同的业务和数据层操作,因此,你可以在 iOS、Android 和 Web 应用中使用相同的 API。
API 在移动应用开发中非常重要,因此监控 API 以确保高可用性变得同样关键。如果 API 发生故障,整个应用程序可能会停止工作,用户可能无法执行任何需要 API 可用的操作,这通常是任何服务器操作,尽管不包括离线操作。
为什么 API 监控至关重要
API 是任何应用程序中非常重要的一部分,无论是移动应用还是 Web 应用。如今,API 在项目中被广泛使用,为客户端(移动应用或 Web 应用)与服务器端的业务逻辑和数据访问层交互提供更多灵活性。由于应用程序在执行用户操作时非常依赖 API,因此必须实施 API 监控,以避免任何停机或糟糕的用户体验。当没有适当的 API 监控时,可能会影响应用程序的质量和响应时间,有时甚至会导致应用程序停机。
同样,监控你所开发的 API,以及你可能在应用程序中使用的第三方 API 也非常重要。
API 监控中的重要因素
在监控 API 时,有一些关键点或领域需要涵盖,以确保可用性:
-
API 可用性:我们需要确保 API 可用;有时,服务器可能由于某些原因宕机,或者根据位置和服务器,连接可能会中断。
-
响应质量:当我们调用 API 时,API 返回的响应质量如何?是否符合协议?
-
响应时间:调用 API 时获取结果的响应时间是多少?
开发者在处理 API 不可用情况中的角色
对于应用程序开发者来说,记住 API 可能并非始终可用,并以优雅的方式处理这些情况,是一个不错的建议。即使应用程序无法执行某些 API 操作,如果它能够友好地告知用户,往往比面对运行时异常能够带来更好的用户体验。编写代码来处理 API 异常和 API 无响应的场景。
各种用于 API 监控的工具
市场上有许多用于 API 监控和测试的工具。选择哪种工具完全取决于你希望通过这些工具实现什么目标。有些工具对性能监控提供了很好的支持,而另一些工具则更适合质量测试和识别错误数据。
一些流行的工具如下:
-
Postman
-
Karate DSL
-
SoapUI
-
HttpMaster
-
REST Assured
-
RestSharp
-
Mockbin
你可以在各自的网站上阅读更多关于这些工具的好处和支持内容,并选择最适合项目需求的工具。
使用 Test Cloud 进行监控
你在前几章中了解了 Xamarin Test Cloud 以及如何在持续集成生命周期中使用它进行持续测试。在这里,我们将更详细地讨论如何使用 Xamarin Test Cloud 以及在不同设备组上运行应用程序后,它提供的分析数据。
我们将在这里使用两个不同的应用程序,查看监控分析并进行比较,以更好地理解如何帮助我们识别应用程序中的各种性能和功能相关问题。
这些是我们将在演示过程中使用的应用程序:
-
PhoneCallApp(我们在前几章中开发的应用程序)
-
Xamarin Store(Test Cloud 提供的一个示例 Android 应用程序)
Xamarin Test Cloud 可以帮助我们识别应用程序在真实设备上的功能相关问题。
它是一个非常好的应用程序监控工具,尤其是在不同移动设备和操作系统版本上进行测试时。
获取各种应用程序功能的详细分析对于确保我们的应用程序在目标设备上按预期运行非常重要。
话虽如此,应用程序能够在不同操作系统版本上运行,以及分析其性能和内存使用情况,也是至关重要的。
使用 Test Cloud 进行监控的好处
Test Cloud 不仅提供监控功能,还可以免去我们手动测试相同应用程序在不同设备上的功能,从而实现真正的持续集成过程。
-
它为我们的 CI 过程提供了持续的测试功能,支持自动化测试运行和详细的报告通知。
-
在不同操作系统版本上测试应用程序对于移动应用的成功至关重要,而 Test Cloud 很好地实现了这一目的。
-
在云端,您可以从大量设备列表中选择不同设备进行应用程序测试。
-
Test Cloud 分析应用程序的性能。
-
Test Cloud 分析不同硬件配置下不同设备的内存使用情况。
PhoneCallApp
让我们通过一些步骤,了解如何监控我们的 PhoneCallApp:
-
点击 PhoneCallApp 图标,查看测试运行的详细信息:

- 在下一页中,您将看到应用程序运行的测试列表:

-
现在,由于我们目前只运行了一个测试,因此 Test Cloud 没有提供前面截图中显示的图形化度量。在接下来的其他示例中,您将能够看到不同测试运行的更详细对比。
-
点击列表中的测试运行,查看其结果:

-
列出的测试运行是我们之前在章节中运行的,并通过命令行将其上传到 Xamarin Test Cloud。
-
为了了解这个界面,我们来看看 Xamarin Test Cloud 界面中的不同部分。
-
这是一个概览屏幕,显示该应用程序所有测试运行的总结:

-
这个屏幕显示了摘要信息,如从总运行测试中有多少测试失败、应用程序在设备上运行了多少次、这些测试在哪些设备上运行等。
-
当你想获取应用程序在不同设备和操作系统版本上的表现报告时,这个屏幕非常有用,可以帮助你简要了解情况。
-
下一步,左侧窗格中会显示在测试运行中包含的 UITests 列表:

-
此屏幕基本上列出了您在项目中包含的所有 Xamarin.UITests。您可以点击这些不同的测试,查看它们在屏幕右侧的相应结果。
-
让我们点击前一屏幕列表中的测试。
-
这将带我们到下一个屏幕,其中包含测试运行的详细报告:

-
仔细看看此屏幕左侧窗格。
-
它提供了一些关于在设备上运行测试的步骤。
-
这些步骤仅是我们之前在代码中编写的,以便在每次测试操作时截取屏幕截图。
-
这些步骤如上所述(我们在这里使用的是之前章节中编写的测试代码屏幕):
- 应用程序启动:应用程序启动时截取屏幕截图;这是在
Tests.cs文件中的BeforeEachTest()方法中编写的:
- 应用程序启动:应用程序启动时截取屏幕截图;这是在

-
- 按下拨号按钮:这是 Xamarin.UITest 按下拨号按钮以发起通话的步骤:

-
- 失败的步骤(断言):这是最后一步,显示的是失败步骤的证据,您可以看到我们收到的结果,并将其与预期结果进行比较。这是决定测试是否通过的最终断言,基于
Assert.IsTrue()条件中的结果。
- 失败的步骤(断言):这是最后一步,显示的是失败步骤的证据,您可以看到我们收到的结果,并将其与预期结果进行比较。这是决定测试是否通过的最终断言,基于
-
您可以点击左侧窗格中的每个步骤并分析所拍摄的屏幕截图,以准确查看测试过程中发生了什么。这是一种很好的方式,可以在测试失败时准确找出问题所在。
-
有时,仅凭截图不足以确定问题。为了进行更详细的分析,Test Cloud 还为我们提供了设备日志,正如下图所示:

-
设备日志是查看应用程序行为和设备在运行应用程序时的表现的绝佳方式,它可以提供更详细的信息。
-
这可以帮助我们在设备上测试失败时准确定位问题;在这种情况下,日志总是拯救我们的利器。
-
点击设备日志,您可以看到每个截图的逐步日志,所有日志都在同一屏幕上展示:

- 当测试失败时,Test Cloud 还为我们提供了一个额外的选项,即查看测试失败:

-
对于自动化测试开发人员来说,在测试失败时查看异常信息非常有用。
-
最后但同样重要的是,还有一个“测试日志”选项,可以用来获取整个测试运行的汇总日志:

Xamarin Store 应用
现在我们已经看到了 Test Cloud 提供的不同选项,用于通过测试运行来监控我们的应用程序及其功能,接下来让我们看看仪表板和测试在多个物理设备上运行、不同操作系统版本下的情况。
这将帮助我们更好地了解如何在 Test Cloud 上进行对比监控,以分析应用程序在不同设备上的行为,并将其进行比较。
Xamarin Store 应用程序是 Test Cloud 在其平台上提供的示例应用,旨在帮助了解平台并了解仪表板的使用。让我们通过以下步骤,了解如何监控应用程序在多个设备上的运行情况,并比较不同的测试运行:
- 像之前的例子一样,前往 Test Cloud 的主页并点击 Xamarin Store 图标:

- 在下一个屏幕上,您将看到不同测试运行的图形表示,并简要了解在所有测试中失败的测试数量、应用程序大小以及不同测试运行期间的峰值内存使用情况:

-
这为我们提供了一个很好的对比视角,展示了应用程序在不同测试运行中的表现。可能应用程序在第一次运行时表现良好,而之后的一些代码更改导致某些功能失败。因此,这个图表非常有用,可以监控影响应用程序功能的变更时间线。
-
你还可以点击图表或测试运行,查看其概述。
-
现在,这个界面为我们提供了一个很好的视图,展示了如何监控在不同设备上运行的应用程序。这是一个非常好的方式,可以跟踪不同设备和操作系统版本上的应用程序:

- 让我们点击其中一个步骤,查看在多个设备上该步骤的结果:

-
红色图标表示测试失败。此页面显示了你选择运行测试的所有设备;它显示了测试通过的所有设备,并在失败的设备上标记红旗。
-
你可以进一步点击每个设备,获取特定设备的屏幕和日志。
使用 Android 监视工具
一个 Android 应用程序的性能对于良好的用户体验和快速响应的应用程序同样重要。Android 设备监视器(ADM)是一个出色的工具,能够识别性能问题,并基于这些问题生成报告,用于分析和确保 Android 应用程序的良好性能:
- 打开 Visual Studio,并从工具栏中运行 Android 设备监视器:

- 一个新的应用程序,Android 设备管理器,应该会打开:

-
返回 Visual Studio 并运行 PhoneCallApp,以便在 Android 设备监视器中列出设备。
-
你可以在模拟器或连接到计算机的物理设备上运行应用程序。
-
应用程序启动后,返回到 Android 设备监视器,你应该能够在左侧窗格中看到正在运行的设备。
-
在设备名称下,你应该能够看到设备上所有正在运行的进程。
-
在列表中选择你的应用程序,你应该能够看到相关信息:

- 要监控应用程序中运行的不同线程,请点击左侧窗格工具栏上的“更新线程”按钮,接着你应该能够看到在右侧显示的由应用程序运行的不同线程:

-
能够监控由应用程序运行的线程,对于找出可能导致额外电池消耗或拖慢应用程序的后台线程非常有帮助。
-
有时,线程可能会发生死锁,在这种情况下很难识别问题。ADM 的这一功能在这方面提供了很大帮助。
-
同样,监控应用程序的内存使用情况是优化应用程序和支持低内存设备的一个重要工具,有时还可以通过减少内存消耗来提高性能。
-
点击左侧面板中的垃圾回收(GC),然后在右侧选择堆(Heap)以查看堆内存分配的详细信息:

- 你可以在“分配跟踪器”标签页中获得更详细的分配监控。点击“开始跟踪”,然后点击“获取分配”按钮以获取分配详情:

-
还有用于监控网络相关使用的选项。
-
Android 设备监控器的一个非常重要的功能是性能分析,它帮助分析在应用程序代码中各个方法所花费的时间及其他细节。它是识别方法级性能和延迟的一个重要工具。
要使用此功能,点击左侧面板中的“开始方法性能分析”按钮:

- 下一步,选择是否进行基于样本的性能分析或基于跟踪的性能分析,然后点击确定:

-
在应用程序中执行你的任务,返回到 ADM 并点击“停止方法性能分析”按钮。
-
会生成一个跟踪文件,包含你想要分析的跟踪信息:
-
时间轴面板:它描述了每个线程和方法的开始和结束时间。我们可以进入特定的时间段,查看每个线程在那个时刻做了什么。
-
分析面板:提供了方法内部发生事件的摘要。我们可以看到哪个方法占用了最多的 CPU 时间,或者它调用了多少次。
-

- 方法位于 Android 层级,可能需要比较哪些方法可能调用了这些 Android 方法。
总结
在本章中,我们学习了不同类型的监控技术,如 API 监控、性能监控和功能监控。我们还讨论了用于 API 级监控的不同工具。我们详细了解了使用 Xamarin Test Cloud 在多个设备上进行功能监控,以及使用 Android Device Monitor 进行性能监控。在下一章中,我们将讨论在不同开发阶段的调试和故障排除。
第十章:调试应用程序
在应用程序开发中,调试是识别问题或故障的过程,使用提供调试方法的调试工具或 IDE。它涉及逐步执行代码,分析变量和方法及其值,以精确找出问题所在。
如果您已经做了应用程序开发一段时间,应该对调试在应用程序开发过程中的重要性有所了解,即使您是一个新开发者或刚开始学习,本章也将帮助您了解调试术语、如何在 Visual Studio 中调试 Xamarin 应用程序,以及如何排除开发过程中可能出现的其他问题。
本章中,您将深入学习以下主题:
-
在 Visual Studio 中调试 Xamarin 应用程序
-
在 Android 模拟器中调试和排除故障
-
调试 Mono 类库并使用调试日志
-
调试 Git 连接
术语
最好先了解调试过程中使用的不同术语。这些术语是常用的,并且在所有调试平台中都很常见:
-
Bug:Bug 是指阻止程序或应用程序执行预期功能的缺陷或问题。
-
Debug:您现在可能已经猜到,debug,顾名思义,涉及从系统或程序中删除 Bug。它通常表示通过深入程序找到问题,并在识别问题后通过修正错误代码来解决问题。
-
Breakpoint:顾名思义,断点是您希望暂停正在运行的应用程序的地方,pause 就是指“暂停”。所以,断点是您希望暂停正在运行的应用程序并查看发生了什么或正在发生什么的程序代码中的一个位置。它在调试应用程序时非常有用,并且是一个至关重要的工具。
在 Visual Studio 中使用 Xamarin 调试
Visual Studio 是一个非常适合调试任何应用程序的 IDE,无论是 Web 应用、移动应用还是桌面应用。它使用的是 IDE 内置的调试器,适用于这三种应用,且非常易于跟随。
为了保持章节内容易于跟随,我们将使用在 Xamarin 上开发和测试的相同 Android 应用程序,并在 Visual Studio 中进行调试。
使用输出窗口
Visual Studio 中的输出窗口是一个可以看到发生的输出的窗口。要查看 Visual Studio 中的输出窗口,请按照以下步骤操作:
- 进入视图(View),点击输出(Output):

- 这将打开一个位于底部的小窗口,您可以看到 Visual Studio 写入的当前和有用的输出。例如,这是我们在重新构建应用程序时,输出窗口中显示的内容:

使用 Console 类显示有用的输出
Console类可以用来打印一些有用的信息,比如日志,输出到输出窗口,以便了解正在执行哪些步骤。如果某个方法在特定步骤后失败,这些信息将显示在输出窗口中。
为了实现这一点,C#有一个Console类,这是一个静态类。这个类有像Write()和WriteLine()这样的方法,可以将任何内容写入输出窗口。Write()方法将内容写入输出窗口,WriteLine()方法也是如此,不过它会在末尾添加一个换行:
- 查看以下截图,并分析如何使用
Console.WriteLine()将方法分解为几个步骤(这是在开发PhoneCallApp时编写的相同Click事件方法):

-
向代码中添加
Console.WriteLine(),如前面的截图所示。 -
现在,运行应用程序,执行操作,并查看根据你的代码写入的输出:

- 通过这种方式,
Console.WriteLine()可以用来将有用的步骤输出/日志写入输出窗口,便于调试时分析问题。
使用断点
如前所述,断点是深入了解代码的好方法,不会太麻烦。它们可以帮助检查变量及其值,检查程序在代码的某个位置或某行的执行流。
使用断点非常简单:
- 在一行上添加断点的最简单方法是点击该行前方的左侧边距,或者点击该行并按下F9键:

-
当设置断点时,你会看到在你点击的边距区域出现一个红点,如前面的截图所示。
-
现在,运行应用程序并点击按钮;当断点处暂停时,程序的执行流会停止,且该行会变成黄色:

- 在此时,你可以通过悬停在变量上来检查断点行之前的变量值:

设置条件断点
你还可以在代码中设置条件断点,这基本上是告诉 Visual Studio,当满足特定条件时才暂停执行:
- 右键点击前面步骤中设置的断点,点击“条件”:

- 这将打开一个小窗口,允许你为断点设置一个条件。例如,在以下截图中,设置的条件是当
phoneNumber == "9900000700"时触发。
因此,只有当满足此条件时,断点才会被触发;否则,它将不会触发。

步进调试代码
当到达断点时,调试工具会让你控制程序的执行流程。你将看到工具栏中的一些按钮,允许你运行和逐步调试代码:

你可以悬停在这些按钮上查看它们各自的名称:
- 单步跳过 (F10):这将执行下一行代码。如果下一行是函数调用,单步跳过将执行该函数并在函数执行完后停止。

- 单步进入 (F11):单步进入将在函数调用的下一行停止,让你可以逐行调试该函数。如果下一行不是函数调用,它的行为将与单步跳过相同:

- 跳出 (Shift + F11):这将返回到当前函数被调用的那一行:

- 继续:这将继续执行,直到下一个断点被触发:

- 停止调试:这将停止调试过程:

使用监视
监视是调试中非常有用的功能,它允许我们查看变量的值、类型以及其他相关信息,并以比悬停变量更好的方式进行评估。
在 Visual Studio 中有两种类型的监视工具:
QuickWatch
QuickWatch 类似于监视,但顾名思义,它允许我们评估当时的值。按以下步骤在 Visual Studio 中使用 QuickWatch:
- 右键点击你想分析的变量并点击“QuickWatch”:

- 这将打开一个新窗口,你可以在其中查看与变量相关的类型、值和其他详细信息:

- 当一个变量的值或字符串过长,无法通过仅仅悬停在变量上正确读取和评估时,这个功能也非常有用。
添加监视
添加监视类似于 QuickWatch,但当你有多个变量需要分析,并且查看每个变量的值可能需要大量时间时,它更有用。
按以下步骤为变量添加监视:
- 右键点击变量并点击“添加监视”:

-
这将把变量添加到监视列表中,并始终显示其值,同时反映其在运行时的任何变化。
-
你还可以按不同的数据类型以特定格式查看这些变量值,比如将 XML 值以 XML 格式显示,或将 JSON 对象的值以
.json格式显示:

- 当你想在每步代码中评估变量的值,并查看它随着每一行代码的变化时,这个功能非常有用。
调试 Mono 类库
Xamarin 附带了 Mono 类库的源代码,您可以使用这些代码调试 Xamarin(以前称为 Mono)源代码:
- 要使用此选项,请转到“调试 | 选项”:

- 然后,进入常规设置,取消选中“启用仅我的代码”选项,并点击“确定”:

- 一旦禁用此选项,我们就可以进入 Mono 类库并调试它们。
Android 调试日志
如本章前面部分所述,我们已经看到如何使用 Console.WriteLine() 方法在 Visual Studio 中调试时写入一些输出步骤。
然而,在像 Android 这样的移动平台上,没有控制台,它只在 Visual Studio 调试期间可用。Android 设备提供了一种日志,您可以在编写 Android 应用程序时使用。这也被称为 logcat,因为使用该命令来获取此日志。
要通过 Visual Studio 访问此功能,请按以下步骤操作:
- 您可以直接从工具栏中的 Android 工具点击设备日志(logcat)图标,或者可以通过“工具 | Android | 设备日志”访问:

- 这将打开一个新窗口,您可以在其中选择应用程序运行的设备。需要明确的是,应用程序必须在物理设备上运行,因为只有在设备上运行应用程序时,调试和日志才会由 Android 设备提供:

-
从列出正在运行应用程序的下拉列表中选择设备。
-
当选择设备时,它会自动开始将运行中的应用程序的日志条目添加到表格中。切换设备会停止并重新启动设备日志:

从命令行访问 logcat
查看调试日志的另一种方法是通过命令行:
-
打开一个控制台窗口,导航到 Android SDK 的
platform-tools文件夹(例如C:\Program Files (x86)\Android\android-sdk\platform-tools)。 -
如果只连接了一个设备,可以使用以下命令查看日志:
$ adb logcat

- 如果连接了多个设备,则必须识别设备。例如,
adb -d logcat显示唯一连接的物理设备的日志,而adb -e logcat显示唯一运行的模拟器的日志。
写入调试日志
您可以使用 Android.Util.Log 类将消息记录到调试日志。它具有不同的日志级别:
-
信息
-
调试
-
警告
-
错误
所有这些级别都是不言自明的。
- 让我们将前一部分中写的
Console.WriteLine()替换为Log.Debug(),将日志写入 logcat:

- 转到 logcat(设备日志)窗口,并通过代码中给定的标签过滤标签,以仅查看我们在代码中写入的日志。在这种情况下,标签将是 PhoneCall:

- 这是一种非常简单直接的调试方式,可以监控在物理设备上运行的应用程序。
调试 Git 连接
Git 对于将代码保存到仓库中是必不可少的,但有时候它可能无法按预期工作,就像我们应用程序遇到的问题一样。如果你无法从仓库中获取或克隆代码,尝试以下步骤来调试 Git:
- 检查你的连接:这是你在遇到 Git 问题时首先需要检查的事项。可能你的连接并不像你认为的那样。可以 ping 任意公共域名站点,例如
www.google.com,来检查你的连接情况:

如果你收到类似前面截图中显示的响应,并且能够成功 ping 通,这意味着你的连接完全正常。
-
GIT_TRACE:这个配置选项会为 Git 网络连接及其所有内部命令提供更详细的跟踪信息。键入你的
git命令并设置GIT_TRACE = 1,它应该会给出详细的跟踪信息:- 添加一个名为
GIT_TRACE的新环境变量,并将其值设置为1。
- 添加一个名为

-
- 运行
git命令并获取详细信息以识别问题:
- 运行

总结
在本章中,我们以不同的方式进行了调试,并学习了如何使用 Visual Studio 和 Xamarin(Android)中的调试工具。本章还解释了 Android 设备日志,也称为 logcat,用于在物理设备上调试应用程序时读取和写入日志。在下一章中,我们将通过一些案例研究,深入了解整个开发、测试和调试过程。
第十一章:案例研究
在本章中,我们将通过整个移动 DevOps 过程,从移动应用开发和集成,到持续测试和部署。
我们将使用两个应用程序作为案例研究,展示整个过程:
-
一个基本的 Hello World 图形界面
-
一个 ButtonWidget
案例研究 1 - Hello World 图形界面
在这个案例研究中,我们将讨论移动 DevOps 生命周期,并通过一个简单的 Android 应用程序来演示,该应用程序的 MainActivity 中包含一个Hello World文本标签。
本研究将简要介绍整个过程,并向您展示一个逐步的工作流。
前提条件
由于这些案例研究将涵盖生命周期中的所有步骤,因此无法详细介绍这些主题,也无法解释 IDE 和 Android 开发基础的不同部分。
以下是顺利完成本章所需的最小前提条件。如果您需要更深入理解以下任何主题,请参阅前面的章节:
-
假设您的计算机上已经安装并配置好了 Visual Studio 和 Xamarin,并准备好进行 Android 应用开发。如果您的系统中没有安装 Visual Studio 和 Xamarin,请参考第三章,使用 Xamarin 进行跨平台移动应用开发,并首先安装它们。
-
对 Visual Studio 的基本理解。
-
对 Android 开发基础的基本理解。
-
您应该拥有一个可以访问的有效 Git 账户。
让我们按照以下步骤开始,为移动应用开发构建一个完整的实用工作流:
- 打开 Visual Studio,选择 文件 | 新建 | 项目:

- 在下一个窗口中,从左侧窗格中选择 Android,然后选择 Blank App (Android)。为您的项目命名,并勾选“创建一个新的 Git 仓库”复选框(这将为您的项目创建一个新的 Git 仓库),然后点击确定:

- Visual Studio 将为您创建一个名为
HelloWorld的新项目:

- 完成后,打开解决方案资源管理器查看项目结构。选择 视图 | 解决方案资源管理器:

- 在解决方案资源管理器中,展开
Resources文件夹和layout文件夹,找到一个名为Main.axml的文件。这是布局文件,或者可以说是我们的 MainActivity 的视图:

- 双击
Main.axml打开它。这应该会为您打开布局设计器:

- 如果您无法在左侧看到工具箱,请前往 视图 | 工具箱 使其显示:

-
现在,我们将仅在活动中添加一个文本视图,显示
HelloWorld。 -
在左侧的工具箱中,从表单小部件部分选择 Text (Medium),并将其拖放到 Activity View 中:

- 双击文本视图并将其文本更改为
Hello World:

-
太棒了,
HelloWorld应用程序完成了,现在我们只需构建解决方案,以确保一切正常并准备好在 Android 设备或模拟器上部署。 -
右键点击解决方案,点击 Build Solution:

-
这将为你构建解决方案,完成时,左下角的蓝色条将显示“Build Succeeded”。
-
若要在模拟器上部署和测试应用程序,请点击顶部工具栏中的 Android Emulator Manager (AVD) 图标:

- 这将打开 Android Emulator Manager,在此你可以从 Visual Studio 提供的列表中选择任何现有的虚拟设备并点击启动按钮:

- 然后,在下一个窗口中点击 Launch,而不更改任何配置:

- 这应该会在你的机器上启动一个新的 AVD:

- 现在,在 AVD 启动后返回到 Visual Studio,选择设备并点击播放按钮,将应用程序部署并启动到 AVD 上:

- 一旦应用程序部署完成,它将打开在 AVD 上,你应该能在 MainActivity 屏幕上看到你的 Hello World 文本:

-
恭喜,你的 HelloWorld 应用程序已经在模拟器上成功运行!
-
现在是时候将我们新创建的项目推送到 Git 远程仓库了。记住,在创建项目时我们已经创建了本地仓库,所以现在需要将本地仓库连接到远程 Git 仓库,然后推送代码。
-
在 Visual Studio 中点击右下角的推送图标。这将打开 Team Explorer,如下截图所示:

-
现在,在发布之前,我们需要在 GitHub 上创建一个仓库,以连接到这个本地仓库。
-
访问 GitHub 并登录到你的帐户。
-
创建一个名为
HelloWorld的新仓库,并复制该仓库的 URL。 -
完成后,返回到 Visual Studio 并点击 Publish Git Repo,如前面的截图所示,然后复制仓库链接并点击 Publish:

-
Visual Studio 可能会要求你提供凭证来连接 Git,这是第一次时需要的,但完成后,它应该会将远程仓库与本地仓库配置连接。
-
之后,点击显示“Changes (2)”的编辑图标,将更改提交到本地。
-
添加一些提交备注,然后点击 Commit All:

- 接下来,点击同步链接,将您的提交更改与远程存储库共享:

- 在下一页上,点击 Push 以将您的更改推送到 GitHub 远程存储库。
由于该应用程序没有太多需要测试的内容,我们将在下一个案例研究中介绍。
案例研究 2 - ButtonWidget
在本案例研究中,我们将创建一个新的 Android 应用程序,该应用程序将在点击时显示一个新的文本视图。我们还将为此应用程序编写 UITest:
- 在 Visual Studio 中创建一个新的空白 Android 应用程序项目,命名为
ButtonWidget,然后点击确定:

-
创建项目后,从解决方案资源管理器中的 Resources | Layout 打开
Main.axml文件。 -
然后,从左侧的工具箱中添加一个文本视图和一个按钮到视图中。
-
为每个 ID 分配标识以便在代码中识别它们。您可以选择它们,然后显示属性窗口,在那里为它们指定 ID:

- 同样,将文本视图的可见性设置为隐藏,因为我们将仅在按钮点击时显示此文本:

- 现在,从解决方案资源管理器中打开
MainActivity.cs文件:

- 在
MainActivtiy.cs中,添加代码以在按钮点击时显示文本视图。更改您的代码以匹配以下屏幕截图显示的内容:

-
就这样。应用程序的编码部分已完成。现在,将添加文本视图,但在点击按钮之前不会显示在应用程序中。
-
构建您的应用程序并运行。您会看到应用程序加载时文本视图不可见:

- 现在,点击按钮,查看文本视图是否出现:

-
现在应用程序正常运行,让我们为其编写 Xamarin.UITest 并将其上传到 Xamarin Test Cloud。
-
将一个新的测试项目添加到解决方案中:

- 在新增项目窗口中,从左侧窗格点击测试,然后选择 UI 测试应用程序(Xamarin.UITest | Android)。为项目命名,然后点击确定:

-
接下来,我们需要添加对应用程序项目的引用,以便
UITest项目可以构建和运行应用程序。 -
在
UITest项目下右键单击引用,然后点击添加引用:

- 在接下来的屏幕上,从左侧选择项目,然后选择 ButtonWidget(我们要测试的应用程序项目),然后点击确定:

- 我们已准备好开始为 ButtonWidget 应用程序编写测试了。从解决方案资源管理器中的 TestProjectName | Tests.cs 打开
Tests.cs文件:

- 现在,修改代码,在
Tests.cs文件中添加一个新测试,测试按钮按下时是否显示文本视图:

- 现在,重新构建并部署解决方案,然后点击“测试 | Windows | 测试资源管理器”:

- 你应该能够在测试资源管理器中看到编写的测试:

-
点击“运行所有”以运行测试。
-
现在,要将这些测试上传到 Xamarin Test Cloud,请登录到你的 Xamarin Test Cloud 帐户。
-
进入帐户设置 | 团队与应用。
-
点击“新建团队”按钮以创建新团队。
-
添加成员到团队,然后点击“新建测试运行”。
-
这将打开一个自引导对话框,我们可以在其中选择平台、选择设备等。
-
设置操作系统为 Android,并选择你希望的设备,然后进入最后一步。
-
你将看到如下屏幕,点击命令将测试上传到 Xamarin Test Cloud:

-
在将应用程序上传到 Xamarin Test Cloud 之前,确保在发布构建配置中构建应用程序。
-
在项目的清单文件中添加互联网权限。
-
一旦你使用发布版本构建了项目,你就可以准备好将应用程序上传到 Xamarin,并在那里的 UITests 中进行调试。使用前一步的命令,将
Xamarin.UITest.[版本]修改为你的 UITest 版本,然后输入 APK 文件的完整路径和UITest文件夹的相对路径,然后在项目的根目录中运行。 -
在对命令进行这些更改后,进入根目录,打开命令提示符窗口,并运行命令将 UITests 上传到 Xamarin:

-
通过此操作,应用程序正在部署并在 Xamarin Test Cloud 上进行真实物理设备测试。
-
你可以使用此命令与 CI 工具一起自动化此过程,作为持续集成和持续测试的一部分。
-
在返回 Xamarin Test Cloud 的 Web 应用程序后,我们可以看到在选定的设备上测试已通过:

总结
在本章中,我们已通过整个应用程序开发、部署、编写测试用例,并通过在 Xamarin Test Cloud 上进行持续测试来测试应用程序的过程。本章使用了两个案例研究,逐步解释了整个过程,从创建一个简单的 Android 项目,到编写 UITests 并使用 Test Cloud 进行持续测试。


浙公网安备 33010602011771号