Blog
Blog
PHODAL

最近,朋友圈都在晒 Uncle Bob 的新书《Clean Architecture》(中文名《架构整洁之道》)的相关内容,书架上也因此新增了一本书。阅读了之后,倒是产生了一些想法,便想写篇文章记录一下。

每个人都有自己对于代码的看法,有自己的偏好。对于我来说,也是如此。作为一个实用主义者,我遵循的东西,比较少,也比较简单。多了,记不住,也不实用。

最近,几个月,几星期,几天,忙在一个大型的 “markdown 工程” 里。平时的时间变得不充裕了,原本早九晚六剩下的时间,远远不够用。周末,在补充这本周、本月里的几点技术心得、笔记的时候,发现:嗯,我有 700+ 的博客了。再算上时间,7 年,平均每年在 100 篇的水平。数量上一算,大抵是有些可怕的。而,我,大抵、或许还是几个在写博客的人吧。

之前在我的那个硬件网站【玩点什么】,遇到了一个 Python 的中文编码问题。大抵的问题是一个中文的 URL 的识别问题。 在访问 URL [https://www.wandianshenme.com/play/category/搭建指南/](https://www.wandianshenme.com/play/category/%E6%90%AD%E5%BB%BA%E6%8C%87%E5%8D%97/) 的时候,报了一个错误: ``` UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range ``` 之前在网上搜索的相关结果都是 Python 2.7 下才有这个问题。然而,在相关的 python 代码里,我已经使用 ``# -*- coding: utf-8 -*-`` 声明了 UTF-8 编码,还是报了这个问题。 对于使用 Django,而且 Python 版本是 2.7 来说,可以尝试这么解决: ```python import sys from importlib import reload reload(sys) if sys.version[0] == '2': reload(sys) sys.setdefaultencoding("utf-8") ``` 我也尝试了这样的一个方法,但是不 work ``` export PYTHONIOENCODING=UTF-8 ``` 于是,之前便不了了之了。 直到最近我的 iTerm 自动将 Git 相关的内容变成了中文: ``` 枚举对象: 5, 完成. 对象计数中: 100% (5/5), 完成. 使用 8 个线程进行压缩 压缩对象中: 100% (3/3), 完成. 写入对象中: 100% (3/3), 705 bytes | 705.00 KiB/s, 完成. 总共 3 (差异 2),复用 0 (差异 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To https://github.com/phodal/play 5af94c0..573f947 master -> master ``` 我又尝试去解决这个问题,结果发现是类似的问题,只需要: ``` export LANG=en_US.UTF-8 export LANGUAGE=en_US.UTF-8 export LC_ALL=en_US.UTF-8 ``` 这样一来,问题就解决了。

过去的几个月里,我们一直在开发一个混合应用。前端框架使用的是 Angular,但是在某些 Android 机型上运行的时候,遇到不支持 History API 的问题。

我的上一篇关于自动化测试的文章,大抵已经在一年以前——一篇关于前端自动化测试的 BDD 框架对比。这么长的时间里,没有相关的文章,总得给自己找一个合适的理由。 编写测试是开发人员日常工作的一小部分,但并非是全部。即使是专业的测试人员,自动化测试也并非是全部的工作。与此同时呢,有了单元测试之外,对于自动化测试的需求,并不是那么强烈。速度,是我们不考虑自动化测试的主要原因,运行起来慢了,进一步地导致编写测试也慢了。UI 上一旦有一丁点的修改,那怕是得引起多少的不愉快,不得不噗呲噗呲地去修改测试。我想说的无非就是,**避免编写 “可怕” 地自动化测试**,尽量用你的单元测试来保障质量。要是你们有 KPI 的限制,请将以上的文字当成废话。 似乎在有些公司里,自动化测试、单元测试并不是技术负责人要考虑的问题,可在我司并非如此,测试也在技术的范围里。每每开始一个项目时,就不得不去考虑自动化测试的问题,选用什么框架合适、需要前后端如何配合、怎样去替换第三方的服务。这些内容完全交给测试人员吧,怕是会遇到一些不顺。测试人员有自己的测试技术栈,拥有自己的 “银弹” —— 过去的经验和代码库。哪怕经验再丰富的测试人员,有时遇到一些新的项目、技术栈,这些东西可能就用不上了,又或者是使用某些框架可能会更加便利。因此呢,要成为更好的技术人,测试也是要考虑的范畴。 说到 Web 方面的自动化测试,我算是个有经验的老手。从顶层的 DSL 到底层的 Web Driver,到底来说,还是颇有经验的。可是说到 APP 的自动化测试,在项目上尝试过,但也不敢说经验丰富。而最近的项目,正在实施相应的移动应用自动化测试。看了看方案,与之前的 Web 或者是 React Native 的自动化测试,从底层对比架构吧,相似、差距也不是太大。便想着写篇文章来记录一下,相应的架构设计。 ## 技术远景 作为一个团队的技术负责人,我希望:拥有一个移动应用测试架构,它能快速让测试人员快速上手——阅读、编写测试用例。与此同时,我希望这些测试用例是能让非技术人员阅读,诸如业务分析人员,并且符合真实的用户使用场景。 ## 架构设计 当我们谈到业务分析人员也能编写的测试,我们说的只有 BDD(Behavior Driven Development,行为驱动开发)。它是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA(测试人员)和非技术人员或商业参与者之间的协作。 BDD 在这一种上相当的迷人——能让非技术人员编写测试。而其核心的部分在于:创建了一个环境隔离的 DSL,仿人类语言的 DSL。咳咳,这个 DSL 实现起来,可不轻松。关注顶层 DSL 的同时,开发人员还要努力实现好底层的实现。举个简单的例子,如下是之前在 BDD 一文中的 DSL 示例,这是顶层的设计: ```markdown 功能: 失败的登录 场景大纲: 失败的登录 假设 当我在网站的首页 ``` 对应的,开发人员需要编写实现: ```javascript ... Given('当我在网站的首页', function() { return this.driver.get('http://0.0.0.0:7272/'); }); .. ``` 从上述的代码中,一眼就可以看出复杂的地方,实现一个领域特定(业务特定)的 DSL 语言。 我们要完成的 DSL 实现,上层是提供一个 DSL,下层则是对接 driver 的 Agent 层。在 Web 领域里,这个 driver 的 Agent 层负责对接不同的浏览器,诸如 Selenium,driver 则视不同的浏览器而有所不同,如 ChromeDriver、FirefoxDriver、PhantomJSDriver 等等。Selenium 这样的测试框架,除了通过 driver 直接操作了浏览器,还提供了不同语言的编程接口。 相似的,在 APP 领域也有这样的方案,它要通常这个 agent 来连接物理设备,并提供一系列的编程接口。 ## 架构设计方案 对整个架构有了一个基本的认识之后,让我们继续往下移动,来重新发掘一下:我们究竟需要哪些基本元素? - BDD 测试框架,为开发人员提供可创建 DSL 的接口。 - 移动设备的测试编程接口,提供一个操作移动应用的接口。 - 连接移动设备的操作库,即移动端的 WebDriver。 - 用于编写测试时的 UI 检查工具。 从这一点上来看,它与 Web 应用的 BDD 架构差不多。为此,我们需要准备如下的一些框架: - Robot Framework,一个支持 BDD 的、基于 Python 编写的功能自动化测试软件框架。 - Appium,是一个开源测试自动化框架,用于原生,混合和移动 Web 应用程序。它使用 WebDriver 协议来驱动 iOS、Android 和 Windows 应用程序。 - XCUITest Driver,基于 Apple 官方的界面自动化测试 XCUITest 封装的测试接口,可以直接执行 iOS 的自动化测试。 - UiAutomator2 Driver,则是 Google 官方提供的用于 Android 系统的测试接口,可以直接执行 Android 的自动化测试。 - Appium Inspector,用于查找 iOS/Android 上的元素 - UiAutomator Viewer,由 Android SDK 自带的元素查找工具。 由于我们计划的顶层是由 DSL 来实现,而对应的 BDD 层实现是由 Robot Framework 来完成的。Robot Framework 使用的是 Python 语言,我们就需要找到对应的 Python 主要依赖有: - robotframework,即 Robot Framework 本身 - robotframework-appiumlibrary,用于为 Robot Framework 提供 Appium 相应的接口封装 - robotframework-ride,用于 Robot Framework 的测试数据编辑器 有了这些主要的库,我们就可以编写我们的 DSL?不,我们还需要配置好,对应的移动端 Driver。 **Android Driver 依赖** 比较简单,通过 ``appium-uiautomator2-driver`` 库就拥有了 driver。 **iOS Driver 依赖** 为了实现对 iOS 设备的自动化测试,需要安装 XCUITest,为此我们需要下面的这一系列工具: - ``libimobiledevice``,是一个跨平台的用于与 iOS 设备通讯的协议库,它可以让 Windows、macOS、GNU/Linux 系统连接 iPhone/iPod Touch 等iOS 设备。 - ``carthage`` 是一个简单的、去中心化的依赖管理工具。 - ``ios-deploy`` 是一个使用命令行安装 iOS 应用程序到连接设备的工具 - ``xcodebuild``,是苹果发布自动构建的工具。 - ``xcpretty``,用于对 xcodebuild 的输出进行格式化,包含输出 report 功能。 看,有了这一系列的知识,我们几乎知道怎么做搭建移动应用的自动化测试。 ## 结论 还是 Web 大法好。

所谓最优,就是从一堆非最佳的方案中找到最好的一个,或者整合一个。

这篇文章,则针对上一篇文章,做一些相应的插件管理机制相关的补充。该方案基于 Cordova 框架的插件管理方案,做了尽可能的精简。

最近的一个项目,是一个关于在移动应用中嵌入 WebView,并在其中实现 JavaScript 能调用原生代码。虽然已经有 Cordova 这样的成熟方案,但是它太 “重” 了——直接在一个拥有大量代码的项目上,修改起来并不容易。

“微” 害架构,即微架构以不合理的方式运行着,其表现形式不适当地采用 “微架构”(微服务、APP 插件化、微前端等)技术拆分臃肿的单体应用,导致软件架构进一步复杂化、难以维护,使得原本具有优势的微架构微微出现一些问题。

Feeds

RSS / Atom

最近文章

存档

2026 (1 月)
2025 (12 个月)
2024 (12 个月)
2023 (12 个月)
2022 (12 个月)
2021 (12 个月)
2020 (12 个月)
2019 (12 个月)
2018 (12 个月)
2017 (12 个月)
2016 (12 个月)
2015 (12 个月)
2014 (12 个月)
2013 (9 个月)
2012 (3 个月)
2011 (1 月)
2010 (1 月)
1991 (1 月)

分类

标签

作者