iOS Swift中的单元测试和TDD — pt1

单元测试是测试单个单元/组件的软件测试级别。 目的是通过测试组成程序的最小单元来测试程序的业务逻辑。 在面向对象中,这些最小单位是方法。 因此,我们通过提供输入来测试所有这些方法,并通过比较方法的输出并将其与我们的预期输出进行比较来测试逻辑。 简而言之,这是适合您的单元测试

  • 减少错误。
  • 改善设计。
  • 允许重构。
  • 降低变更成本。
  • 好的文档。 简洁的代码示例胜于文档的许多段落
  • 减少了程序员遇到的最大恐惧之一,那就是对一段代码进行更改,而不知道会破坏什么。

到目前为止,大家可能都在想。

如此多的讨论,让我们编写一些单元测试。

此处下载启动项目

这是一个简单的应用程序,它通过分别以米为单位的身高和以kg为单位的体重来计算一个人的BMI。 它包含一个名为BMICalculator的类,其中包含我们应用程序的业务逻辑,即用于计算一个人的BMI的逻辑,是的,您猜对了! 在本教程中,我们将测试该类。

运行项目,您将看到此屏幕。

玩应用程序,增加身高和体重,然后看一下您的BMI。

PS:请忽略应用程序的UI,因为我的设计技能不太好。 🙁

有两种方法可以在项目中添加单元测试。

1.从新项目开始

您可以在创建新项目时通过选中底部的“ 包括单元测试”复选框来添加单元测试

由于我们已经在项目中添加了单元测试,因此我们跳过此步骤。

2.在已经创建的项目中添加单元测试包

您也可以在已经创建的项目中添加单元测试。

  1. 转到文件>新建>目标
  2. 选择iOS单元测试套件
  3. 点击下一步

打开项目并转到底部的BMI CalculatorTests ,然后选择BMI_CalculatorTests.swift。 您会看到类似这样的内容。

当我们通过上述两种方法中的任何一种将单元测试添加到项目中时,这是Xcode创建的自定义单元测试文件。 让我们快速看一下单元测试的一些重要组成部分。

  1. 在最顶部,有一个导入,即导入XCTest。 XCTest库旨在提供一个通用框架,用于在Swift中为Swift软件包和应用程序编写单元测试。
  2. 在它下面,您将看到@testable import BMI_Calculator 。 这是Apple帮助您将应用程序代码导入到单元测试目标中的方式,以便您可以运行测试。 使用@testable时 ,无需将应用程序成员身份中的任何文件提供给测试目标。 Apple为您做到这一点,创建了一个很好的干净的分隔。
  3. 要创建单元测试,您必须继承XCTestCase 。 通过继承它,您将覆盖它的两种方法,即setupteardown 。 正如其名称所表明的,它们用于在开始测试之前设置您的测试,并在完成测试之后将您的测试分解。 我们将在本教程的后面部分中对它们进行更详细的介绍,但其目的是为单元测试设置一个简洁的表述,并确保单元测试不依赖于先前单元测试的状态,否则它们将很难管理并杀死编写单元测试的目的,即独立测试系统的一个单元
  4. 那么,每种测试方法和类别中最顶部的菱形形状是什么? 尝试将鼠标光标悬停在它们上方。 它们是运行测试的嵌入式按钮。 如果将鼠标悬停在其旁边的菱形上 ,则可以单击以运行测试。 您的应用及其测试目标将被构建,测试将运行,并且您将看到测试成功的通知。 如果要在此测试用例中运行所有测试,请单击类声明旁边的按钮。
  5. 最后,要使您的功能可测试,您必须以其他测试字启动功能,否则菱形内联按钮将不会随您的功能一起出现。

有了所有这些信息,我们就可以测试我们的应用程序了。 因此,让我们测试我们的BMI计算器。

本示例不执行任何操作。 它只是一个模板,告诉您单元测试的外观。您也可以删除或保留它,没关系。 因此,利用我们所拥有的所有知识,现在我们可以看到单元测试的真正力量。

在我们的项目中,转到BMICalculator类。 您会看到类似这样的内容。

这是应用程序所有业务逻辑都存在的类。 它有一个公共方法calculateBMI ,该方法以体重(kg)和身高(米)为单位,计算BMI并将这些值传递给私有函数getBMIType ,该函数根据BMI的值返回结果。 我们将为calculateBMI方法编写单元测试。

正如我之前所说,我们将测试BMICalculator类。 我们将从创建单元测试类开始。

  1. 转到文件
  2. 新文件
  3. 然后选择“单元测试用例类”。
  4. 在选择选项中,键入类名称: BMICalculatorTest并按Next。

单击“ 下一步”之后,将转到一个新屏幕,在该屏幕上,系统将询问您将BMICalculatorTest类添加到何处 。 确保在单元测试组(即BMI CalculatorTests)中创建它,并确保仅选择了单元测试目标。

如果您做对了所有事情,您都会看到类似这样的内容。

删除testExampletestPerformanceExample,因为我们正在编写它们,这是BMICalculator类自己的测试函数。

除去testExampletestPerformanceExample之后,您的BMICalculatorTest类必须看起来像这样。

  1. 添加@testable导入

import XCTest下面添加以下行

  @testable导入BMI_Calculator 

这会将您的应用程序导入单元测试中。

2. 声明BMICalculator的对象

制作一个类型为BMICalculator的变量

  var bmiCalculator:BMICalculator? 

3. 设置bmiCalculator

设置方法中添加以下代码

 覆盖func setUp(){ 
super.setUp()
bmiCalculator = BMICalculator()}

如前所述,设置方法用于在测试之前进行必要的设置。 您可以在此处进行变量初始化。

4. 配置拆解

在tearDown方法中添加以下代码

 覆盖func tearDown(){ 
super.tearDown()
bmiCalculator = nil}

在这里,我们在运行单元测试后添加了所有清理工作。 您可以使deinit或使变量nil。

tearDown方法下面添加以下方法

  func testCalculateBMI(){让result1 = bmiCalculator?.calculateBMI(体重:70,身高:1.63)let result2 = bmiCalculator?.calculateBMI(体重:60,身高:1.63)let result3 = bmiCalculator?.calculateBMI(体重:40,身高:1.63)assert(result1!==“您超重”,“测试用例1失败”)assert(result2!==“您是完美的”,“测试用例2失败”“)assert(result3!==”您不足WEIGHT”,“测试用例3失败”)} 

因此,这里我们测试了这三种情况下的calculateBMI函数。 即OverweightUnderweightPerfect ,通过对三个不同的重量和高度值进行测试并将它们与我们的预期输出进行比较。 assert将计算的输出与预期的输出进行比较,如果测试失败,则显示消息。

现在,通过单击功能左侧的菱形按钮运行测试。

WoooooOOoohoooooo,我们的单元测试成功。 🎉🎉🎉

现在,将这些行添加到result3下面的方法中

 让result4 = bmiCalculator?.calculateBMI(体重:40,高度:0) 

并在函数末尾断言。

  assert(result4!==“身高或体重不能为零”,“测试用例4失败”) 

让我们再次运行测试。

糟糕,我们的测试未通过😱😱😱,并且此失败的测试告诉我们,我们忘记处理用户输入0表示身高或体重的情况。

用以下函数替换BMICalculator类中的calculateBMI。

  func computeBMI(weight:Double,height:Double)-> String {var result =“” if(weight> 0 && height> 0){let bmi = weight /(height * height)result = getBMIType(bmi:bmi.rounded ())}其他{result =“身高或体重不能为零”}返回结果} 

因此,我在这里所做的只是检查输入是否大于零。 如果是,则计算BMI,否则显示消息“ 身高或体重不能为零”

现在运行测试。 我们的单元测试有效。 😄

就是这样。 恭喜,您已经精通iOS swift的编写单元测试。 🎉

您可以从此处下载最终项目

因此,这是我在iOS swift中进行单元测试和TDD系列的第一篇文章。 我将用已经准备好的几篇文章系列来覆盖整个主题。 您还可以查看有关此主题的一本精彩的书,其中包括使用Swift测试驱动的iOS开发

这是我在Medium的第一篇文章。 因此,如果您喜欢这篇文章并认为它很有用,请给我👏,分享并关注。 我很想听听任何有建设性的意见,这些意见可以帮助我改善未来。

您可以在LinkedIn Facebook上关注我 Github 。 您也可以通过@ osama.binbashir@yahoo.com与我联系。