可以说,这篇博文,貌似拖的时间有点久,
不过,还好一点,就是没难产!
小鱼准备这篇博文,也算是有一段时间了,
其实也不是说一直在准备,就是中间有的写了Locust系列博文,
不信,那你点点看, 我真的不骗人!
小屌丝: 鱼哥,你就别扯了, 再扯一会,我都没耐心了~~
小鱼: 话不跑偏,不是你鱼哥!
言归正传,我们开始扯正儿八经的东西。
话说回来,为什么要分享这篇博文, 小鱼不是炫耀,也没什么可炫耀的,
尤其跟 各位大佬相比, 小鱼就更没有值得一提的炫耀姿势了。
哦不, 是资本,最近总打错字!!
本质就是希望,能有更多的大佬,实现进大厂梦,从而赢娶“白富美”。
我们先来看一下,资深测试开发的招聘信息:
小屌丝:鱼哥,这个招聘信息,也没什么特别牛X的内容啊,是写的谦虚了一些???
小鱼:嗯,确实,写的有些谦虚,但是,你逐条品一品,
小屌丝:哎~鱼哥,别说,还真是,有点那种味道…
小屌丝:鱼哥,那你就,结合你自身经历,给俺详细分析分析呗!!
小鱼:嗯,我们就来详细分析一下。
产品质量保证,测试技术和工具
---> 了解小鱼面试方(套)式(路)的,肯定会知道,就这一句话,小鱼能问一个半小时不带(要)停的。
不过,也很少会有像小鱼这种BT的人,毕竟,男人何必为难男人(女人)。
又跑偏了,我们接着分析;
①产品质量保证: 这是一道背锅题
首先,从环境来说: 测试环境,预发环境,线上环境
其次,从版本来说:小版本迭代,大版本迭代
第三,从流程来说:需求→设计→开发→测试→部署
第四,从交流来说:产品vs 开发 vs 测试
每个过程,都是那么的心塞。
不信,看图说话
测试环境 VS 生产环境
②测试技术、工具: 这是一道送命题
首先,面试官会根据你简历上的技术来问,
--> 问原理,问逻辑,问实现方式,问项目运用
其次,面试官会问根据简历技术的进行适当扩展,
--> 这里就不举例子,因为扩展的太多,我怕收不回来
第三,面试官会问到是否了解本公司的测试技术
-->如果了解,并熟练运用过,那稳稳的
-->如果都没听说过,或者没运用过, 那也是稳稳的
第四:如果是资深测试开发,那应该有一种能力,
-->搞出来一个类似的工具(可能是全栈来搞的事情),
-->或者,没搞出工具,也得搞得出一套框架并在项目中实战过。
不然,何能定位到 资深这个level。
第五:不过,如果把这些 例如 Fiddler,Postman,JM,selenium等工具,用的像了解妹子的了解这些工具,那也可以的。
总的来说,测试技术、测试工具,质量保证,就是背锅侠送人头的。
别灰心,我们继续往下分析
大中型项目测试体系建立,测试流程、测试实施、质量和风险控制
首先,中大型项目,针对不同的面试官,定义也不一样,
-->如果针对阿里,京东,拼多多,字节这种公司的面试官,那认为只要产品没有流量,没并发未达到xxxxW的,都算小项目…(心塞)
其次,测试流程看的就是你的老东家是否有完整的体系,规范,你做的项目是什么方式,迭代,瀑布,devop 等等。
-->这就是为什么要写项目经验了,而且还要写的很牛X的那种。
第三,测试实施,可能很多大佬并没有经历过。
-->这倒不难,因为很多接项目的公司,只要完成测试环境的测试,剩下的就是运维的工作,并没有正在意义上的测试实施。(传统行业更常见一些)
第四,质量和风险控制,
-->讲真,如果没有做产品经验或者没有上线经验,这真的是很难能打动面试官,
-->虽然小鱼常说,上线是一个团队的事情,但是,如果连上线经验都没有,即使过了面试,给offer,那定级肯定也不会高。
-->大部分企业,都希望每个员工都会造飞机,虽然最后进公司可能就是拧螺丝。为了就是一个人倒下,会有千千万万人立马顶上。
落地APP自动化测试、兼容性测试、持续推进测试效率
如果,前两点,你觉得不能体现你技术的地方,
那么,从这点开始,你的技术,将会完全暴露在面试官面前。
举个例子:
①请问做过APP自动化吗;
②用什么语言,什么工具;
③写的什么框架,能解读一下框架吗;
④你写的框架的优势是什么;
⑤是否考虑到了性能,并发,如何考虑的;
⑥列举你做过的一个项目,详细说一下 怎么写的?
⑦这个岗位,主要是以APP自动化为主。
一不小心,泄露了小鱼的面试的方(tao)式(lu)…
熟知互联网敏捷流程和分级测试,灰度发布,A/B 测试,把控测试进度
这里,很多大厂,都希望做过互联网产品的,为啥呢?因为:
①可以 996,
②有先进的技术;
③有流量;
④有上线流程;
⑤有敏捷,devops等流程经验;
⑦怎么跟 产品大佬,开发大佬 友好相(互)处(怼);
⑧出现问题,怎么处(甩)理(锅)。
推动研发团队质量意识,保证质量的同时提升研发效率
这就厉害了,如何保证开发团队的质量,
产品靠嘴,测试靠腿!
为啥呢?
产品提需求,靠的就是动动嘴。
测试提BUG,靠的就是跑得快,要不,提一个一级缺陷你试试!!!
所以,招聘信息的每条内容,都不是随便写写的,
当然,这刨除啥也不是的。
了解招聘信息,弄懂岗位需求,那么接下来,
就要为自己量身定做了。
也是到了该会会面试官的时候了。
在分析这个"如何给自己定位"之前,小鱼先分享一个故事。
前言:
大约在2019年的夏天,小鱼计划招聘一名2年左右测试开发人员(主要业务方向为主),
高潮:
某天早上,hr推给的一个简历,也是临时追加的一名候选人,具体啥情况,小鱼就不说了, 在礼貌性的询问了一些技术问题后,小鱼问了一个常规问题,
小鱼:为什么要应聘测试开发的岗位,,
求职大佬:因为我找不到理想的后端java开发岗位,而他朋友对他说测试开发岗位的要求低,应聘成功率非常高!
小鱼:那你对这种非本意的转岗,有没有一个明确的规划,或者,以后就是要从事测试开发岗位,还是骑驴找马,那有没有 了解测试开发岗位的职责,以及工作内容?
求职大佬:额… 并没有特别了解,也不熟悉测试开发的流程…
小鱼:那你有没有一个自己的规划,或者说,我如果转岗测试开发,前三年希望达到什么level,3-5年希望自己又能达到那个level
求职大佬:这个… 还没有~ ~ ~
结尾:
其实,很多求职者,跟小鱼面试的那位求职者,差不多,没有一个明确的一个规划,或者说,我就是想做测试开发,或者后端java开发,但是,具体做到什么level,自己是要往 管理方向发展,还是技术方向专研,并没有明确规划。
也有些人觉得,这个是很难规划的,毕竟世事难料~ ~ ,毕竟今天晚上定好的规划,明天早上就(累的) 想不起来了。
这个真的是想多了,你能左右的只有你自己,自己的事都没料明白,还料啥其他的事。
关于如何给自己定位,小鱼分享一下,
这个可能并不适用于每个人,但是,只要有一个明确的目标,有规划,有行动,就好。
这里,举个例子:
①目标: 资深测试开发专家;
②现在能力:移动APP自动化框架设计,WebUI自动化框架设计,API自动化框架设计及实战,性能自动化;
接口自动化框架设计,性能自动化框架设计,数据库优化,前端Vue,js,语言:python(主),Java等;
③需要进阶:大数据方向,算法,安全;
④扩展能力:数据分析;
⑤备战岗位:测试开发总监;
⑥职业考虑:需要符合自我价值观的平台,互相创造利益。
给自己定位好以后,就需要朝着方向努力,
这不仅仅需要平台的支撑,
同时也需要自己的付出。
关于这部分的内容,小鱼先上一个脑图,这个脑图,是小鱼自己的一个技能掌握,也是学习的一个思路。
老规矩, 上脑图
小屌丝:嗯,鱼哥,这看着还可以啊,也不算多嘛。
小鱼:嗯,确实不多,就是8本书+三个教程归纳总结的内容而已,确实不是很多。
小屌丝:挖草…
注:
这里,小鱼并没有单列出 测试开发基础理论知识,
因为,小鱼觉得,这些知识,在大学可以学习一些,或者自己买本理论教程看一遍,就能牢牢记住的内容。
万丈高楼平地起,地基那是很重要!
这里,小鱼再次强调一次,学习语言,基础 很重要,很重要,
因为有好多同学问小鱼,
“鱼哥,我想学习Web UI自动化,是不是知道 selenium怎么用就行,不需要理解selenium的原理”
讲真的, 学习一个技术,如果原理都不去搞,真的没啥意义,
而且,原理很是重要。
不然,为啥每个大佬在讲课的时候,都会花上一段时间来唠叨 技术的原理。
关于如何学习基础知识,三个方向:
①买本书,一般0基础入门,都是讲的很基础的内容
②培训机构:很多,这里就不说了,可以私信,小鱼会适当推荐…
③网上教程: 菜鸟教程,w3cschool, 小鱼的博客
这里小鱼推荐的还是 看奕然的博客(或者奕然的主页),因为你看这些生硬的教程,不一定有耐心, 不过我得博客就不一样了,美图… 趣文…注释…易懂…。。
最关键的是,“奕然还有颜值”。 这个可以信!!
这里,咱们也来一个看例说话:
某大佬想学习 Web UI自动化,那么他需要学习的知识:
①html
②JavaScript
③语言:Java / python / Ruby等
④工具:selenium / Pytest / Robot Framework等
⑤数据库:MySQL
⑥关联的第三方库
没看错,没看错,趋确实需要这么多内容;
但是这些内容,跟我们准备高考的知识相比,
也不多嘛~ ~
关机技术进阶,
小鱼也是提供三个方向:
①买进阶书籍,例如,python的进阶,大数据拔高 等
②培训机构:嗯,同样,可以私信问小鱼,小鱼说一句:不便宜…
③网站搜索: github,小鱼的博客
④跟着大佬学习:当然,如果有大佬愿意带你的话。
关于技术进阶,不是一天两天能学习成的,
换句话说,大部分同学用时间+汗水 换来 技术提升。
而少部分用的啥呢,1%的天赋。
这里 举个AI界"神"一样的大佬: 杨清,
咱们编程的第一句话是 “hello word”,
人家的编程的第一句话是 “Caffe”。
这差距… 哎~~
不管怎样,技术的进阶,还是需要的,
这里小鱼给大家整理的姿势,一定要慢慢学习,据说有108篇~ ~
点击下面的,即可提升自己的…,也可以让她开心…:
性能知识:点击 性能学习与进阶
WebUI自动化:点击Web UI自动化学习与进阶
移动APP自动化:点击 移动APP自动化学习与进阶
全链路压测:点击 全链路压测从理论到真实系统改造
性能测试: 点击 性能测试基础到实战(Jmeter/Locust)
Pyhton开发:点击 Python学习与进阶
MySQL:点击 MySQL学习与进阶
接口自动化:点击 接口自动化学习与进阶
并发(接口&性能):点击 并发学习与进阶
当然,
如果觉得这些知识太零散了,也可以像小鱼那样,整理出脑图;
如果自己又不想整理,觉得没头绪或者没时间,可以问小鱼要啊。
这些又不是免费的, 有钱啥都能干~ ~
看图聊天
这个代码能力,就是一点点敲出来的,
没有什么特别的快捷方式,
但是,小鱼也要强调一下,代码规范,代码整洁度,代码注释 这与敲码年龄没有绝对关系,
例如:
小鱼就见识过一位敲了8年代码的"大佬",,在review这位大佬代码的时候,真心看不下去了…
然后,这位"大佬",后来的结局,应该想得到…
强调一下,
如果能去大公司,尽量去大公司,不管从代码规范,撸码方式等都会有提升。
并没有说小公司不好,切勿多想。
提升代码能力,小鱼的方式有以下几点:
1、看github,例如 requests,写的确实很规范;
2、多思考,多撸码,多看大平台代码;
3、进项目,提升代码能力最快捷方式 就是 项目中实践;
4、找个靠得住的大佬,认个亲啥的 :
-->如果妹子颜值在线,这点不难;如果汉子颜值在线,这难上加难!
同样,小鱼在这,Share一下"requests"库 api.py文档的代码,
一起感受大神的代码:
api.py
# -*- coding: utf-8 -*- """ requests.api ~~~~~~~~~~~~ This module implements the Requests API. :copyright: (c) 2012 by Kenneth Reitz. :license: Apache2, see LICENSE for more details. """ from . import sessions def request(method, url, **kwargs): """Constructs and sends a :class:`Request <Request>`. :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary, list of tuples or bytes to send in the query string for the :class:`Request`. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers to add for the file. :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. :param timeout: (optional) How many seconds to wait for the server to send data before giving up, as a float, or a :ref:`(connect timeout, read timeout) <timeouts>` tuple. :type timeout: float or tuple :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. :param verify: (optional) Either a boolean, in which case it controls whether we verify the server's TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to ``True``. :param stream: (optional) if ``False``, the response content will be immediately downloaded. :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. :return: :class:`Response <Response>` object :rtype: requests.Response Usage:: >>> import requests >>> req = requests.request('GET', 'https://httpbin.org/get') >>> req <Response [200]> """ # By using the 'with' statement we are sure the session is closed, thus we # avoid leaving sockets open which can trigger a ResourceWarning in some # cases, and look like a memory leak in others. with sessions.Session() as session: return session.request(method=method, url=url, **kwargs) def get(url, params=None, **kwargs): r"""Sends a GET request. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary, list of tuples or bytes to send in the query string for the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ kwargs.setdefault('allow_redirects', True) return request('get', url, params=params, **kwargs) def options(url, **kwargs): r"""Sends an OPTIONS request. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ kwargs.setdefault('allow_redirects', True) return request('options', url, **kwargs) def head(url, **kwargs): r"""Sends a HEAD request. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. If `allow_redirects` is not provided, it will be set to `False` (as opposed to the default :meth:`request` behavior). :return: :class:`Response <Response>` object :rtype: requests.Response """ kwargs.setdefault('allow_redirects', False) return request('head', url, **kwargs) def post(url, data=None, json=None, **kwargs): r"""Sends a POST request. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json data to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ return request('post', url, data=data, json=json, **kwargs) def put(url, data=None, **kwargs): r"""Sends a PUT request. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json data to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ return request('put', url, data=data, **kwargs) def patch(url, data=None, **kwargs): r"""Sends a PATCH request. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json data to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ return request('patch', url, data=data, **kwargs) def delete(url, **kwargs): r"""Sends a DELETE request. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :return: :class:`Response <Response>` object :rtype: requests.Response """ return request('delete', url, **kwargs)
整体看,
代码整洁度,很nice;
代码能力,很nice;
代码注释,很nice。
小鱼曾看过一篇文章,在这个世界上,99.8%的人的成功,都是平台提供,即 平台成就人;
只有0.2%,是 人成就平台。
所以,针对我们,要想让面试官能高看你一眼,需要的就是大平台。
小鱼归纳4句话:
进超级大厂,做流量产品,搞前沿技术,跟产品经理谈爱情!
详细强制解释一下:
进大厂:国内的 我们熟知的 BBAT,华为,拼多多,京东,美团,滴滴,等
做流量产品:淘宝,拼多多,美团,lol,京东等
搞前沿技术:这是不是很多呢,小鱼不搞技术,就信了吧!
跟产品经理谈爱情:这在大厂,很常见的事情,怼天怼地怼产品,产品不行项目上!
所以,
项目经验丰不丰富,看你怼的产品经理多不多。
稍后篇章会介绍,如何把项目经验搞得丰富,让产品经理看了你的简历,也想跟你过几招~
我是Carl_奕然
51testding认证讲师
CSDN博客专家
关注我,带你学习更多知识。