TestNG关键特性梳理

转自:
http://www.cnblogs.com/rilley/archive/2012/11/09/2762818.html 
https://www.cnblogs.com/silence-hust/p/4539363.html

1、测试套件组件层级结构(suite--test--class--method & group)

	<suite name="ParametersTest">
	  <test name="Regression1">
	    <classes>
	      <class name="com.example.ParameterSample" />
	      <class name="com.example.ParameterTest">
	        <mtehods>
	          <include name="database.*" />
	          <exclude name="inProgress" />
	        </methods>
	      </class>
	    </classes>
	  </test>    
	  <test name="Parameters">
	    <packages>
	      <package name="test.parameters.Parameter*" />
	    </packages>
	  </test>   
	</suite>    
一个suite(套件) 由一个或多个测试组成。 
一个test(测试) 由一个或多个类组成 
一个class(类) 由一个或多个方法组成。

@BeforeSuite/@AfterSuite 在某个测试套件开始之前/在某个套件所有测试方法执行之后 
@BeforeTest/@AfterTest 在某个测试开始之前/在某个测试所有测试方法执行之后 
@BeforeClass/@AfterClass 在某个测试类开始之前/在某个类的所有测试方法执行之后 
@BeforeMethod/@AfterMethod 在某个测试方法之前/在某个测试方法执行之后 
@BeforeGroup/@AfterGroup 在某个组的所有测试方法之前/在某个组的所有测试方法执行之后


组:测试方法组:

			public class Test1 {
			  @Test(groups = { "functest", "checkintest" })
			  public void testMethod1() {
			  }
			 
			  @Test(groups = {"window.checkintest"} )
			  public void testMethod2() {
			  }
			 
			  @Test(groups = { "functest" })
			  public void testMethod3() {
			  }
			}
测试类组:
				@Test(groups = { "checkin-test" })
				public class All {
				 
				  @Test(groups = { "func-test" )
				  public void method1() { ... }
				 
				  public void method2() { ... }
				}
引用组:
定义<suite>全局的组groups:
定义属于某个<test>的组groups:
				<suite>
					<test name="Regression1">
					  <groups>
					    <define name="functest">		-----Groups of groups
					      <include name="windows"/>
					      <include name="linux"/>
					    </define>
					    <define name="all">
					      <include name="functest"/>
					      <include name="checkintest"/>
					    </define>
					    <run>
					      <include name="all"/>	    -------<run>
					    </run>
					  </groups>
					  <classes>
					    <class name="test.sample.Test1"/>
					  </classes>
					</test>
				</suite>
以上:执行test.sample.Test1类中<include name="all"/>的分组

测试执行:略:命令行、ant、maven、Java API...

2、@Test(expectedExceptions  

    @Test(expectedExceptions = {ReservationException.class, FlightCanceledException.class})  
    public void shouldThrowIfPlaneIsFull()   
    {  

3、参数化测试---数据驱动式测试 @Parameters("myName")、@DataProvider  

  
    两种方法:  
        利用@Parameters传递参数:
            可以在suite--test--class--method & group等不同的层级定义参数,如在suite层级:  
                测试类:  
                            public class ParameterizedTest1 {    
                                @Test    
                                @Parameters("myName")    
                                public void parameterTest(String myName) {    
                                    System.out.println("Parameterized value is : " + myName);    
                                }    
                            }    
                testng.xml:  
                            <suite name="Suite1">    
                                <test name="test1">    
                                    <parameter name="myName" value="manisha"/>     
                                    <classes>    
                                        <class name="ParameterizedTest1" />    
                                    </classes>    
                                </test>    
                            </suite>    
利用@DataProvider传递参数:  
    测试类:  
            @Test(dataProvider = "range-provider")  
            public void testIsBetWeen(int n, int lower, int upper, boolean expected)  
            {  
              println("Received " + n + " " + lower + "-" + upper + " expected: " + expected);  
              assert.assertEquals(expected, isBetween(n, lower, upper));  
            } 
    DataProvider:  
            @DataProvider(name = "range-provider")  
            public Object[][] rangeData()  
            {  
              int lower = 5;  
              int upper = 10;  
  
              return new Object[][] {  
                { lower-1, lower, upper, false},  
                { lower, lower, upper, true},  
                { lower+1, lower, upper, true},  
                { upper, lower, upper, true},  
                { upper+1, lower, upper, false},  
              };  
            }  
如何构造一个DataProvider:  
  
    入参:数据提供者本身可以接受两个类型的参数:Method和ITestContext  
        @DataProvider  
        public Object[][] craete() { ... }  
  
        @DataProvider  
        public Object[][] create(Method method) { ... }  
  
        @DataProvider  
        public Object[][] create(ITestContext context) { ... }  
  
        @DataProvider  
        public Object[][] create(Method method, ITestContext context) { ... }  
            Method:java.lang.reflect.Method,将调用的测试方法  
            ITestContext:当前的测试上下文,是运行时刻的信息,不是静态的信息,这使得数据提供者能够知道当前测试执行的运行时刻参数,如context.getIncludeGroups()可以获取测试函数所属的group列表  

返回类型:  
    1、Object[][]  
    2、Iterator----延迟数据提供者 ***

            @DataProvider(name = "generate-accounts-lazy")  
            public Iterator generateAccountsLazy  
            {  
              return new AccountIterator();  
            }  
  
            @Test(dataProvider = "generate-accounts-lazy")  
            public void testAccount(Account a)  
            {  
              System.out.println("Testing account " + a);  
            }  
  
            class AccountIterator implements Iterator  
            {  
              private static final int MAX = 4;  
              private int index = 0;  
  
              public boolean hasNext()  
              {  
                return index < MAX;  
              }  
  
              public Object next()  
              {  
                return new Object[] { new Account(index++); }   
              }  
  
              public void remove()  
              {  
                throw new UnsupportedOperationException();   
              }  
            }  

4、@Factory详解------如何进行参数值变化性测试  

    采用工厂的方法来创建测试数据并配合完成测试  
  
    简单使用:  
                    public class SimpleTest {  
                        @Test  
                        public void simpleTest1(){  
                            System.out.println("simple test one");  
                        }  
                        @Test  
                        public void simpleTest2(){  
                            System.out.println("simple test two");  
                        }  
                    }  
                        
                    public class SimpleTestFactory  
                    {  
                      @Factory  
                      public Object[] factoryMethod() {  
                        return new Object[] { new SimpleTest(), new SimpleTest() };  
                      }  
                    }  

                    //被执行的测试类为:SimpleTestFactory。SimpleTestFactory工厂类,在带有@Factory注解的方法中调用被执行的测试类,TestNg会自动调用被执行类中带有@Test注解的方法。 

简单使用2:  
  
        使用@Factory最大的好处就是可以在初始化的时候将参数传给测试类:  

                public class SimpleTest {  
                    private int para;  
                    public SimpleTest(int para) {  
                        this.para = para;  
                    }  
                        
                    @Test  
                    public void testMethodOne(){  
                        int value = para + 1;  
                        System.out.println("Test method one output: " + value);  
                    }  
                    @Test  
                    public void testMethodTwo(){  
                        int value = para + 2;  
                        System.out.println("Test method two output: " + value);  
                    }  
                }  
                   
                public class SimpleTestFactory {  
                       
                    @Factory  
                    public Object[] factoryMethod(){  
                        return new Object[] { new SimpleTest(0), new SimpleTest(10)};  
                    }  
                }  
结合DataProvider???未测试:  
                public class DataProviderTest  
                {  
                  private int param;  
                     
                  @Factory(dataProvider = "dataMethod")  
                  public DataProviderTest(int param) {  
                    this.param = param;  
                  }  
                     
                  @DataProvider  
                  public static Object[][] dataMethod() {  
                    return new Object[][] { new Object[]{ 0 }, new Object[]{ 10 } };  
                  }  
                     
                  @Test  
                  public void testMethodOne() {  
                    int opValue = param + 1;  
                    System.out.println("Test method one output: " + opValue);  
                  }  
                     
                  @Test  
                  public void testMethodTwo() {  
                    int opValue = param + 2;  
                    System.out.println("Test method two output: " + opValue);  
                  }  
                }  
5、异步消息测试 @Test(timeOut = 10000  
  
        a\预先发消息:@beforexx,send & sleep,#dependon  
        b\  
            有回调方法:在测试方法中,监视返回结果  
            没有回调方法:定期检查预期的值。如果过了一段时间还没有检查到预期值,就失败并退出。  
  
        private volatile boolean success = false;  
  
        @Test(groups = “send”)  
        public void sendMessage()  
        {  
          // send the message  
        }  
  
        @Test(timeOut = 10000, dependsOnGroups = {“send”})  
        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%的调用成功,就认为总体测试通过。  

6、并发测试 @Test(invocationCount = 100, threadPoolSize = 10) 、 <suite parallel=“methods” thread-count = “2”>  

  

    法一:  

        private Singleton singleton;  
  
        @Test(invocationCount = 100, threadPoolSize = 10)  
        public void testSingleton()  
        {  
          Thread.yield();  
          Singleton p = Singleton.getInstance();  
        }  
  
        public static Singleton getInstance()  
        {  
          if (instance == null) {  
            Thread.yield();  
            Assert.assertNull(instance);  
            instance = new Singleton();  
          }  
          return instance;  
        }  

  
        //@invocationCount相当简单,在不考虑并发时也可以使用:他决定了TestNG调用一个测试方法的次数。  

        //@threadPoolSize要求TestNG分配一定数量的线程,并使用这些线程来调用这个测试方法  

法二:  

    <suite name=”TestNG JDK 1.5” verbose=“1” parallel=“methods” thread-count = “2”>......</suite>  
    thread-count属性指定了线程数目,TestNG将使用这些线程来执行这个测试套件中的所有测试方法  
    parallel属性告诉TestNG您在执行这些测试时希望采用的并行模式。  
        =”methods” 在这种模式下,每个测试方法将在他自己的一个线程中执行。  
        =”test” 在这种模式下,在某个标签内的所有测试方法将在他们自己的一个线程中执行。  
            如果希望测试不安全的代码,这一点是非常重要的。在method模式中,所有限制都被取消,无法预测哪些方法将在同一个线程中执行,哪些方法将在不同的测试中执行。  

7、依赖测试 @Test(dependsOnGroups、dependsOnMethods)  



DRY原则:  

        public class CreditCardTest  
        {  
          @Test(groups = "web.credit-card")  
          public void test1() {}  
  
          @Test(groups = "web.credit-card")  
          public void test2() {}  
        }  
        替换为:  
        @Test(groups = "web.credit-card")  
        public class CreditCardTest  
        {  
          public void test1() {}  
          public void test2() {}  
        } 
        减少维护成本  


annotation继承:  

        @Test(groups = "web.credit-card")  
        class BaseWebTest {}  
  
        public class WebTest extends BaseWebTest   
        {  
          public test1() {}  
          public test2() {}  
        }  
        所有扩展自BaseWebTest的类都会看到,他们所有的工有方法都自动成为web.credit-card组的成员。  
        WebTest变成了一个普通的传统Java对象(POJO),不带任何annotation。  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值