# TestNG `@Factory`注解教程

> 原文： [https://howtodoinjava.com/testng/testng-factory-annotation-tutorial/](https://howtodoinjava.com/testng/testng-factory-annotation-tutorial/)

让我们了解 **TestNG `@Factory`注解**，该注解允许根据某些数据集或条件在运行时创建测试。

```java
Table of Contents

1\. When to use testng factory
2\. Basic testng factory example
3\. TestNG factory - test parameters
4\. TestNG @Factory with @DataProvider
5\. TestNG @Factory - dependent tests

```

## 1\. 何时使用 testng 工厂

有时我们可能需要**使用不同的数据值**运行一组测试。 为此，我们可以在 testng XML 的套件中定义一组独立的测试，并测试所需的场景。 这种方法的问题在于，如果您获得了额外的数据集，则需要重新定义测试。

TestNG 通过提供`@Factory`注解功能解决了此问题。 TestNG 中的工厂在运行时动态定义和创建测试。

工厂方法必须返回`Object`类的数组，即`Object[]`。

## 2\. 基本的 testng 工厂示例

让我们使用 TestNG 的`@Factory`注解创建一个示例程序，以了解**如何使用工厂**。

```java
public class SimpleTest 
{
	@Test
	public void simpleTest() {
		System.out.println("Simple Test Method.");
	}
}

public class SimpleTestFactory 
{
	@Factory
	public Object[] factoryMethod() {
		return new Object[] { new SimpleTest(), new SimpleTest() };
	}
}

```

上一类在其中定义了工厂方法。 通过在相应的测试方法上方声明`@Factory`来定义工厂方法。

让我们现在运行工厂。

```java
Simple Test Method.
Simple Test Method.
PASSED: simpleTest
PASSED: simpleTest

```

如您在前面的测试结果中看到的，`SimpleTestFactory`类的测试方法执行了两次。 该执行基于工厂方法返回的`Object`数组。 当所述方法返回`SimpleTest`类的两个对象时，TestNG 在指定的返回对象内部查找并在其中执行所有测试方法。 在这种情况下，由于只有一种测试方法，因此 TestNG 会执行相应的测试方法。

## 3\. TestNG 工厂参数

使用工厂方法的**主要优点之一是，您可以在初始化它们时将参数传递给测试类**。 然后，可以在上述类中存在的所有测试方法中使用这些参数。

```java
public class SimpleTest 
{
	private int param;

	public SimpleTest(int param) {
		this.param = param;
	}

	@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);
	}
}

public class SimpleTestFactory 
{
	@Factory
	public Object[] factoryMethod() {
		return new Object[] { new SimpleTest(0), new SimpleTest(1) };
	}
}

```

上一个测试类的构造器将一个参数作为整数，并将其分配给局部变量`param`。 然后，在测试类中提供的两种测试方法中使用此变量。 每个测试方法都会为`param`添加一个值，并在执行时将其打印到控制台。

现在开始运行测试。

```java
Test method one output: 2
Test method one output: 1
Test method two output: 3
Test method two output: 2

PASSED: testMethodOne
PASSED: testMethodOne
PASSED: testMethodTwo
PASSED: testMethodTwo

```

从前面的测试结果中可以看到，每个测试方法分别执行两次。 测试方法使用初始化测试类时传递的参数，并且控制台显示相应的输出。

## 4\. TestNG `@Factory`和`@DataProvider`

`@DataProvider`功能也可以与`@Factory`注解一起使用，以在运行时创建测试。 这可以通过在类的构造器或常规方法上声明`@Factory`注解来完成。

```java
public class DataProviderTest 
{
	private int param;

	@Factory(dataProvider = "dataMethod")
	public DataProviderTest(int param) {
		this.param = param;
	}

	@DataProvider
	public static Object[][] dataMethod() {
		return new Object[][] { { 0 }, { 1 } };
	}

	@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);
	}
}

```

前面的类类似于我们先前使用的测试类。 测试类的构造器带有`@Factory`注解。 此注解使用名为`dataMethod`的`DataProvider`方法为测试类的构造器提供值。 `DataProvider`方法返回一个双对象数组，其中第一个数组代表数据集，该数据集确定要迭代测试的次数，而第二个数组是每次迭代将传递给测试方法的实际参数值。 所述双对象数组包含两个数据集，其值分别为 0 和 1。

现在开始运行测试。

```java
Test method one output: 2
Test method one output: 1
Test method two output: 3
Test method two output: 2

PASSED: testMethodOne
PASSED: testMethodOne
PASSED: testMethodTwo
PASSED: testMethodTwo

```

## 5\. TestNG `@Factory` – 依赖测试

到目前为止，我们已经看到了工厂实现的不同示例。 让我们看看与工厂类一起使用时如何执行依赖方法。

```java
public class DependencyTest 
{
	private int param;

	public DependencyTest(int param) {
		this.param = param;
	}

	@Test(dependsOnMethods = { "testMethodTwo" })
	public void testMethodOne() {
		System.out.println("Test method one with param values: " + this.param);
	}

	@Test
	public void testMethodTwo() {
		System.out.println("Test method two with param values: " + this.param);
	}
}

public class SimpleTestFactory 
{
	@Factory
	public Object[] factoryMethod() 
	{
		return new Object[] { new DependencyTest(1), new DependencyTest(2) };
	}
}

```

此类包含两种测试方法`testMethodOne`和`testMethodTwo`，其中`testMethodOne`取决于`testMethodTwo`。 该类的构造器将一个参数作为整数，并将其值设置为名为`param`的内部变量。 这两种测试方法在执行时都会将其方法名称和`param`变量值一起打印到控制台。

现在开始运行测试。

```java
Test method two with param values: 2
Test method two with param values: 1
Test method one with param values: 2
Test method one with param values: 1

PASSED: testMethodTwo
PASSED: testMethodTwo
PASSED: testMethodOne
PASSED: testMethodOne

```

从前面的测试结果可以看出，`testMethodTwo`的两个实例都在`testMethodOne`的任何实例之前执行。 这是 TestNG 中工厂实现的默认行为，它将在实际测试方法之前执行从属测试方法的所有实例。

这与 TestNG 中的 **`@Factory`注解有关**。 如果您有任何疑问，请告诉我。

学习愉快！

参考：

[TestNG 文档](http://testng.org/doc/documentation-main.html)