├── 01Quick Start.md ├── 02Testing Basics.md ├── 03Writing Test Classes and Methods.md ├── 04Running Tests and Viewing Results.md ├── 05Debugging Tests.md ├── 06Automating the Test Process with Continuous Integration.md ├── 07Writing Testable Code.md ├── 08Command-Line Testing.md ├── 09Transitioning from OCUnit to XCTest.md ├── Document Revision History.md ├── Introduction.md └── README.md /01Quick Start.md: -------------------------------------------------------------------------------- 1 | 本章由CocoaChina翻译小组成员dada翻译 [github地址](https://github.com/sherlockdan) 2 | 3 | #快速开始 4 | 5 | 本文的目的在于让测试成为你软件开发的重要组成部分,并使测试更方便并易于使用。 6 | 7 | ##Test Navigator 测试导航栏 8 | 测试时我们会频繁使用Xcode5的测试导航栏。 9 | 10 | 测试导航是Xcode工作区的一部分,被设计用来方便的创建、管理、运行和审核测试功能。点击导航的选择栏,在问题导航和调试导航栏的中间那个就是测试导航。当你的工程定义了一组测试功能,你会在导航栏看到如下图所示: 11 | 12 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-test_nav-overall_2x.png) 13 | 14 | 上面的测试导航展示了一个样板工程中的测试包、类和方法的分级表。这个工程是一个计算器应用。计算器引擎实现为一个框架包。你可以`SampleCalcTests`测试包的分级的顶部看到应用中的测试代码。 15 | 16 | >注意: Xcode的目标生成产品。Xcode的测试目标生成测试包并展示在测试导航栏中。 17 | 18 | >如果你的测试使用存储数据文件、图片,和其他的类型,则可以把它们添加到测试包中,并使用`NSBundle`的API在运行时访问。和测试类一同使用`+[NSBundle bundleForClass:]`来保证测试类从包中取得正确的数据。更多的信息可见[NSBundle Class Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSBundle_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40003624). 19 | 20 | >Xcode schemes 控制那些编译的内容。Schemes也可以控制可用的测试方法来执行测试操作。你可以在测试导航面板列表中通过Control+单击项目来启动或关闭测试包、类和方法,或者从快捷菜单中启用或者关闭测试,也可以在scheme中启用或者关闭测试。 21 | 22 | 23 | 24 | 此视图中的激活的测试包是`SampleCalcTests`。`SampleCalcTests`包括了一个测试类,总共有9个测试方法。 25 | 当你按住表中任何一个项目的箭头,运行按钮![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-test_navigator_run_button_2x.png) 26 | 会展示右边的项目名。这是比较快捷的方式运行包里所有的测试或者任何独立的测试。测试返回通过或失败结果给Xcode。当测试被执行,标识会更新从而向你展示结果,绿色的对勾标记是通过,红色的X为失败。在下面的测试导航面板中,两个测试被判定为失败。 27 | 28 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-test_nav-indicators_2x.png) 29 | 30 | 31 | 点击列表中的任意测试类或测试方法都会在源码编辑器中打开测试类。测试类和方法标记在源码编辑器的侧栏中,和标记放在一起,和在测试导航面板中的工作方式相同。测试失败在源码编辑器中相关的断言处展示结果字符串。 32 | 33 | 测试导航面板底部是添加按钮 (+) ,还有一个过滤控制器。你可以缩小范围,比如只在活跃的scheme中测试或者只测试失败的测试,也可以通过名称筛选测试。 34 | 35 | 更多测试导航详细信息可见[Test Navigator Help](https://developer.apple.com/library/mac/recipes/xcode_help-test_navigator/_index.html#//apple_ref/doc/uid/TP40013329)。 36 | 37 | 38 | 39 | ##给你的应用添加测试 40 | 41 | 在Xcode5中创建新的应用和框架/库类会预配置一个测试目标。当你打开新工程,在测试导航面板上可以看到一个测试包、一个测试类和一个测试方法的模板。但是如果打开一个比较老的版本的Xcode的工程就不会有测试目标了。下面的工作流程展示了一个假定没有集成测试目标的工程。 42 | 43 | 44 | ###创建测试目标 45 | 打开测试目标,点击左下角的(+)按钮,从菜单中选择New Test Target。 46 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_01_2x.png) 47 | 48 | 根据你的设置偏好和需求,在新目标助手中编辑Product Name和其他参数。 49 | 50 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_02_2x.png) 51 | 52 | 点击完成按钮来添加目标,测试导航面板中包含了模板测试类和一个测试方法。 53 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_03_2x.png) 54 | 55 | ###运行测试并查看结果 56 | 现在你已经把测试加到了工程中,你会想要运行这些测试来做一些有用的事。但首先要在测试导航面板中把鼠标悬停在`SampleCalcTests`测试类上并点击运行按钮来运行所有的测试方法,在测试导航面板中抛出了一个错误来。点击`testExample`方法可以看到下面图中的测试结果、源代码和高亮的错误情况: 57 | 58 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_04_2x.png) 59 | 60 | 61 | 62 | 测试失败的原因是测试的模板类包含了一个默认的测试方法`XCTFail()`,一个强制判为失败的断言。 63 | 64 | ###编辑测试代码然后继续运行 65 | 66 | 因为这是一个计算器应用的样板工程,你可能要在最开始的时候检查它是否能正确执行加法。因为测试编译到app项目里面,不管多复杂,你都可以按照你的需求添加所有的上下文和其他所需信息来执行测试。 67 | 68 | 插入下方的#import和实例变量声明到`SampleCalcTests.m`文件中 69 | 70 | 71 | 72 | #import 73 | // 74 | // Import the application specific header files 75 | #import "CalcViewController.h" 76 | #import "CalcAppDelegate.h" 77 | 78 | @interface CalcTests : XCTestCase { 79 | // add instance variables to the CalcTests class 80 | @private 81 | NSApplication *app; 82 | CalcAppDelegate *appDelegate; 83 | CalcViewController *calcViewController; 84 | NSView *calcView; 85 | } 86 | @end 87 | 88 | 89 | 90 | 91 | 给测试方法一个描述性名称,比如`testAddition`,然后添加到implementation资源中。 92 | 93 | 94 | 95 | 96 | 97 | - (void) testAddition 98 | { 99 | // obtain the app variables for test access 100 | app = [NSApplication sharedApplication]; 101 | calcViewController = (CalcViewController*)[[NSApplication sharedApplication] delegate]; 102 | calcView = calcViewController.view; 103 | 104 | // perform two addition tests 105 | [calcViewController press:[calcView viewWithTag: 6]]; // 6 106 | [calcViewController press:[calcView viewWithTag:13]]; // + 107 | [calcViewController press:[calcView viewWithTag: 2]]; // 2 108 | [calcViewController press:[calcView viewWithTag:12]]; // = 109 | XCTAssertEqualObjects([calcViewController.displayField stringValue], @"8", @"Part 1 failed."); 110 | 111 | [calcViewController press:[calcView viewWithTag:13]]; // + 112 | [calcViewController press:[calcView viewWithTag: 2]]; // 2 113 | [calcViewController press:[calcView viewWithTag:12]]; // = 114 | XCTAssertEqualObjects([calcViewController.displayField stringValue], @"10", @"Part 2 failed."); 115 | } 116 | 117 | 118 | 119 | 120 | 121 | 现在,点击运行按钮运行`testAddition`方法。 122 | 123 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_05_2x.png) 124 | 125 | >**注意:**测试导航的列表的改变,反应了`testExample`已经被替换为`testAddition`。 126 | 127 | 这里仍有错误,看下面的代码,第一部分成功,第二部分有问题。仔细观察,错误很明显:字符引用"11"多了1。改为“10”就能测试成功了。 128 | 129 | 130 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_06_2x.png) 131 | 132 | 133 | 134 | ###相同的通用代码使用setUp() 和 tearDown()方法 135 | 136 | Xcode运行测试方法一次测试所有测试包中的测试类。在这个小例子里只有一个测试方法被实现了,这里需要访问三个计算器应用对象变量的功能。如果在该类中写了4个或5个测试方法,你会发现你在每一次测试方法获得应用的对象状态中,重复了相同的代码。XCTest框架为测试类提供了实例方法`setUp` 和 `tearDown`,你可以用它在每个测试方法运行之前或者之后运行通用代码的调用。 137 | 138 | 139 | setUp和tearDown很简单。在`testAddition`资源里`Mac_Calc_Tests.m`,在第四行用// obtain the app variable for test access 开头,并将它们粘贴到模板提供的默认的`setUp`实例方法中。 140 | 141 | - (void)setUp 142 | { 143 | [super setUp]; 144 | // Put setup code here. This method is called before the invocation of each test method in the class. 145 | 146 | // obtain the app variables for test access 147 | app = [NSApplication sharedApplication]; 148 | calcViewController = (CalcViewController*)[[NSApplication sharedApplication] delegate]; 149 | calcView = calcViewController.view; 150 | } 151 | 152 | 现在使用少的重复代码添加第二个测试方法:`testMultiplication`以及其他。 153 | 154 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-add_testing_07_2x.png) 155 | 156 | 157 | ##总结 158 | 当你看完这篇简短的快速开始,会发现向工程添加测试很简单。这里有几个要注意的地方: 159 | 160 | 1.Xcode配置好了大部分基本的测试设置。当你添加一个测试目标,Xcode会为项目创建测试包文件,添加测试包到测试导航面板,为工程添加XCTest框架,并且为测试类和方法提供模板。 161 | 162 | 2.测试导航面板可以很方便的定位和编辑测试方法。你可以使用导航面板里的指示按钮快速运行测试,或在测试类实现打开时直接在资源编辑器中运行。当测试失败,测试导航面板中的标识跟源码编辑器中错误的地方相对应。 163 | 164 | 3.单个测试方法可以包括多个断言,导致单个通过或失败结果。这个方法可让你根据项目需要创建简单或者非常复杂的测试。 165 | 166 | 4.`setUp` 和 `tearDown`实例方法为你提供了一种途径来把相同的代码用在很多个测试方法中,从而获得更高的一致性,并简化调试。 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /02Testing Basics.md: -------------------------------------------------------------------------------- 1 | 本章由CocoaChina翻译小组成员dada翻译 [github地址](https://github.com/sherlockdan) 2 | 3 | #测试基础# 4 | 测试是指检验你的应用程序代码和库代码能否成功运行的过程,用于衡量预期结果。通过执行一些操作,测试可在执行一些操作后检查一个对象的实例变量的状态,以确定你的代码在受到边界条件变化时是否会抛出一个特定异常等。 5 | 6 | ##定义测试范围 7 | 所有的软件都是组合体,也就是说,小组件组合到一起形成较大的、功能更强的高级组件,直到符合项目的需求。良好的测试需要涵盖该组合的所有功能。其中单元测试通常处理该项目功能级的小组件。而XCTest允许你为任何层次结构的各个级别的组件编写相应的测试。 8 | 9 | 测试组件由什么构成取决于你自己,可以是一个类中的一个方法,也可以是完成一个基本目的的一组方法。例如,可以是一个算数运算,就像[Quick Start](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_1_quick_start/testing_1_quick_start.html#//apple_ref/doc/uid/TP40014132-CH2-SW1)一章中的计算器应用的例子。处理TableView的内容间和代码数据结构中持有的列表名称间的交互有不同的方法。每个方法和操作都意味着应用程序功能的组成部分和对其的测试。一个测试组件的行为应该是完全确定的,无论测试成功或者失败。 10 | 11 | 把你的应用程序的行为划分为越多的组件,就越能有效地测试你的代码是否能满足参考标准的各种细节,尤其是当项目不断增长和变化时。对于有很多组件的大型项目来说,你需要运行很多测试来彻底检测整个项目。如果可能的话,测试应该快速运行,但有一些测试确实很大,所以运行的可能会慢些。当有一些故障问题时,可以经常运行一些小型的快速的测试,这样可以轻松诊断和修复问题。 12 | 13 | 为项目组件设计测试是测试驱动开发(test-drivendevelopment,TDD)的基础,也是一种在编写代码测试之前先编写测试逻辑的编码方式。这种开发方法可以让你在实施之前确定代码需求和边界情况。编写测试后,你要开发旨在通过测试的算法。在代码通过测试后,你才有了提高代码的基础,才有信心在下一次运行这些测试时能鉴定一些预期行为(导致你的产品产生bug)的变化。 14 | 15 | 甚至在你不使用测试驱动开发时,测试还可以降低修改代码时引入的bug数量,从而帮你提高代码的特性和功能。在一款运行的应用程序中进行测试以确保未来的更改不会改变应用的行为。当你修复这些bug后,你需要添加测试以确认该bug已经被修复。测试还应该检测你的代码,所以有成功和失败两种预期,以覆盖所有边界条件。 16 | 17 | >注意:为一个没有考虑到测试的项目添加测试可能会要求重构部分代码来使测试更加简单。“[Writing Testable Code](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/A1-guidelines_writing_testable_code/A1-guidelines_writing_testable_code.html#//apple_ref/doc/uid/TP40014132-CH8-SW1)”包含有用的编写可测试代码的简单指南。 18 | 19 | 组件可以包括你的应用程序的各部分之间的交互。由于有些类型的测试可能需要很长时间,所以你可能希望定期或者只在一台服务器上运行它们。下面一节你将看到,你可以组织自己的测试并以多种方式运行它们,以满足不同的需求。 20 | 21 | ##应用程序测试和库测试 22 | Xcode提供两种类型的测试:应用程序测试和库测试。 23 | 24 | 应用程序测试。应用程序测试可以检查app的代码组件,比如计算器的算术运算的例子。你可以利用应用程序测试来确保你的UI控件保持原有位置,并且你的控件和控制器对象能够和对象模型正确地工作。 25 | 26 | 库测试。库测试可检查独立代码(不在应用程序中运行的代码)的行为是否正确。利用库测试,你可以将整个库的组件放在一起进行测试,通常是测试库的对象和方法。你也可以使用库测试来执行代码的压力测试,以确保它在极端的情况下也能正确执行(不大可能出现在一个运行的app中)。这些测试可以帮助你生成“强壮的”代码,即使在没有预料的情况下也可以正常运行。 27 | 28 | ##XCTest—Xcode测试框架 29 | XCTest是Xcode 5及以上版本中使用的测试框架。如果你以前用过Xcode OCUnit测试,你可能会发现XCTest和OCUnit有些相似。XCTest是OCUnit的更现代化的替代,可以更好的与Xcode集成,为将来Xcode测试功能的改进奠定了基础。Xcode把XCTest.框架并入你的项目,而不是SenTestingKit.框架。该框架提供可以让你设计测试并在代码中运行的API。 30 | >注意:Xcode包括一个迁移助手,可用来转换包含OCUnit测试的项目。更多OCUnit向XCTest转换的详细信息,请参阅“[Transitioning from OCUnit to XCTest](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/A3-transitioning_ocunit_to_xctest/A3-transitioning_ocunit_to_xctest.html#//apple_ref/doc/uid/TP40014132-CH10-SW1)” 31 | 32 | ##测试从哪里入手 33 | 当你开始创建测试时,记住下面的方法: 34 | 35 | 专注于测试你的代码的最基础的功能,模型类和方法,它们与控制器相交互。 36 | 37 | 应用程序的高级框图很可能会包含Model、View和Controller类别,对于每个使用Cocoa和Cocoa Touch的开发者来说,这是一个熟悉的设计模式。当你编写要覆盖所有Model类别的测试时,你必须要知道app的基础已经进行了良好的测试,而且要在编写Controller classes测试之前--它将带你接触你应用程序更复杂的部分。 38 | 39 | 作为一个可选的起始点,如果你正在编写一个框架或库,你可能想从API的接口开始。从那里,你可以按照你的方式进入内部类。该文档其它部分你可以学到如何创建、运行并使用Xcode提供的工具来调试开发项目的测试。 40 | -------------------------------------------------------------------------------- /03Writing Test Classes and Methods.md: -------------------------------------------------------------------------------- 1 | 本章由CocoaChina翻译小组成员dada翻译 [github地址](https://github.com/sherlockdan) 2 | 3 | #编写测试类与方法 4 | 当你使用测试导航面板往项目中添加测试目标时,Xcode 会在测试导航面板里展示出测试类与方法。在测试目标里是包含测试方法的测试类。本章节讲述怎样创建测试类和编写测试方法。 5 | 6 | 7 | ##测试目标,测试包,测试导航 8 | 在学习创建测试类前,有必要看看测试导航面板。它对创建和运行测试工作极为重要。 9 | 10 | 测试导航面板罗列了测试包里的所有组件内容,并在一个层次列表里展示出测试类和测试方法。下面是一个工程的测试导航面板视图,包含了多个测试目标,展示了测试包、测试类以及测试方法的嵌套层级。 11 | 12 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-testnav-bundle_hierarchy_2x.png) 13 | 14 | 测试包可包含多个测试类。你可以使用测试类把测试分到相关的组群中,或者按照功能分,或者按照组织目的分。比如,对于本章中的计算器示例工程,你可以创建`BasicFunctionsTests`, `AdvancedFunctionsTests`以及 `DisplayTests classes`三个类,但他们都属于`Mac_Calc_Tests`测试包。 15 | 16 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-testnav-three_test_classes_2x.png) 17 | 18 | 一些测试类型可能会共享某些类型的安装和卸载需求,把这些测试整合到类里面会更加合理,这样可以最小化每个测试方法所需编写的代码。 19 | 20 | ##创建测试类 21 | 可以使用加号按钮(+)和测试导航面板中的 New Test Class 命令创建新测试类。 22 | 23 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-testnav-new_test_class_2x.png) 24 | 25 | 基于你在配置页面键入的测试类名,你添加的每个类都会使得一个名为 _TestClassName_.m 的文件被添加到项目中。 26 | 27 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-test_class_config_sheet_2x.png) 28 | 29 | >注意:所有测试类都是`XCTest`框架`XCTestCase`类的子类。 30 | 31 | 尽管Xcode会默认的把测试类添加到为工程测试目标所创建的组中,你还是可以在项目中组织自己选择的文件。当你按下Next按钮,标准的 Xcode 添加文件页面如下所示: 32 | 33 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-file_handling_sheet_2x.png) 34 | 35 | 你可以用相同的方法在工程导航面板中添加文件。具体使用方法详见[Adding an Existing File or Folder](https://developer.apple.com/library/mac/recipes/xcode_help-structure_navigator/articles/Adding_an_Existing_File_or_Folder.html#//apple_ref/doc/uid/TP40009934-CH17) 36 | 37 | >注意:当你用 Xcode5 及以上版本创建工程时,一个测试目标和相关的测试包都会默认的被创建,名字根据工程名获得。比如创建名为`MyApp`的项目,则会自动生成名为`MyAppTests`的测试包,以及一个名为`MyAppTests`的测试类,关联在`MyAppTests.m`实例文件中。 38 | 39 | ##测试类的结构 40 | 测试类包含如下的基本结构 41 | 42 | ```objective-c 43 | #import 44 | 45 | @interface MyAppTests : XCTestCase 46 | @end 47 | 48 | @implementation MyAppTests 49 | 50 | // setUp and tearDown 51 | - (void)setUp 52 | { 53 | [super setUp]; 54 | // Put additional setup code here. 55 | } 56 | 57 | - (void)tearDown 58 | { 59 | // Put additional teardown code here. 60 | [super tearDown]; 61 | } 62 | 63 | // test methods 64 | - (void)testXXXX 65 | { 66 | // setup code 67 | // test logic and XCTest assertions go here. 68 | // teardown code 69 | } 70 | @end 71 | ``` 72 | 73 | 测试类用 Objective-C 实现。注意实现里包含了方法,比如 setup 和 teardown 的基本实例方法;这些方法是必须的。如果类中所有的测试方法都需要相同的代码,你可以定制 setUp 和 tearDown 来包含这些代码。你添加的代码在每一个测试方法的之前和之后执行。你可以有选择性的添加定制的设置 (+ (void)setUp) 和卸载 teardown (+ (void)tearDown) 方法,他们在类里所有测试方法的之前和之后执行。 74 | 75 | Xcode 执行测试可以明确这些方法的使用,这正是我们接下来的内容要讨论的。 76 | 77 | ##测试执行的流程 78 | 在执行测试的过程中,XCTest 找到所有继承于`XCTestCase`的类(也就是说所有的测试类),并为每个类运行它的所有测试方法。 79 | 80 | 对于每个类来说,测试开始于类的 setup 方法的运行。对于每个测试方法来说,一个新的类实例被创建,它的实例 setup 方法就会执行。在跑完了测试方法之后,实例卸载方法。类中这样连续重复执行所有测试方法。在运行的类卸载了最后的测试方法后,Xcode会执行类卸载方法,并开始下一个类。这种序列一直重复直到跑完所有测试类的所有测试方法。 81 | 82 | 83 | ##编写测试方法 84 | 你通过编写测试方法把测试写到测试类中,一个测试方法是以 *test* 开头的测试类的实例方法,没有参数,返回`void`,比如`testColorIsRed`.测试方法调用工程中的代码,如果代码没有产生预期的结果,那么会用一系列的断言API报错。比如,一个函数返回值可能与预期值相比不同,或者你的测试方法使用了某个类里不适当的方法都将会抛出异常。[“XCTest Assertions”](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_3_writing_test_classes/testing_3_writing_test_classes.html#//apple_ref/doc/uid/TP40014132-CH4-SW34)描述了这些情况。 85 | 86 | 为了使测试方法能够正常访问被测试代码,引入正确的头文件到测试类中很重要。 87 | 88 | 当 Xcode 运行测试时,它调用的每个测试方法都是独立的。因此每个方法需要准备和清理辅助变量、结构以及与主题API进行交互的对象等。如果类中所有测试方法的代码是相同的,你可以直接把它添加到必需的`setUp`和`tearDown`的实例方法中,详见[“Test Class Structure”](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_3_writing_test_classes/testing_3_writing_test_classes.html#//apple_ref/doc/uid/TP40014132-CH4-SW2)。 89 | 90 | 下面是个测试方法的模型: 91 | 92 | ```objective-c 93 | - (void)testColorIsRed { 94 | ... // Set up, call test subject API. (Code could be shared in setUp method.) 95 | ... // Test logic and values, assertions report pass/fail to testing framework. 96 | ... // Tear down. (Code could be shared in tearDown method. 97 | } 98 | ``` 99 | 100 | 这里有一个简单的测试方法例子,检查是否成功地为 SampleCalc 创建了`CalcView`实例,详见[“Quick Start”](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_1_quick_start/testing_1_quick_start.html#//apple_ref/doc/uid/TP40014132-CH2-SW1)章节: 101 | 102 | 103 | ```objective-c 104 | - (void) testCalcView { 105 | // setup 106 | app = [NSApplication sharedApplication]; 107 | calcViewController = (CalcViewController*)[NSApplication sharedApplication] delegate]; 108 | calcView = calcViewController.view; 109 | 110 | XCTAssertNotNil(calcView, @"Cannot find CalcView instance"); 111 | // no teardown needed 112 | } 113 | ``` 114 | 更为深入一点的例子可以查看_Testing Apps and Frameworkssample_工程代码。 115 | 116 | 117 | ##XCTest断言 118 | 119 | 你的测试方法使用 XCTest 框架提供的断言来呈现 Xcode 显示的测试结果。所有断言都有一个相似的形式:项目比较或逻辑表达式,一个失败结果字符串格式,和插入到字符串格式中的参数。 120 | 121 | 122 | >注意:所有断言的最后一个参数是`format...`,格式字符串和变量参数列表。XCTest 为所有断言提供了默认的失败结果字符串,可使用参数传递到断言里。`format`字符串提供了可选的额外的失败自定义描述,就可以进一步选择提供的描述。这个参数是可选的,也可以完全被忽略。 123 | 124 | 125 | 比如,[Quick Start](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_1_quick_start/testing_1_quick_start.html#//apple_ref/doc/uid/TP40014132-CH2-SW1)里`testAddition`方法中的断言: 126 | 127 | ```objective-c 128 | XCTAssertEqualObjects([calcViewController.displayField stringValue], @"10", @"Part 2 failed."); 129 | ``` 130 | 131 | 阅读这段简单明了的语句,是说:“Indicate a failure when a string created from the value of the controller’s display field is not the same as the reference string ‘8’” 。如果断言失败,那么 Xcode 在测试导航面板发出失败信号,然后 Xcode 会在 issues 导航面板、源码编辑器以及其他地方展示失败的描述。下面是源代码编辑器中典型的断言结果: 132 | 133 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-test_failure_assert_result_2x.png) 134 | 135 | 测试类可以包含多个断言,如果任何断言包含失败报告,那么 Xcode 都发出的测试失败信号。 136 | 137 | 断言分为五种类型:无条件失败、等价测试、nil测试、Boolean测试以及异常测试。 138 | 139 | ##用类别区分断言 140 | 141 | 下面的区域列出了 XCTest 断言。你可以在 Xcode 中使用 Quick Help 查看`XCTestAssertions.h`来引用来获得更多关于 XCTest 断言的信息。 142 | 143 | ###无条件失败 144 | __XCTFail__。生成一个无条件失败 145 | 146 | XCTFail(format...) 147 | 148 | 149 | ###等价测试 150 | __XCTAssertEqualObjects__。当_expression1_不等于_expression2_时报错(或者一个对象为空,另一个不为空)。 151 | 152 | XCTAssertEqualObjects(expression1, expression2, format...) 153 | 154 | __XCTAssertNotEqualObjects__。当_expression1_等于_expression2_时报错 155 | 156 | XCTAssertNotEqualObjects(expression1, expression2, format...) 157 | 158 | 159 | __XCTAssertEqual__。当_expression1_不等于_expression2_时报错,这个测试用于C语言的标量。 160 | 161 | XCTAssertEqual(expression1, expression2, format...) 162 | 163 | __XCTAssertNotEqual__。当_expression1_等于_expression2_时报错,这个测试用于C语言的标量。 164 | 165 | XCTAssertNotEqual(expression1, expression2, format...) 166 | 167 | 168 | __XCTAssertEqualWithAccuracy__。当_expression1_和_expression2_之间的差别高于 _accuracy_ 时报错。这种测试适用于 floats 和 doubles 这些标量,两者之间的细微差异导致它们不完全相等,但是对所有的标量都有效。 169 | 170 | XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, format...) 171 | 172 | __XCTAssertNotEqualWithAccuracy__。当_expression1_和_expression2_之间的差别低于 _accuracy_ 时报错。这种测试适用于 floats 和 doubles 这些标量,两者之间的细微差异导致它们不完全相等,但是对所有的标量都有效。 173 | 174 | 175 | XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, format...) 176 | 177 | 178 | ###Nil(空)测试 179 | 180 | __XCTAssertNil__。当_expression_参数非nil时报错。 181 | 182 | XCTAssertNil(expression, format...) 183 | 184 | __XCTAssertNotNil__。当_expression_参数为nil时报错。 185 | 186 | XCTAssertNotNil(expression, format...) 187 | 188 | 189 | ###布尔测试 190 | 191 | 192 | __XCTAssertTrue__。当_expression_计算结果为_false_时报错。 193 | 194 | XCTAssertTrue(expression, format...) 195 | 196 | __XCTAssert__。当_expression_计算结果为_false_时报错,与_XCTAssertTrue_同义。 197 | 198 | XCTAssert(expression, format...) 199 | 200 | 201 | __XCTAssertFalse__。当_expression_计算结果为_true_时报错。 202 | 203 | XCTAssertFalse(expression, format...) 204 | 205 | 206 | ###异常测试 207 | 208 | __XCTAssertThrows__。当_expression_不抛出异常时报错误。 209 | 210 | XCTAssertThrows(expression, format...) 211 | 212 | __XCTAssertThrowsSpecific__。当_expression_针对指定类不抛出异常时报错。 213 | 214 | XCTAssertThrowsSpecific(expression, exception_class, format...) 215 | 216 | __XCTAssertThrowsSpecificNamed__。当_expression_针对特定类和特定名字不抛出异常时报错。对于AppKit框架或Foundation框架非常有用,抛出带有特定名字的NSException(NSInvalidArgumentException等等)。 217 | 218 | XCTAssertThrowsSpecificNamed(expression, exception_class, exception_name, format...) 219 | 220 | 221 | __XCTAssertNoThrow__。当_expression_抛出异常时报错。 222 | 223 | XCTAssertNoThrow(expression, format...) 224 | 225 | 226 | __XCTAssertNoThrowSpecific__。当_expression_针对指定类抛出异常时报错。任意其他异常都可以;也就是说它不会报错。 227 | 228 | XCTAssertNoThrowSpecific(expression, exception_class, format...) 229 | 230 | 231 | __XCTAssertNoThrowSpecificNamed__。当_expression_针对特定类和特定名字抛出异常时报错。对于 AppKit 框架或 Foundation 框架非常有用,抛出带有特定名字的NSException(NSInvalidArgumentException等等)。 232 | 233 | 234 | XCTAssertNoThrowSpecificNamed(expression, exception_class, exception_name, format...) 235 | 236 | 237 | -------------------------------------------------------------------------------- /04Running Tests and Viewing Results.md: -------------------------------------------------------------------------------- 1 | 本章由CocoaChina翻译小组成员migrant翻译[微博](http://weibo.com/u/2168385817) 2 | 3 | #运行测试并查看结果# 4 | 5 | 正如在 [“Quick Start”] (https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_1_quick_start/testing_1_quick_start.html#//apple_ref/doc/uid/TP40014132-CH2-SW1)看到的那样,使用 Xcode 测试导航面板,可以很容易的运行测试并查看其结果。有另外几种运行测试的交互方法。Xcode运行测试取决于一个scheme中包括并开启了哪些test target。测试导航面板让你无需使用scheme编辑器就能直接控制那些被包含、被开启或被关闭的 test target、类以及方法。 6 | 7 | ## 运行测试命令 8 | 9 | 为了将运行测试作为编码流程的一部分,测试导航面板为提供了便捷的方法。测试可以直接在源代码编辑器里运行,或使用 Product 菜单运行。 10 | 11 | ### 使用测试导航面板 12 | 13 | 在测试导航面板中,将鼠标悬停在测试包、类或方法名上时,会出现一个“Run”按钮。你可以运行某个特定测试,也可以运行一个类中的测试或运行一个测试包中的所有测试,这取决于鼠标停留在列表中的位置。 14 | 15 | 1.将鼠标悬停在测试包名上,并点击右边出现的运行按钮来测试一个包中的所有测试。 16 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-run-bundle_2x.png) 17 | 18 | 2.将鼠标悬停在类名上,并点击右边出现的运行按钮来测试一个类中的所有测试。 19 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-run-class_2x.png) 20 | 21 | 3.将鼠标悬停在测试名称上,并点击右边出现的运行按钮来测试一个单独的测试。 22 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-run-method_2x.png) 23 | 24 | ### 使用源代码编辑器 25 | 当在源代码编辑器中打开一个测试类,每个测试方法名字旁的边栏会有很明显的指示器。在指示器上悬停鼠标,出现一个运行按钮。点击按钮运行该测试方法,指示器随后显示该测试成功或失败的状态。再次将鼠标悬停到指示器上可以再次显示运行按钮来重复测试。这种机制一次只运行一个测试。 26 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-run_editor_1_2x.png) 27 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-run_editor_2_2x.png) 28 | 29 | >__注意:__出现在 @implementation 旁边的指示器同样也适用于类,允许你运行类中所有的测试。 30 | 31 | ### 使用 Product 菜单 32 | 33 | Product 菜单包括了从键盘直接运行测试的快捷命令。 34 | 35 | Product > Test。运行当前激活的方案(scheme)。键盘快捷键是 Command-U。 36 | 37 | Product > Build for > Testing 和 Product > Perform Action > Test without Building。这两个命令可以用来构建测试包并运行独立于其它的测试。这是简化构建和测试进程的快捷命令。对于修改了代码并在构建过程中检查警告或错误时,这是特别有用的,或者如果你知道当前的构建是最新的,它也可以加速测试过程。键盘快捷方式分别是 38 | Shift-Command-U 和 Control-Command-U。 39 | 40 | Product > Perform Action > Test。当你编辑一个测试方法时,这个动态菜单选项展示当前光标所处的测试方法,并允许你使用键盘快捷方式来运行测试。命令的名称取决于将要运行的测试,比如,Product > Perform Action > Test testAddition。快捷键是 Control-Option-Command-U。 41 | 42 | >__注意:__除了源代码编辑器,该命令还基于工程导航面板和测试导航面板中的选择情况运行。当任何一个导航面板处于激活状态,源代码编辑器就失去了焦点,并且该命令将使用任何一个导航面板中的当前选择作为输入。在测试导航面板中,可以选择测试包,类或方法。在工程导航面板中,可以选择测试类实现文件,例如 CalcTests.m。 43 | 44 | Product > Perform Action > Test Again 。当测试方法在调试/编辑代码中暴露出问题时,返回最后一个被执行的测试方法非常有用。像 Product > Perform 45 | Action > Test 命令,运行的测试名称在命令中出现,例如,Product > Perform Action > Test Again testAddition。键盘快捷方式是 Control-Option-Command-G。 46 | 47 | ## 显示测试结果 48 | XCTest 框架有几种不同的方式在 Xcode 中展示测试结果。下面的屏幕截图展示了从哪里查看这些结果。 49 | 50 | 1.在一个或一组测试运行后,你可以在测试导航面板中浏览 测试通过/失败指示。 51 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-results-testnav_2x.png) 52 | 53 | 如果测试方法被折叠到各自的类中,或测试类被折叠到测试包中,该标识则反映了封闭测试的集合状态。在本例中,BasicFunctionsTests 类中至少有一个方法被标记为失败。 54 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-results-testnav-collapsed_2x.png) 55 | 56 | 2.在源代码编辑器中,你可以浏览 测试通过/失败 标识和调试信息。 57 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-results-srceditor_2x.png) 58 | 59 | 3.在日志导航面板中,你可以浏览相关的错误描述和其他一些输出摘要。点击左边的提示箭头标识,可以展开所有的测试运行细节。 60 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-log-navigator-results_2x.png) 61 | 62 | >__注意:__除了左边展开的三角图标,测试失败项右边的小图标可以展开以显示更多信息,正如上图显示的 testMultiplication 失败。 63 | 64 | 4.调试控制台以文本形式展示了测试运行的综合信息。这些信息和日志导航面板中显示的信息一样,但如果你已经处于 debug 状态,那么 debug 的输出也会出现在这里。 65 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-results-dbgconsole_2x.png) 66 | 67 | ##使用Schemes(方案)和Test Target(测试目标) 68 | 69 | Xcode Scheme 控制着构建、运行、测试和调试这些菜单命令的行为。当创建 TestTarget 并使用测试导航面板执行其他测试系统操作时,Xcode 5 为我们管理 Scheme 配置--例如,当你开启或关闭一个测试方法、测试类或测试包时。使用 Xcode Server 和持续集成需要通过设置 Manage Schemes 页面中的复选框来将一个 Scheme 设置成共享,并将其连同你的工程和源代码导出到一个源文件仓库。 70 | 71 | Scheme 配置方法如下: 72 | 73 | 1.选择 Scheme menu > Manage Schemes,弹出 scheme 管理页。 74 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-manage-schemes-sheet_2x.png) 75 | 76 | 这个工程中有两个 Scheme,一个用来构建应用,一个用来构建框架/库。右侧的 Shared 复选框用来将 scheme 配置为共享,并允许 Xcode Server bots 使用。 77 | 78 | 2.在管理页中,双击一个scheme,显示 scheme editor。一个 scheme 的测试行为标识了你执行测试命令时 Xcode 执行的测试。 79 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-edit%E2%80%93schemes-sheet_2x.png) 80 | 81 | >__注意:__测试目标、测试类和测试方法所关联的测试导航面板和配置/设置助手通常维护所有关于测试操作的 scheme 设置。 82 | 83 | 关于使用、配置和编辑 scheme 的更多信息可以查看 [Scheme Configuration Help](https://developer.apple.com/library/ios/recipes/xcode_help-scheme_editor/_index.html#//apple_ref/doc/uid/TP40010402),或者视频 [WWDC 2012: Working with Schemes and Projects in Xcode](https://developer.apple.com/videos/wwdc/2012/?id=408)。 84 | 85 | ## 构建设置--测试应用,测试库 86 | 87 | 应用测试在你应用的上下文中运行,允许你创建测试,这些测试结合了来自不同类、库/框架和应用功能角度的行为。库测试独立于你的应用,在一个库或框架中采用实验类和方法,来验证他们的行为符合库的明确要求。 88 | 89 | 两种类型的测试包需要不同的构建设置。在新 target 助手中通过选测目标参数来创建 test target 时,会执行构建设置配置。目标助手随着目标下拉菜单显示。名为 SampleCalc 的应用和名为 CalcLibrary 的库可供选择。 90 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-new_target_assistant-targets_2x.png) 91 | 92 | 选择 SampleCalc 作为改测试目标所关联的构建产品会使构建设置用来测试一个应用。测试的执行基于应用进程;测试在得到 applicationDidFinishLaunching 通知后执行。默认的产品名称 "SampleCalc Tests" 来自于目标名 SampleCalc ,你可以根据自己的偏好改变它。 93 | 94 | 如果你选择 CalcLibrary 作为关联的构建产品,目标助手将会配置构建设置来测试库。Xcode 引导测试运行时的上下文和框架/库,以及你的测试代码--基于一个 Xcode 管理的进程。这种情况下默认的产品名字来自于库目标 (“CalcLibrary Tests”)。同样,你可以基于自己的喜好修改。 95 | 96 | ### 默认构建设置 97 | 98 | 大多数情况下,配置构建设置来测试应用或库所要做的唯一一件事就是选择正确的测试目标。Xcode 则自动关注构建设置管理。因为你可能有一个需要复杂构建设置的工程,所以了解 Xcode 为应用测试和库测试所建立的标准构建设置是非常有用的。 99 | 100 | 我们使用 SampleCalc 工程作为例子来演示正确的默认设置。 101 | 102 | 1.在工程导航面板中单击 SampleCalc 进入工程编辑器,然后选择 SampleCalcTests 应用测试目标。在编辑器的 General 面板中,有一个目标快捷菜单。该下拉菜单应当展示以 SampleCalc 为目标。 103 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-app_library_1_2x.png) 104 | 105 | 你可以检查该构建设置是否正确。 106 | 107 | 2.点击构建设置,在搜索框中输入 Bundle Loader。针对 SampleCalc 的应用测试被 SampleCalc app 加载。你可以看到针对 Debug 和 Release 的作为自定义参数的可执行文件路径。搜索 Test Host 也可以看到相同的路径。 108 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-app_library_2_2x.png) 109 | 110 | 该工程的库目标名为 CalcLibrary,并且已经与名为 CalcLibraryTests 的测试目标关联。 111 | 112 | 3.选择 CalcLibraryTests 目标并查看 General 面板。 113 | 114 | CalcLibrary 被作为目标。 115 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-app_library_3_2x.png) 116 | 117 | 4.像应用测试目标一样,你可以使用 Build Settings 面板查看 Bundle Loader 和 Test Host 构建设置,下图显示 Bundle Loader 搜索设置。 118 | ![](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-app_library_4_2x.png) 119 | 120 | 在库测试目标的案例中,Bundle Loader 和 Test Host 项目都没有关联的参数。这表明 Xcode 已经默认正确地配置了它们。 121 | 122 | ## 测试目的 123 | 应用测试在 OS X、iOS (设备上) 和 iOS 模拟器上运行。库测试在 OS X 和 iOS 模拟器上运行。Xcode Server 可以通过恰当的配置源代码仓库,共享方案和 bot 在运行 OS X Server 的 Mac 上运行。更多关于建立 Xcode Server 运行目标的信息,请查看 [Automating the Test Process with Continuous Integration](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_6_automating_with_continuous_integration/testing_6_automating_with_continuous_integration.html#//apple_ref/doc/uid/TP40014132-CH7-SW1)。 124 | -------------------------------------------------------------------------------- /05Debugging Tests.md: -------------------------------------------------------------------------------- 1 | 本章由CocoaChina翻译小组成员migrant翻译[微博](http://weibo.com/u/2168385817) 2 | 3 | # 调试测试 # 4 | 5 | 所有标准的 Xcode 调试工具在执行测试时都可以使用。 6 | 7 | ## 测试调试工作流 8 | 9 | 要确定的第一件事情是:造成测试失败的问题是测试中的代码有 bug 还是执行的测试方法存在 bug。测试失败可以指出一些不同类型的问题--既有你的假设,正在测试中的代码需求,也有测试代码本身--所以调试测试可以横跨几个不同的工作流。然而,通常你的测试方法是相对较小和直接的,所以最好首先检查测试的目的是什么,以及它是如何实现的。 10 | 11 | 值得注意的一些常见问题: 12 | 13 | 1.测试的逻辑是否正确?实现是否正确? 14 | 测试方法用作比较基础使用的字面值,检查它们的笔误和错误始终是个好主意。 15 | 16 | 2.假设是什么? 17 | 例如,你可能在测试方法里使用了错误的数据类型,创建了一个你所测试的代码的范围错误。 18 | 19 | 3.是否使用了正确的断言来报告“通过/失败”状态? 20 | 例如,可能测试的状态需要 XTCAssertTrue 而不是 XCTAssertFalse。有时这很容易造成错误。 21 | 22 | 假设你的测试假设是正确的,并且测试方法也正确,那么错误一定在测试的代码中。现在来定位并修复它。 23 | 24 | ## 具体的测试调试工具 25 | 26 | Xcode 有几个工具专门用来在你测试时定位和调试代码。 27 | 28 | ### 测试失败断点 29 | 30 | 在断点导航面板中(breakpoint navigator),点击 Add (+) 按钮,选择 Add Test Failure Breakpoint 设置一个特殊的断点。 31 | ![](http://www.cocoachina.com/cms/uploads/allimg/140709/4196_140709171606_1.png) 32 | 33 | 当测试方法触发了失败断言,这个断点会终止测试的运行。在测试代码发生错误点后马上停止运行,可以让你快速的找到问题发生的位置。你可以看看 testAddition 测试方法,通过为错误字符串设置用来比较的参考标准,比较字符串被强行断言为失败。测试失败断点检测该失败断言并停止了该点测试的执行。 34 | 35 | ![](http://www.cocoachina.com/cms/uploads/allimg/140709/4196_140709171606_2.png) 36 | 37 | 当测试中断,你也就停止了测试的执行。然后在断言前设置一个常规的断点,再次运行测试(为了简单起见,你可以在源代码编辑器侧栏中点击“Run”按钮来运行该测试),并继续调试操作来修复问题。 38 | 39 | ### 使用工程菜单命令运行测试 40 | 调试测试方法时,最好记住菜单命令 Project > Perform Action > Test Again 和 Project > Perform Action > Test。如果你正在测试失败发生后编辑修复代码,或运行你正在编写的测试方法,它们提供了一个便捷的方式来测试最后一个方法。更多信息请查看 [Using the Product menu](https://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_4_running_tests/testing_4_running_tests.html#//apple_ref/doc/uid/TP40014132-CH5-SW8)。当然你也可以始终使用测试导航面板或源代码编辑器侧边栏中的“Run”按钮来运行测试,都很方便。 41 | 42 | ### 辅助编辑器类 43 | 辅助编辑器分类中增加了两个专门的分类来运行特殊的测试。 44 | 45 | ![](http://www.cocoachina.com/cms/uploads/allimg/140709/4196_140709171606_3.png) 46 | 47 | 1.Test Callers category。如果你修复了一个引起应用测试失败的方法,你可能会想要检查该方法在其他测试中是否被调用并成功运行。带着这个问题,在源代码编辑器中打开辅助编辑器,并从菜单中选择 Test Classes 分类。你可以从下拉菜单定位到任何调用它的测试方法,这样你就可以运行它们,以确保你的修复没有造成其它问题。 48 | 49 | 2.Test Classes category。该分类和 Test Callers 类似,不过显示的是包含测试方法的类列表,这些方法与主源码编辑器中编辑的类相关。对于增加测试来说,这是个好机会,例如,给还没有被并入测试方法中的新方法增加测试。 50 | 51 | ### 测试时的异常断点 52 | 通常,当异常被异常断点捕获时就会终止测试执行,所以测试运行时通常会关闭异常断点以避免不适当的定位抛出的断点。当你寻找一个特定的问题并想终止测试来修复它时可以打开异常断点。 53 | -------------------------------------------------------------------------------- /06Automating the Test Process with Continuous Integration.md: -------------------------------------------------------------------------------- 1 | # 自动化测试过程的持续集成 # 2 | 3 | 在开发过程中除了以交互方式运行测试外,还可以充分采取使用Xcode Server进行自动化测试。本章将介绍如何使用`OS X Server`和`Xcode Server`的持续集成功能来增强和扩展你的开发测试。 4 | 5 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/bot_viewer-summary_2x.png) 6 | 7 | ## 基于服务器的持续集成测试 ## 8 | 9 | `Xcode`测试具有交互性,它能确保您的代码在其指定的需求下不偏离正确的轨道,并且可以很简单地找到并修复`bug`。一系列快速运行的功能测试不仅可以校正你的开发,还可以让你高效率自信地构建一款健壮的应用程序。 10 | 11 | 这就是说,成功的开发项目往往超出单个开发人员实现和维护的能力范围。像源码管理,服务器上的自动化测试可让你顺利高效地根据团队的需要进行开发工作。通过`Xcode Server``Xcode`支持基于服务器的持续集成工作流。`Xcode Server`适用于 `OS X Server`,可以自动化应用程序的构建、分析、测试以及归档的一体化过程。 12 | 13 | 下面是使用基于服务器测试的一些优点: 14 | 1. 使用服务器可以进行脱机构建和测试,以缓解开发系统做实施和调试的压力,特别是在全方位测试时可能需要很长的时间来执行。 15 | 16 | 2. 开发团队的所有成员使用相同的scheme可在服务器上运行相同的测试,从而提高测试的一致性,整个团队也可以构建产品,就像构建和测试报告。 17 | 18 | 3. 你可以灵活调整调度项目需求和团队的需求。比如,当团队中任意一个成员向源码管理系统提交新工作或者在设定的时间定期提交时测试运行就可以开始了。测试运行也可以按照需要手动启动。 19 | 20 | 4. 服务器以同样的方式反复运行测试。随着时间的推移,服务器的报告可以让你和你的团队对构建过程中的问题、警告以及测试解决方案有个整体的轮廓。 21 | 22 | 5. 你的项目可以有更多的目的地进行测试,更具自动性,而且比手动运行测试系统更加经济。例如,您可以有任意数量的iOS设备连接到服务器,使用单一的配置,该系统可以构建和测试库、应用程序、所有测试以及iOS模拟器的多个版本。 23 | 24 | 你的项目可以基于多个目的进行测试,另外它的自动性比手动运行测试更经济。比如你可以有任意数量的连接到服务器的iOS设备,通过单一配置让,系统可以构建和测试库、应用程序、所有测试以及并联iOS模拟器的多个版本 25 | 26 | >注意 27 | >当你的项目工作横跨`iOS`和`mac OS X`时,应用就会有两个约束: 28 | > 29 | >`OS X`项目构建和测试时,安装有`OS X`服务器必须处于运行当中。 30 | > 31 | >`iOS`和`OS X`的项目需要各自不同的`scheme`和`bot`。 32 | 33 | ## 概述 - 使用Xcode的服务器和持续集成 ## 34 | 35 | 使用`Xcode Server`和持续集成的工作流可以设计无缝和透明的交互式开发。使用基于服务器持续集成的主要任务是服务器的安装和配置项目,在这里我们简要描述一下。在开始使用`Xcode`服务器和持续集成系统时,只需要三个高级任务。此后,该任务要做的显示正在进行的监测结果和进行不定期的维护。本文简要总结这些任务的详细信息[Xcode Continuous Integration Guide](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/000-About_Continuous_Integration/about_continuous_integration.html#//apple_ref/doc/uid/TP40013292)。 36 | 37 | ### 共享计划,脚本,和集成 ### 38 | 39 | 首先,了解要讨论的`Xcode Server`所使用的一些关键术语是非常有用的。 40 | 41 | **Shared schemes.**相信您应该已经很熟悉`Xcode scheme`的概念了;它是构建项目的计划。它定义了需要构建哪些目标,依赖目标需要构建什么,什么样的构建设置将被传递到构建过程中。因为服务器是要建立自己的代码,它需要访问这些信息。要做到这一点,在你的计划中配置`scheme`的设置,并使之成为`shared scheme`,并签入源代码库。你可以手动地在你为项目定义的`scheme`中,选择列表中`scheme`右边的`Shared`复选框,使用`Scheme Manager`。 42 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-manage-schemes-sheet_2x.png) 43 | 44 | >**注意:**在大多数情况下,当你创建一个`bot`时,`Xcode`会为你自动配置共享scheme。 45 | 46 | **Bots.** 在`Xcode`中进行`Mac`开发时,你创建的`bots`会运行在单独的服务器上,它们在那里执行这些集成。`Bot`是用于分析、构建、测试以及按计划归档项目的配置。`Bot`有助于确保您的产品始终处于可释放状态,当有故障时,该服务会通知你或那些代码发生更改导致失败人。 47 | 48 | **Integrations.**`Bot`执行集成,集成是一个单独运行的`Bot`。 49 | 50 | ### 配置 ### 51 | 在开始使用Xcode服务器和持续集成系统前,需要完成三个高级任务。 52 | 53 | ### 安装和设置`Xcode Server`### 54 | 55 | 即使你之前从来没有建立过服务器,你也将会觉得这很简单很容易完成。您需要在目标机器上安装`OS X Server`和配置`Xcode Server`。当然你还需要在服务器上安装好`Xcode`。 56 | 57 | >注意:你要确定运行在目标机上的`OS X`,`Mac OS X Server`和`Xcode Server` 版本都是兼容的。。 58 | 59 | 关于安装`OS X Server`和配置`Xcode Server`的详细信息,请参阅["Install OS X Server and Configure the Xcode Service"](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/200-Adopting_a_Continuous_Integration_Workflow/adopt_continuous_integration.html#//apple_ref/doc/uid/TP40013292-CH3)得到详细的指示说明。 60 | 61 | ### 连接Xcode Server到源代码库 ### 62 | 63 | 你的 bots 必须能够访问项目的源代码库。`Xcode Server` 支持两种流行的源代码控制系统:`Git`和`Subversion`。你可以使用`Git`和托管在远程服务器上的`Subversion` 版本库,你可以在安装了`OS X Server`的服务器上托管和使用`Git`仓库。 64 | 65 | 最简单的情况,当你创建一个新的项目时,设立远程存储库就能满足了。在`Xcode`中,你可以选择选项来创建一个`git` 仓库,并在新项目设置工作流中,从弹出菜单 “Create git repository” 中选择服务器。 66 | 67 | 还有其他一些方法来设置源代码库,这取决于您正在使用的项目,以其相对应的源代码控制状态等等。关于设置源代码存储库的详细说明,请查阅 "[Enable Access to Your Source Code Repositories](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/PublishYourCodetoaSourceRepository/PublishYourCodetoaSourceRepository.html#//apple_ref/doc/uid/TP40013292-CH8)"。 68 | 69 | ### 选择 Product > 创建配置bot和运行bots ### 70 | 71 | Bots 是自动化工作流程的核心;他们使用项目`schemes`去构建和测试产品。在`Xcode`中,你在自己的开发系统上创建 bots,并使之定期运行或者在你每次提交源码的时候运行。你也可以配置 Bot 以电子邮件报告形式通知你集成使用成功与否。 72 | 73 | 有关创建和运行Bots的详细信息,参见["Configure Bots to Perform Continuous Integrations"](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/ConfigureBots/ConfigureBots.html#//apple_ref/doc/uid/TP40013292-CH9)。 74 | 75 | ## 持续集成工作流程 ## 76 | 77 | 当你已经完成后三个配置任务后,`Xcode Server`和持续集成系统就已经启动和运行了。它被设计成一个易懂的交互式开发工作流程。根据你配置`bots` 和实现集成的方式,你可以像过去那样以同样的方式来执行代码开发以及本地的、交互式的测试任务。通常情况下,你会在到达停止点、完成特定任务等时,提交你的工作到源代码库。 78 | 79 | Bots运行在服务器上,执行你配置的集成,并返回报告。在 _Xcode_中可以使用log navigator管理Bots,查看测试结果,阅读集成志,启动整合,并下载产品构建信息和归档。例如,下面就是使用log navigator得到的可用的测试结果视图: 80 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-integration_viewer-tests_2x.png) 81 | 82 | 您还可以使用Web浏览器来查看测试和报告。 83 | 84 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-integration_page-tests_2x.png) 85 | 86 | 想要了解所有管理bots的不同功能,并查看更多的集成结果,请参阅,参见 ["Manage and Monitor Bots from the Log Navigator"](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/300-Working_with_Bots/view_integration_results.html#//apple_ref/doc/uid/TP40013292-CH4) 和 ["Manage and Monitor Bots from a Web Browser"](https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/MonitorBotsandDownloadProductsfromaWebBrowser/MonitorBotsandDownloadProductsfromaWebBrowser.html#//apple_ref/doc/uid/TP40013292-CH10)。 87 | -------------------------------------------------------------------------------- /07Writing Testable Code.md: -------------------------------------------------------------------------------- 1 | # 编写测试的代码 # 2 | 3 | Xcode集成了对测试的支持,使您能够构建测试包,以支持各种不同方式的开发工作。使用测试,可以发现代码中潜在的回归,并测试预期的成功与否,并验证应用程序的行为。通过确保对象能以预期的方式运行,测试能提高代码的稳定性。 4 | 5 | 当然,通过测试让程序达到稳定的水平也取决于你写的测试的质量。同样,编写良好测试的难易度也取决于你的编码方式。专为测试设计的代码编写有助于编写良好的测试。阅读下面的指南,以确保你的代码是可测试的,以有效减小编写良好测试的难度。 6 | 7 | ## 指南 ## 8 | 9 | - **定义API的需求** 10 | 11 | 为添加到项目中的每个方法或者函数定义需求和结果非常重要。对于需求,包括输入和输出范围,exceptions 抛出异常,条件限制,以及返回值的类型(尤其如果值是类的实例时)。定义要求并确保满足代码中的需求可以帮助你编写出健壮的安全的代码。 12 | 13 | - **边写边测(Write test cases as you write code)** 14 | 15 | 每当你设计和编写一个方法或函数时,就应该编写一个或多个测试用例来确保API的需求得到满足。记住,为现有代码编写测试要比为你正在编写的代码难得多。 16 | 17 | - **检查边界条件** 18 | 19 | 如果对一个方法的参数值必须在特定范围内,你的测试应包括该范围的最低值和最高值。例如,如果一个程序有一个整数参数,那么该参数值的范围要在 0 和 100 之间(包括首尾值),该方法的测试代码应该为参数传递0,50和100这些值。 20 | 21 | - **使用negative测试** 22 | 23 | negative 测试可以确保您的代码能适当地响应出错的条件。当收到无效的或意外的输入值时,它可以验证代码的行为。同样的,还可以验证它返回错误代码或引发异常时的行为。例如,如果一个整数参数范围必须为 0?100(包含首尾值),创建测试用例并传值 -1 和 101,以确保该程序能引发一个异常或返回一个错误代码。 24 | 25 | - **编写全面的测试用例** 26 | 27 | 全面的测试通过结合不同的代码模块来实现 API 的一些更复杂的行为。虽然简单,隔离测试提供值,堆叠测试表现复杂的行为,这样能捕获住更多的问题。这些类型的测试在更现实的条件下模拟你的代码的行为。例如,除了将对象添加到数组,你还可以创建数组,为之添加几个对象,使用不同的方法删除若干对象,然后确保集合以及其余对象的数量是正确的。 28 | 29 | - **覆盖测试用例的bug修复** 30 | 31 | 每当你修复完一个 bug,都要编写一个或多个测试用例,来验证此次修复的有效性。 32 | 33 | -------------------------------------------------------------------------------- /08Command-Line Testing.md: -------------------------------------------------------------------------------- 1 | # 命令行测试 # 2 | 3 | 使用 Xcode 的命令行工具,可以编写自动化脚本来构建和测试您的项目。通过使用此功能,你可以充分利用现有构建自动化系统的优势。 4 | 5 | ## 使用xcodebuild运行测试 ## 6 | 7 | `xcodebuild`命令行工具像 Xcode IDE 和 OS X Server 中的 Xcode 服务一样驱动测试。用`BuildAction`运行`xcodebuil`测试。用`-destination`参数指定不同的测试目的。例如,要在本地 OS X "My Mac 64 Bit" 测试`MyApp`,使用如下命令来指定目标和架构: 8 | 9 | ``` 10 | > xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'platform=OS X,arch=x86_64' 11 | ``` 12 | 13 | 如果你有`development-enabled`设备插入,你可以按照名称或 id 调用他们。例如,如果你有一个名为"Development iPod touch"的 iPod 设备连接了测试的代码,可以使用下面的命令: 14 | 15 | ``` 16 | > xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'platform=iOS,name=Development iPod touch' 17 | ``` 18 | 19 | 测试也可以在 iOS模拟器上运行。使用模拟器可以应对不同的外形因素和操作系统版本。例如: 20 | 21 | ``` 22 | > xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone,0S=7.0' 23 | ``` 24 | 25 | `-destination`参数可以被连接在一起,这样你只需使用一个命令,就可以跨目标进行指定集成共享方案。例如,下面的命令把之前的三个例子合并到一个命令中: 26 | 27 | ``` 28 | > xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp 29 | -destination 'platform=OS X,arch=x86_64' 30 | -destination 'platform=iOS,name=Development iPod touch' 31 | -destination 'platform=iOS Simulator,name=iPhone,0S=7.0' 32 | ``` 33 | 34 | 如果测试失败,`xcodebuild`将返回一个非零的退出代码。 35 | 36 | 这些都是你所需要了解的命令行运行测试的要领。有关`xcodebuild`更详细的信息,请在终端的应用程序窗口中使用`man`命令进行查找。 37 | ``` 38 | > man xcodebuild 39 | ``` 40 | -------------------------------------------------------------------------------- /09Transitioning from OCUnit to XCTest.md: -------------------------------------------------------------------------------- 1 | # 从OCUnit过渡到XCTest # 2 | 3 | `XCTest`是`Xcode5`中新引入的一个测试框架。`XCTest`是上一代现代化测试框架`OCUnit`的重新现代化实现。`XCTest`提供了与`Xcode`更好的集成并且奠定了未来改进`Xcode`测试能力的基础。`XCTest`的许多的功能都类似于之前的`OCUnit`。 4 | 5 | ## OCUnit和XCTest兼容性 ## 6 | 自 Xcode2.1 以来,`OCUnit`都是 Xcode测试的基础,很多现有的项目都是基于`OCUnit`测试。它们可以继续使用,因为 Xcode 5为基于`OCUnit`和`XCTest` 的两种项目提供了等同的功能。 7 | 8 | 将基于`OCUnit`测试的现有项目从 Xcode 5 之前的版本添加进 Xcode 5中时,项目会兼容当前 iOS 和 OS X 版本,同样的,iOS 7之前的版本以及 OS X v10.8 之前的版本也是如此。 9 | 10 | 基于`OCUnit`的测试可以在 iOS 6 和 iOS 7 上运行,所以针对iOS 和 OS X 旧版本的项目仍然能有效地选择使用 `OCUnit`。当你需要把项目从 Xcode 5 回归至早期版本的Xcode,并对应用程序进行维护时,这也不失为一个很好的选择。 11 | 12 | 如果你的项目开发工作主要集中于 iOS 7 或更高版本,或在 OS X v10.8 或更高版本,或两者兼而有之,把项目转为使用`XCTest` 将是一个正确的选择。 13 | 14 | >注意:OCUnit 在 Xcode 5.1 中被标记为已过时。 15 | 16 | ## 从OCUnit过渡至XCTest ## 17 | 18 | 从 OCUnit 到 XCTest 的转换是一个复杂的操作,包括更新源文件,其中包括测试类和修改项目配置设置。Xcode5 中有一个转换工作流程的助手可帮你实现这些转换,选择 Edit > Refactor > Convert OCUnit to XCTest。使用该工具来成功地将项目迁移使用 XCTest。 19 | 20 | OCUnit 到 XCTest 转换工具是基于`target-by-target`的。该工具会检查你选择的目标,并且在执行自动转换后让你知道它们是否可以用XCTest运行。 21 | 22 | >注意:建议您在进行`OCUnit`到`XCTest`的迁移时,将所有目标放到一个项目中。 23 | 24 | 更新项目`OCUnit`到`XCTest`: 25 | 26 | 1.选择 Edit > Refactor > Convert OCUnit to XCTest。 27 | 28 | 2.点击下一步,进入到下一个工作表。 29 | 30 | 3.在出现的表单中,选择要转换的测试目标。 31 | 32 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-select_targets_2x.png) 33 | 34 | 4.要查看一个特定的目标是否能与 XCTest 转换,请单击其名称。 35 | 36 | 5.单击下一步按钮。 37 | 38 | 助手弹出了一个`FileMerge`界面,您可以评估其他来源的变化。 39 | 40 | ![](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/art/twx-conversion-filemerge_2x.png) 41 | 42 | 左边是更新后的源文件,右边是原始文件。你可以浏览所有可能的变化,并丢弃那些你觉得有问题的代码。 43 | 44 | 6.如果你对所有的更改都满意,就可以单击保存按钮。 45 | 46 | Xcode会把更改写入文件。 47 | 48 | 当转换完成,运行测试目标,并检查其输出,以确保测试按预期运行。如果出现任何问题,请参阅["Debugging Tests"](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_5_debugging_tests/testing_5_debugging_tests.html#//apple_ref/doc/uid/TP40014132-CH6-SW1)一章来查看帮助。 49 | 50 | 51 | -------------------------------------------------------------------------------- /Document Revision History.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CocoaChinaTranslationTeam/TestingWithXcodeDocsCN/260230bf0dc4edb1bd9e97c0786c69f3b5229ae2/Document Revision History.md -------------------------------------------------------------------------------- /Introduction.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CocoaChinaTranslationTeam/TestingWithXcodeDocsCN/260230bf0dc4edb1bd9e97c0786c69f3b5229ae2/Introduction.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TestingWithXcodeDocsCN 2 | 3 | 4 | > ![](https://eapnaq.blu.livefilestore.com/y2p1PJW0P1iadSL_AUlwZ91fqNIZlO2Ir96iLIyJGVOTi53oe3hwCFBtLkUps7waeRO1IKgAz6N6bJ6DxsSzvAFMMKEOEMDDwsYn6IVuvhqNzQ/cocoachina.png?psid=1) 5 | 6 | > **CocoaChina翻译小组** 7 | 8 | ====================== 9 | 10 | - [TestingWithXcode英文官方文档地址](https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/testing_with_xcode/Introduction/Introduction.html#//apple_ref/doc/uid/TP40014132-CH1-SW1) 11 | 12 | 13 | 14 | ### 参与进来 15 | 16 | 朋友们如果发现文档中存在问题,非常欢迎参与进来校正,让我们一起把文档的质量提高,力求达到表述准确,词句通畅。 17 | 18 | 19 | --------------------------------------------------------------------------------