TestNG – 预期异常和预期消息教程

在编写单元测试时,在某些情况下,我们需要验证在执行过程中程序是否引发了异常。 通过允许用户指定在执行过程中测试方法引发的异常类型,TestNG 提供了一种测试此类情况的功能。 它支持为验证提供多个值。 如果测试引发的异常不属于用户输入列表,则测试方法将标记为失败。

让我们创建一个示例测试,并了解异常测试如何在 TestNG 中工作。

@Test ( expectedExceptions = { IOException.class, NullPointerException.class } )

让我们看一个例子,以更好地理解它。

预期异常测试示例

在下面的测试中,我们有两种测试方法,即exceptionTestOne()exceptionTestTwo()。 这里exceptionTestOne()抛出IOException,而exceptionTestTwo()抛出Exception。 在使用Test注解时,使用ExpectedExceptions属性值提到了在运行这些测试时验证的预期异常。

public class ExceptionTestDemo 
{
	@Test(expectedExceptions = { IOException.class })
	public void exceptionTestOne() throws Exception {
		throw new IOException();
	}

	@Test(expectedExceptions = { IOException.class, NullPointerException.class })
	public void exceptionTestTwo() throws Exception {
		throw new Exception();
	}
}

以上测试运行的输出如下:

[TestNG] Running: C:\Users\somepath\testng-customsuite.xml

PASSED: exceptionTestOne
FAILED: exceptionTestTwo

org.testng.TestException: 
Expected exception java.io.IOException but got org.testng.TestException: 
Expected exception java.io.IOException but got java.lang.Exception
	at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1497)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1245)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: org.testng.TestException: 
Expected exception java.io.IOException but got java.lang.Exception
	at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1497)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:754)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	... 16 more
Caused by: java.lang.Exception
	at com.howtodoinjava.test.ExceptionTestDemo.exceptionTestTwo(ExceptionTestDemo.java:16)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	... 18 more

===============================================
    Default test
    Tests run: 2, Failures: 1, Skips: 0
===============================================

从测试结果中可以看出,exceptionTestTwo()在执行期间被 TestNG 标记为失败。 测试失败,因为所述方法引发的异常与ExpectedExceptions列表中提供的异常列表不匹配。

带有验证消息的预期异常测试的示例

您还可以根据测试引发的异常消息来验证测试。 正则表达式也可以用于验证错误消息,可以使用.*.完成此操作,具体取决于正则表达式的位置,我们可以在验证异常消息时使用它进行模式匹配,例如开始,包含,结束于。

让我们学习如何根据抛出的异常消息编写异常测试。

public class ExceptionTestDemo 
{
	@Test(expectedExceptions = { IOException.class }, expectedExceptionsMessageRegExp = "Pass Message test")
	public void exceptionTestOne() throws Exception {
		throw new IOException("Pass Message test");
	}

	@Test(expectedExceptions = { IOException.class }, expectedExceptionsMessageRegExp = ".* Message .*")
	public void exceptionTestTwo() throws Exception {
		throw new IOException("Pass Message test");
	}

	@Test(expectedExceptions = { IOException.class }, expectedExceptionsMessageRegExp = "Pass Message test")
	public void exceptionTestThree() throws Exception {
		throw new IOException("Fail Message test");
	}
}

以上测试运行的输出如下:

[TestNG] Running: C:\Users\somepath\testng-customsuite.xml

PASSED: exceptionTestOne
PASSED: exceptionTestTwo
FAILED: exceptionTestThree

org.testng.TestException: 
Expected exception java.io.IOException but got org.testng.TestException: 
The exception was thrown with the wrong message: expected "Pass Message test" but got "Fail Message test"
	at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1497)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1245)
	at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
	at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
	at org.testng.TestRunner.privateRun(TestRunner.java:767)
	at org.testng.TestRunner.run(TestRunner.java:617)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
	at org.testng.SuiteRunner.run(SuiteRunner.java:240)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
	at org.testng.TestNG.run(TestNG.java:1057)
	at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:111)
	at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:204)
	at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:175)
Caused by: org.testng.TestException: 
The exception was thrown with the wrong message: expected "Pass Message test" but got "Fail Message test"
	at org.testng.internal.Invoker.handleInvocationResults(Invoker.java:1481)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:754)
	at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
	at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
	... 16 more
Caused by: java.io.IOException: Fail Message test
	at com.howtodoinjava.test.ExceptionTestDemo.exceptionTestThree(ExceptionTestDemo.java:21)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
	at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
	... 18 more

===============================================
    Default test
    Tests run: 3, Failures: 1, Skips: 0
===============================================

在上述测试方法中,exceptionTestThree()失败,因为预期的消息不匹配。