Автор оригинала: Pankaj Kumar.
Тестирование-это платформа тестирования для Java-приложений, вдохновленная JUnit и NUnit.
Тестирование
Тестирование предоставляет множество функций, которые упрощают написание и запуск тестовых случаев:
- Аннотации на основе
- Плагины для основных IDE, таких как Eclipse и IDEA.
- Автоматическое создание наборов тестов
- Создание отчетов на основе HTML
- Возможность запуска одного метода тестирования с использованием плагинов IDE.
- Тестирование на основе данных с использованием
@dataProvider - Никаких дополнительных зависимостей для запуска и ведения журнала
- XML-файл TestNG для запуска наборов тестов с различными конфигурациями
Проверка зависимости Maven
Библиотеки тестирования присутствуют в репозитории maven, вы можете добавить ниже зависимость maven, чтобы включить тестирование в свой проект.
org.testng testng 6.14.3 test
Плагин TestNG Eclipse
Я использую Eclipse для тестирования примера проекта, поэтому давайте сначала установим плагин TestNG Eclipse.
Перейдите в раздел “Eclipse Marketplace” и найдите раздел “Тестирование”.
Нажмите “Установить” и перейдите к дальнейшим экранам, чтобы установить его. Вам придется принять его лицензионное соглашение и перезапустить Eclipse после завершения установки.
Перейдите в раздел “Окно | Показать вид | Другое”, и внутри “Java” вы должны увидеть “Тестирование”.
Это означает, что TestNG для Eclipse успешно установлен, и мы готовы создать наши тестовые классы TestNG.
Создать класс TestNG
Перейдите к своему проекту в проводнике и нажмите “Создать | Другое”, выберите “Класс TestNG” и нажмите “Далее”.
На следующем экране мы должны указать конфигурации нашего класса тестирования, выбрать аннотации для включения в класс и нажать кнопку “Готово”.
Это создаст класс скелета тестирования, как показано ниже.
package com.journaldev.utils;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
public class TestUtils {
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
}
@BeforeMethod
public void beforeMethod() {
}
@AfterMethod
public void afterMethod() {
}
@DataProvider
public Object[][] dp() {
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
};
}
@BeforeClass
public void beforeClass() {
}
@AfterClass
public void afterClass() {
}
@BeforeTest
public void beforeTest() {
}
@AfterTest
public void afterTest() {
}
@BeforeSuite
public void beforeSuite() {
}
@AfterSuite
public void afterSuite() {
}
}
Вот и все, мы можем запустить наш базовый класс тестирования, перейдя в “Выполнить как | Тестовый тест”, как показано на рисунке ниже.
Поскольку в нашем тестовом классе ничего нет, он должен пройти все тесты. Вы можете проверить “Консоль” на наличие созданных журналов, а “Просмотр тестирования” покажет вам основные сведения о вашем тестовом запуске.
Поток набора тестов TestNG
Я добавил некоторые консольные журналы в аннотированные методы, чтобы понять ход выполнения тестирования.
package com.journaldev.utils;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
public class TestUtils {
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
System.out.println("Inside @Test");
}
@BeforeMethod
public void beforeMethod() {
System.out.println("Inside @BeforeMethod");
}
@AfterMethod
public void afterMethod() {
System.out.println("Inside @AfterMethod");
}
@DataProvider
public Object[][] dp() {
System.out.println("Inside @DataProvider");
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
};
}
@BeforeClass
public void beforeClass() {
System.out.println("Inside @BeforeClass");
}
@AfterClass
public void afterClass() {
System.out.println("Inside @AfterClass");
}
@BeforeTest
public void beforeTest() {
System.out.println("Inside @BeforeTest");
}
@AfterTest
public void afterTest() {
System.out.println("Inside @AfterTest");
}
@BeforeSuite
public void beforeSuite() {
System.out.println("Inside @BeforeSuite");
}
@AfterSuite
public void afterSuite() {
System.out.println("Inside @AfterSuite");
}
}
Когда я запускаю его снова, ниже генерируются журналы консоли.
[RemoteTestNG] detected TestNG version 6.14.3
Inside @BeforeSuite
Inside @BeforeTest
Inside @BeforeClass
Inside @DataProvider
Inside @BeforeMethod
Inside @Test
Inside @AfterMethod
Inside @BeforeMethod
Inside @Test
Inside @AfterMethod
Inside @AfterClass
Inside @AfterTest
PASSED: f(1, "a")
PASSED: f(2, "b")
===============================================
Default test
Tests run: 2, Failures: 0, Skips: 0
===============================================
Inside @AfterSuite
===============================================
Default suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Основываясь на приведенных выше выводах, мы можем вывести поток тестирования теста как:
BeforeSuite -> BeforeTest -> BeforeClass -> DataProvider ->
{ BeforeMethod -> Test -> AfterMethod } * N
-> AfterClass -> AfterTest -> AfterSuite
N-это количество раз, когда выполняется наш метод тестирования, и это зависит от количества входных данных, сгенерированных методом @dataProvider .
Мы можем использовать методы @BeforeXXX для некоторой предварительной обработки и инициализации ресурсов, которые мы хотим использовать в наборе тестов. Аналогично, мы можем использовать @AfterXXX методы для последующей обработки и закрытия ресурсов.
Учебное пособие по тестированию
Теперь, когда мы ознакомились с основами тестирования и настроили его в Eclipse, давайте создадим класс с несколькими методами и используем TestNG для запуска некоторых тестовых случаев на нем.
package com.journaldev.utils;
public class Utils {
public static String NAME = "";
public int add(int x, int y) {
return x + y;
}
public int subtract(int x, int y) {
return x - y;
}
public static void setName(String s) {
System.out.println("Setting NAME to " + s);
NAME = s;
}
}
Я добавил несколько общедоступных методов, а также статические и пустые методы. Ниже приведен мой класс TestNG для тестирования этих методов.
package com.journaldev.utils;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestUtils {
@Test(dataProvider = "dp")
public void test_add(Integer x, Integer y) {
Utils u = new Utils();
Assert.assertEquals(u.add(x, y), x + y);
}
@Test(dataProvider = "dp")
public void test_subtract(Integer x, Integer y) {
Utils u = new Utils();
Assert.assertEquals(u.subtract(x, y), x - y);
}
@Test(dataProvider = "dpName")
public void test_setName(String s) {
Utils.setName(s);
Assert.assertEquals(Utils.NAME, s);
}
@DataProvider
public Object[][] dp() {
return new Object[][] { new Object[] { 1, 1 }, new Object[] { 2, 2 }, };
}
@DataProvider
public Object[][] dpName() {
return new Object[][] { new Object[] { "Utils" }, new Object[] { "MyUtils" }, };
}
}
Теперь, когда мы запускаем выше класса в качестве теста TestNG, мы получаем следующий вывод в консоли.
[RemoteTestNG] detected TestNG version 6.14.3
Setting NAME to Utils
Setting NAME to MyUtils
PASSED: test_add(1, 1)
PASSED: test_add(2, 2)
PASSED: test_setName("Utils")
PASSED: test_setName("MyUtils")
PASSED: test_subtract(1, 1)
PASSED: test_subtract(2, 2)
===============================================
Default test
Tests run: 6, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 6, Failures: 0, Skips: 0
===============================================
Обновите проект, и вы увидите вновь созданный каталог тестовый вывод .
Открыть index.html в любом браузере, и вы должны увидеть HTML-отчет, как показано на рисунке ниже.
Набор XML-тестов TestNG
Одной из лучших частей тестирования является автоматическое создание xml-файла набора тестов.
Мы можем отредактировать его и добавить в него параметры, мы также можем использовать его для запуска одного метода тестирования. XML-пакет TestNG предоставляет множество опций, и он очень полезен, когда вы хотите запустить тестовый случай через командную строку, например, на сервере без Eclipse. Мы можем запустить xml-файл набора тестов TestNG, используя приведенную ниже команду:
$java com.journaldev.utils.TestUtils testng.xml
TestNG XML-очень обширная тема, если вы хотите изучить ее подробнее, просмотрите ее документацию .
Тестирование Выполняется Одним Методом Тестирования
Мы также можем запустить один метод тестирования, это очень полезно, когда в нашем тестовом классе много методов, и мы заинтересованы только в том, чтобы протестировать несколько из них.
Тестирование Тестирование с ошибками
Давайте посмотрим, что произойдет, когда в нашем коде появится ошибка, измените метод Utils class setName , как показано ниже.
public static void setName(String s) {
System.out.println("Setting NAME to " + s);
// NAME = s; //introducing bug intentionally
}
Теперь, когда мы снова запускаем тестовый класс, мы получаем следующий вывод в консоли.
[RemoteTestNG] detected TestNG version 6.14.3
Setting NAME to Utils
Setting NAME to MyUtils
FAILED: test_setName("Utils")
java.lang.AssertionError: expected [Utils] but found []
at org.testng.Assert.fail(Assert.java:96)
at org.testng.Assert.failNotEquals(Assert.java:776)
at org.testng.Assert.assertEqualsImpl(Assert.java:137)
at org.testng.Assert.assertEquals(Assert.java:118)
at org.testng.Assert.assertEquals(Assert.java:453)
at org.testng.Assert.assertEquals(Assert.java:463)
at com.journaldev.utils.TestUtils.test_setName(TestUtils.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
FAILED: test_setName("MyUtils")
java.lang.AssertionError: expected [MyUtils] but found []
at org.testng.Assert.fail(Assert.java:96)
at org.testng.Assert.failNotEquals(Assert.java:776)
at org.testng.Assert.assertEqualsImpl(Assert.java:137)
at org.testng.Assert.assertEquals(Assert.java:118)
at org.testng.Assert.assertEquals(Assert.java:453)
at org.testng.Assert.assertEquals(Assert.java:463)
at com.journaldev.utils.TestUtils.test_setName(TestUtils.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Вы заметили, что я запускаю тест только для метода setName.:)
Запуск тестов TestNG из командной строки
Хорошо, что мы можем запускать наши тестовые случаи из Eclipse, но в большинстве случаев мы хотим запускать все тестовые случаи проекта при его создании. Что ж, maven автоматически запускает тестовые примеры для нас. На изображениях ниже показан вывод команды mvn clean install .
Пример Успеха
Случай Отказа
Порядок Тестирования Тестовых Случаев
Тестовые случаи тестирования выполняются в порядке их имен методов. Таким образом, в нашем случае порядок выполнения будет следующим: test_add -> test_setName -> test_subtract .
Мы можем изменить порядок, установив приоритет методов тестирования. Если нам нужен порядок выполнения как test_add -> test_subtract -> Имя набора тестов , мы можем изменить нашу аннотацию @Test, как показано ниже.
@Test(dataProvider = "dp", priority=1)
public void test_add(Integer x, Integer y) {
}
@Test(dataProvider = "dp", priority=2)
public void test_subtract(Integer x, Integer y) {
}
@Test(dataProvider = "dpName", priority=3)
public void test_setName(String s) {
}
Обратите внимание, что сначала выполняются методы с более низким приоритетом.
Резюме
Тестирование-очень популярная платформа модульного тестирования, и мне очень понравилось, что ее очень легко настроить и использовать в проекте. Мы изучили основы тестирования и рассмотрели наиболее распространенные примеры его использования в нашем проекте.