TestNG 是一个很棒的测试框架。它提供了许多功能,可以帮助我们构建健壮且可维护的框架。在本章中,我们将学习如何在TestNG中重试失败的测试。
您必须在自动化测试运行期间看到随机故障。这些失败可能不一定是因为产品错误。这些失败可能是由于以下原因
- 随机浏览器问题或浏览器无响应
- 随机机器问题
- 服务器问题,如服务器响应中的意外延迟
这些失败是真实的,应该进行调查,但这些失败不一定是因为产品中的错误。TestNG提供了一个很棒的功能,您可以使用该功能多次重试测试用例,然后将其声明为失败。这意味着,如果您发现故障,可以自动重新运行测试以确保测试始终失败。这样,它可以减少因随机问题导致的错误故障,并且您可以花更多时间调试真正的故障
在本章中,让我们研究如何在TestNG中实现失败机制的重试。为了实现这一点,我们必须首先了解org.testng.IRetryAnalyzer接口。接口定义是
1
2
3
4
5
6
7
8
9
10
|
public
interface
IRetryAnalyzer
{
/**
* Returns true if the test method has to be retried, false otherwise.
*
* @param result The result of the test method that just ran.
* @return true if the test method has to be retried, false otherwise.
*/
public
boolean
retry
(
ITestResult
result
)
;
}
|
该接口只有一种方法
1
|
public
boolean
retry
(
ITestResult
result
)
;
|
一旦测试方法失败,将调用此方法。您可以从ITestResult输入参数到此方法获取测试的详细信息,如上面的方法定义所示。如果要重新执行失败的测试,此方法实现应返回true,如果不想重新执行测试,则返回false。通常,此接口的实现决定根据您的要求基于固定计数器或复杂逻辑重试失败测试的次数。这个界面的简单实现如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package
Tests
;
import
org
.
testng
.
IRetryAnalyzer
;
import
org
.
testng
.
ITestResult
;
public
class
RetryAnalyzer
implements
IRetryAnalyzer
{
int
counter
=
0
;
int
retryLimit
=
4
;
/*
* (non-Javadoc)
* @see org.testng.IRetryAnalyzer#retry(org.testng.ITestResult)
*
* This method decides how many times a test needs to be rerun.
* TestNg will call this method every time a test fails. So we
* can put some code in here to decide when to rerun the test.
*
* Note: This method will return true if a tests needs to be retried
* and false it not.
*
*/
@
Override
public
boolean
retry
(
ITestResult
result
)
{
if
(
counter
<
retryLimit
)
{
counter
++
;
return
true
;
}
return
false
;
}
}
|
我们现在有一个简单的IRetryAnalyzer实现。仔细查看重试方法实现,此方法可确保重试失败的测试4次。这是因为我们指定了retryLimit = 4;
让我们看看我们如何使用它,有两种方法可以在测试中包含重试分析器
- 通过在@Test注释中指定retryAnalyzer值
- 通过在Listener接口上实现,在运行时添加Retry分析器
在@Test注释中指定retryAnalyzer属性
我们可以通过简单地使用以下语法来实现这一点@Test(retryAnalyzer =“IRetryAnalyzer实现类”)。下面是执行此操作的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
org
.
testng
.
Assert
;
import
org
.
testng
.
annotations
.
Test
;
public
class
Test001
{
@
Test
(
retryAnalyzer
=
Tests
.
RetryAnalyzer
.
class
)
public
void
Test1
(
)
{
Assert
.
assertEquals
(
false
,
true
)
;
}
@
Test
public
void
Test2
(
)
{
Assert
.
assertEquals
(
false
,
true
)
;
}
}
|
这里我们有两个测试,一个测试指定哪个类用作重试分析器。如果我们运行此测试,我们将得到以下结果

您可以看到Test1运行了4次,并且仅在最后一次运行时标记为失败。由于重试分析器,它运行了4次。但是,看看Test2我们可以看到它只运行一次。这是显而易见的,因为我们从未为Test2指定retryAnalyzer。
让我们看一下将retryAnalyzer添加到测试中的第二种方法。
在运行时指定retryAnalyzer
在这种情况下,您需要实现ITestAnnotationTransformer接口。ITestAnnotationTransformer接口属于称为TestNG Listeners的广泛接口类别。你可以在这里阅读更多。此接口定义如下所示
1
2
3
4
5
6
7
|
public
class
AnnotationTransformer
implements
IAnnotationTransformer
{
@
Override
public
void
transform
(
ITestAnnotation
annotation
,
Class
testClass
,
Constructor
testConstructor
,
Method
testMethod
)
{
// TODO Auto-generated method stub
}
}
|
此接口用于在运行时以编程方式向测试方法添加注释。在测试运行期间为每个测试调用Transform方法。这个接口的简单实现可以帮助我们像这样设置重试分析器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package
Tests
;
import
java
.
lang
.
reflect
.
Constructor
;
import
java
.
lang
.
reflect
.
Method
;
import
org
.
testng
.
IAnnotationTransformer
;
import
org
.
testng
.
annotations
.
ITestAnnotation
;
public
class
AnnotationTransformer
implements
IAnnotationTransformer
{
@
Override
public
void
transform
(
ITestAnnotation
annotation
,
Class
testClass
,
Constructor
testConstructor
,
Method
testMethod
)
{
annotation
.
setRetryAnalyzer
(
RetryAnalyzer
.
class
)
;
}
}
|
一旦我们实现了IAnnotationTransformer,我们只需要在testng run xml中将它添加为一个监听器。像这样
1
2
3
4
5
6
7
8
9
10
11
12
|
<
!
DOCTYPE
suite
SYSTEM
"http://testng.org/testng-1.0.dtd"
>
<
suite
name
=
"RetryFailedTests"
verbose
=
"1"
>
<
listeners
>
<
listener
class
-
name
=
"Tests.AnnotationTransformer"
/
>
<
/
listeners
>
<
test
name
=
"RetryMulitple"
>
<
classes
>
<
class
name
=
"Tests.Test001"
/
>
<
/
classes
>
<
/
test
>
<
/
suite
>
|
现在我们不必在@Test注释中指定retryAnalyzer属性。更新的测试将如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package
Tests
;
import
org
.
testng
.
Assert
;
import
org
.
testng
.
annotations
.
Test
;
public
class
Test001
{
@
Test
public
void
Test1
(
)
{
Assert
.
assertEquals
(
false
,
true
)
;
}
@
Test
public
void
Test2
(
)
{
Assert
.
assertEquals
(
false
,
true
)
;
}
}
|
您现在可以简单地运行测试,看看TestNG每次重新执行Test1和Test2 4次。这就是这个主题。在下一节中,我们将看到如何使用自定义Java Annotation直接指定测试中的重试限制计数。