本文为在霍格沃兹测试开发学社中学习到的一些技术,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~
今天课程的主讲老师是 阔海 。特别喜欢他自我介绍中的座右铭:致力于通过技术手段提高测试团队的工作效率,并改善产品交付的可靠性。 也是我一直在追求和渴望的工作内容,自己也悄悄的把它加在了我的座右铭上。 我之前的座右铭是:每天进步一点点,终会质变! 量变产生质变,督促着自己不断的学习提升,不断的成为更好的自己。一直都要在路上,从不停止脚步👣
今天的课程也别出心裁,很是生动有趣。因为是学习新的内容,原本认为会很枯燥可能还会带有一些难度,但是老师用坚果生产流水线的场景很好的讲解了testng框架的使用方法,随着流水线的需求不断的升级,需求虽有难度,但是testng总有办法解决,像一步步升级打怪,不知不觉中一节课程都学完了,也没有感受到学习的烧脑痛苦(不排除课程就简单哈,主要是想说这种学习的感觉)。
可以这么说,这节课是我最喜欢的一节课。必须把链接打出来,送老师上墙,哈哈哈
<dependency>
<groupId>org.testnggroupId>
<artifactId>testngartifactId>
<version>6.14.3version>
dependency>
Testng和流水线的是什么关系?
生产线其实是一个流程的控制装置,给货物一个运转的驱动力,让货物按照顺序完成计划的操作,从而达到预期的效果。
测试的本质是什么? 也是让我们的被测功能,按照一个预定好的测试计划,执行一个个测试用例,从而达到可上线的目的。
其实两者在本质上是一致的。

如下图所示:用@Test注解,依次装入坚果


| 注解 | 作用 |
|---|---|
| @AfterMethod | 被注解的方法将在每一个测试方法调用后运行 |
所以check方法,在每次装入坚果的方法执行之后都会被执行,满足了需求。

testng的流程控制就是通过各种注解来实现的:
| 注解 | 作用 |
|---|---|
| @BeforeSuite | 被注释的方法将在所有测试运行前运行 |
| @AfterSuite | 被注释的方法将在所有测试运行后运行 |
| @BeforeTest | 被注释的方法将在测试运行前运行 |
| @AfterTest | 被注释的方法将在测试运行后运行 |
| @BeforeClass | 被注释的方法将在当前类的第一个测试方法运行前运行 |
| @AfterClass | 被注释的方法将在当前类的所有测试方法运行后运行 |
| @BeforeMethod | 被注释的方法将在每一个测试方法运行前运行 |
| @AfterMethod | 被注释的方法将在每一个测试方法运行后运行 |
下图很好的诠释了,注解执行的洋葱结构:


| 注解 | 作用 |
|---|---|
| @Test(enabled = false) | 禁用测试用例,被标注的测试用例将不会被执行 |
如下图所示:装入坚果C和坚果D的方法不会被执行。


| 注解 | 作用 |
|---|---|
| @Test(groups = {“group1”}) | 组的概念,可以将具有相似功能的测试方法分组。一个测试方法可以属于多个分组 |
DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite1">
<test name="testngDemo">
<groups>
<run>
<include name = "group1" />
run>
groups>
<classes>
<class name="com.example.testng.TestNgGroup"/>
classes>
test>
suite>


| 注解 | 作用 |
|---|---|
| @Test(dependsOnMethods = “putInA”) | 声明被依赖的方法,该方法将在被依赖方法成功执行之后,才会执行。假如被依赖的方法执行失败,则该方法会被跳过 |
备注:依赖单个方法可以这样写 @Test(dependsOnMethods = “putInA”),如果依赖多个方法则这样写@Test(dependsOnMethods = {“putInC”,“putInB”})
如下图所示:


解决方案如下:

| 注解 | 作用 |
|---|---|
| @Test(threadPoolSize = 5) | 线程池内的线程个数;设置为5,表示该测试方法将会在5个不同的线程中同时执行 |
| @Test(invocationCount = 5) | 执行的总次数;设置5,表示该测试方法应该被执行的总次数为5 |
| @Test(timeOut = 5) | 超时时间,单位是毫秒;设置5,该测试方法每次执行所消耗的时间如果大于5ms,则测试失败 |
如下图所示:装配坚果C是多线程运行,同一时间点执行,不会让装配坚果D、E处在等待状态,满足了需求。


解决方案如下:

| 注解 | 作用 |
|---|---|
| @DataProvider(name = “packageList”) | testng数据参数化,注解中用name给这个provider起名字 |
| @Test(dataProvider= “packageList”) | 该测试用例使用名为packageList的provider提供的数据作为测试数据 |
public class TestNgDataProvider {
@DataProvider(name = "packageList")
public Object[][] putInList(){
Object[][] list = new Object[][]{
{"包裹1",0,1,0,1,0},
{"包裹2",1,1,1,1,0},
{"包裹3",1,1,1,1,1}
};
return list;
}
@Test(dataProvider= "packageList")
public void putIn(String packageName,int a,int b,int c,int d,int e){
Out.out("开始装配:"+packageName);
Out.out("装入"+a+"个坚果A");
Out.out("装入"+b+"个坚果B");
Out.out("装入"+c+"个坚果C");
Out.out("装入"+d+"个坚果D");
Out.out("装入"+e+"个坚果E");
}
}
如下图所示:根据不同的数据源,在同一条生产生产不同的包裹。

testng测试框架的课程学习完了,老师配坚果流水线的场景的确是很生动吧?寓教于乐,虽然学过的知识,时间长了就会忘记,估计这个课程的内容会因为它的有趣比其他课程会忘的慢一点(哈哈哈哈)。另外,理论结合实践,在以后的工作中,遇到类似的问题/需求,自己也能过很快的找到解决方案。
文末说明
推荐博文:接口测试经典面试题:Session、cookie、token有什么区别?