Рубрики
Без рубрики

Учебное пособие по тестированию

Тестирование-это платформа тестирования для Java-приложений, вдохновленная JUnit и NUnit. TestNG TestNG предоставляет множество функций, которые облегчают написание

Автор оригинала: 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) {
}

Обратите внимание, что сначала выполняются методы с более низким приоритетом.

Резюме

Тестирование-очень популярная платформа модульного тестирования, и мне очень понравилось, что ее очень легко настроить и использовать в проекте. Мы изучили основы тестирования и рассмотрели наиболее распространенные примеры его использования в нашем проекте.