Tag: Khaterine Castellano

在Swift中编写更好的单元测试:第二部分

问题 在本系列的第一部分中,我定义了我认为是“良好”的单元测试。 这是我最终得到的定义: 如果我们可以同意一个单元测试(或者实际上是任何一个测试)是由一些设置 ,我们正在测试的动作以及关于该动作效果的断言组成的,那么我可以这么简单地说,一种“好的”单元测试可以使这三个组件中的每一个都清晰可见。 您可能还记得,我们以如下所示的测试结束了这篇文章: var sut,其他:用户! func test_equals_allPropertiesMatch_isTrue(){ (sut,other)=(.create(),.create()) XCTAssertEqual(ut,其他) XCTAssertEqual(other,sut) } func test_equals_nameDiffers_isFalse(){ (其他)=(.create(name:“ Jo”),.create()) XCTAssertNotEqual(sut,其他) XCTAssertNotEqual(other,sut) } 我们压缩了设置,以便测试主体仅包含对测试场景重要的信息。 例如,当重要的是两个用户对象的名称不同时,我们在设置中仅包括该信息。 这是提高测试总体可读性的好方法。 但是,我们还有更多可以做的事情。 您可能查看了上述测试,并认为“设置还可以,但是为什么在这里却有两个断言呢?”很好的问题! 我很高兴您关注这个问题。 请记住,以上测试涵盖了User类型上的==函数。 在不给您带来全部数学负担的情况下,平等是“等价关系”的一个示例,而关于等价关系的重要内容之一就是对称性的概念。 简而言之,如果我有两个某种类型的实例a和b ,则永远不会出现a == b为true但b == a为false的情况。 如果这是可能的,那么我们对平等的定义是有缺陷的。 因此,有必要验证我们的==的自定义定义是对称的。 但是,仅看那里的两个断言,就完全不清楚这是意图。 这些测试只是在断言一件事。 经过一段时间和倾向,其他工程师可能会弄清楚为什么我们添加第二个断言,但是我们绝对可以做得更好。 但是…如何? 解决方案 让我们开始做我们可能想到的最简单的事情。 我们有两行代码,而我们只想有一行代码。 解决方案? 一个功能! func assertSymmetricallyEqual(_ sut:用户,_其他:用户){ XCTAssertEqual(ut,其他) XCTAssertEqual(other,sut) } (注意:这里我们专注于测试是否相等,但是对于不平等,您可以做完全相同的事情)。 现在我们的测试变为: var […]

在Swift中编写更好的单元测试:第一部分

问题 瞧,我们是这里的朋友,所以我觉得我很坦白:我在职业生涯中写了一些非常糟糕的单元测试。 20行怪物,具有多个模拟和断言以及异步期望。 您在书中看到的这类标题为“如何修复以前工作过的白痴留下的混乱”的书。我还必须在写完单元测试和不太那么说的代码后维护该代码。更好。 可以这么说,我现在将编写“好的”单元测试作为优先事项。 在开始之前,我将定义我认为是“良好”的单元测试。 如果我们可以同意一个单元测试(或者实际上是任何一个测试)是由一些设置 ,我们正在测试的动作以及关于该动作效果的断言组成的,那么我可以这么简单地说,一种“好的”单元测试可以使这三个组件中的每一个都清晰可见。 (此外:这可能与您对“好的”单元测试的定义有所不同,而这只是我们俩都必须忍受的。) 在一些博客文章中,我将向您展示我们在Clue所做的一些工作,以确保我们始终试图编写“良好”的单元测试。 在本文中,我们将看一个简单的技巧,我们可以使用它来最小化单元测试的设置部分,同时保持清晰度。 假设我们要在一个简单的Swift结构上对相等方法进行单元测试。 struct用户:Equatable { 命名:字符串 让电子邮件:字符串 让需求验证:布尔 静态函数==(lhs:用户,rhs:用户)-> Bool { 返回lhs.name == rhs.name && lhs.email == rhs.email && lhs.needsVerification == rhs.needsVerification } } 我们可以(无限)有许多不同的参数组合可以传递给此方法进行测试。 显然,我们无法对所有这些进行测试,因此我们必须选择一些代表总体趋势的案例。 对该方法进行单元测试的有效方法(实际上,我通常会使用测试驱动的开发方法编写这种方法)是从两个User的所有属性均相等的情况开始,然后测试每个属性不同时会发生什么。 这给了我们这样的测试套件: func test_equals_allPropertiesMatch_isTrue(){ let sut = User(名称:“”,电子邮件:“”,needsVerification:false) 让其他=用户(名称:“”,电子邮件:“”,需要验证:false) XCTAssertEqual(ut,其他) XCTAssertEqual(other,sut) } func test_equals_nameDiffers_isFalse(){ let sut = User(名称:“ Jo”,电子邮件:“”,需要验证:false) 让其他=用户(名称:“”,电子邮件:“”,需要验证:false) […]