当前位置: 首页 > 科技观察

在Xcode7中使用Swift进行单元测试

时间:2023-03-17 17:09:59 科技观察

每个iOS程序员都必须不时调试他们的应用程序。除非您是那些超级精明的人中的一员,否则当您花费无数小时追查一个bug***却发现它只是一个简单的语法错误时,您肯定体验过那种绝望的感觉。或者更糟:您根本就没有发现这些错误。无论你是编程新手,还是开发过很多APP的老司机,定期编写单元测试会让你的代码更可靠、更安全、更容易调试!幸运的是,Xcode7和Swift支持单元测试。虽然单元测试不能保证(并且您将使用它编写)一个绝对没有错误的应用程序,但它是您验证每段代码是否按预期工作的一种方式,并且它使调试过程更加容易。顾名思义,在单元测试中,您为特定代码单元的特定功能创建小测试,然后确保每个代码单元都通过这些测试。如果通过,旁边会出现一个小绿旗,如果测试由于任何原因失败,Xcode会将测试标记为“失败”。这会提示您查看代码以找出失败的原因。演示项目概述首先下载我为您准备的启动项目。一个简洁的小应用程序:它对给定的数字和百分比进行乘法计算。(例如80的10%是8。)PercentageCalculator项目非常简单。您唯一需要注意的是ViewController.swift文件。里面的代码都有注释,很容易理解。有5个IBOutlets:分别对应屏幕上的一个UIElement,除了标题(title)外,还有2个slider对应2个IBActions。每个IBAction的方法名称准确描述了它做什么和将要做什么。当滑块值发生变化时,相应的百分比或数值也会随之变化。还有两个简单的函数“updateLabels()”和“percentage()”可以执行预期的操作:第一个函数在滑块更改时更新标签,第二个函数采用两个浮点数并返回百分比计算结果。在模拟器中运行应用程序。起初一切似乎都很正常。但是当你开始改变数字时,你会发现计算结果是错误的。为了找到错误,我们将代码分成不同的单元并测试每个单元以查看每个单元是否按预期工作。这不会修复错误,但会缩小您的搜索范围。我在创建项目的时候,默认勾选了创建测试文件的选项(如果要手动添加,在iOSSource下选择selectFile>New>File>UnitTestCaseClass)。在我们的示例中,测试文件已由Xcode自动创建,可以在项目导航器的“PercentageCalculatorTests”文件夹中找到。在PercentageCalculatorTests.swift文件中,PercentageCalculatorTests类为我们创建了4个方法。其中2个是测试方法的例子,你可以删除它们(它们都以关键字test开头,在它们左侧的垂直栏中有一个方形图标,并且名称都以“...Example”结尾,所以你可以通过这些来判断它们是测试方法)。另外两个方法setUp()和tearDown()是特殊的样板方法,分别在每个测试方法执行之前和之后执行。开始编写单元测试现在是时候编写您的第一个单元测试函数了!对于本教程,我们只测试ViewController类,并且需要在PercentageCalculatorTests中添加它的一个实例。类百分比计算器测试:XCTestCase{varvc:ViewController!overridefuncsetUp(){super.setUp()//在这里写设置代码。在调用此类中的每个测试函数之前将调用此方法。}overridefunctearDown(){//在这里写拆解代码。该方法将在调用该类中的每个测试函数后调用。super.tearDown()}}PercentageCalculatorTests是XCTestCase的子类,封装在XCTest框架中。XCTestCase子类的每个实例负责测试项目的特定部分,例如测试功能。在setup方法中实例化一个vc。这样您将为每个测试方法获得一个“全新”的ViewController实例,因为setUp()将在每个测试方法执行之前被调用一次。修改setUp()方法如下:overridefuncsetUp(){super.setUp()letstoryboard=UIStoryboard(name:"Main",bundle:NSBundle.mainBundle())vc=storyboard.instantiateInitialViewController()as!ViewController}现在你应该记住所有测试方法的名称都必须以关键字test开头,否则Xcode将无法识别它们。添加一个新的testPercentageCalculator()测试方法来验证ViewController中的percentage()是否正常工作。functestPercentageCalculator(){}单元测试是检查某段代码是否按预期工作的地方。被测试的代码段一般只有几行,通常只需要测试一个方法或一个函数。单元测试是这样工作的:你给一个代码单元一个输入值,让这个值通过代码,然后检查输出值是否符合预期。与“我们期望的”进行比较的部分由XCTAssert函数处理。最简单的XCTAssert函数是XCTAssert(expression:BooleanType)。此函数接受一个布尔表达式(类似于5>3、8.90==8.90或true),然后如果表达式为真则通过测试,否则测试失败。尝试一下!首先将以下行添加到testPercentageCalculator()方法。然后将光标移动到方法名称左侧边栏中的方形图标。停止光标后,方形图标变为执行光标。单击它开始测试。functestPercentageCalculator(){XCTAssert(true)}如果一切顺利,则测试通过,方法左侧会出现一个绿色复选标记。验证百分比计算现在开始:测试percentage()方法!使用ViewController-vc属性的实例调用此方法。给这个方法两个浮点数,比如50和50,并将结果存储在常量p中。在此示例中,p应为25(50的50%为25)。然后使用XCTAssert(p==25)检查是否是这种情况并执行测试方法。将testPercentageCalculator()改成这样:functestPercentageCalculator(){//应该是25letp=vc.percentage(50,50)XCTAssert(p==25)}测试成功,说明ViewController的percentage()函数起作用了好吧,我们应该继续在别处寻找错误。也许错误在updateLabels()内部?验证标签现在添加一个新的测试方法testLabelValuesShowedProperly()来验证标签是否可以正确显示文本。和以前一样,在ViewController上调用一个方法-这次是updateLabels()-并查看每个标签的文本属性是否与我们期望的相同。请注意,您正在向XCTAssert函数传递一个新参数:一条字符串类型的消息。如果我们这次要检查多个值(调用XCTAssert三次)来完成测试,这将很方便。如果测试失败,该消息将准确指出我们哪里出错了。functestLabelValuesShowedProperly(){vc.updateLabels(Float(80.0),Float(50.0),Float(40.0))//标签应显示80、50和40XCTAssert(vc.numberLabel.text=="80.0","numberLabeldoesn'tshowtherighttext")XCTAssert(vc.percentageLabel.text=="50.0%","percentageLabeldoesn'tshowtherighttext")XCTAssert(vc.resultLabel.text="40.0","re??sultLabeldoesn'tshowtherighttext")}当您尝试执行此测试方法时,它将向编译器收到错误消息:numberLabel、percentageLabel和resultsLabel为nil。这是怎么回事?我在storyboard文件中创建了这些labels,所以它们只有在视图加载(loaded)时才被初始化,但是,由于单元测试没有触发loadView()方法,labels并没有被创建,只能是nil。一种可能的解决方案是调用vc.loadView(),但Apple在其文档中不建议您这样做,因为在再次加载已经加载的对象时可能会导致内存泄漏。正确的做法应该是先访问vc的view属性,这会让vc依次触发所有对应的方法,而不仅仅包括loadView()。将testLabelValuesShowedProperly()更改为:functestLabelValuesShowedProperly(){let_=vc.viewvc.updateLabels(Float(80.0),Float(50.0),Float(40.0))//标签应显示80、50和40XCTAssert(vc.numberLabel.text="80.0","numberLabeldoes'tshowtherighttext")XCTAssert(vc.percentageLabel.text="50.0%","percentageLabeldoes'tshowtherighttext")XCTAssert(vc.resultLabel.text="40.0","re??sultLabeldoesn'tshowtherighttext"")}注意下划线(_)忽略了常量的名称。因为我们实际上并不需要使用这个视图。添加下划线告诉编译器“只是假装访问这个视图并触发相应的方法。”执行测试。(如果您想一次执行我们测试类的所有测试,您也可以单击“classPercentageCalculatorTests”旁边的框。让我们修复错误如您所见,测试失败!我们传递给XCTAssert的错误详细信息方法可以帮助我们快速识别bug的可能原因,这个测试告诉我们resultsLabel没有显示正确的文本,所以我们进入ViewController中查看这些标签的文本值设置在哪里。仔细查看ViewController.swift的updateLabels()代码,发现bug原因:self.resultLabel.text="\(rV+10)"应该是:self.resultLabel.text="\(rV)"update代码后再次运行测试,一切正常!结论在本教程中,您了解了Xcode中的单元测试以及它如何帮助您查找代码中的错误。除了防止bug,单元测试还可以用于性能测试和异步测试。您还对UI测试感兴趣,您可以在其中记录您在应用程序上执行的操作,以测试您的应用程序在实际使用场景中的行为方式。如果这听起来很有趣,请务必查看有关UI测试的WWDC视频。该项目的最终版本可以在Github上下载。如果您对UI测试有任何疑问,或者在学习本教程时遇到问题,请在评论中联系我!关于作者:MaximeDefauw是一位经验丰富的程序员,曾在AppStore和GooglePlay商店发布过多个应用程序。他今年16岁,住在比利时。他最近在旧金山的WWDC15上获得了Apple的奖学金。Max精通Objective-C、C、C#,现在还精通Swift。当他不编码时,他通常在曲棍球场或高尔夫球场。在推特上关注他@MaximeDefauw。