先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注软件测试)
正文
7、可视化报告
用例执行后,就是到了向团队展示结果的时候了,一个可视化的报告可以便于团队成员了解到每次自动化接口用例执行的成功数、失败数等数据。
8、可持续集成
对于已经有测试用例并测试完成的接口,我们希望能够形成回归用例,在下一个版本迭代或上线之前,通过已有用例进行一个回归测试,确保新上线的功能不影响已有功能。因此,这就需要接口自动化测试是可持续集成的而不是一次性的。
- 接口测试自动化框架选型
结合我们对接口测试自动化框架的需求及目前市场上的很多测试工具的特点,总结成下表:
这里简单列举一下:
1、fiddler
fiddler 是一个 HTTP 协议调试代理工具,Web 和手机测试都会用到,同时也支持接口测试。它能够记录并检查所有你的电脑和互联网之间的 http 通讯,设置断点,查看所有的“进出”Fiddler 的数据(指 cookie,html,js,css 等文件)。
2、postman
它是 Google 开发的一个插件,安装在 Chrome 浏览器上,能支持不同接口测试请求,可以管理测试套件和自动化运行。弱点是自动化断言功能不强大,不能和 Jenkins、代码管理库进行持续集成测试。
3、wireshak
这是一款抓包工具,支持 TCP、UDP、HTTP 等协议。如果做底层网络数据测试,一般都需要用到它,但是用作接口测试,它就有点不友好。因为刷新数据太快,不好定位每个操作对应的接口。
4、soupUI
soapUI 是一个开源测试工具,通过 soap/http 来检查、调用、实现 Web Service 的功能/负载/符合性测试。该工具既可作为一个单独的测试软件使用,也可利用插件集成到 Eclipse,maven2.X,Netbeans 和 intellij 中使用。把一个或多个测试套件(TestSuite)组织成项目,每个测试套件包含一个或多个测试用例(TestCase),每个测试用例包含一个或多个测试步骤,包括发送请求、接受响应、分析结果、改变测试执行流程等。该工具能够支持接口自动化测试和接口性能测试,也支持和 Jenkins 做持续集成测试。
5、Java 代码做接口测试
为什么要用代码做接口自动化测试呢?一些工具功能是有限制,很多公司需要一些特定的功能,工具不支持,只好用代码进行开发。一般用 Java 做自动化测试,主要利用 httpclient.jar 包,然后利用 JUnit 或者 TestNG 这样的单元测试工具,进行测试用例的开发,接着在 Jenkins 或我们的 aone 上创建一个 job,进行持续集成测试。
6、Python 代码做接口测试
和 Java 一样,用 Python 做接口测试,可以利用一个功能强大的第三方库 Requests,它能方便地创建接口自动化用例。Python 下的单元测试框架,一般采用 unittest。生成测试报告,一般选择 HTMLTestRunner.py。同样,可以结合 Jenkins 做持续集成测试。
接口测试自动化实践
TestNG 与 Junit 对比
- 综合性对比
我在日常测试工作中,使用的比较多的自动化测试工具是 Java 代码做接口测试,这里先介绍下我对单元测试工具 TestNG 和 Junit 的对比。先用一张表格总结一下他们的特点对比。
TestNG 与 JUnit 的相同点如下:
1、都有注解,即都使用 annotation,且大部分 annotation 相同;
2、都可以进行单元测试(Unit test);
3、都是针对 Java 测试的工具;
TestNG 与 JUnit 的不同点如下:
1、TestNG 支持的注解更丰富,如@ExpectedExceptions、@DataProvider 等;
2、JUnit 4 中要求@BeforeClass、@AfterClass 方法声明为 static,这就限制了该方法中使用的变量必须是 static。而 TestNG 中@BeforeClass 修饰的方法可以跟普通函数完全一样;
3、JUnit 只能使用 IDE 运行,TestNG 的运行方式有:命令行、ant 和 IDE;
4、JUnit 4 依赖性非常强,测试用例间有严格的先后顺序。前一个测试不成功,后续所有的依赖测试都会失败。TestNG 利用@Test 的 dependsOnMethods 属性来应对测试依赖性问题。某方法依赖的方法失败,它将被跳过,而不是标记为失败。
5、对于 n 个不同参数组合的测试,JUnit 4 要写 n 个测试用例。每个测试用例完成的任务基本是相同的,只是方法的参数有所改变。TestNG 的参数化测试只需要一个测试用例,然后把所需要的参数加到 TestNG 的 xml 配置文件中或使用@DataProvider 方式注入不同的参数。这样的好处是参数与测试代码分离,非程序员也可以修改参数,同时修改无需重新编译测试代码。
6、JUnit 4 的测试结果通过 Green/Red bar 体现,TestNG 的结果除了 Green/Red bar,还有 Console 窗口和 test-output 文件夹,对测试结果的描述更加详细,方便定位错误。
- 详细特性对比
下面详细介绍一下 TestNG 与 Junit 特性对比:
1、框架整合:
Spring+TestNG+Maven 整合:
- pom.xml 中增加 testng 依赖:
- 测试类增加 1 条注解@ContextConfiguration(locations = “classpath:applicationContext.xml”)并继承 AbstractTestNGSpringContextTests,范例如下
@ContextConfiguration(locations = “classpath:applicationContext.xml”)
public class BaseTest extends AbstractTestNGSpringContextTests{
@Test
public void testMethods() { … }
}
Spring+Junit+Maven 整合:
- pom.xml 中增加 junit 依赖:
- 测试类增加 2 条注解
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:applicationContext.xml”),如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:applicationContext.xml”)
public class BaseTest{
@Test
public void testMethods() { … }
}
2、注解支持
主要区别以下两点:
1、在 JUnit 4 中,我们必须声明“@BeforeClass”和“@AfterClass”方法作为静态方法。TestNG 在方法声明中更灵活,它没有这个约束。
2、在 JUnit 4 中,注释命名约定有点混乱,例如“Before”,“After”和“Expected”,我们并不真正了解“Before”和“After”之前的内容,以及要测试中的“预期” 方法。TestiNG 更容易理解,它使用类似“BeforeMethod”,“AfterMethod”和“ExpectedException”就很明了。
3、异常测试
“异常测试”是指从单元测试中抛出的异常,此功能在 JUnit 4 和 TestNG 中都可实现。JUnit 4
@Test(expected = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
TestNG
@Test(expectedExceptions = ArithmeticException.class) public void divisionWithException() { int i = 1/0; }
4、忽略测试
忽略测试意思是在单元测试哪些是可以被忽略的,这个特性在两个框架都已经实现。
JUnit 4
@Ignore(“Not Ready to Run”) @Test public void divisionWithException() { System.out.println(“Method is not ready yet”); }
TestNG
@Test(enabled=false) public void divisionWithException() { System.out.println(“Method is not ready yet”); }
5、超时测试
时间测试意思是如果一个单元测试运行的时间超过了一个指定的毫秒数,那么测试将终止并且标记为失败的测试,这个特性在两个框架都已经实现。
JUnit 4
@Test(timeout = 1000) public void infinity() { while(true); }
TestNG
@Test(timeOut = 1000) public voi
6、套件测试
“套件测试”是指捆绑几个单元测试并一起运行。此功能在 JUnit 4 和 TestNG 中都可实现。然而,两者都使用非常不同的方法来实现它。
JUnit 4
“@RunWith”和“@Suite”用于运行套件测试。下面的类代码表示在 JunitTest3 执行之后,单元测试“JunitTest1”和“JunitTest2”一起运行。所有的声明都是在类内定义的。
@RunWith(Suite.class) @Suite.SuiteClasses({ JunitTest1.class, JunitTest2.class }) public class JunitTest3 { }
TestNG
XML 文件用于运行套件测试。以下 XML 文件表示单元测试“TestNGTest1”和“TestNGTest2”将一起运行。
TestNG 可以做捆绑类测试,也可以捆绑方法测试。凭借 TestNG 独特的“分组”概念,每种方法都可以与一个组合相结合,可以根据功能对测试进行分类(分组)。例如,
下面是一个有四个方法的类,三个组(method1,method2 和 method3)
@Test(groups=“method1”) public void testingMethod1() { System.out.println(“Method - testingMethod1()”); }
@Test(groups=“method2”) public void testingMethod2() { System.out.println(“Method - testingMethod2()”); }
@Test(groups=“method1”) public void testingMethod1_1() { System.out.println(“Method - testingMethod1_1()”); }
@Test(groups=“method4”) public void testingMethod4() { System.out.println(“Method - testingMethod4()”); }
使用以下 XML 文件,可以仅使用组“method1”执行单元测试。
7、参数化测试
“参数化测试”是指单位测试参数值的变化。此功能在 JUnit 4 和 TestNG 中都实现。然而,两者都使用非常不同的方法来实现它。
Junit4 参数化测试:
- 步骤如下:
1.通过@Parameters 标识静态参数构造方法
2.通过测试类构造方法引入参数
3.测试方法使用参数
@RunWith(value = Parameterized.class)
public class JunitTest {
private int number;
public JunitTest6(int number) {
this.number = number;
}
@Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
return Arrays.asList(data);
}
@Test
public void pushTest() {
System.out.println("Parameterized Number is : " + number);
}
}
- 缺点:
- 一个测试类只能有一个静态的参数构造方法;
- 测试类需要使用@RunWith(Parameterized.class),无法兼容 spring-test 的 runner
- @RunWith(SpringJUnit4ClassRunner.class),会导致无法通过注解注入待测服务
- 需要在测试类中添加一个构造方法(一种冗余设计)
TestNG 参数化测试:
- 步骤如下:
1.通过@dataProvider 注解标识参数构造方法
2.测试方法在注解@Test 中通过 dataProvider 属性指定参数构造方法,便可在测试方法中使用参数
@Test(dataProvider = “Data-Provider-Function”)
public void parameterIntTest(Class clzz, String[] number) {
System.out.println("Parameterized Number is : " + number[0]);
System.out.println("Parameterized Number is : " + number[1]);
}
除此之外,TestNG 还支持通过 testng.xml 构造参数:
public class TestNGTest {
@Test @Parameters(value=“number”)
public void parameterIntTest(int number) {
System.out.println("Parameterized Number is : " + number);
}
}
XML 文件的内容如下
8、依赖测试
“参数化测试”表示方法是依赖性测试,它将在所需方法之前执行。如果依赖方法失败,则所有后续测试将会被跳过,不会被标记为失败。
JUnit 4
JUnit 框架着重于测试隔离; 目前它不支持此功能。
TestNG
它使用“dependOnMethods”来实现依赖测试如下
@Test public void method1() {
System.out.println(“This is method 1”);
}
@Test(dependsOnMethods={“method1”})
public void method2() {
System.out.println(“This is method 2”);
}
TestNG 接口自动化实践
- 参数化测试示例
以 DeviceStatusHSFService 为例,测试类如下:
public class DeviceStatusHSFServiceTest {
private DeviceStatusHSFService deviceStatusHSFService;
@BeforeTest(alwaysRun = true)
public void beforeTest() {
String envName = System.getProperty(“maven.env”); //运行环境可配置
SwitchENV switchEnv = new SwitchENV(envName); //运行环境可配置
deviceStatusHSFService = HsfRepository.getConsumer(DeviceStatusHSFService.class, switchEnv.getEnv(),
“HSF”, switchEnv.getHsfVersion(), “aicloud-device-center”, switchEnv.getTargetIp()).getTarget();
}
@Test(dataProvider = “updateDeviceStatus”, dataProviderClass = DeviceStatusHSFServiceTestDataProvider.class)
public void updateDeviceStatusTest(Long userId, String uuid, DeviceStatus deviceStatus){
Result result = deviceStatusHSFService.updateDeviceStatus(userId, uuid, deviceStatus);
System.out.println(“traceId:”+EagleEye.getTraceId()+result.toString());
Boolean res = result.getResult();
assertTrue(res);
}
}
其中通过 SwitchENV 类实现运行环境可配置:
/**
- 自定义环境配置
*/
public class SwitchENV {
/**
- 运行环境
*/
private Env env;
/**
- hsf环境
*/
private String hsfVersion;
/**
- 目标机器
*/
private String targetIp;
/**
- 环境名称
*/
private String envName;
public SwitchENV(String envName) {
Properties prop = new Properties();
// TODO: 本地自动化测试切换环境专用
if (envName == null) {
envName = “pre1”;
}
switch (envName) {
case “online”: {
InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream(
“config/application-online.properties”);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
env = Env.ONLINE;
break;
}
case “pre1”: {
InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream(
“config/application-pre1.properties”);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
env = Env.PREPARE;
break;
}
case “pre2”: {
InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream(
“config/application-pre2.properties”);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
env = Env.PREPARE;
break;
}
case “pre3”: {
InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream(
“config/application-pre3.properties”);
try {
prop.load(in);
} catch (IOException e) {
e.printStackTrace();
}
env = Env.PREPARE;
break;
}
default:
try {
throw new Exception(“环境变量输入错误!”);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
hsfVersion = prop.getProperty(“hsfVersion”).trim();
targetIp= prop.getProperty(“targetIp”).trim();
this.envName = envName;
}
public Env getEnv() {
return env;
}
public String getHsfVersion() {
return hsfVersion;
}
public String getTargetIp() {
return targetIp;
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
tch (IOException e) {
e.printStackTrace();
}
env = Env.PREPARE;
break;
}
default:
try {
throw new Exception(“环境变量输入错误!”);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
hsfVersion = prop.getProperty(“hsfVersion”).trim();
targetIp= prop.getProperty(“targetIp”).trim();
this.envName = envName;
}
public Env getEnv() {
return env;
}
public String getHsfVersion() {
return hsfVersion;
}
public String getTargetIp() {
return targetIp;
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注软件测试)
[外链图片转存中…(img-BwDT9zqW-1713197226991)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!