本文为继续上篇文章。
2. 断言
常见的断言方式有 JUnit 自带的 Assert 和 Hamcrest。JUnit 自带的断言方法功能十分有限只能满足最基本的需求。Hamcrest 相对来讲功能丰富一些,但是该库已经多年不更新。而且 Hamcrest 和 JUnit 自带的断言方法一样,有个致命的缺点,就是当一个 case 中有多个断言时,如果其中一个断言失败,那么在它之后的断言都不会执行。这里向大家推荐一款新的断言神器 AssertJ。
AseertJ: 号称流式断言。什么是流式,常见的断言器一条断言语句只能对实际值断言一个校验点,而 AseertJ 支持一条断言语句对实际值同时断言多个校验点,这样使得断言的语句更加简洁适合阅读。AseertJ 还支持一次性执行所有断言,然后收集所有失败的断言一起反馈。当然除此之外 AseertJ 还有很多其他特性,可以参考官方文档慢慢挖掘。下面将举例说明一下 AseertJ 的优势:
<code>public
class
TestCase
extends
BaseCase
{ UserProfileBO user =new
UserProfileBO();public
void
init
()
{ user.setAddress(" 杭州 "
); user.setMobile("1386800000"
); user.setUserName(" 测试账号 "
); }public
void
testAssertJUnit
()
{ Assert.assertEquals(" 地址 "
,user.getAddress()," 宁波 "
); Assert.assertEquals(" 手机 "
,user.getMobile(),"13868000000"
); Assert.assertEquals(" 手机 "
,user.getUserName()," 测试 "
); Assert.assertNotNull(user.getMobile()); Assert.assertTrue(user.getMobile().startsWith("138"
)); Assert.assertTrue(user.getMobile().length() ==11
); }public
void
testHamcrestMatchers
()
{ MatcherAssert.assertThat(user.getAddress(), equalTo(" 宁波 "
)); MatcherAssert.assertThat(user.getMobile(), equalTo("13868000000"
)); MatcherAssert.assertThat(user.getUserName(), equalTo(" 测试 "
)); MatcherAssert.assertThat(user.getMobile(), allOf(is(nullValue()),startsWith("136"
))); }public
void
testAssertJ
()
{ SoftAssertions.assertSoftly(softly -> { softly.assertThat(user.getAddress().equals(" 宁波 "
)); softly.assertThat(user.getMobile().equals("13868000000"
)); softly.assertThat(user.getUserName().equals(" 测试 "
)); }); Assertions.assertThat(user.getMobile()) .isNotNull() .startsWith("136"
) .hasSize(11
); } }/<code>
3.jenkins 集成接口测试
(1)设置测试代码的仓库地址及身份信息
(2)设置 maven 运行参数
希望执行部分接口用例,可以通过-Dtest=XXX(测试类名) 的方式执行指定的 case,多个类名用逗号 “,” 隔开
(3)设置 Job 执行机制,下图表示每天定时执行
4.pipeline 参数注入
前面写 pipeline 的时候提过,我们的接口测试代码是需要支持外部参数注入的,比如测试的服务地址,不同的分支代码可能部署在不同测试服务器上,需要在 pipeline 中通过参数化的方式驱动对不同的服务器进行接口测试。
这里我们可以使用 maven 的-D(Properties 属性)来实现,举例如下:
(1)dubbo 使用 properties 配置文件,但具体参数使用 ${key}占位符方式打包替换
(2)maven 的 pom 文件中指定对应配置文件中的参数值 (此处指定的参数值会被通过 maven -D 传递过来的参数值覆盖)
此处注意:还需要启动 resources 的 filter 过滤器
(3) 使用 maven 命令行设置属性值
并对该值进行参数化支持 pipeline 传参
5.Pipeline 代码实现
<code> stage(' 接口自动化测试 '
) { steps{ echo"starting interfaceTest......"
script { timeout(5
) { waitUntil {try
{ sh"nc -z
${serverIP}
${jettyPort}
"return
true
}catch
(exception) {return
false
} } } build job: ITEST_JOBNAME, parameters: [string(name:"dubbourl"
, value:"
${serverIP}
:${params.dubboPort}
")] } } }/<code>
测试代码规范 (仅供参考)
- 测试项目命名规范
接口测试:一般需要独立测试项目,测试项目的命名规则为:“test-“+ 被测试的项目名,如 test-kano。单元测试:不需要重建独立测试项目,和开发代码放在同一项目即可。
- 测试目录定义规范
测试代码统一放在测试项目的 “src/test/java” 下。测试配置文件统一放置在 “src/test/resources” 下。
- 包名定义规范
与被测试项目中的包名一致。
- 测试类命名规范
测试类的命名规则是:以 Test 开头,以它要测试的对象的名称结尾,例如Test+ 被测试的业务、Test+ 被测试的接口、Test+ 被测试的类另外一种方式是:以 Test 结尾,以它要测试的对象的名称开头,例如被测试的业务 +Test、被测试的接口 +Test、被测试的类 +Test视个人习惯而定,为了 case 定位方便,目前测试团队一般用第一种。
- 测试用例命名规范
测试用例的命名规则是:test+ 用例操作 _ 条件状态,统一使用 lowerCamelCase 风格,必须遵从驼峰形式。单词的约定与测试类命名同
- 接口测试代码常见约束
(1)数据清理和构造
- @BeforeClass @Before 中做数据准备等相关操作:加载测试类以前需要加载所有测试用例共同的场景数据,同时在运行单个测试用例的时候加载特别的测试数据。
- @AfterClass @After 中做测试数据清理等相关操作:在执行完相关测试以后清理用例现场。
(2)断言
- 不要做无谓的断言在测试模式下,有时会情不自禁的滥用断言。这种做法会导致维护更困难,需要极力避免。仅对测试方法名指示的特性进行明确测试,因为对于一般性代码而言,保证测试代码尽可能少是一个重要目标。
- 使用显式断言方式应该总是优先使用 assertEquals(a, b) 而不是 assertTrue(a == b), 因为前者会给出更有意义的测试失败信息。在事先不确定输入值的情况下,这条规则尤为重要。
- 断言的参数顺序要合适
(3)测试用例保持独立
- 确保测试代码独立于项目代码之外。
- 为了保证测试稳定可靠且便于维护,测试用例之间决不能有相互依赖,也不能依赖执行的先后次序。
(4)测试代码要考虑错误处理
- 如果前面的代码执行失败,后续语句会导致代码崩溃,剩下的测试都无法执行。任何时候都要为测试失败做好准备,避免单个失败的测试项中断整个测试套件的执行。
- 不要写自己的 catch 代码块,即只有 test 失败的情况,不应该存在 catch 情况。
结语
接口测试是一个非常庞杂的体系,很难用一篇文章阐述清楚,其他实践如接口测试覆盖率统计、标准协议页面化测试平台(提供给没有编码能力的产品或测试人员使用)、maven 项目骨架建立标准化测试工程、dubbo/hessian/restful/webservice 等接口协议具体实现等等限于篇幅也没有做具体阐述。期待大家一起探讨。
(文章来源于霍格沃兹测试学院)
专栏
软件测试工程师如何获取高薪职位
9.9币
0人已购
關鍵字: assertThat Assert maven