模式1-哨兵断言
这是一种让测试用例快速失败的断言,一般存在于用例的前部,甚至是setup阶段,或者是底层的测试框架中。如何判断需要使用这种类型的断言呢?当测试用例中出现了if这样的判断来决定测试用例的执行路径时,就需要考虑是否引入哨兵断言了。这样就可以在测试用例用引入测试逻辑。
典型的案例是,在UI 自动化测试中,往往会首先判断一下某个页面的标志性icon是否存在,如果存在,则继续执行该页面下的操作。
另外一种场景是,在通过API接口进行业务场景自动化测试时,我们会假设协议层通讯正常,request/response可以正常发送和接收。HTTP restful的业务请求的执行结果,无论正确/错误,都在更上层的response中体现,其HTTP状态码(HTTP Status Code)应该都是200,表示消息传输正常。
因此,我们可以在测试框架的通信层首先对状态码进行断言,保证协议层的通信正常,然后再将返回的body交由上层代码进行处理。一个简单的示例如下:
代码语言:javascript复制 @Test
public void testUserLogin() {
expect().statusCode(200).
body(
"success", equalTo(true),
"userInfo.userId", equalTo("admin"),
"userInfo.firstName", equalTo("admin"),
"userInfo.lastName", equalTo("admin"),
"error", equalTo(null)).
when().
get("/user/login?userName=admin&password=abc");
}
//为简单起见,该案例直接将body信息进行了验证。
其中的 statusCode(200)就是一个简单的哨兵断言案例。如果有需要,如每个用例均需要完成的哨兵断言,甚至都可以考虑放进setup方法中进行,便于重复使用。
模式2-Delta断言
Delta断言让我们有机会脱离SUT的具体状态来进行验证。如在某个测试用例中,测试用例需要验证转账1个亿的准确性。因此,我们可以通过验证该账户转账前后的资金差异来确定结果是否准确。如以下的伪代码
代码语言:javascript复制@Test
代码语言:javascript复制@Test
public void testBalance() {
long balanceBefore=api.queryBalance();
api.trans(1,"aaa","bbb");
long delta = api.queryBalence() - balanceBefore();
assertThat(delta).isEqualto(1);
}
采取这种方式的好处是,在断言时可以不必要知道该账户在转账前后的具体资金是什么。如果没有采用delta验证,而是直接验证转账(前)后的该账户资金余额,那么则要求该测试用例需要严格控制上下文,保证每次执行该用例时,系统账户的金额处于预期的状态下。
代码语言:javascript复制@Test
public void testBalance() {
long balanceBefore=api.queryBalance();
assertThat(balanceBefore).isEqualto(123456789);
api.trans(1,"aaa","bbb");
assertThat(api.queryBalance()).isEqualto(123456788);
}
对比这两个案例来看,案例2所示的案例对于被测系统的环境控制要求较高,如果该用例执行时,系统没有将该账户余额正确设置为初始值,用例就会在第一步失败。如果其它用例中也用到了该账户进行了转账/入账的操作,并没有及时复原(如reset数据库)的话,由于用例间的潜在数据依赖关系,也会导致用例执行失败。