AI人工智能与软件测试

用python实现简单的版本号生成工具

我们发布比较频繁,每次发布都需要从 release 分支打 1 个 tag,不过可能是因为年纪大了的缘故吧,尽管借鉴了一些版本号的制定规则,不过每次我都记不太住,需要翻文档去重新复习,不如把这步自动化一下,为未来的自己节约一点时间,另外有了工具就好统一规则,后面所有相关的项目都可以用同一套规则来生成版本号,去掉了人工对齐的成本,变相提升了效率。

版本号规则

我们的版本号大概长这个样子

v1.00.0-hotfix-20221111-1
版本号   发布类型 发布时间  第几次发布
  • 版本号规则: 大版本 1 位 + 小版本 2 位 + patch 版本号 1,比如 v1.00.0 表示大版本是 1,小版本是 0,patch 版本是 0
  • 发布类型:普通发布/hotfix/adhoc(临时版本)

设计

首先不考虑写页面做系统,其实用 vue 随便写个单页应用是可以很快搞定的,不过没那个必要,用命令行工具就好了,简单快速,而且生成了版本号之后可以调用 githlab(我们公司用私有化部署的版本)api 来自动打 tag,在微服务化当道的今天,手动为每次发布的所有 repo 打版本号本身就不是一个很好的体验。命令行工具在这方面比单页应用更具优势一些。

另外交互式的命令行可以省去很多参数 validation 的工作量,这也应该是考虑的。随便搜索了一下,发现了 1 个名为 inquirer 的库可以很好的满足我的需求。

代码实现

import inquirer
from datetime import datetime

STR_MAP = {
	'regular': '',
	'hotfix': '-hotfix',
	'adhoc': '-adhoc'
}

def build_version(options):
	release_type = STR_MAP[options['release_type'][0]]
	date = datetime.now().strftime('%Y%m%d')
	return f"v{options['version']}{release_type}-{date}-{options['seq']}"

if __name__ == "__main__":

	questions = [
		inquirer.Text("version", message="Please enter a version, for sample 1.00.0", default='2.00.0'),
		inquirer.Checkbox(
			"release_type",
			message="Please select a release type",
			choices=["regular", "hotfix", "adhoc"],
			default=['regular']
		),
		inquirer.Text("seq", message="please enter the sequence", default='1'),
		inquirer.Confirm(
			"correct",
			message="This will generate a tag name. Continue?",
			default=False,
		),
	]
	answers = inquirer.prompt(questions)

	if answers['correct']:
		tag_name = build_version(answers)
		print(tag_name)
	else:
		print('nothing to do')

整体流程非常的简单

python requests的替代者?httpx初体验

python 的 requests 库由于其使用简单,文档丰富成为了很多人在发送 http 请求时候的优选选择。前几天看到了一个类似的实现 httpx,在这里简单使用体验一下,顺便简单分享一下体验心得。

相比较 requests,httpx 支持 sync 和 async 的 API,支持 http1.1 和 http2。httpx 尽最大努力兼容 requests 的 API,这样一来用户从 requests 转换到 httpx 的成本就相对较为低廉了。

基本 API

>>> import httpx
>>> r = httpx.get('https://www.example.org/')
>>> r
<Response [200 OK]>
>>> r.status_code
200
>>> r.headers['content-type']
'text/html; charset=UTF-8'
>>> r.text
'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>...'

简单扫一圈,满眼都是 requests 当年的样子。下面是 requests 的 API,大家来找茬,看看哪里不一样。

>>> import requests
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>> r.status_code
200
>> r.headers['content-type']
'application/json; charset=utf8'
>> r.encoding
'utf-8'
>> r.text
'{"type":"User"...'
>> r.json()
{'private_gists': 419, 'total_private_repos': 77, ...}

不能说非常相似,只能说是一模一样。

httpx client

requests 为一组 http 请求提供了 session 对象来进行统一设置和管理,httpx 则相应的提供了 client 对象。我们来对比一下使用方式先。

如何优化selenium webdriver的执行速度

让自动化测试脚本正常工作只是自动化测试的第一步,由于自动化脚本会经常执行并更新,因此测试脚本需要

  • 可以快速执行
  • 容易维护
  • 容易阅读

本文会提供一些让 selenium 自动化脚本运行的更快的技巧。

在 page_source 中断言 text 比直接使用 text 属性断言要快

我们经常会需要断言页面中的某个部分包含一些具体的文本,下面的语句的输出结果是相同的

driver.page_source
driver.find_element(:tag_name => body') .

不过对于第二条语句来说,selenium 需要去分析页面的结构,最后再找到对应的元素并输入结果,这显然是需要花费时间的。如果页面比较小的化,那么二者的差距可能不大,不过对于大的页面来说,第一条语句速度明显会更快一些。

使用 page text 的情况

expect(driver.find_element(:tag_name => "body").text).to include("platform- and language-neutral wire protocol")

使用 page source 的情况

expect(driver.page_source).to include("platform- and language-neutral wire protocol")

来看一下差距

Method 1: Search whole document text took 0.823076 seconds
Method 2: Search whole document HTML took 0.039573 seconds

当然两者的使用场景是不太相同的,不过我们这里只关注性能,显然 page source 要更快速一些。

元素越具体,获取 text 的速度越快

根据经验,我们可以通过缩小更具体的 Web 控件的范围来节省执行时间。下面的两个断言语句在很大程度上实现了相同的功能,但在执行时间上有很大的不同。

expect(driver.find_element(:tag_name, body).text).to include(language-neutral wire)

这条语句的执行时间是 0.93s

expect(driver.find_element(:id, abstract).text).to include(language-neutral wire)

这个断言只执行了 0.02s

很明显,第 2 个断言除了在执行速度上更快之外,断言也更加精确,更容易理解。

使用变量去缓存没有变化的元素

我经常看到有人编写如下测试来检查页面上的多个文本。

driver.navigate.to(site_url + "/WebDriverStandard.html") expect(driver.find_element(:tag_name, "body").text).to include("Firefox")
expect(driver.find_element(:tag_name, "body") ").text).to include("chrome")
expect(driver.find_element(:tag_name, "body").text).to include("W3C")

执行时间 2.35s

上述三个测试语句非常低效,因为每个测试语句都调用driver.find_element(:tag_name, 'body').text,当网页很大时,这可能是费时费力的工作。

自动化测试的9大规则

看到了一篇不错的关于自动化测试文章,简单翻译了一下。

在我的软件测试生涯中,我听到了许多说法,如 “我们不需要团队中的测试人员!“到 “我们需要用 100%的覆盖率来自动化一切!"。每当我听到这些时,我都会摇头。我打赌你知道为什么。这两个极端都是错误的,因为我认为每个软件开发团队都应该有一个测试人员在其中。当然,100%的测试自动化覆盖率也是不可能的,也是没有效率和要求的。

在这篇文章中,我将分享我在测试自动化方面学到的经验,这些经验是我在软件测试行业工作了 13 年以上的艰苦历程中总结出来的。我将分享我在过去几年中对测试自动化和要避免的陷阱的详细看法。我将分享我在测试自动化方面的注意事项,以帮助你不犯同样的错误。

应该去做的事情

雇用合适的人

雇用具有软件工程技能的人是必须的。没有正确的技能,你的测试自动化会失败。因此,需要在招聘过程中投入大量时间,以确定适合你的需求的人。我建议你写下你想通过新员工实现的目标。一旦目标明确,就从中引申出具体的技能。

现在是时候写一份朗朗上口、不太长的职位描述,并说明所需的核心技能。不要在长长的技能清单中过度使用技术术语和要求。这可能会对潜在的雇员产生负面的影响。

在面试过程中与人交谈时,技术能力是必须的。你可以在编码挑战或临时进行的代码审查中验证它们。然而,不要只看技术能力。检查是否适合团队或公司,以及在与人合作、沟通和解决问题时的正确心态也非常重要。

一旦你雇用了合适的人从事你的自动化工作,相信他们会做正确的事情。给他们尽可能多的上下文,让他们与公司的其他角色一起,如开发人员、设计师和产品人员。在最好的情况下,每个开发团队都有一个测试工程师加入。

在寻找正确的测试自动化工具方面花点时间

在公司拥有正确的测试自动化人员是一个很大的优势。下一个挑战是找到并选择正确的测试自动化工具。而这需要时间。在选择工具之前,与所有参与方坐下来,定义测试自动化的目标。在这个过程中,尽量提出尽可能多的关于工具、自身环境和将要建立的产品的问题。在这些问题的帮助下,你将创建一个长长的选择标准列表,以帮助你找到适合你需要的测试自动化工具。

该列表可以有以下标准。

  • 该工具是否支持不同的编程语言?
  • 该工具是否能够针对不同的操作系统进行自动化?
  • 该工具是否支持 CI/CD?
  • 该工具是否提供报告功能?
  • 该工具是否有很好的文档,是否提供支持或有一个伟大的社区或干爹?
  • 该工具是否满足预算要求?
  • 配置该工具的复杂程度如何?
  • 该工具是否提供灵活的测试执行能力,例如在不同的操作系统或环境下?

上面的列表只包含了一些可能的问题,以找到合适的工具。因此,需要投入足够的时间来找到适合你需求和环境的工具。也可能是你需要一个以上的自动化工具用于你的技术架构中的不同层,或者是除了测试自动化工具之外,还需要一个测试自动化管理平台。那么你应该分别对每个工具进行选择。

轻装上阵

一旦你确定了适合你的需求的自动化工具,现在是在你的团队或公司内进行配置和实施的时候了。在最初的几天或几周内,试着学习所有关于这个工具和它的功能。一旦你和你的团队熟悉了它,就开始进行第一个自动化方案的工作。但开始时一定要简单! 看看那些容易自动化的产品功能,并帮助团队专注于质量的其他部分。当这个测试是强大的并提供可靠的结果时,就可以进入下一个自动化阶段。开始在更复杂的情况下工作,看看结果。我们也建议在产品的某些部分进行测试,这些部分每天或每周都不会改变。通常一个产品的核心功能是自动化的完美起点。

让开发人员参与到自动化过程中来

编写测试自动化代码并不容易。**它的复杂性与编写生产代码的复杂性相同,这一点永远不应该被低估。**通常一个软件开发团队有 3-5 个软件开发人员和至少 1 个软件测试工程师。这个比例是可以的。然而,测试工程师很难赶上所有对产品进行的代码修改。他/她不仅需要手动测试软件,而且还需要编写复杂的自动化。这一切对团队中的一个人来说是不可能做到的。因此,软件开发人员也必须负责编写测试自动化代码。不仅在单元测试层面,其他层次的自动化测试也可以涉猎。

每个团队都应该坐在一起讨论自动化过程。每个人都必须清楚,产品的质量是每个人的责任。这种心态要求团队中的每个人都支持自动化。如果不是这样,你的自动化过程很可能会失败。

在 ci/cd 上投资时间

与工具选择的时间投资类似。一个软件开发团队必须在 cicd 的配置上投入足够的时间。pipeline 的配置方式必须支持开发团队的需求。例如,在每次提交时运行,在拉代码时运行或在夜间执行整个测试套件。

同样重要的是,定义哪一层的哪些测试应该在什么时候被自动化。在最好的情况下,团队正在制定一个 cicd 策略。一旦 pipeline 策略被实施,重要的是结果对团队中的每个人都是透明的,甚至更好的是对公司中的每个人都是透明的,例如用一个 dashboard。

cicd 工作和投入的时间不应该被低估。根据项目或产品的规模,这可能是一个人甚至整个团队的全职工作。

不应该做的事情

不要因为一个工具被追捧就选择它

我的不做清单的第一点是,当选择一个新的测试自动化工具时,不要因为它在软件开发或测试社区中被炒作而盲目地选择一个工具。如果你真的很幸运,这个工具可能对你有用,但在大多数情况下,你会用它失败。正如我在前面提到的,选择一个工具需要时间。如果没有在选择过程中的这种投资,从长远来看,你可能会损失更多的钱,因为在产品开发过程中的某个时刻,你会发现这个工具不支持某个特殊功能,或者不能按照你需要的方式进行扩展。

在选择工具时,最好检查一下目前什么工具被炒得很热,为什么?也许这种追捧有一个合理的理由,你可能会从中受益。跟上新的工具,并与社区保持联系,获得最新的消息,这总是好的。

不要试图将一切都自动化

我在前面已经提到了这一点。每当你的团队或公司里有人告诉你要把所有事情都自动化的时候,你就装聋作哑好了。这个人很可能是一个从未从事过软件开发的人,或者对测试自动化毫无概念。我见过一些没有经验的人,他们是自动化的新手,试图把所有的东西都自动化,但他们很快就发现,这是不可能的。当你看到有这种观点的人时,和他们谈谈,并解释其消极的一面。

你应该做的是看一下你的产品和代码架构,并确定你的应用程序的关键部分。然后花时间为这些部分创建一个自动化战略。

有了明确的重点和策略,少量的自动化方案可以对产品的整体质量产生更大的影响。

不要太早实现自动化

在产品开发团队中开始使用自动化时,一个典型的错误是开始的太早了。如果团队正在开发一个全新的功能或产品,真的很有可能功能会改变。在这种情况下,开始实施自动化是没有意义的。投入的时间可能会被浪费掉。相反,团队应该从基础开始。例如,建立 CI/CD pipeline,考虑功能所需的数据结构。从中得出一个测试数据策略,也许准备测试数据生成的脚本。

一旦功能越来越成熟,就慢慢开始自动化。我建议与产品所有者保持密切的关系,以了解即将到来的产品功能和变化。使用这些信息来创建你的自动化策略。

永远不要用自动化来取代人工测试

最后但并非最不重要的是,不要用自动化来取代人工测试!人工测试是自动化的重要组成部分。在产品的开发过程中,手工测试是如此强大的一部分,它永远不应该被机器取代。为什么呢?嗯,自动化测试将由机器/计算机执行。机器所做的正是测试自动化代码中的内容,仅此而已。这并不坏,我们都知道这是有用的信息,但软件同学进行手工测试时,会发现更多的问题。首先,测试人员的行为就像一个用户。使用产品的用户会使用它,例如用鼠标、键盘或用手指在使用产品时使用他/她的所有感官。在大多数情况下,手工测试会发现没有人想到会发生的问题。

因此,测试自动化是人工测试的重要补充。

总结

正如你在这篇文章中所看到的,一个人在从事测试自动化时可能会犯很多错误。在雇佣自动化专家、寻找合适的工具和寻找合适的时机开始自动化时,有许多话题需要记住。

逃离云服务?为什么大家在讨论避免使用云服务

之前 ruby on rails 的创始人 dhh 在 twitter 上宣布由于云服务的价格过于昂贵,他们决定自己买服务器自建服务以节约成本。在今年 9 月 15 号的Our cloud exit has already yielded $1m/year in savings这篇博客中,dhh 宣布他们公司37 signals目前云服务的月花费从 18 万美金降到了 8 万美金,也就是 1 年可以节约 100 万美金。10 月 27 号,twitter 也宣布他们的去云化项目为公司降低了 60%的成本。在这之后关于去云化的讨论逐渐热门起来,目前看来一些公司确实在认真思考从云端逃离的可能性。

为什么大家都在逃离云服务

我觉得核心问题还是全球经济衰退,除了裁员节省成本之外,少用或者甚至不用云服务可以带来可观的成本降低。讽刺的是当初云服务的兴起就跟成本节约相关,如今屠龙的少年却成了恶龙,在被人们慢慢抛弃。

在很多年前,互联网应用运维难度大,机器带宽等成本相对较高,资源整合型的云服务可以显著为小型团队节约成本,降低了构建产品的门槛。但这么多年过去了,硬件成本逐步走低,而云服务的定价却变化不大,高溢价就降低了云服务的性价比,从而会影响大家的理性选择。

初创企业往往是云服务利润的贡献者,这几年大量的初创企业倒闭导致云服务商失去了一大块利润来源,这也在一定程度上降低了云服务厂商降价的积极性。

简单来说云服务的存量用户嫌贵,增量用户变少,因此整个市场就显得萧条。

我们是否真的需要云服务

对于大公司来说,云服务确实是必须的,因为规模化带来的巨大成本优势是非常有吸引力的。比如大公司扩张的过程中可以不需要去某些海外市场建机房攒带宽,直接买云服务就可以了,这些服务对于大公司业务来说是一个积极的补充,因此大公司对云的使用其实是混合云为主,自建机房加上云服务辅助,这样就可以尽可能的降低边际成本。

对于初创公司来说,用云服务其实是最快产品化的选择,很多时候如果你拿了投资人的钱的话,你是没得选的,必须上云,然后快速进行产品迭代。如果你产品的最初版本就在云端运行而且运行的很好,那么你是没有动力去买服务器然后托管的。不过随着业务的发展,从成本角度考虑,把服务从纯云端切回混合部署的方式可能会是一个不错的选择,首先可以降低成本,其次可以把核心的数据资产攥在自己手上,从经济上和安全性上考量,混合云的方式都有存在的价值。

所以我认为云服务是必须的,这是一种资源整合带来的规模化优势的体现,很多场景下确实可以降低成本,但完全依赖云服务则不一定可取。

云服务的未来会怎么样

既然大家都在逃离,那么是不是云服务和云计算的前景就变得暗淡了呢?

不一定,我觉得云服务可能跟经济一样有其周期性,如果云服务持续的改进和创新,那么这个周期性可能就会显得很明显。比如经济好的时候,大家都选择创业,大公司选择开拓市场,那么云服务厂商会跟着一同繁荣。但如果经济下行,创业潮过去,大公司选择降本增效,那么云服务自然就会受到冷遇。

云服务的本质决定了这是一种相对来说高效的做法,理论上讲长远看还是有市场的,不过云服务还是需要逐步演进的,比如为解决气候变化问题逐步淘汰低能效的机器,使用清洁能源来替换化石能源等。

逃离可能只是经济发展放缓带来的暂时性问题,一旦云服务迭代跟上了,降低了成本和定价,提升了服务的稳定性,流失的用户是有回归的可能性的。

2023年你还能看到希望么

对很多人来说 2022 年可能是非常糟心的一年,我们有理由去期待 2023 年会触底反弹,经济环境变好,收入提高,内卷的情况得以缓解。不过从目前得到的消息来看,一切可能没有那么乐观。

关于裁员

最近跟字节的朋友聊天,消息可能不是特别准确,不过字节大概已经在开始裁员了,飞书的目标是 10%,其他业务不清楚。根据字节的体量估计的话,有可能会涉及到万人级别。

跟腾讯的朋友聊天,他们表示已经收到消息,明年裁员会继续,不过手段会多样化,基本上会通过不续约和低绩效的方式进行淘汰。

我们公司是二线厂,今年下半年一直在裁员,年底的时候消停了一些,不过估计明年还是会继续的。

国外的话亚马逊开始裁员,估计会回到疫情之前的人员规模。

可以看到 2023 年互联网的企业的主旋律还是裁员,保住饭碗苟下去应该是大多数人的明智之举。

关于换工作

跟猎头聊了一下,字节国内的 hc 应该基本上冻结了,我们公司只裁人不招人,腾讯那边不清楚,少量的 hc 进行血液流通还是会有的。其他厂没有了解过,不过根据之前被裁的同事反馈 2022 下半年还是能找到工作的,机会不多,但不是完全没有。很多人去了字节,算是一个稳定的退路,但 2023 年估计字节也不好进去,除非降低预期往二三线厂看看,不然退路方面的可选择面还是比较少的。

2023 也不是不能换工作,比如换个行业之类的也是比较不错的思路,不过还是不建议裸辞,找到了再换可能更好一点。

另外这几年创业的热潮似乎已经冷却,新的工作机会很难创造出来,去初创企业搏一搏的机会可能都会很少了。

关于年终奖

最近腾讯的朋友们表示已经在吹风了,说今年的年终奖会比之前少很多,其他厂不知道怎么样,不过整个互联网行业的年终收益估计都会有所折扣吧。我们公司也是年终奖大幅减少,并且取消了年度涨薪。

如果是合同规定的年终奖,比如合同规定了 15 薪,那么年底就是 3 薪,这是毋庸置疑的;不过如果合同规定的是浮动年终奖,那么可以讨论的空间可能就不大了。

关于希望

经济滞胀,收入锐减,消费降级,预期降低可能会是 2023 年的主旋律,按道理说在这种大环境下,大家退一步躺平,心平气和,看破红尘反而最有可能海阔天空。但现实的情况是,大家都不想失业,于是越来越卷,越来越焦虑。

希望还是有的,不过是从长期来看。对于 2023,也许不能期待太多,只能把目光放长远,看看 3 年 5 年之后,活在当下但心在远方,坚持下去吧。