diff --git a/Chapter1 - iOS/1.75.md b/Chapter1 - iOS/1.75.md
index dd0e4da..f797ead 100644
--- a/Chapter1 - iOS/1.75.md
+++ b/Chapter1 - iOS/1.75.md
@@ -248,7 +248,7 @@ TDD 强调不断的测试推动代码的开发,这样`简化了`代码,保
TDD 开发过程类似下图:
-
+
- 先编写该功能的测试用例,实现测试代码。这时候去跑测试,是不通过的,也就是到了红色的状态
- 然后编写真正的功能实现代码。这时候去跑测试,测试通过,也就是到了绿色的状态
@@ -266,11 +266,11 @@ TDD 开发过程类似下图:
1. 新建一个工程,确保 “Include Unit Tests” 选项是选中的状态
- 
+ 
2. 创建后的工程目录如下
- 
+ 
3. 删除 Xcode 创建的测试模版文件 `TDDDemoTests.m`
@@ -284,7 +284,7 @@ TDD 开发过程类似下图:
6. 实现测试用例代码。创建继承自 Unit Test Case class 的测试类,命名为 `工程前缀+测试类名+Test`,也就是 `TDDPersonTest.m`。
- 
+ 
7. 因为要测试 Person 类,所以在主工程中创建 Person 类
@@ -986,67 +986,158 @@ SPEC_END
很多 UI 自动化测试框架的底层实现都依赖于 `Accessibility`,也就是 App 可用性。`UI Accessibility` 是 iOS 3.0 引入的一个人性化功能,帮助身体不便的人士方便使用 App。
+Accessibility 通过对 UI 元素进行分类和标记。分类成类似按钮、文本框、文本等类型,使用 identifier 来区分不同 UI 元素。[无痕埋点的设计与实现](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter1%20-%20iOS/1.55.md)里面也使用 `accessibilityIdentifier` 来绑定业务数据。
+
+1. 使用 Xcode 自带的 UI测试则在创建工程的时候需要勾选 “Include UI Tests”。
+2. 像单元测试意义,UI 测试方法命名以 test 开头。将鼠标光标移到方法内,点击 Xcode 左下方的红色按钮,开始录制 UI 脚本。
+
+
+
+解释说明:
+
+```objective-c
+/*! Proxy for an application that may or may not be running. */
+@interface XCUIApplication : XCUIElement
+// ...
+@end
+```
+
+- `XCUIApplication launch` 来启动测试。`XCUIApplication` 是 UIApplication 在测试进程中的代理,用来和 App 进行一些交互。
+
+- 使用 `staticTexts`来获取当前屏幕上的静态文本(UILabel)元素的代理。等价于 `[app descendantsMatchingType:XCUIElementTypeStaticText]`。XCUIElementTypeStaticText 参数是枚举类型。
+
+ ```objective-c
+ typedef NS_ENUM(NSUInteger, XCUIElementType) {
+ XCUIElementTypeAny = 0,
+ XCUIElementTypeOther = 1,
+ XCUIElementTypeApplication = 2,
+ XCUIElementTypeGroup = 3,
+ XCUIElementTypeWindow = 4,
+ XCUIElementTypeSheet = 5,
+ XCUIElementTypeDrawer = 6,
+ XCUIElementTypeAlert = 7,
+ XCUIElementTypeDialog = 8,
+ XCUIElementTypeButton = 9,
+ XCUIElementTypeRadioButton = 10,
+ XCUIElementTypeRadioGroup = 11,
+ XCUIElementTypeCheckBox = 12,
+ XCUIElementTypeDisclosureTriangle = 13,
+ XCUIElementTypePopUpButton = 14,
+ XCUIElementTypeComboBox = 15,
+ XCUIElementTypeMenuButton = 16,
+ XCUIElementTypeToolbarButton = 17,
+ XCUIElementTypePopover = 18,
+ XCUIElementTypeKeyboard = 19,
+ XCUIElementTypeKey = 20,
+ XCUIElementTypeNavigationBar = 21,
+ XCUIElementTypeTabBar = 22,
+ XCUIElementTypeTabGroup = 23,
+ XCUIElementTypeToolbar = 24,
+ XCUIElementTypeStatusBar = 25,
+ XCUIElementTypeTable = 26,
+ XCUIElementTypeTableRow = 27,
+ XCUIElementTypeTableColumn = 28,
+ XCUIElementTypeOutline = 29,
+ XCUIElementTypeOutlineRow = 30,
+ XCUIElementTypeBrowser = 31,
+ XCUIElementTypeCollectionView = 32,
+ XCUIElementTypeSlider = 33,
+ XCUIElementTypePageIndicator = 34,
+ XCUIElementTypeProgressIndicator = 35,
+ XCUIElementTypeActivityIndicator = 36,
+ XCUIElementTypeSegmentedControl = 37,
+ XCUIElementTypePicker = 38,
+ XCUIElementTypePickerWheel = 39,
+ XCUIElementTypeSwitch = 40,
+ XCUIElementTypeToggle = 41,
+ XCUIElementTypeLink = 42,
+ XCUIElementTypeImage = 43,
+ XCUIElementTypeIcon = 44,
+ XCUIElementTypeSearchField = 45,
+ XCUIElementTypeScrollView = 46,
+ XCUIElementTypeScrollBar = 47,
+ XCUIElementTypeStaticText = 48,
+ XCUIElementTypeTextField = 49,
+ XCUIElementTypeSecureTextField = 50,
+ XCUIElementTypeDatePicker = 51,
+ XCUIElementTypeTextView = 52,
+ XCUIElementTypeMenu = 53,
+ XCUIElementTypeMenuItem = 54,
+ XCUIElementTypeMenuBar = 55,
+ XCUIElementTypeMenuBarItem = 56,
+ XCUIElementTypeMap = 57,
+ XCUIElementTypeWebView = 58,
+ XCUIElementTypeIncrementArrow = 59,
+ XCUIElementTypeDecrementArrow = 60,
+ XCUIElementTypeTimeline = 61,
+ XCUIElementTypeRatingIndicator = 62,
+ XCUIElementTypeValueIndicator = 63,
+ XCUIElementTypeSplitGroup = 64,
+ XCUIElementTypeSplitter = 65,
+ XCUIElementTypeRelevanceIndicator = 66,
+ XCUIElementTypeColorWell = 67,
+ XCUIElementTypeHelpTag = 68,
+ XCUIElementTypeMatte = 69,
+ XCUIElementTypeDockItem = 70,
+ XCUIElementTypeRuler = 71,
+ XCUIElementTypeRulerMarker = 72,
+ XCUIElementTypeGrid = 73,
+ XCUIElementTypeLevelIndicator = 74,
+ XCUIElementTypeCell = 75,
+ XCUIElementTypeLayoutArea = 76,
+ XCUIElementTypeLayoutItem = 77,
+ XCUIElementTypeHandle = 78,
+ XCUIElementTypeStepper = 79,
+ XCUIElementTypeTab = 80,
+ XCUIElementTypeTouchBar = 81,
+ XCUIElementTypeStatusItem = 82,
+ };
+ ```
+
+- 通过 `XCUIApplication` 实例化对象调用 `descendantsMatchingType:` 方法得到的是 `XCUIElementQuery` 类型。比如 `@property (readonly, copy*) XCUIElementQuery *staticTexts;`
+
+ ```objective-c
+ /*! Returns a query for all descendants of the element matching the specified type. */
+ - (XCUIElementQuery *)descendantsMatchingType:(XCUIElementType)type;
+ ```
+
+- `descendantsMatchingType` 返回所有后代的类型匹配对象。`childrenMatchingType` 返回当前层级子元素的类型匹配对象
+
+ ```objective-c
+ /*! Returns a query for direct children of the element matching the specified type. */
+ - (XCUIElementQuery *)childrenMatchingType:(XCUIElementType)type;
+
+ ```
+
+- 拿到 `XCUIElementQuery` 后不能直接拿到 `XCUIElement`。和 `XCUIApplication` 类似,`XCUIElement` 不能直接访问 UI 元素,它是 UI 元素在测试框架中的代理。可以通过 `Accessibility` 中的 `frame`、`identifier` 来获取。
+
+
+
+对比很多自动化测试框架都需要找出 UI 元素,也就是借助于 `Accessibility` 的 `identifier`。这里的唯一标识生成对比[为 UIAutomation 添加自动化测试标签的探索](http://yulingtianxia.com/blog/2016/03/28/Add-UITest-Label-for-UIAutomation/)]
+
+
+
+第三方 UI 自动化测试框架挺多的,可以查看下典型的 [appium](https://github.com/appium/appium)、[macaca](https://github.com/alibaba/macaca)。
+
## 七、 测试经验总结
-
-
-
-
-1. 背景
-2. 软件测试的概念、分类
-3. 本文主要想讲的测试划分。
-
-- 每个类具有什么属性、具有什么方法都是确定的,所以拿 Objective-C 举例子,`.h` 中会有公有的属性以及方法,`.m` 中一般是私有属性和私有方法、公有方法。类的行为设计为方法,写代码之前我们一般需要做到心中有数,一个功能需要几个类、每个类的属性和方法分别是什么,需要暴露什么属性和接口。**UML图** 不是必须要画,但是需要胸有成竹。针对一个类在测试的时候 `.m` 文件中的私有方法没有办法在 Unit Test 类中访问,一般可以将需要测试的类增加分类。在分类的 `.h` 文件中将方法进行声明。在测试的 Uint Test 中引入分类头文件。下面举例子
-
-```Objective-C
-// Person.h
-
-- (void)eat;
-
-// Person.m
-
-- (void)eat
-{
- NSLog(@"eat");
-}
-
-- (vood)sleep
-{
- NSLog(@"sleep");
-}
-
-// Person+UnitTestHelper.h
-
-- (void)sleep;
-```
-
-另一种思路是没必要针对每个类的私有方法或者每个方法进行测试,因为等全部功能做完后针对每个类的接口测试,一般会覆盖据大多数的方法。等测试完看如果方法未被覆盖,则针对性的补充 Unit Test
+TDD 写好测试再写业务代码,BDD 先写实现代码,再写基于行为的测试代码。另一种思路是没必要针对每个类的私有方法或者每个方法进行测试,因为等全部功能做完后针对每个类的接口测试,一般会覆盖据大多数的方法。等测试完看如果方法未被覆盖,则针对性的补充 `Unit Test`。
目前,UI 测试(appium) 还是建议在核心逻辑且长时间没有改动的情况下去做,这样子每次发版本的时候可以当作核心逻辑回归了,目前来看价值是方便后续的迭代和维护上有一些便利性。其他的功能性测试还是走 BDD。
-对于类、函数、方法的走 TDD,老老实实写 UT、走 UT 覆盖率的把控
+对于类、函数、方法的走 TDD,老老实实写 UT、走 UT 覆盖率的把控。
-> 目前,UITesting 还是建议在核心逻辑且长时间没有改动的情况下去做,这样子每次发版本的时候可以当作核心逻辑回归了,目前来看价值是方便后续的迭代和维护上有一些便利性。例如之前我们分享SDK升级微信和QQSDK,以便支持 universal link 功能,当时有了UITesing,基本上免去了测试人员介入。
+UITesting 还是建议在核心逻辑且长时间没有改动的情况下去做,这样子每次发版本的时候可以当作核心逻辑回归,目前来看价值是方便后续的迭代和维护上有一些便利性。例如用户中心 SDK 升级后,当时有了UITesing,基本上免去了测试人员介入。
-> 如果是一些活动页和逻辑经常变动的,老老实实走测试黑盒...
+如果是一些活动页和逻辑经常变动的,老老实实走测试黑盒...
-> 我觉得一直有个误区,就是觉得自动测试是为了质量,其实质量都是附送的,测试先行是让开发更快更爽的
+我觉得一直有个误区,就是觉得自动测试是为了质量,其实质量都是附送的,测试先行是让开发更快更爽的
-> appium 但是后来他自己也说 在iOS平台好像不是很好搞 能做的事情挺少的
+
-> 投入产出比是不高 那你试试monkey test
-
-> wwdc上这张图也很清楚,UI其实需要的占比很小的,还是要靠单测驱动
-
-> 当时我找个UITest的bug都花了不少力气
-
-> UTTest主要测逻辑的
-
-> UITest可以测你页面渲染的对不对、按钮点击是否有问题
-
-不过 macaca appium 都可以做到iOS自动化
+WWDC 这张图也很清楚,UI 其实需要的占比较小,还是要靠单测驱动。
diff --git a/Chapter1 - iOS/1.80.md b/Chapter1 - iOS/1.80.md
index c8347eb..e69de29 100644
--- a/Chapter1 - iOS/1.80.md
+++ b/Chapter1 - iOS/1.80.md
@@ -1,2 +0,0 @@
-# 打造一个通用、可配置、多句柄的数据上报 SDK
-
diff --git a/assets/2020-07-14-TestingPercentage.png b/assets/2020-07-14-TestingPercentage.png
new file mode 100644
index 0000000..d5c83d6
Binary files /dev/null and b/assets/2020-07-14-TestingPercentage.png differ
diff --git a/assets/2020-07-15-XcodeUITesting.png b/assets/2020-07-15-XcodeUITesting.png
new file mode 100644
index 0000000..35e36a2
Binary files /dev/null and b/assets/2020-07-15-XcodeUITesting.png differ