2014-09-28 96 views
1

我有幾個類文件需要用testng執行,當我把標籤中的每一個東西都貼上標籤時,執行變得隨機導致執行失敗。testng在測試中保存順序

下面是我的TestNG的文件

<suite name="shakeout" parallel="tests" thread-count="1"> 

    <test name="test1" preserve-order="true"> 
    <parameter name="deviceCategory" value="iPhone"> 
    <parameter name="deviceId" value="<IMEI NO>"> 
    <classes> 
    <class name="com.test1.setup.SetUp"> 
    <class name="com.test2.signin.SignIn"> 
    <classes> 
</test> 
</suite> 

這裏的「設置」類必須執行,其次是「簽到」,然而執行發生隨機和整體測試情況是越來越失敗。

+0

有時候當然不可能避免,但是,你知道,測試的訂單要求是代碼味道。這種排序,具體來說,被稱爲[時間耦合](https://www.google.com/search?q=temporal+coupling)。在你的情況下,它可能在代碼中,或者它可能只在測試中。無論如何,這可能是值得處理的。 – acdcjunior 2014-09-28 17:48:33

+0

爲了在一個序列中執行需要做些什麼改變? – Badrinath 2014-09-28 17:59:12

回答

0

我已經創建了AssignTestPriorityTransformer來解決這個問題。

從主類中調用:

TestNG ng = new TestNG(); 
ng.setAnnotationTransformer(new AssignTestPriorityTransformer()); 
ng.run(); 

這裏是類:

import java.lang.reflect.Constructor; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import javassist.*; 

import org.testng.IAnnotationTransformer; 
import org.testng.annotations.ITestAnnotation; 

public class AssignTestPriorityTransformer implements IAnnotationTransformer 
{ 
    static ClassPool s_ClassPool = ClassPool.getDefault(); 
    static Map<String, Integer> classesForPriority = new HashMap<String, Integer>(); 
    static Map<String, Integer> methodsForPriority = new HashMap<String, Integer>(); 
    static int num=1; 

    public void transform(ITestAnnotation p_annotation, Class p_testClass, Constructor p_testConstructor, Method p_testMethod) 
    { 
     int keyValue; 
     //every class gets number which will be added in front of priority number 
     if (classesForPriority.isEmpty()) 
     { 
      classesForPriority.put(p_testMethod.getDeclaringClass().getCanonicalName(), num); 
      keyValue=num; 
      num++; 
     } 
     else 
     { 
       if (classesForPriority.get(p_testMethod.getDeclaringClass().getCanonicalName())==null){ 
        classesForPriority.put(p_testMethod.getDeclaringClass().getCanonicalName(), num); 
        keyValue=num; 
        num++; 
       } 
       else 
        keyValue=classesForPriority.get(p_testMethod.getDeclaringClass().getCanonicalName()); 
     } 


     // get the order number of method in the class 
     int priorityInt = getMethodLineNumber(p_testMethod); 
     //transform number to include class number at the beginning plus additional number for meaking the ordering correct 
     String priorityString = Integer.toString(priorityInt); 
     if (priorityString.length()==1) 
      priorityString=keyValue + "1000" + priorityString; 
     else if (priorityString.length()==2) 
      priorityString=keyValue + "100" + priorityString; 
     else if (priorityString.length()==3) 
      priorityString=keyValue + "10" + priorityString; 
     else if (priorityString.length()>=4) 
      priorityString=keyValue + "1" + priorityString; 

     priorityInt = Integer.parseInt(priorityString); 
     p_annotation.setPriority(priorityInt); 
     //p_annotation.setPriority(getMethodLineNumber(p_testMethod));  
     //System.out.println(p_testMethod.getDeclaringClass().getCanonicalName() + "." + p_testMethod.getName() + " has priority: " + priorityInt); 
    } 
    private int getMethodLineNumber(Method p_testMethod) 
    { 
     try 
     { 
      CtClass cc = s_ClassPool.get(p_testMethod.getDeclaringClass().getCanonicalName()); 
      CtMethod methodX = cc.getDeclaredMethod(p_testMethod.getName()); 
      //System.out.println("*******" + p_testMethod.getName() + " has priority " + methodX.getMethodInfo().getLineNumber(0) + "*******"); 
      //populate map with method names and orders 
      CtMethod[] m = cc.getDeclaredMethods(); 
      if (methodsForPriority.get(methodX.toString())==null) { 
       for (int i = 0; i < m.length; i++) { 
        methodsForPriority.put(m[i].toString(), i+1); 
        //System.out.println(m[i].toString() + methodsForPriority.get(m[i].toString())); 
       } 
      } 
      //int methodNumberInClass = methodsForPriority.get(methodX.toString()); 
      return methodsForPriority.get(methodX.toString());//methodX.getMethodInfo().getLineNumber(0);   
     } 
     catch(Exception e) 
     { 
      throw new RuntimeException("Getting of line number of method "+p_testMethod+" failed", e); 
     } 
    } 
} 
0

你爲什麼不定義它們(「設置」類必須執行,其次是「簽到」 )在suite標籤中有一個preserve-order =「true」屬性的不同「測試」塊中?