ios swift 测试框架翻译之Quick例子和一ArrangeActAssert
2016-05-18 14:15
1416 查看
XCTest高效测试:Arrange, Act, 和 Assert
无论你是使用XCTest, Quick或者其他的一些测试框架,你都能通过下面简单的模式写出高效的单元测试:1. Arrange
2. Act
3. Assert
使用 Arrange, Act, 和Assert
现在。我们来看一个名字叫做Banana的简单类:// Banana/Banana.swift /** A delicious banana. Tastes better if you peel it first. */ public class Banana { private var isPeeled = false /** Peels the banana. */ public func peel() { isPeeled = true } /** You shouldn't eat a banana unless it's been peeled. */ public var isEdible: Bool { return isPeeled } }
//Banana.h @interface Banana : NSObject @property (assign,nonatomic) BOOL isPeeled; -(void)peel; -(BOOL)isEdibal; -(NSString*)offer:(Banana*)banana; @end //Banana.m -(instancetype)init{ self = [super init]; if (self) { _isPeeled = false; } return self; } -(void)peel{ _isPeeled = true; } -(BOOL)isEdibal{ return self.isPeeled; } -(NSString*)offer:(Banana*)banana{ if (banana.isEdibal) { return @"Hey, want a banana?"; } else { return @"Hey, want me to peel this banana for you?"; } }
接下来验证Banana.peel()方法去假定做些什么:
// BananaTests/BananaTests.swift class BananaTests: XCTestCase { func testPeel() { // Arrange: Create the banana we'll be peeling. let banana = Banana() // Act: Peel the banana. banana.peel() // Assert: Verify that the banana is now edible. XCTAssertTrue(banana.isEdible) } }
//objectes-c .m文件 - (void)setUp { [super setUp]; // Arrange: Create a banana and peel it. self.banana = [[Banana alloc]init]; } -(void)testPeel { // Act: Create the string used to offer the banana. [self.banana peel]; // Assert: Verify it's the right string. XCTAssertEqual(message, @"Hey, want a banana?"); }
使用清晰的测试方法名:
我们必须确保testPeel()方法;如果Banana.peel() 方法不能停止工作;我们知道。
事实上这些是经常发生的当我们的应用代码改变的时候,这意味着:
1. 我们的测试突然停止,因此我们会去修改测试的代码 2. 我们所做的改变我们的应用(这里应该指的是测试代码)应该知道如何工作--也许应为我们新增了一个类的特征--因此我们去改变测试代码
如果测试开始停止,我门如何知道适应于那种情况导致的?也许使你惊讶这个的测试的名字是我们最好的指导。好的测试名字:
1. 清楚告诉测什么的。
2. 清楚告诉测试是通过还是失败
方法 testPeel()是清楚的名字吗?我们来使他更清晰:
// BananaTests.swift //-func testPeel() { +func testPeel_makesTheBananaEdible() { // Arrange: Create the banana we'll be peeling. let banana = Banana() // Act: Peel the banana. banana.peel() // Assert: Verify that the banana is now edible. XCTAssertTrue(banana.isEdible) }
//objectes-c .m文件 - (void)testPeel_makesTheBananaEdible() { [super setUp]; // Arrange: Create a banana and peel it. self.banana = [[Banana alloc]init]; } -(void)testPeel_makesTheBananaEdible() { // Act: Create the string used to offer the banana. [self.banana peel]; // Assert: Verify it's the right string. XCTAssertEqual(message, @"Hey, want a banana?"); }
这个新方法名:
1. 清楚这个方法是测试什么:testPeel 表明他是Banana.peel() 的方法。 2. 清楚知道测试通过:通过方法的返回,makesTheBananaEdible表明香蕉是水果一类的。
条件测试
假设我们想要为人们提供香蕉,使用offer()函数:// Banana/Offer.swift /** Given a banana, returns a string that can be used to offer someone the banana. */ public func offer(banana: Banana) -> String { if banana.isEdible { return "Hey, want a banana?" } else { return "Hey, want me to peel this banana for you?" } }
我们的代码做了两件事:
1. 也许售卖的香蕉已经是剥好皮的…
2. …或者售卖的是没有剥皮的
让我对这两个事件进行测试:
// BananaTests/OfferTests.swift class OfferTests: XCTestCase { func testOffer_whenTheBananaIsPeeled_offersTheBanana() { // Arrange: Create a banana and peel it. let banana = Banana() banana.peel() // Act: Create the string used to offer the banana. let message = offer(banana) // Assert: Verify it's the right string. XCTAssertEqual(message, "Hey, want a banana?") } func testOffer_whenTheBananaIsntPeeled_offersToPeelTheBanana() { // Arrange: Create a banana. let banana = Banana() // Act: Create the string used to offer the banana. let message = offer(banana) // Assert: Verify it's the right string. XCTAssertEqual(message, "Hey, want me to peel this banana for you?") } }
//oc -(void)testOffer_whenTheBananaIsPeeled_offersTheBanana { // Arrange: Create a banana and peel it. [self.banana peel]; // Act: Create the string used to offer the banana. NSString *message = [self.banana offer:(self.banana)]; // Assert: Verify it's the right string. XCTAssertEqual(message, @"Hey, want a banana?"); } -(void)testOffer_whenTheBananaIsntPeeled_offersToPeelTheBanana { // Arrange: Create a banana and peel it. // Act: Create the string used to offer the banana. NSString *message = [self.banana offer:(self.banana)]; // Assert: Verify it's the right string. XCTAssertEqual(message, @"Hey,want me to peel this banana for you?"); }
我们的测试名字明确的指示出在那种条件下的测试通过:在
whenTheBananaIsPeeled条件下
offer的应该是
offersTheBanana, 和即使这个香蕉没有剥皮?我们还是要去做一些测试。
在我们的测试代码中每一个测试都有
`if去声明。我们去写一些测试的时候这是一个很好模式:
它确保每种设定的情况都有测试。如果一种情况下测试没有工作;或者测试条件需要改变,我们能够快速的找到在代码中位置并查看它。
XCTestCase.setUp()更短的 “Arrange”步骤
我们的OfferTests和”Arrange”两个包含着相似的代码:两者都创建了一个香蕉。我们应该讲代码移动到一个单独的地方,为什呢?就像这样,如果我们改变了Banana类的初始化,我们必须去改变每一个测试类的创建的banana;
我们的测试方法将非常的短–这是一件非常好的事情,如果(只有)使得测试类变得更容易阅读。
接下啦,让我们移动Banana 的初始化 到 XCTestCase.setUp() 方法,他在每一测试方法之前调用。
// OfferTests.swift class OfferTests: XCTestCase { + var banana: Banana! + + override func setUp() { + super.setUp() + banana = Banana() + } + func testOffer_whenTheBananaIsPeeled_offersTheBanana() { - // Arrange: Create a banana and peel it. - let banana = Banana() + // Arrange: Peel the banana. banana.peel() // Act: Create the string used to offer the banana. let message = offer(banana) // Assert: Verify it's the right string. XCTAssertEqual(message, "Hey, want a banana?") } func testOffer_whenTheBananaIsntPeeled_offersToPeelTheBanana() { - // Arrange: Create a banana. - let banana = Banana() - // Act: Create the string used to offer the banana. let message = offer(banana) // Assert: Verify it's the right string. XCTAssertEqual(message, "Hey, want me to peel this banana for you?") } }
共享 “Arrange”代码 贯穿到多个测试中
如果你发现你在多个测试类中使用了相似的”arrange” 步骤,你也许想去定义一个辅助函数在你的测试target中:// BananaTests/BananaHelpers.swift internal func createNewPeeledBanana() -> Banana { let banana = Banana() banana.peel() return banana }
你的帮助类中的函数:函数不能有子类,或者能保留任何的状态,子类和多状态可以保证你的测试类容易读。
相关文章推荐
- Swift 初步了解
- swift 往系统日历中添加提醒事项
- Swift学习之--TableView的基本使用
- Swift学习第二枪
- ios swift 测试框架翻译之Quick例子和一组例子的有序测试
- ios swift 测试框架翻译之Quick例子和一组例子的有序测试
- 今天看到一篇不错的swift入门材料,默默分享一下
- swift版QQ音乐播放器(一)
- swift基础语法--闭包
- Swift Snapkit 看这篇基本就"够"了
- Swift讲解专题十三——下标访问
- swift 数据存储
- swift中便利函数的构造
- Cocopods第三方库管理工具创建Swift项目&OC项目就
- swift中KVC构造函数,和执行流程
- swift 中高德地图随时读取坐标地点的写法
- 所有接口添加plist文件的写法 swift
- 【Swift】反射(Reflection)的介绍
- swift base64转UIImage,UIImage转base64
- 什么是Swift