Порядок виконання тестів у TestNG


76

Як налаштувати порядок виконання тестів у TestNG?

Наприклад:

public class Test1 {
  @Test
  public void test1() {
      System.out.println("test1");
  }

  @Test
  public void test2() {
      System.out.println("test2");
  }

  @Test
  public void test3() {
      System.out.println("test3");
  }
}

У вищевказаному наборі порядок виконання тестів є довільним. Для одного виконання результатом може бути:

test1
test3
test2

Як мені виконати тести в тому порядку, в якому вони були написані?

Відповіді:


84

Це спрацює.

@Test(priority=1)
public void Test1() {

}

@Test(priority=2)
public void Test2() {

}

@Test(priority=3)
public void Test3() {

}

priorityзаохочує наказ про виконання, але не гарантує, що попередній рівень пріоритету виконаний. test3може початися до test2завершення. Якщо потрібна гарантія, оголосіть залежність.

На відміну від рішень, які оголошують залежності, тести, які використовують, priorityбудуть виконуватися, навіть якщо один тест не вдається. Цю проблему із залежностями можна вирішити @Test(...alwaysRun = true...)відповідно до документації .


65

У TestNG ви використовуєте dependOnMethods та / або dependOnGroups:

@Test(groups = "a")
public void f1() {}

@Test(groups = "a")
public void f2() {}

@Test(dependsOnGroups = "a")
public void g() {}

У цьому випадку g () буде працювати лише після завершення та успіху f1 () та f2 ().

Багато прикладів ви знайдете в документації: http://testng.org/doc/documentation-main.html#test-groups


Однак рішення Седріка має деякі недоліки при роботі з плагіном TestNG Eclipse, версія. 5.9.0.4, як і раніше, кожен запуск TestCase показує повідомлення про те, що групи не підтримуються цим плагіном.
honzajde

2
dependsOnGroupsнадзвичайно корисний, але мені здається, що TestNG ігнорує, priorityколи обидва поєднуються разом.
Г. Демецький,

29

Щоб розглянути конкретний сценарій, про який йдеться:

@Test
public void Test1() {

}

@Test (dependsOnMethods={"Test1"})
public void Test2() {

}

@Test (dependsOnMethods={"Test2"})
public void Test3() {

}

7

Якщо ви не хочете використовувати @Test(priority = )опцію в TestNG, ви можете скористатися бібліотекою javaassist і TestNG, IMethodInterceptorщоб визначити пріоритети тестів відповідно до порядку, в якому методи тестування визначені в класі тесту. Це базується на наведеному тут рішенні .

Додайте цього слухача до свого тестового класу:

package cs.jacob.listeners;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;

public class PriorityInterceptor implements IMethodInterceptor {
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {

    Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() {
        private int getLineNo(IMethodInstance mi) {
        int result = 0;

        String methodName = mi.getMethod().getConstructorOrMethod().getMethod().getName();
        String className  = mi.getMethod().getConstructorOrMethod().getDeclaringClass().getCanonicalName();
        ClassPool pool    = ClassPool.getDefault();

        try {
            CtClass cc        = pool.get(className);
            CtMethod ctMethod = cc.getDeclaredMethod(methodName);
            result            = ctMethod.getMethodInfo().getLineNumber(0);
        } catch (NotFoundException e) {
            e.printStackTrace();
        }

        return result;
        }

        public int compare(IMethodInstance m1, IMethodInstance m2) {
        return getLineNo(m1) - getLineNo(m2);
        }
    };

    IMethodInstance[] array = methods.toArray(new IMethodInstance[methods.size()]);
    Arrays.sort(array, comparator);
    return Arrays.asList(array);
    }
}

Це в основному з’ясовує номери рядків методів і сортує їх за зростанням номера їх рядків, тобто порядок, за яким вони визначаються в класі.


1
Це справжнє рішення, якщо вам доведеться перенести кілька сотень тестів з junit
Vitali Carbivnicii

Це вирішує проблему збереження замовлення у випадку, коли ви не використовуєте прапор залежності в коді.
Анкіт Гупта,

7

Використовуй це:

public class TestNG
{
        @BeforeTest
        public void setUp() 
        {
                   /*--Initialize broowsers--*/

        }

        @Test(priority=0)
        public void Login() 
        {

        }

        @Test(priority=2)
        public void Logout() 
        {

        }

        @AfterTest
        public void tearDown() 
        {
                //--Close driver--//

        }

}

Зазвичай TestNG надає кількість анотацій, які ми можемо використовувати @BeforeSuite, @BeforeTest, @BeforeClassдля ініціалізації браузерів / налаштування.

Ми можемо призначити пріоритет, якщо ви написали у своєму сценарії кількість тестових кейсів і хочете виконати відповідно до призначеного пріоритету, тоді використовуйте: @Test(priority=0)починаючи з 0,1,2,3 ....

Тим часом ми можемо згрупувати кількість тестових кейсів і виконати його групуванням. для цього ми будемо використовувати@Test(Groups='Regression')

Наприкінці, як закриття браузерів, ми можемо використовувати @AfterTest, @AfterSuite, @AfterClassанотації.


6
@Test(dependsOnMethods="someBloodyMethod")

3
Я можу зазначити, що це не особливо корисна відповідь - я пропоную розширити ваші відповіді трохи докладніше!

4

Якщо я правильно розумію ваше запитання в тому, що ви хочете запускати тести у визначеному порядку, можна використовувати TestNG IMethodInterceptor. Погляньте на http://beust.com/weblog2/archives/000479.html, як їх використовувати.

Якщо ви хочете запустити певну попередню ініціалізацію, загляньте на IHookable http://testng.org/javadoc/org/testng/IHookable.html та відповідний потік http://groups.google.com/group/testng-users/browse_thread/ потік / 42596505990e8484 / 3923db2f127a9a9c? lnk = gst & q = IHookable # 3923db2f127a9a9c


2

Piggy резервне копіювання відповіді користувача user1927494: Якщо ви хочете запустити один тест перед усіма іншими, ви можете зробити це:

@Test()
public void testOrderDoesntMatter_1() {
}

@Test(priority=-1)
public void testToRunFirst() {
}

@Test()
public void testOrderDoesntMatter_2() {
}

2

Вказавши методи тестування, які будуть виконуватися в testNg.xml, ми можемо виконувати тестові кейси в бажаному порядку

<suite>
<test name="selenium1">
 		<classes>
			<class name="com.test.SeleniumTest" >
			    <methods><include name="methodB"></include>
			        <include name="methodA"></include>
			    </methods>    
			 </class>
		</classes>
 
	</test>
</suite>


1

Використовуючи параметр пріоритету для @Test, ми можемо контролювати порядок виконання тесту.


2
На жаль, не в TestNG.
Mariusz Jamro

@MariuszJamro Я не розумію, чому? Priorityпараметр ще не існував у 2012 році?
G. Demecki

1

Впорядкування методів у файлі класу непередбачуване, тому вам потрібно або використовувати залежності, або явно включати свої методи в XML.

За замовчуванням TestNG запускає ваші тести в тому порядку, в якому вони знайдені у файлі XML. Якщо ви хочете, щоб класи та методи, перелічені у цьому файлі, працювали у непередбачуваному порядку, встановіть для атрибута збереження порядку значення


1

Я зіткнувся з тією ж проблемою, можлива причина пов’язана з паралельним виконанням testng, а рішення полягає в додаванні опції Пріоритет або просто оновлення зберіг-замовлення = "true" у вашому testng.xml.

<test name="Firefox Test" preserve-order="true">

1
save-order = "true", за замовчуванням у testng.xml, і він працює лише для того порядку, який ви визначили у testng.xml, тому вирішення вашої проблеми лише додає пріоритет @Tests
Кіран,

1

Відповідь із важливим поясненням:

Існує два параметри " TestNG ", які повинні визначати порядок виконання тестів:

@Test(dependsOnGroups= "someGroup")

І:

@Test(dependsOnMethods= "someMethod")

В обох випадках ці функції залежатимуть від методу або групи,

Але відмінності:

В цьому випадку:

@Test(dependsOnGroups= "someGroup")

Метод буде залежати від усієї групи, тому необов'язково, що відразу після виконання залежної функції цей метод також буде виконаний, але це може відбутися пізніше під час запуску та навіть після запуску інших тестів.

Важливо зазначити, що у випадку, якщо в цьому наборі тестів використовується один і той же набір параметрів, це безпечний рецепт проблем, оскільки спочатку запускатимуться залежні методи усього набору тестів, і лише потім методи, що залежать від них.

Однак у цьому випадку:

@Test(dependsOnMethods= "someMethod")

Навіть якщо цей параметр використовується більше одного разу в рамках одного набору тестів, залежний метод все одно буде виконаний після негайного виконання залежного методу.

Сподіваюся, це зрозуміло і допоможе.


0

Існують способи виконання тестів у заданому порядку. Зазвичай, тести повинні бути повторюваними та незалежними, щоб гарантувати, що це тестування лише бажаної функціональності та не залежить від побічних ефектів коду поза тестуванням.

Отже, щоб відповісти на ваше запитання, вам потрібно буде надати більше інформації, наприклад, ЧОМУ важливо проводити тести в певному порядку.


19
Є багато ситуацій, коли залежності корисні, особливо для інтеграції та функціонального тестування. Наприклад, тестування веб-сайту: спочатку потрібно протестувати сторінку входу, а потім наступну сторінку тощо ... Очищати та відтворювати стан з нуля весь час недоцільно і веде до дуже повільних тестів. Крім того, залежності дають вам набагато кращу діагностику, наприклад, "1 тест не вдався, 99 тестів пропущено" замість традиційного "100 тестів не вдалося", що не допомагає зрозуміти, що всі ці помилки насправді тому, що один тест не вдався.
Седрік Беуст,

0

Якщо ви випадково використовуєте додаткові речі, наприклад dependsOnMethods, вам може знадобитися визначити весь потік @Test у вашому файлі testng.xml. AFAIK, порядок, визначений у вашому XML-файлі набору (testng.xml), замінить усі інші стратегії замовлення.


0

використання: save-order = "true" enabled = "true", який запускав би тестові кейси таким чином, як ви писали.

<suite name="Sanity" verbose="1" parallel="" thread-count="">   
<test name="Automation" preserve-order="true"  enabled="true">
        <listeners>
            <listener class-name="com.yourtest.testNgListner.RetryListener" />
        </listeners>
        <parameter name="BrowserName" value="chrome" />
        <classes>
            <class name="com.yourtest.Suites.InitilizeClass" />
            <class name="com.yourtest.Suites.SurveyTestCases" />
            <methods>
                <include name="valid_Login" />
                <include name="verifyManageSurveyPage" />
                <include name="verifySurveyDesignerPage" />
                <include name="cloneAndDeleteSurvey" />
                <include name="createAndDelete_Responses" />
                <include name="previewSurvey" />
                <include name="verifySurveyLink" />
                <include name="verifySurveyResponses" />
                <include name="verifySurveyReports" />
            </methods>
        </classes>
    </test>
</suite>

-5

Такі тести, як одиничні? Для чого? Тести ПОВИННІ бути незалежними, інакше .... Ви не можете запускати тест індивідуально. Якщо вони незалежні, навіщо взагалі втручатися? Плюс - що таке "замовлення", якщо ви запускаєте їх у декількох потоках на декількох ядрах?


2
Насправді цілком можливо змішати залежності та паралелізм. Погляньте на цю статтю, щоб дізнатись, як це робить TestNG
Седрік

Люди використовують JUnit для багатьох речей, крім модульних тестів. Майже у всіх цих додаткових випадках існують випадки, коли вам потрібно робити речі в певному порядку. Це одне з основних обґрунтувань для розробки TestNG, BTW.
Джеффікінс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.