一个测试用例的运行必须在另一个用例执行后,二者必须前后运行(不能同时运行,或顺序颠倒)
执行哪些测试,排除哪些测试
参考:http://blog.csdn.net/wanglha/article/details/42004695
如果一个方法失败,取决于你有一个很难依赖于它(alwaysRun= false,这是默认的),没有标记的方法依赖于它的失败,但作为跳过。跳过的方法将被报告为例如在最终报告(在HTML中,既不是红也不是绿的颜色),这是很重要的,因为跳过的方法不一定是失败。
场景1: 依赖组
public class DependencyTestUsingAnnotation {
String message = "Manisha";
MessageUtil messageUtil = new MessageUtil(message);
@Test(groups = { "init" })
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Manisha";
Assert.assertEquals(message, messageUtil.printMessage());
}
<span style="color:#ff0000;"><strong>@Test(dependsOnGroups = { "init.*" })//依赖的组执行失败时,此方法跳过</strong></span>
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Manisha";
Assert.assertEquals(message, messageUtil.salutationMessage());
}
@Test(groups = { "init" })
public void initEnvironmentTest() {
System.out.println("This is initEnvironmentTest");
}
}
下面参考:http://blog.csdn.net/wanghantong/article/details/40379983
public class TestngDependOnGroups {
@Test(groups = { "init" })
public void serverStartedOk() {
System.out.println("serverStartedOk.....");
}
@Test(groups = { "init2" })
public void initEnvironment() {
System.out.println("initEnvironment.....");
throw new RuntimeException("unexpected fail......");
}
@Test(dependsOnGroups = { "init.*" }, alwaysRun = true)
public void method1() {
System.err.println("I am over here.....");
}
}
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="framework_testng" > <test verbose="2" name="TestngDependOnGroups"> <classes> <class name="com.dragon.testng.annotation.TestngDependOnGroups"> </class> </classes> </test> </suite>
运行结果:我们发现在配置了顺序依赖之后,即使initEnvironment()方法抛出了异常,method1()还是执行了并且passed
@Test(groups = "init")
public void launchServer() {}
@Test(dependsOnGroups = "init", groups = "deploy-apps")
public void deploy() {}
<strong><span style="color:#ff0000;">@Test(dependsOnGroups = "init", groups = "deploy-apps")</span></strong>
public void deployAuthenticationServer() {}
@Test(dependsOnGroups = "deploy-apps")
public void test1() {}
@Test(dependsOnGroups = "deploy-apps")
public void test2() {}
场景2:依赖方法
public class DependencyTestUsingAnnotation {
String message = "Manisha";
MessageUtil messageUtil = new MessageUtil(message);
@Test
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Manisha";
Assert.assertEquals(message, messageUtil.printMessage());
}
<span style="color:#ff0000;"><strong> @Test(dependsOnMethods = { "initEnvironmentTest" })</strong></span><pre name="code" class="java"><span style="color:#ff0000;"><strong>//依赖的方法执行失败时,此方法跳过</strong></span>
public void testSalutationMessage() { System.out.println("Inside testSalutationMessage()");message = "Hi!" + "Manisha";Assert.assertEquals(message, messageUtil.salutationMessage()); } @Test public void initEnvironmentTest() {System.out.println("This is initEnvironmentTest"); }}
异步测试 异步代码通常出现在下列领域:
基于消息的框架,其中发送者和接收者是解耦合的。(JMS)由java.util.concurrent提供的异步机制(FutureTask)由SWT或Swing这样的工具集开发的图形用户界面,其中代码与主要的图形部分运行在不同的线程中当调用异步时有三种可能的结果:
调用完成并成功。调用完成并失败。调用没有完成。基本上,异步编程遵循着一种非常简单的模式:在发出一个请求时指定一个对象或一个函数,当收到响应时系统会调用回调。场景3:不指定回调方法
<strong>private volatile boolean success = false;
</strong><span style="color:#ff0000;">@BeforeClass</span><strong>
public void sendMessage()
{
// send the message;
// </strong><span style="color:#ff0000;">Successful completion should eventually set success to true;
}</span><strong>
</strong><span style="color:#ff0000;">@Test(timeOut = 10000)</span><strong>
public void waitForAnswer()
{
</strong><span style="color:#ff0000;">while (!success) {</span><strong>
Thead.sleep(1000);
}
}</strong>
场景4:有回调方法:
@Test(g<span style="color:#ff0000;">roups = “send”)</span>
public void sendMessage()
{
// send the message
}
@Test(timeOu<span style="color:#ff0000;">t = 10000, dependsOnGroups = {“send”})</span>
public void waitForAnswer()
{
while (!success) {
Thread.sleep(1000);
}
}
现在sendMessage()是一个@Test方法,他将包含在最终的报告中,如果发送消息失败,TestNG将跳过waitForAnswer测试方法,并把他表示为SKIP。
@Test(timeOut = 10000, invocationCount=100, successPercentage = 98)
public void waitForAnswer ……
TestNG调用该方法100次,如果98%的调用成功,就认为总体测试通过。
测试多线程代码 -并发测试
@Test(invocationCount = 100, threadPoolSize = 10)
public void testSingleton()
{
Thread.yield();
Singleton p = Singleton.getInstance();
}
@invocationCount相当简单,在不考虑并发时也可以使用:他决定了TestNG调用一个测试方法的次数。
@threadPoolSize要求TestNG分配一定数量的线程,并使用这些线程来调用这个测试方法,当一个测试完成之后,执行他的线程将归还给线程池,然后可以用于下一次调用。
并发执行
<suite name=”TestNG JDK 1.5” verbose=“1” parallel=“methods” thread-count = “2”>......</suite>thread-count属性指定了线程数目,TestNG将使用这些线程来执行这个测试套件中的所有测试方法,parallel属性告诉TestNG您在执行这些测试时希望采用的并行模式。
parallel=”methods” 在这种模式下,每个测试方法将在他自己的一个线程中执行。
parallel=”test” 在这种模式下,在某个标签内的所有测试方法将在他们自己的一个线程中执行。
在tests模式中,TestNG保证每个将在他自己的线程中执行。如果希望测试不安全的代码,这一点是非常重要的。在method模式中,所有限制都被取消,无法预测哪些方法将在同一个线程中执行,哪些方法将在不同的测试中执行。
语法@Test annotation和配置annotation(@BeforeClass, @AfterClass, @BeforeMethod…)都可以属于分组
场景5:
@Test(groups = {"group1"})
@Test(groups = {"group1", "group2"})
@Test(groups = "group1")
<strong><span style="color:#ff0000;">@Test(groups = "group2")</span></strong>
public class B
{
@Test
public test1() {}
@Test(groups = "group3")
public test2() {}
}
test1属于group2组,<span style="color:#ff0000;"><strong>test2同时属于group2组和group3组</strong></span>
分组与运行时刻
<suite name="Simple suite">
<test name="GroupTest">
<groups>
<run>
<include name="group1" />
</run>
</groups>
<classes>
<class name="com.example.A" />
</classes>
</test>
</suite>
<span style="color:#ff0000;"><strong>这个testng.xml告诉TestNG执行com.example.A类中所有属于group1组的测试方法。</strong>
</span>
在testng.xml中利用正则表达式来指定组。
<groups>
<d<span style="color:#ff0000;"><strong>efine name="all-web</strong></span>">
<include name="jsp" />
<include name="servlet" />
</define>
<run>
<include name="all-web">
</run>
</groups>
执行分组
利用Java API
TestNG tng = new TestNG(); tng.setGroups("jsp, servlet"); tng.setExcludeGroups("broken")排除失败的测试 创建一个特书的组如broken
@Test(groups = { "web", "broken"})然后在运行时刻排除这个组。
<exclude name="broken" />例子:http://blog.csdn.net/wanghantong/article/details/40380231
public class TestngDependencyOnXML {
@Test(groups = { "ss" })
public void a() {
System.out.println("this is method a, Groups ss");
}
@Test(groups = { "ss" })
public void b() {
System.out.println("this is method b, Groups ss");
}
@Test(groups = { "xx" })
public void c() {
System.out.println("this is method c ,Groups xx");
}
@Test(groups = { "xx" })
public void d() {
System.out.println("this is method d, Groups xx");
}
@Test(groups = { "yy" })
public void e() {
System.out.println("this is method e , Groups yy");
}
}
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <suite name="framework_testng"> <test name="testng-dependOnXML" > <groups > <dependencies > <group name="ss" depends-on="xx yy" /> </dependencies> </groups> <classes> <class name="com.dragon.testng.annotation.TestngDependencyOnXML" /> </classes> </test> </suite>
参考:http://blog.sina.com.cn/s/blog_64693fd401014kza.html
例如 @BeforeMethod void FuncBefore() @Test void TestCase1() @Test void TestCase2() 执行的顺序为 FuncBefore TestCase1 FuncBefore TestCase2 但是,在将TestCase放入某一个Group之后,@BeforeMethod失效了: @BeforeMethod void FuncBefore() @Test(groups = "GroupA") void TestCase1() @Test(groups = "GroupA") void TestCase2() 当我们执行GroupA的测试脚本时,执行顺序为 TestCase1 TestCase2 原因:@BeforeMethod未被包含进GroupA中,因此运行GroupA时无法执行,看似“失效”了。当未指定Group时,@BeforeTest和@Test同时被视作处于一个“全局group”,因此会执行。 解决方法: 1、将@BeforeMethod同样加入GroupA 2、设置@BeforeMethod的属性alwaysRun=true: @BeforeMethod(alwaysRun = true) void FuncBefore()
在使用组,不再面临重构的问题。只要我们不修改dependsOnGroups或组属性,我们的测试将继续运行,设立适当的依赖
dependsOnMethods的问题: 通过字符串来执行方法名称,如果将来对他进行重构,代码就有可能失效。方法名称违反了”不要重复自己”的原则,方法名称即在Java方法中用到,也在字符串中使用,另外,等我们不断添加新的测试方法时,这个测试用例伸缩性也不好。