单元测试
一些废话 #
影响敏捷,很重要的一个因素是”持续迭代”。
影响持续迭代,很重要的一个因素是”代码交付”。
影响代码交付,很重要的一个因素是自动化单元测试(UT),自动化集成测试(IT)。只有高质量的代码交付,是有效的”持续(continues)”
如果有人说自动化单元测试因为代价过高,不必做。我愿称之为没有太多项目经验,他一定没有因为重视质量,做全了UT/IT 而节约了巨大维护成本的经历和体验。
代码交付质量的重要性不言而喻,(若有不同观点,譬如”代码交付质量大可不必太在意”者,可以绕道走开)单元测试作为代码交付的第一道把关,有效的减少了后续所有团队成员返工的工作。花时间写一段有效的单元测试,我认为有以下几点好处:
让开发人员带入用例的思考。一个方法的输入,其输入的可能性本身,就是值得思考的,调用方法的人可以看作是这个方法的”客户”,顾客在某个输入框,很可能会像猴子一样输入任何意想不到的值。
避开低级错误。
重新思考对方法封装和抽象的合理性。写UT的过程,实际上是在思考,我该如何用这个方法,一个单纯写方法的人,很难换位思考,许多问题,是只有他在用这个方法时,才会发问,这是哪个傻逼写的function~
可重复使用,UT的价值无限大。需求变更在所难免,重构方法也是在所难免的。凡是任何一点点的重构,一段UT,都能覆盖一定的测试用例范围,他能在将来被人用无数次,他能非常有效的发现一些重构引入的旧逻辑下的新问题。
我一直以为,用UT确保代码交付质量是行业共识,其实,不然,行业并不是那么看重代码交付质量,进度才是最重要的,而因为代码质量造成的运维问题,往往被嫁祸到其它因素之上,比如别的与我集成的模块,比如人为因素,比如客户需求不明等。难道在写UT时候,对用例思考过程中,发现需求不明确的地方,不应该迅速跟客户确认需求吗?
tmd我觉得这篇博客,以上写的全是废话呢?(我一直以为这些是行业共识)(黑人问号脸🧓🏿❓️)
敏捷团队,对每个团队成员,包括产品,开发,测试的素质要求相对传统团队来的要高,需要测试人员以自动化批量化的思维,需要开发有产品的思维,同时需要开发能够覆盖ops 的一系列pipeline 的搭建。不过,对公司的贡献是1+1 > n 的一种值得一试的模式。
我是一个nobody,我说这些是行业共识没用,以下是我从马丁老爷子博客摘来的一些观点:
第一篇,自测代码 - by 马丁福勒 - 链接:SelfTestingCode #
马丁老爷子表示,自测代码是持续集成的关键,我们的态度是假设任何没有UT 覆盖的代码都会被破坏。为了避免,或者迅速发现这些新引入的bug,我们需要频繁的运行,这些覆盖完全的自测代码。
原文如下:
You have self-testing code when you can run a series of automated tests against the code base and be confident that, should the tests pass, your code is free of any substantial defects. One way I think of it is that as well as building your software system, you simultaneously build a bug detector that’s able to detect any faults inside the system. Should anyone in the team accidentally introduce a bug, the detector goes off. By running the test suite frequently, at least several times a day, you’re able to detect such bugs soon after they are introduced, so you can just look in the recent changes, which makes it much easier to find them. No programming episode is complete without working code and the tests to keep it working. Our attitude is to assume that any non-trivial code without tests is broken.
Self-testing code is a key part of Continuous Integration, indeed I say that you aren’t really doing continuous integration unless you have self-testing code. As a pillar of Continuous Integration, it is also a necessary part of Continuous Delivery.
还是这篇,马丁老爷子表示,自测试代码的一个明显好处是它可以大大减少进入生产软件的错误数量。 其核心是建立一种测试文化,让开发人员自然而然地考虑一起编写代码和测试。
原文如下:
One obvious benefit of self-testing code is that it can drastically reduce the number of bugs that get into production software. At the heart of this is building up a testing culture that where developers are naturally thinking about writing code and tests together.
最后,马丁老爷子表示,这种文化,能给团队带入一种良性循环。而不是每天忙着救火。
原文如下:
With self-testing code, it’s a different picture. Here people are confident that fixing small problems to clean the code can be done safely, because should you make a mistake (or rather “when I make a mistake”) the bug detector will go off and you can quickly recover and continue. With that safety net, you can spend time keeping the code in good shape, and end up in a virtuous spiral where you get steadily faster at adding new features
第二篇,实用测试金字塔 - by Ham Vocke - 链接:The Practical Test Pyramid #
开篇导言中写到:由自动化测试推动的大幅缩短的反馈循环与敏捷开发实践、持续交付和 DevOps 文化齐头并进。拥有有效的软件测试方法可以让团队快速而自信地行动。
我希望大家都能体会到,快速迭代也能自信的上线,经过一连串自动化UT + IT 后,发布到生产环境的结果就是,拍着胸脯说,我的软件上线没问题。
原文如下:
The drastically shortened feedback loop fuelled by automated tests goes hand in hand with agile development practices, continuous delivery and DevOps culture. Having an effective software testing approach allows teams to move fast and with confidence.
Ham Vocke所表达的第一个观点是,自动化的重要性:每个公司都在试图寻找成为一流数字公司的方法。今天创新的车轮转动得飞快。如果公司想跟上步伐,就必须寻找在不牺牲质量的情况下更快地交付软件的方法。
手动构建、测试和部署越来越多的软件很快就变得不可能了——除非你想把所有的时间都花在手动、重复的工作上,而不是有效的生产力交付上。自动化一切(包括构建、测试、部署)是您前进的唯一途径。
原文如下:
Building, testing and deploying an ever-increasing amount of software manually soon becomes impossible — unless you want to spend all your time with manual, repetitive work instead of delivering working software. Automating everything — from build to tests, deployment and infrastructure — is your only way forward.
Ham Vocke表示:手动测试很傻,手动测试所有变更和影响范围是耗时、重复和乏味的。 重复是无聊的,无聊会导致错误。
之后,作者给了许多不同方面的实操,幸运的是,这些实操都是可执行的。包括了:单元测试,数据库自动化集成测试,消息消费自动化测试,前端自动化集成测试,end to end 自动化测试,接口自动化测试。
最后 #
拥有一个可靠的测试会付出一些工作。 从长远来看,它会得到回报,它会让你作为开发者的生活更加平静,相信我。