软件测试培训
10.19
xampp安装配置
xampp简易建站程序
-
extend
-
apache
提供网络服务器
-
MariaDB
-
PHP
-
Perl
xampp里面的`htdocs`目录相当于浏览器中的`localhost`路径
zentao
10.21
软件的研发过程
立项 - 需求分析 - 系统架构设计(Top Level Design) - 系统详细设计(Detailed Design)- 系统实现 - 测试 - 产品运维
测试在产品中的阶段
单元测试 - 集成测试 - 系统测试 - 验收测试
在软件研发过程中,越早进入越好。
测试过程
测试规划 - 测试策划(方针、策略) - 测试计划 - 测试用例 - 测试规格说明书
测试活动开展
测试过程监控:进度、质量
测试方针
系统类型、开发模式、项目范围、建立测试计划
软件开发模式
瀑布模型
-
按照软件开发流程推进,每个阶段完成后需要提供大量文档作为下一阶段的输入。
-
特别不喜欢需求变更
-
需求RMD
敏捷模型
- 把一个项目拆分成多个端对端的小项目(end-end,可以单独开发测试交付的小项目)小冲刺、快速迭代。
- 小项目中由==story==组成,一个team花费若干时间对一个小项目进行冲刺(sprint)不强调文档,成员face-to-face
- 缺点:小team需要不同的工种加进来,形成利益共同体,会对公司的组织架构产生挑战。
测试策略:怎么做
- 单元测试:
白盒测试,代码走查、审查review(技术经理 把关),评审(大佬们 针对重要代码),逻辑覆盖
- 静态测试:不run
-
动态测试:run
-
集成测试:
-
整体组装测试:第一次整体组装运行,叫做==smoke test==
-
渐增式集成测试:模块逐渐组装
-
系统测试:
可用性、易用性、可靠性、安全性、可维护性、可移植性。
- 压测、负载测试
- 可靠性:如果有错误发生,恢复的时间衡量,SLA
-
可维护性:扩展、维护的方便;模块之间的消息是可以跟踪、解释的,便于troubleshooting
-
验收测试
-
alpha测试:用户参与,但测试是在开发一方的测试环境
-
beta测试:用户和最终用户参与,测试是在用户一方的测试或生产环境
各种环境
-
开发者
-
开发环境 || 测试环境
两者之间数据不能渗透的;除非是版本发布之后,通过一些自动化部署工具,比如==Jenkins==,把新版本自动部署到测试环境,并且自动配置生成一些测试脚本,生成测试报告......
-
用户
-
测试环境 || 生产环境
10.26
考试前检查环境
- 宿主机中的禅道环境和xampp工具
- 浏览器的插件;
- 虚拟机中的eclipse、pycharm以及python版本;
- 宿主机ping通虚拟机(有时是ping不通的)
注意:我们学习时的禅道和xampp是安装到虚拟机中的。
(用户名密码:admin/Admin123,访问网址:http://localhost/zentao/www/my)
回归测试
是什么
在某个版本基础上,进行了测试,发现了缺陷;在这些缺陷被开发解决后,我们需要验证的包括:
- 缺陷报告的问题是否已经解决?
- 该解决方案是否引入了新的问题?
所以在提交解决方案之后,需要进行==回归测试==,目的是判断是否解决原有问题和引入新的问题。
缺陷的处理流程
- (瀑布模型)
发现缺陷 - 提交bug(zentao中的激活) - bug审核确认 - 分配给开发 - 开发确认 复现 - 提交解决方案(zentao中的解决) - 回归测试(zentao中的确认 or 未确认)
- (敏捷模型)
发现缺陷 - 提交bug - 开发解决 - 回归测试
操作题3.25
这是个20分的题,需要很熟练,20分钟内完成。
执行发送邮件的回归测试
-
配置禅道 - 导入项目
-
zentao - 组织 - 用户 - 批量添加用户
-
建立新的项目,将文档中的说明粘贴到项目描述中。建立好之后在项目 - 概况 中可以看到。

-
建立冲刺和版本信息
-
由于是回归测试,bug是属于旧版本V1的。
在测试 - bug中,需要填写 冲刺 和 版本 的信息。
所以要先去建立冲刺和版本。
建立冲刺:

冲刺里面:添加团队成员:

建立版本
冲刺 - 测试 - 版本:新建V1和V2

[!note] 注意:版本是在冲刺里面
-
建立bug
注意:优先级别忘选

-
将bug建立测试用例
-
打开bug - 建用例


-
执行回归测试,验证bug是否被解决
-
bug1,测试下来与预期结果不符:
不需要转bug,直接点关闭就行。(因为只是对bug进行的校验)

回到bug1里面:把 结果 改成现在发现的结果,把影响版本加上v2

-
bug2:测试下来,同样是失败的。也回到bug界面改一下结果和影响版本
-
bug3:测试下来没过,回去改一下bug
-
注意:如果bug被解决了,回到bug里面,把版本加上V2,然后把bug改成已确认、已解决。
- bug的状态:激活/已解决
已解决这个状态是开发改完代码,认为改好了,才设的。
激活是测试完发现没改好,重新指定为bug。
- bug的确认:已确认/未确认
如果测试完已解决bug,需要把状态改为已解决、已确认。
如果测试完发现bug没解决,需要把状态改为激活、未确认
-
导出bug和测试用例

- 导出项目概况
Win10 截图快捷键:Win Shift S

本题注意事项
- 先把excel表中的bug导入到项目中 - 记得创建sprint、导入用户、版本V1、V2
- 原则上,导入的bug的状态,都应该是fixed。
- 根据bug生成testcase,注意testcase的标题和bug是反着的。
给bug或者testcase写标题用简洁的方式来写。
如:打开xxx页面后输入xxx和yyy,操作结果。 - 以新版本的软件为基础,运行testcase,验证。
- 如果bug仍然存在,bug状态保持激活,要把实测结果改成最新测出来的结果,bug版本上加上V2版本。
- 如果bug不存在了,bug要变成解决+确认,并且影响的版本要加上V2
- 题目要求的文件,记得导出保存上传
10.28
有关数据库操作
mysql数据库登陆、创建数据库、创建表、在表中增加数据、查询表的数据。
考试mysql环境准备
-
xampp的mysql路径下:
C:\xampp\mysql -
在
C:\xampp\mysql\bin目录下启动cmd
(直接在地址栏输入cmd即可)
登录MySQL:
mysql -u root -p
# passwd是空的

- 创建数据库
CREATE DATABASE db_school DEFAULT CHARACTER SET GB2312;
-- 指定编码,中文GB2312
- 使用数据库
USE db_school;
- 在数据库中,创建表
CREATE TABLE 表名(字段名1 数据类型 默认值 约束,...字段名2 数据类型 默认值 约束);
-
数据类型
int(9)-- 表示整数的范围number(9)--整数,总共9个数字组成number(9,2)-- 小数,总共9位,小数点后2位char(9)--总共9个字符varchar(25)-- 最多25个字符,但是有几个就算几个;前面的是固定位数,不足就补齐。ENUM('F','M'): 指定使用指定数据: 枚举。 -
约束
-
非空约束:NOT NULL;(如果数据为空就会报错)
-
唯一约束:UNIQUE;
-
PRIMARY KEY:主键 -- 能代表这个记录,主键唯一且非空。
这些约束可以在字段中定义(行级约束);也可以在所有的字段最后定义(表级约束)
-
-- 创建学生表,字段:学号,姓名,性别,班级
CREATE TABLE t_student(
stu_no CHAR(9) PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender ENUM('F', 'M') DEFAULT 'F',
class_no VARCHAR(15) -- 注意最后一行这里不能有逗号
) DEFAULT CHARSET=GB2312; -- 注意之类要有分号结束
- 查看表的结构
DESC t_student;
- 在表中增加数据
INSERT INTO 表名(字段1, 字段2, 字段3...)values(值1, 值2,值3...)
INSERT INTO t_student
(stu_no, name, gender, class_no)
VALUES
('202210281', 'Zhangsan', 'M', 'abc001');
COMMIT; -- 对修改进行确认
- 查询数据
SELECT stu_no, name, gender
FROM t_student
where gender='M';
SQL语句执行次序
| 语句 | 执行次序 |
|---|---|
| select | 3 -- 做完行筛选,再做列筛选 |
| from | 1 -- 选择数据集合 |
| where | 2 -- 对选定的数据集合进行 行筛选(记录筛选) |
| order by | 4 -- 最后进行排序 |
- SQL脚本以及脚本执行
source xxx.sql
-- 或者 --
@xxx.sql
11.02
1.2.1操作题 -- 写SQL脚本
- 新建一个notepad文件
注意文件格式和编码格式ANSI。

- notepad里面编写脚本:
[!warning] 注意:加了判断语句,如果数据库存在就删掉。
考试环境:在宿主机的xampp下,C:\xampp\mysql\bin目录下启动cmd
-- 考试环境:在宿主机的xampp下,C:\xampp\mysql\bin目录下启动cmd
-- 如果该数据库已存在就删除
DROP DATABASE IF EXISTS db_eshop;
-- 创建数据库
CREATE DATABASE db_eshop DEFAULT CHARACTER SET GB2312;
USE db_eshop;
-- 创建表
CREATE TABLE products(
pid CHAR(10) NOT NULL,
Pname VARCHAR(50) NOT NULL,
Pclass VARCHAR(50) NOT NULL,
PRIMARY KEY(pid)
)DEFAULT CHARSET=GB2312;
-- 增加数据
INSERT INTO products(pid, pname, pclass) VALUES('A001','手套','劳保用品');
- 技巧:
如何将excel中50列数据全部变成INSERT INTO的插入语句?
-
在商品表中添加列,把INSERT INTO语句插进去:

[!warning] 注意 单引号在excel中要写成两个单引号 ''

-
把50行语句粘贴至notepad,把空格全部替换掉。然后粘贴到脚本中。
-
保存sql脚本,在cmd中运行
source C:\\Users\\test\\Desktop\\2022001\\1.2.1\\1.2.1.sql
- 运行好之后,查询并保存结果
-- 查看数据并保存
SELECT pid,pname,pclass FROM products INTO OUTFILE "C:\\Users\\test\\Desktop\\2022001\\1.2.1\\1.2.1.txt";
[!note] 注意:路径要用双引号
11.04
JUnit 白盒单元测试
- 配置Eclipse新建项目

-
在项目的src下面新建package,命名一般是域名反过来(com.test)
-
在package下面新建class,编写一个Bmi计算的类
package com.ms.test;
public class BmiFunc {
/*
* Bmi = 体重/(身高平方)
* Bmi < 18.5 : too thin
* Bmi < 24: normal
* Bmi < 28: a little overweight
* Bmi < 32: overweight
* or : heavily over weight
*/
private float height;
private float weight;
//构造函数
public BmiFunc() {
}
public BmiFunc(float height, float weight) {
this.weight = weight;
this.height = height;
}
//获取数据的接口
public float getHeight() {
return this.height;
}
public float getWeight() {
return this.weight;
}
//设定数据的方法
public void setHeight(float h) {
this.height = h;
}
public void setWeight(float w) {
this.weight = w;
}
//计算bmi指数
public float bmiRate() {
return this.weight / (this.height * this.height);
}
// 判断bmi
public String bmiJudge() {
float rslt = bmiRate(); //先计算
if (rslt <= 18.5) {
return "1";
} else if (rslt <= 24.0) {
return "2";
} else if (rslt <= 28.0) {
return "3";
}else if (rslt <= 32.0){
return "4";
}else {
return "5";
}
}
}
- 在项目的src下面新建Junit Test Case


- excel表写测试用例
- Junit里面写单元测试代码
package com.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.ms.test.BmiFunc;
class testBmi {
@Test
void testcase1() {
BmiFunc bj = new BmiFunc(2.0f, 70.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。第一个参数是实际结果;第二个参数是预期结果
assertEquals("1", rslt);
}
@Test
void testcase2() {
BmiFunc bj = new BmiFunc(2.0f, 74.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("1", rslt);
}
@Test
void testcase3() {
BmiFunc bj = new BmiFunc(2.0f, 90.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("2", rslt);
}
@Test
void testcase4() {
BmiFunc bj = new BmiFunc(2.0f, 96.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("2", rslt);
}
@Test
void testcase5() {
BmiFunc bj = new BmiFunc(2.0f, 109.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("3", rslt);
}
@Test
void testcase6() {
BmiFunc bj = new BmiFunc(2.0f, 112.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("3", rslt);
}
@Test
void testcase7() {
BmiFunc bj = new BmiFunc(2.0f, 123.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("4", rslt);
}
@Test
void testcase8() {
BmiFunc bj = new BmiFunc(2.0f, 128.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("4", rslt);
}
@Test
void testcase9() {
BmiFunc bj = new BmiFunc(2.0f, 130.0f); //这个函数也是一个对象,new一个对象出来
String rslt = bj.bmiJudge();
//断言,就是进行测试判断。实际结果是rslt,预期结果是"1"
assertEquals("5", rslt);
}
}
-
在testcase1方法上右键运行,获取单个断言成功or失败的结果;
-
在class TestBmiFunc上右键运行,获取里面所有的testcase的结果。
Junit黑盒测试
- 把代码打成jar包
file - export - jar file
-
新建项目
-
在src下面新建文件夹lib,把jar包复制粘贴进来

- Jar包右键 - Add to Build Path

- src下面新建JUnit Test Case,写好单元测试代码,同上。
1.1.1操作题
-
阅读题目要求、函数说明
-
eclipse里面新建项目、项目中新建lib文件夹,导入jar包(直接拖进来,或者文件复制粘贴) - build path - add to build path
-
src下面新建Junit Test Case
别忘了import给的类:
//package.class
import callphone.CheckPhone;

- excel中编辑测试用例,并按照测试用例写单元测试代码
package com.test;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import callphone.CheckPhone;
class callPhoneTest {
@Test
void testcase1() {
CheckPhone cp = new CheckPhone();
boolean rslt = cp.checkNum("123456789");
assertEquals(false, rslt);
}
@Test
void testcase2() {
CheckPhone cp = new CheckPhone();
boolean rslt = cp.checkNum("123456789123");
assertEquals(false, rslt);
}
@Test
void testcase3() {
CheckPhone cp = new CheckPhone();
boolean rslt = cp.checkNum("1234567891a");
assertEquals(false, rslt);
}
@Test
void testcase4() {
CheckPhone cp = new CheckPhone();
boolean rslt = cp.checkNum("21345678912");
assertEquals(false, rslt);
}
@Test
void testcase5() {
CheckPhone cp = new CheckPhone();
boolean rslt = cp.checkNum("12345678912");
assertEquals(true, rslt);
}
}
-
运行单元测试获取结果(class名右键运行)
-
将结果写入测试用例表
| 序号 | 输入数据 | 测试说明 | 实际输出 | 期望输出 | 测试结果 |
|---|---|---|---|---|---|

- 保存单元测试的Java文件、截图、测试用例表到考试文件夹
重点
- 写测试用例表: 序号-输入数据-测试描述-实际输出-期望输出-测试结果
采用等价类方法,要记得算上边界条件和特殊条件(输入为空等)。 - new一个类的实例出来,函数调用:
实例名.函数名() - 断言的方法:
assertEquals(期望值,实际值变量)
11.09 场景测试
了解概念
- 按照测试流程来分:单元 - 集成 - 系统 - 验收。
- 按照测试方法:白盒、黑盒、回归测试、场景测试、分组测试。
场景测试
定义
- 基于用例的场景测试:用户 操作测试对象的实际过程
- 根据测试流程来做的各种测试,都是需求分析之后的,这些可能和实际应用之间存在差异。需求比能不能描述出用户的真正目的。
- 基于软件实际使用场景,通过测试用例,描述完整的==基本流==;基本流确定后,包含多个==备选流==(即基本流出现偏差)。
How?
- 利益驱动:人们想要获得某个功能,他们怎么才能得到这个功能?
- 事务驱动:执行步骤是什么?需求的数据是什么?输入和输出是什么?
- 参考竞品:优点
理想的测试场景
- 肥皂剧测试:源于真实生活、夸张、浓缩、有趣。
操作题2.1.2
部署环境
- 学习环境:安装了xampp+zentao,删除了原来的mysql和tomcat,导致没有电子商城系统。
- 解决:安装mysql和Tomcat,把提供的电子商城项目部署在自己安装的tomcat中;或者再重开一个虚拟机,还原到原来的环境。
- 初始win10系统中,浏览器打开:localhost/EShop/,观察连通性
- 安装了zentao的虚拟机中,浏览器打开:<初始虚拟机IP地址>/EShop/,观察连通性。这样在zentao的学习环境中就可以访问电子商城系统了。
题目执行
-
新建项目
-
新建功能测试用例,把基本流和备选流分别创建测试用例。
-
依次对项目进行测试。
-
如果发现bug,即某一步失败了,在测试用例的执行界面中,测试结果选择失败,并且转bug:

- Bug标题改一下,加上细节描述;优先级也要改成2

- 如果某一步卡住了,后面的步骤要都选为阻塞状态:

转bug的的界面的对勾点到失败的这一步就行
11.11
分组测试
概念
- 测试过程中,如果需要进行多组输入,穷尽是测试代价比较大。
- 采用组合测试的方法减少测试用例。
- 步骤:测试对象 - 输入空间建模 - 产生组合设计 - 生成测试用例 - 执行测试用例
例题2.2.1
pict
-
创建分组用例的算法工具。计算每个输入数据的组合种类。
-
使用方法:notepad建立供选文件,标点符号要用英文的,格式要用ANSI:

/o: N,N是分组的类型,基本上是每个字段算一组。

如果全覆盖的用例不算多的话,就挨个建立测试用例,去测试,失败的转bug。html页面每次换了新的参数,要刷新。
Python基础知识
- 变量只是内存中地址的一个别名。不分类型。
- 变量名字最好遵守:望文生义;小写字母,下划线分隔,不要驼峰!!
- 浮点数运算,牵扯到二进制和十进制转换,会产生略微的误差。
编码
英文字符:用==ASCII==编码;汉字用==gbk==或==gb2312==;台湾繁体字用big5。
-
gbk或者gb2312:
-
两个字节编码一个汉字,每个字节的最高位都是1;第一个字节称为区码;第二个字节是位码。
-
不同方式的编码类型会造成混乱
-
==UTF-8==编码
-
对于英语体系,原有的ASC编码不变一个字符一个字节 ;对于汉字,一个汉字三个字节。
-
编码转换
b_str = "抽烟喝酒烫头"
# encode方法
b_utf8 = b_str.encode("utf8")
b_gbk = b_str.encode("gbk")
# decode方法
b_str = b_utf8.decode("utf8")
占位符
price = float(input("请输入苹果的单价:"))
print(f"苹果的单价为{price}元")
# f"{变量名}" ,的用法,大括号会成为占位符,里面的变量会生效。
tuple元组
x,y = (2,3) # 拆包,把2,3这个元组拆给了下x,y
a_tuple= x, y # 组包,把x,y组装成了元组,赋值给a_tuple
x,y = y,x # 交换俩变量的值的写法,实际是右边的y,x先组包,再拆包给y,x
set集合
- 无序、唯一,用
{ }表示。可以用来去重。
函数传参
func(*nums)传入不定长参数,打包成元组。func(**kwarg)传入k,v字典参数,打包成字典。
文件读写
# 文件的读写之前,需要打开文件,open
with open("a.csv", encoding='utf8') as f:
f.write('name,age,gender\n')
f.write('zhangsan,21,M\n')
11.18 selenium
python Selenium基本用法
- 检查chrome版本和chromedriver版本


这两个版本不一致的话,selenium运行不了,会报版本不一致错误。
-
更新chromedriver的方法:
- 在官网:chromedriver.storage.googleapis.com/index.html中下载小版本一致的驱动程序exe文件(107.0.5304.xxx),放到python39的路径中(用
where python来查询python路径)覆盖旧版本。
- 在官网:chromedriver.storage.googleapis.com/index.html中下载小版本一致的驱动程序exe文件(107.0.5304.xxx),放到python39的路径中(用
-
浏览器中安装Selenium IDE插件
google的话本地插件程序拖进去;edge的话是直接在线搜索安装。
- 检查百度输入框的id

输入框的id是==kw==
-
同理,检查百度一下按钮的ID:su
-
写自动化测试代码
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
#获取浏览器对象,打开网页
chrome = webdriver.Chrome()
chrome.get("http://www.baidu.com")
time.sleep(3)
# 检查百度输入框的ID叫kw,获取这个输入框,并输入内容
input_s = chrome.find_element(By.ID, "kw")
input_s.send_keys("python")
time.sleep(3)
# 检查百度一下的按钮的ID叫su,获取这个button按钮,并点击
btn_s = chrome.find_element(By.ID, "su")
btn_s.click()
time.sleep(5)
# 关闭浏览器
chrome.close()
浏览器selenium基本用法
-
打开selenium ide界面
-
从浏览器的扩展程序界面打开
-
或者直接从扩展程序的index.html文件进去

-
新建project
-
输入网址 - 点击 REC - 执行操作(输入python点击百度一下)- 点击stop - 命名
-
在command里面就能看到操作的分解步骤:

如果不需要某个command,就在下面点 // 把这个command disable掉
- 导出项目为python pytest文件

-
pytest文件导入到pycharm
-
右键class名 - 运行测试(如果失败可以尝试在pycharm的settings - Tool里面把testing选择pytest)

11.23 python操作题3.1.1
环境配置
-
考试环境没有打开Selenium,在浏览器中打开扩展页,enable起来。
-
提供的脚本server.py,在该文件夹中打开cmd,运行
python server.py,会启动服务器,并监听端口7272。这时启动浏览器,访问localhost:7272就能访问服务器。
测试登陆界面的步骤
- 打开到server登录界面,打开selenium ide,新建项目,输入网址开始录制。

-
在server登录界面输入用户名密码开始登录,显示错误值之后,停止录制。
-
在项目界面输入target网址

- 为了校验确实是跳到了Error Page,需要加上一句断言来判断:

-
输入好之后,点击左上角Run来测试一下能不能跑起来。OK之后保存side文件,export为python test文件,去pycharm建项目打开它。
-
把pycharm里面的settings - tools - Python Integrated Tools - Testing 改为 pytest

- 得根据题目要求 - 导入user文件中的用户名密码 - 循环测试代码 编写
def test_invalidLogin(self): # 在这里导入用户名密码来测试
# input users.csv path
fn = r"C:\Users\test\Desktop\2022001\3.1.1\3.1.1\users.csv"
self.driver.get("http://localhost:7272/")
self.driver.set_window_size(1050, 840)
# input username and passwd
with open(fn, 'r', encoding='utf8') as f:
for line in f:
# 最后一个字符是换行符,省略掉;csv是用, 来作为分割的。
uname, pwd = line[:-1].split(',')
# 因为测试是多次执行的,执行完还要回来重新输入,但是每次回来都会保留上次输入的文件名
# 所以click方法之后,加上clear,先清除文本框,再输入新的用户名和密码
self.driver.find_element(By.ID, "username_field").click()
self.driver.find_element(By.ID, "username_field").clear()
self.driver.find_element(By.ID, "username_field").send_keys(uname)
self.driver.find_element(By.ID, "password_field").click()
self.driver.find_element(By.ID, "password_field").clear()
self.driver.find_element(By.ID, "password_field").send_keys(pwd)
self.driver.find_element(By.ID, "login_button").click()
assert self.driver.find_element(By.CSS_SELECTOR, "h1").text == "Error Page"
# 判断完一次就back回去开始下一次
self.driver.back()
- 截图保存测试结果
另一道题:测试ESHOP
- 注意:EShop环境在原始的虚拟机中,URL是
http://localhost:8080/EShop
[!note] 注意在考试环境中的EShop是不加8080端口的
-
assert识别文本可以有两种判断方式:
-
assert text
-
assert element present

-
脚本几乎一样
class TestEshopValidLogin():
def setup_method(self, method):
self.driver = webdriver.Chrome()
self.vars = {}
def teardown_method(self, method):
self.driver.quit()
def test_eshopValidLogin(self):
self.driver.get("http://localhost/EShop/mer.do?method=browseIndexMer")
self.driver.set_window_size(1050, 840)
fn = r"C:\Users\test\Desktop\user.csv"
with open(fn, 'r', encoding='utf8') as f:
for line in f:
usr, psw = line[:-1].split(',')
self.driver.find_element(By.NAME, "loginName").click()
self.driver.find_element(By.NAME, "loginName").clear()
self.driver.find_element(By.NAME, "loginName").send_keys(usr)
self.driver.find_element(By.NAME, "loginPwd").click()
self.driver.find_element(By.NAME, "loginPwd").clear()
self.driver.find_element(By.NAME, "loginPwd").send_keys(psw)
self.driver.find_element(By.CSS_SELECTOR, ".UserRegster > input:nth-child(2)").click()
elements = self.driver.find_elements(By.XPATH, "//span[contains(.,\'安全退出\')]")
assert len(elements) > 0
self.driver.back()
[!tip] 注意事项
- usr、pwd的获取:去除最后的换行符,用逗号分隔
- 每次输入usr、pwd之前,都要先清除文本框
- 每次循环最后都back()一下
11.23理论题部分
职业道德部分
参考PPT
操作系统部分
Linux
- Linux中一般将guest account来宾用户设置为==nobody==。权限较低,不能登录
- Linux init启动进程需要读取 /etc/inittab 文件
- 用来设置命令别名alias的文件为 profile
windows
- win10系统中自带 tasklist 命令用于显示每个进程中主持的服务
- 连接到共享文件夹或者共享打印机时,使用的登录方式是:网络登录
- win10默认文件系统:NTFS
网络
-
逻辑功能上,分为==资源子网==和==通信子网==
-
MAC地址是一个 ==6 字节==的二进制串
软件工程
-
软件=程序+文档+数据;程序=算法+数据结构
-
软件可以分为:系统软件、应用软件、工具软件
-
软件工程三要素:方法+工具+过程
-
敏捷开发:
- 响应变更胜过遵循计划、个体与交互胜过流程与工具、可工作的软件胜过文档。
- 是通过用户故事来定义每一阶段的目标
- 及早、持续交付有价值的软件
- 测试管理 - 产品待办事项、冲刺
-
测试人员负责:自动测试脚本、用户故事、测试结果日志 (单元测试一般是开发做的)
-
主流构建标准
- 构建or组件:不同的应用有相似的流程,称为==MVC模型==,构建提供了基本流程或思路;我们需要做的是用语言把模型开发出来,提供一些数据放进去。
-
DOM:Document - object - module,是操作文档相关应用的构建
-
软件产品质量

-
可辨识性属于:易用性;信息安全性包含了可核查性子特性;可移植性包含:易安装性、适应性;兼容性=共存+互操作性
-
B/S(浏览器 服务器)和==C/S==(客户端 服务器)架构的区别:
-
BS体系功能构件相对集中,扩展性差;CS体系功能构件相对分散
- BS缺乏对动态页面的支持,无法集成数据库处理能力,数据库查询操作慢
软件测试
-
场景测试
-
基本流:系统从初始态 - 终止态
- 异常流 实际是一种:备选流;备选流越多,出现意外的异常流概率就越少。
-
场景是通过交互序列产生的
-
组合测试
-
单一选择测试:每个测试输入的每个可能的取值,都至少包含在整个测试用例集合中一次
-
驱动测试
-
关键字驱动测试
数据、脚本、业务的分离
-
数据驱动测试
- 将测试逻辑与测试数据分开
-
软件本地化测试:测试界面翻译
-
回归测试
-
目标是验证缺陷得到了正确修复,同时没有影响原有功能。
-
验收测试
-
alpha测试:在开发环境完成测试;beta测试:在用户环境完成测试
-
风险控制
-
使用盗版测试工具属于:投机风险
- 给设备买保险属于:风险转移
- 测试人员风险属于技术风险
各种测试过程
- 测试用例规格说明 - 从测试依据导出测试用例
- 为测试环境需求提供满足声明:测试环境准备报告
- 测试策划过程成功 - 产生测试计划
- 测试人员分配 + 测试度量标准 + 测试工具选用 = 测试计划。(不包含测试用例)
- 测试监控过程产生 - 变更后的测试计划 + 测试状态报告 + 风险信息
- 测试策略:强调怎么做,说明设计原则
- 测试规程 安排的执行次序优于包含的测试用例的优先级。
- W模型,测试团队越早介入越好,在需求分析就介入项目。
组织级测试过程
用于开发和管理组织级测试规格说明,包含:组织级测试方针和组织级测试策略。
- ==组织级测试方针==是执行性文档,描述组织内的测试目的、目标和总体范围
- ==组织级测试策略==是详细的技术文档,定义了如何执行测试,是通用文档。
测试工具和应用
-
Katalon Studio内置的脚本语言:Groovy;UFT用的是:VB;LoadRunner用的是:C;Ranorex Studio用的是==C#==
-
Selenium
-
WebDriver定位策略有:
By.id,By.name,By.ClassName等;定位属性动态变化用By.xpath - 断言来判断输入值是否正确:assertValue
- IDE使用open打开浏览器
- Selenium WebServer通过JSON协议与各种绑定的语言通信
DevOps
- Jenkins:持续集成工具,自动生成软件新版本、自动部署、自动化回归测试跑测试脚本。
- 开发、运营、质量管理三个团队之间的沟通协作整合
数据库
- 数据库管理系统 属于 系统软件
- 系统软件:支持应用软件运行
- 数据库中的主键默认创建索引 PRIMARY KEY;创建表的时候是不能直接指定索引的,除非指定主键,默认主键有索引的。
- 用户权限授予、取消
- 授予:GRANT
- 取消:
REVOKE SELECT ON Customer FROM User1 Revoke/GRANT + Role或者CRUD语句 on 哪个表 FROM 哪个用户- VIEW视图
- 从大表里面选出部分列的数据展示(比如取出一些敏感数据列)
CREATE VIEW必须包含SELECT- 存储过程
- 可以执行已命名的SQL语句
- 对数据库和表进行更新:
alter database、alter table
Java
- Java的环境变量==JAVA_HOME==指向Java安装路径
\Java\Jdk - Jdk是开发环境,Jre是运行环境;jdk包含了Jre
- Java环境变量classpath指向
%JAVA_HOME%\lib和%JAVA_HOME%\lib\tools.jar %JAVA_HOME%就是\Java\Jdk
Java6还需要配置环境变量;Java8不需要配了
相关笔记
- SoftwareTesting/软件工程基础 - 软件工程基础知识
- Database/MySQL入门 - MySQL数据库基础