从测试到开发的五个月

每当工作闲暇,我都会时常想起好久没有更新微信公众号的文章了,总想等工作不忙的时候赶紧跟大家分享我从测试转开发这段时间的经历和感受,但工作总是有忙不完的忙,一刻都停不下来。

终于等到这一周有两天工作不是那么忙碌了,才决定将前几天写到一半的文章更新完。这是我这几个月下来感受最轻松的两天,暂时没有bug需要去调查和测试,不用去看十几年的C代码,终于有大块时间去写我负责的Python Client端代码了。这种写着代码,听着歌曲去重构,Debug,修改Unit Test Suite感觉真是幸福。

幸福的时光总是短暂的,今天就又来了两个Bug需要去调查 ε=(´ο`*)))唉…

又把我打回原形,调查大半天之后发现原来是QA测的不对,可以松口气晚上可以不用工作更新下微信公众号了。

这五个月来,几乎每天都是白天八小时,晚上继续背着电脑回家准备继续工作,周日偶尔去公司,经常在家学习。因为角色的转变,新的项目,需要学习的地方很多。从业务到技术,再加上产品发布在即,作为一名开发新人也肩负起Bug Fix的任务,十年前的代码,全英文的文档,复杂的系统,如果不全力一搏,真担心自己转型失败,那就太打脸了。

一天的工作忙碌和压力,使得我晚上总是吃的停不下来,吃饭是我一天当中最轻松的时刻。去年我跟别人打赌减肥赢奖金,我毫无怨念的拿到了第一的奖金,可是今年再和别人打赌减肥,至今我都还没开始,马上年底了,输掉奖金是毫无悬念的。总结下来,大概是因为今年工作太忙,工作压力大的缘故,使得我无法在八小时之余安心去继续练习吉他,做keep,年假还没来得及休,真是计划不如变化快。

虽然我还是个小开发,当角色变了,角度也会有变化。

自动化测试是本分,DevOps是阶梯

这几年下来相信你也会真切感受到,如果一名测试人员不懂自动化测试,不会写自动化测试脚本,不但难有升职或是跳槽的机会,很有可能会被企业所淘汰。

个人觉得DevOps是未来一段时间很多企业要走的路,一般的二线城市能把DevOps讲明白并且实施的人太少了,所以尽早掌握实施DevOps的人,就有机会成为DevOps教练或是测试架构师这样的角色。

没有做好抗压的准备,不要去做开发

这几个月来遇到压力非常多,从刚开始的学习C语言,到C语言考核;从学习全英文的业务文档,到业务文档的分享(也是一种考核);从调研C代码的代码覆盖率、Git分享,到调查并解决Bug;从每天的站立会汇报到每周与国外同事的例会。终于等到九月份,Title从Quality Assurance Engineer变成了Software Engineer,这其中的压力、痛苦和短暂的喜悦只有走过的人才知道。

与年龄想匹配的能力

这点非常重要,如果现在问你,你与刚毕业两三年的同行年轻人有哪些优势?如果你不能肯定和清楚的说出自己优势的话,那就要好好反思一下了。

如果从开发角度来说,我现在就是与年龄不相匹配的能力,因此测试相关的技能以及DevOps相关知识依旧是我要好好掌握的功课。

学好英语

对于国内公司来说,工作上不会用到英语,但我想说如果想在测试和开发领域有更长远发展,英文非常重要。一般最流行开源的自动化测试框架、技术、DevOps相关的工具以及搜索最有效的解决问题的方案一般都是英文。如果你的英语不好,坚持一年半载去硬啃一手英文资料,形成习惯,受益终生。

最受欢迎的 Python 自动化测试框架推荐

随着技术的进步和自动化技术的出现,市面上出现了一些自动化测试框架。只需要进行一些适用性和效率参数的调整,这些自动化测试框架就能够开箱即用,大大节省了开发时间。

本文整理了当前最受欢迎的 Python 自动化测试框架。

Robot Framework

这是最流行的开源 Python 自动化测试框架,表格式的测试数据语法和关键词驱动测试使得它在全球的测试人员中非常流行。它还拥有众多可用的工具和库,并且留有 API 扩展空间,使得这个框架非常先进和健壮。

Robot Framework 完全用 Python 开发,对于验收测试非常有用。该框架可以运行在 Java 和.NET 环境,同时支持跨平台,如 Windows、MacOS 和 Linux。它无疑是最易用的自动化测试框架,能允许开发者进行并行测试。

RedwoodHQ

这是一个流行的自动化测试工具,它之所以流行是因为它支持大部分流行的编程语言,如 Java、Python、C# 等。它还支持多个测试人员在一个平台上协作并运行测试用例。

RedwoodHQ 有一个内置的 IDE(集成开发环境),可以在那里创建、修改以及运行测试用例。RedwoodHQ 是对用户最友好或对测试人员最友好的平台之一,它关注一个重大项目的全部测试过程。

Jasmine

这是一套 Javascript 行为驱动开发测试框架(BDD),不依赖于其他任何框架和 DOM,适用于任何使用 JavaScript 的地方。除了 JavaScript 之外,Jasmine 还被用于 Python 和 Ruby 自动化测试。

因此,使用 Jasmine 可以并行运行客户端测试用例和服务端测试用例。它是一个将客户端和服务端单元测试结合起来的完美的测试框架,而且被认为是测试领域的未来。

Pytest

如果项目比较小、复杂度比较低,Pytest 是最适合的自动化测试平台。大部分 Python 开发者用它来进行单元测试。它也具有 Robot Framework 所闻名的验收测试能力。

Pytest 最好的特性之一是,它提供了测试用例的详细失败信息,使开发者可以快速准确地改正问题。它还有各种可用插件来给现有测试技术和测试用例增加更多功能和多样性。

如何做好功能测试

当你第一次开始接触测试这个行业的时候,首先听说的应该都是功能测试。

功能测试是通过一些测试手段来验证开发做出的代码是否符合产品需求。这些年功能测试好像不太受欢迎了,不少同学开始尝试自动化测试,测试开发等等,结果是功能测试、自动化测试、测试开发一样都没做好。

我们通常认为的功能测试是根据需求,采取以下测试流程:需求分析,用例编写,用例评审,提测验证,Bug回归验证,上线与线上回归等测试。如此日复一日,年复一年,可是等准备换工作的时候却得不到认可,你也遇到这种情况吗?

那么如何做好功能测试?功能测试用到哪些知识?有哪些相关的建议呢?

需求分析

业务方在提出需求的时候,产品是要分析这个需求的价值,影响范围和实现代价的。在需求评审的时候,作为一个测试人员必须了解这次需求的内容,影响到哪些现有的功能,涉及到的操作系统或是类别等,然后准确的评估出工作量,防止因评估不足造成后期测试不充分。

再者,关注开发和产品的讨论,关注需求最后如何实现?其中做出的变动和难点就是测试的时候必须重点关注的部分,不能因为这些暂时和你没有关系就不去关注,防止欠债越来越多,不能做好充分的的测试。

第三,需求评审结束后,要求产品更新此次评审过程中的所有改动部分,同时确保之后的任何需求变化都及时更新。

第四,根据产品需求,同时与在会人员进行探讨,设计测试方案及时间安排,此时可以粗粒度考虑,时间上要合理。

用例设计与评审

测试用例是每个测试人员工作过程中必须要完成的工作,它对测试工作起到指导作用,也是相关业务的一个文档沉淀。在以往面试的经验中,有许多人的测试用例写的没有章法,他们是凭着感觉去写测试用例,也没有从用户的角度来思考如何编写测试用例,对于测试用例设计较为常见的方法论也不清楚。

假如面试的时候给你一个场景:一个全新的App要发布,如果让你来测试,你能想到哪些测试方案?如果你只能想到如何去测试app的功能的话,作为功能测试人员就考虑不够全面。此时除了App的功能以外,还应关注App的兼容性,易用性,接口的功能测试和性能测试,数据的存储以及容灾情况等等都应考虑在内。

测试用例可设计为两类: 一类是开发自测和验收提测试标准的冒烟测试用例;一类是针对需求的全面测试用例。

编写完测试用例后主动联系相关人员进行用例评审,在评审过程中及时修改不合适的用例。

测试流程,注重项目控制

项目的流程控制在需求开始的时候就应该重视起来,只是很多时候我们没有意识到这是测试的工作,有的是产品来控制,有的是专门的项目经理来控制。

测试人员需要有关注整体项目的意识。如果你不关注项目进度,什么时候提测什么时候开始测试,那么在测试过程中会遇到测试的内容和最初的需求不一致时候就会额外需要时间来解决,导致项目延期。另外主动关注项目,长此以往,你的这份主动性也会是你有效的竞争力。

需求一旦明确了由你来负责的时候,就要时刻来关注项目的情况。中间变更需求的时候,要评估是否影响项目进度,如果影响了重新进行排期。如果开发提测试晚了,是否影响上线时间,如果影响需要及时跟相关的人员沟通,发风险邮件,通知大家详细的情况。

同时在测试过程中,发现了bug需要详细描述问题,以方便开发去进行重现和修改。同时给bug准确分级,实时跟踪进度,保证项目高质量的按期完成。

上线回归与项目总结

一个需求上线完成后,要及时进行线上回归,同时必须回归我们在需求评审的时候考虑到的可能影响到的原有的功能,以确保新功能完全上线成功。

在一个项目完成后,最好有一份个人总结报告,总结整个项目过程中遇到的问题及最后的解决办法,有哪些需要注意的问题?有什么可以借鉴的方案或是改进策略?项目中有没有通用性的问题等等。

能力的总结和沉淀

在找工作的时候,很多做功能测试多年的同学都遭遇过面试失败,究其原因,我觉得最核心的原因是:不具备相应工作年限应该具备的能力。

我们应该时常问自己一句话:离开现有的平台,我还有什么?如果仅仅是对现在公司业务和工具的熟悉,那是没有任何优势可言的。

对同类业务流程的掌握,项目的整体把控,快速了解业务并能根据需求选择测试方案,引入提高测试效率测试方案和工具,测试过程中遇到问题的预判和解决办法等才是功能测试人员必须具备的能力。

这些方面你做到了吗?不要抱怨功能测试如何如何,认清行业现状和自己的优缺点,做好自己的职业规划。

如果你不善于编码,那么做务专家也是功能测试人员一个很好的选择。

做了9年测试,我为何转开发?

最近几个月以来一直没有更新公众号文章,是因为五月开始,因为项目原因我有机会转为开发,我非常珍惜这一机会,所以一直在努力学习开发相关的技能。

做了9年测试,我为何转开发?

从三年前我在心里就种下了做开发的种子,因为这些年做自动化测试的原因,在写了很多自动化测试用例代码之后,觉得自己还是喜欢写代码,我想在技术上有更深入的学习,无疑作为开发是最直接的办法,所以一直在努力多看、多写代码,一直准备着等待能成为开发测试工程师,或是开发工程师的那一天。

最近茹炳晟的一篇文章我看了也很受启发《我为何从开发转测试,并坚持了16年,我们正好是相反的职业历程,虽然如此,但是都是想往更好的职业发展方向上去努力,他在视频里提到了很多未来测试可以做的工作,不了解的可以去看看,可以开阔大家的思路,个人觉得良好的代码能力是做好工程师相关的工作基础。测试不是只要认真仔细的点点点就可以了,不是测试这工作更适合女生,不是做测试比做开发轻松,不是可以不思进取还能高枕无忧,做好测试同样需要比别人更多的努力才能看起来轻而易举。

因为我学的是毕业之后再没接触的C语言,在这几个月的学习过程中,深刻体会了做开发我还有太多未知的领域知识需要去学习,作为开发语言需要深入的学习,这跟学自动化测试不一样,初学自动化测试脚本语言可以边用边查边学,但C语言不一样,它需要很系统的去学,从数组,指针,结构体,链表,二叉树,数据机构都要一个个突破,了解算法、操作系统、编译原理等等。

虽然是转开发,但是作为测试出身,我会一如既往的关注测试。

希望通过角色的转变能让我有更全方位的角度来看待产品质量,测试相关的思考和技术,分享更多有价值的内容。

C-print

如何打印下面的字符?

$
##
$$$
###
$$$
##
$

示例 1:

int main()
{
char array[] = {'#', '$'};
for (int row = 1; row <= 7; row++) {
for (int hashNum = 1; hashNum <= 4 - abs(4 - row); hashNum++)
{
printf("%c", array[row % 2]);
}
printf("\n");
}
}

C - Score Input Sort Show

#include "stdafx.h"
#include <stdio.h>
#define N 5
//Score Input Sort Show
void input(double[]);
void sortAsc(double[]);
void sortDesc(double[]);
void show(double[]);

int main()
{
double scores[N];
input(scores);

printf("[SORT ASC]\n");
sortAsc(scores);
show(scores);

printf("[SORT DESC]\n");
sortDesc(scores);
show(scores);

return 0;
}

void input(double socres[])
{
int i;
for (i = 0; i < N; i++) {
printf("Please enter %d student's score: ", i+1);
scanf_s("%lf", &socres[i]);
}
}

void sortAsc(double socres[])
{
int i, j;
double temp;
for (i = 0; i < N - 1; i++)
{
{
for (j = 0; j < N - i - 1; j++)
{
if (socres[j] > socres[j + 1])
{
temp = socres[j];
socres[j] = socres[j + 1];
socres[j + 1] = temp;
}
}
}
}
}

void sortDesc(double socres[])
{
int i, j;
double temp;
for (i = 0; i < N - 1; i++)
{
{
for (j = 0; j < N - i - 1; j++)
{
if (socres[j] < socres[j + 1])
{
temp = socres[j];
socres[j] = socres[j + 1];
socres[j + 1] = temp;
}
}
}
}
}

void show(double scores[])
{
int i;
printf("********************************************\n");
printf("Chinese\tMath\tEnglish\tPhysics\tChemistry\t\n");

for (i = 0; i< N; i++)
{
printf("%.2lf\t", scores[i]);
}
printf("\n********************************************\n");
}

C-Language 计算图形的面积

#include "stdafx.h"
#include <stdio.h>

/*
计算图形的面积:
1. 圆的面积 = π * radius * radius
2. 矩形面积 = weight * height
3. 三角形面积 = 1/2 * weight * height
@author Xianpeng Shen
*/

double calcCircle(double);
double calcSquare(double, double);
double calcTriangle(double, double);
int validate(double);

int main()
{
int choice; // 用户选择
double area; // 图形面积
double radius; // 圆半径
double weight, height; // 图形的宽和高
printf("1. 圆\n2. 矩形\n3. 三角形\n");
printf("本系统支持三种图形面积计算,请选择:");
scanf_s("%d", &choice);
while (choice > 3 || choice < 1) {
printf("只能输入1~3整数,请重新输入:");
scanf_s("%d", &choice);
}

switch (choice)
{
case 1:
printf("请输入圆的半径:");
do
{
scanf_s("%lf", &radius);
if (!(validate(radius))) {
printf("不能为负数,请重新输入一个整数:");
}
} while (!validate(radius));
area = calcCircle(radius);
break;
case 2:
printf("请输入矩形的长和宽:");
do
{
scanf_s("%lf%lf", &weight, &height);
if (!validate(weight) || !validate(height)) {
printf("不能为负数,请重新输入两个正数:");
}
} while (!validate(weight) || !validate(height));
area = calcSquare(weight, height);
break;
case 3:
printf("请输入三角形的底和高:");
do
{
scanf_s("%lf%lf", &weight, &height);
if (!validate(weight) || !validate(height)) {
printf("不能为负数,请重新输入两个正数:");
}
} while (!validate(weight) || !validate(height));
area = calcTriangle(weight, height);
break;
default:
printf("只能输入1~3整数,请重新输入:");
break;
}
printf("图形面积为:%.2lf\n", area);
}

double calcCircle(double radius)
{
return 3.14 * radius * radius;
}

double calcSquare(double weight, double height)
{
return weight * height;
}

double calcTriangle(double weight, double height)
{
return weight * height / 2;
}

int validate(double num)
{
return num > 0; // 如果 num>0, 返回一个非零值,表示真。
}

C-Language 自定义函数

求次幂函数power

#include <stdio.h>

double power(double, int); // 形式参数

int main()
{
printf("%.2lf的%d次幂等于:%.2lf\n", 5.2, 2, power(5.2, 2)); //实际参数
return 0;
}

double power(double num1, int num2) // 形式参数
{
double result = 1;
int i;
for (i = 0; i < num2; i++)
{
result *= num1; // 累乘
}
return result;
}

我眼中的高级测试工程师

满足什么样的技术和经验才算高级工程师呢?说说我心中的高级工程师。

具有丰富的行业测试经验

最好有传统和互联网大公司工作经验,没有的话至少与这些公司的高级测试工程师有交流,了解他们是如何开展测试的,有助提高自己的眼界。

有良好的测试基础

掌握必要的测试理论,熟悉测试流程,需求分析,测试用例设计方法,根据项目实际需要制定测试方案。

有丰富的业务能力

做好功能测试的前提是熟悉业务,能更好的站在产品的角度去设计测试用例,才能发现基本功能以外的问题,能给产品提出建设性的需求和意见。

熟悉相关的测试工具

软件测试用到的相关工具非常多,了解和使用过这些工具,能更好的结合公司的要求及项目的需求来权衡引入哪些工具,提高工作效率。

  1. 管理工具:比如JIRA,Testlink,Wiki,Confluence
  2. 持续集成:Jenkins,Bamboo,Travis CI等,了解他们之间的区别以及如何实施。
  3. 自动化测试:web和mobile平台之间是如何做自动化才测试的,用到哪些工具。了解Selenium,WebDriver,Appium,Robotium测试框架,以及用哪些语言去开发自动化测试用例,Python?Java?JavaScript?知道如何选择如何实施。
  4. 性能测试:了解Jmeter,LoadRunner这两个主要的性能测试工具,如何开展性能测试。

有良好的代码能力

良好的代码能力可以快速掌握自动化测试,甚至可以开发测试平台。另外,当你跳槽到任何一家公司可以让你快速熟悉Java、Python、Javascript等任何语言编写的自动化测试用例。

语言能力

包括沟通能力和外语能力。沟通是一个测试人员在工作中必不可少的一项基本技能,良好的沟通会让开发人员了解问题所在,接受你的意见,从产品人员那里更好的了解需求。虽然只有在外企的时候才会用到英语,但是随着测试人员也需要学习很多的技术,开源社区的发展,很多第一手资料都是用英文写的,所以学好英文对于扩展和学习新知识有很大帮助。

所以说成为一名优秀的高级测试工程师所要求的能力还是很多的,一起努力吧!💪

Error: Permission denied (publickey)

如果你想在一台电脑上配置 github 和 bitbucket,如何配置多个 SSH git key?
输入以下命令生成 SSH Key,注意在生成过程中最好输入新的名字,比如 id_rsa_github 和 id_rsa_bitbucket

ssh-keygen -t rsa -C "your_email@youremail.com"

然后将生成的 SSH key 文件内容复制到对应网址的个人用户设置中即可。但是明明按照官方教程做的但是在 git clone 的时候还是遇到以下问题:
Error: Permission denied (publickey)
困恼了几天的错误终于解决了。

参看这个文档

由于我用的是macOS Sierra 10.13.3,文档这里写着如果是macOS Sierra 10.12.2 及以后的版本需要在
~/.ssh 目录下创建一个 config 文件
congfig 文件的具体配置如下:

Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa_github

Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa_bitbucket

配置了这个文件之后,再次尝试

git clone git@github.com:shenxianpeng/blog.git

可以 download 代码了,两个 SSH git 都好用了 : )