[译] 单元测试,精益创业,以及两者之间的关系-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

[译] 单元测试,精益创业,以及两者之间的关系

简介: 本文讲的是[译] 单元测试,精益创业,以及两者之间的关系,我曾经以为是为了产出高质量的代码:你总是需要测试因为你总是需要写出高质量的代码。
本文讲的是[译] 单元测试,精益创业,以及两者之间的关系,

为什么软件需要测试?

我曾经以为是为了产出高质量的代码:你总是需要测试因为你总是需要写出高质量的代码。
但是这个观点有几点问题。

有时候质量不是主要问题。
在“精益创业” 这本书中,作者 Rric Ries 说过有时候发布一个软件最终发现没人真的想用它。
这也是他创作的动机之一: 为创业初期建立一套更好的方法论,在真正投入时间去构建一个高质量的产品时,就能够发现这款产品是否能够成功的方法论。
如果没人用你的软件的话那么确保高质量纯属浪费时间。

即使高质量很有必要,但高质量与测试之间的关系却很模糊的。
一个 QA 的团队跟自动化的单元测试又什么不同?
他们的确不一样,但他们又分别给出什么样的质量?
什么时候需要特别的测试?

另外,测试是有成本的:你怎样辨别成本的花费是否超出回报?
比如说,有一家做税务申报软件的公司(我稍微改了一下细节)。
他们使用 Selenium 来对他们网站的 UI 来测试... 但是他们的应用依然很烂,而且每次改变 UI 测试都会崩溃。
这个测试并没有改变产品的质量,相反浪费了程序员的时间来维护测试。
他们做错了什么?

说我们都需要写出高质量的软件并不能帮助解决这些问题。
那我们回头来更加深入的讨论一下。

测试的意义是什么?

康熙字典 :) )里告诉我们测试是为了 “举证,通过一定原则或标准或实验来,证明真理,真实性。“
软件质量就在那里,是的,但事实却又不仅如此。

准确的说,这只是英语定义,可以肯定,有很多不说英语的开发者。
我不想被字典来束缚我们的行为。
人类语言是数世纪以来对世界的观察和理解,也是我们可以拿来借鉴的宝库。

那我们来以这个为出发点来看看能学到点什么。

测试的第一个方面

下面这个是测试吧?

def test_add():
    assert add(2, 2) == 5

没错,他还真是,没毛病。
看函数名,一点都没错。
测试说明 add() 做了他该做的:将两个数相加得到结果。

你注意到这个测试是的。
幸运的是我们的开发流程进入到了另一步:代码审查。
亲爱的读者们,代码审查告诉我我的代码是错的,2 + 2 = 4,不是 5。

代码审查是不是测试的一种?

根据字典定义来说是的:代码审查就是根据标准来验证代码的 “正确,真实性和质量”,这个从小我们就知道。

那我们假设代码审查跟单元测试一样都是测试的一种。
他们都是测试,却又相当不同。
那主要的区别在哪里?

一种是自动化的,一种是人来做的。

自动化测试具有一致性和可重复性。
你可以这样写:

def test_add_twice():
    for i in range(10000000):
        assert add(i, i) == 2 * i

电脑每次都跑一遍一摸一样的代码。
代码可以保证根据输入每次调用add()返回他们的结果。
人在手动验证一千万种不同的计算时会遇到一些困难,比如无聊、分心、失误、缓慢啦等等。

另一方面,任何人都可以很快的告诉你下面的代码是错的:

def add(a, b):
    return a + b + 1

计算机只按照指令执行操作,孰对孰错,人类能赋予它意义。
只有人才知道软件是为何而生。

现在我们知道每种测试的不同,以及如何组织它:人类来发现意义,自动化测试确保一致性。

测试的第二个方面

我们来看一下测试的另一个方面。
“A/B 测试”是一种尝试不同分类来看哪种结果更好的测试。
比如你为了测试网站新的设计:给 90% 的访问者原有的设计,同时给 10% 的访问者新的设计,看看哪种注册人数多一点。

这是测试吗?
这就叫 “A/B 测试”,跟它的名字一样。

我们来重新看一下字典定义:“举证,通过一定原则标准实验,来证明真理,真实性。”

字典上说这也是测试,因为通过实验
我们通过实验来看看哪个版本更受欢迎。

单于测试和代码审查,对比来说,就是通过一定原则标准来测试。
我们对软件有一些特定规格,一些我们希望软件的行为,同时我们确保它符合规格。

现在我们有了第二种理解与组织测试的方法:通过实验测试 vs 针对规格测试

测试的象限图

将它们放在一起我们得到下面这张关于测试的图表:

1

用户行为

  • 有人买你的产品吗?
  • 设计的改变会影响注册人数吗?
  • 用户知道软件是如何工作的吗?

这些都是无法通过软件是否符合规格来回答。
相反需要你的经验知识:你需要观察人对软件的真实反映。

软件表现

  • 你的软件在负载下表现如何?
  • 你的产品抛出异常吗?

这些问题不能通过对比规范来解答,
你需要把软件跑起来看看到底会发生什么。

功能正确性

  • 你的软件符合规范吗?
  • 它做了它该做的吗?

很容易说自动化的测试可以证明这一点,但有没有想过单元测试在检查 2 + 2 = 5。
在基本的层面上,软件可以在技术上符合规范却完全无法达成规范的初衷。
但只有人明白规范的含义,和辨别是否匹配这个规范。

功能的稳定性

  • 你的公有 API 对于相同输入返回相同的值吗?
  • 你的代码是否提供了它该提供的?

人不是测试这个问题的好办法。
所有人都会忽略小问题:如果一个按钮从 “Send Now” 变成 “Send now”,很多人都不会注意到。
对比来说,如果你的 API 从 sendNow() 变成 send_now(),或者返回一个不同类型的值,你的软件就会崩溃。

这就是说公有的 API,或者其他软件依赖的 API,需要稳定性来确保正确性。
为私有的接口写自动化测试,或者对于迭代较快的代码,更新测试将导致极高的维护成本。

应用上述模型

如何应用模型?

选择如何测试

首先,模型可以帮助你根据你的目标选择合适的测试。

如果一家初创公司做一个没人用的软件。
写自动化测试纯属浪费时间,因为他连用户想要什么都不知道就开始专心实施了。

这里需要用精益创业的方法论,一个专注于用实验找到什么产品将满足客户的需求的方法来解决。
这意味着专注于用户行为象限。
只有证明他值得花费时间来进行下去,才值得对这个产品来做一些为了功能性和稳定性的测试。

了解你是否选择了错误的测试类型

第二,这个模型可以帮助你改变错误的行进路线。
比如说那家初创的税务公司,如果他们对于 UI 进行自动化测试但是并没有发现问题,然后每改变一次 UI,整个系统都要重新来进行一遍测试。
他们的问题在于系统的两个方面:

  1. 税务机制是相当稳定的:税率每年只变一次。
    这就需要他们对核心的税务计算部分进行稳定性或者单元测试。
    正确性可以通过代码审查和税务会计来反馈。
  2. 基于 web 的用户界面
    UI 一直在变,说明不需要稳定性测试。
    正确性测试可以通过人工测试来解决(比如说写代码的开发者)。

讨论测试的根据

最后,这个模型提供了一个公有的术语,来讨论的测试的意义及其不同的目标。

  • 对于人工测试还是单元测试的优异性选择,你可以从一个很清楚地表明它们之间的差异的模型开始。
  • 你也可以从一个完全不同的角度对公司的其他方面(比如市场)来讨论测试。

总结

  • 无论是选择人还是自动化测试来保持持续性,都是有意义的,自动化测试提供准确性,人手工测试提供意义性。
  • 即需要通过实验,也需要对比规范来进行测试。
  • 每个组合提供了不同的测试形式:用户行为、软件行为、正确性、稳定性。
  • 确保根据你的目标和情况来选择合适的测试方式。





原文发布时间为:2017年3月27日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: