TestNG 自动化框架在本地单独运行测试



我是TestNG的初学者。我目前在一家拥有本土 API 自动化框架的公司工作。我习惯于在本地和使用黄瓜时隔离运行我的测试用例。然而,在这个框架中,事情是非常紧密耦合的。让我简要介绍一下框架的不同方面:

测试数据管理:测试数据通过属性文件读取。所有测试用例数据都使用每个 api 模块的键值列在属性中。按键的编号方式按测试用例类型和附加的计数器进行。所以例如:

example.properties

.....
.....
getTestCase38=TC_ID_38
getDescription38= Description_38
getUserID38=<some value>
getUserType38=<some value>
expectedUserType38=<some value>
getTestCase39=TC_ID_39
getDescription39= Description_39
getUserID39=<some value>
getUserType39=<some value>
expectedUserType39=<some value>
postTestCase1=TC_ID_1
postDescription1= Description_1
postUserID1=<some value>
postUserType1=<some value>
expectedUserType1=<some value>
...
...

测试数据流:从属性文件中读取数据。属性文件映射到 TestNG 类。TestNG 类中这些方法的命名约定如下:

public class ModuleA extends ModuleACommon{    
int getcount = 0;
int postcount = 0;
@Test(priority=20)
public void testMoudleAGetPositive38(){
callMethodToReadData(getcount++);
....
}   
@Test(priority=21)
public void testModuleAGetPositive39(){
callMethodToReadData(getcount++);
....
....
} 
......
......
@Test(priority=30)
public void testModuleAPostPositive1(){
callMethodToReadData(postcount++);
....
....
}   
......
......
}

请注意,当调用callMethodToReadData时,计数将递增,并且用于生成密钥以从属性文件访问测试数据。测试用例按顺序设置为优先级,这可确保构造正确的键。这很痛苦,因为如果我想按照此模式添加新的测试用例。假设我想添加一个测试用例并为其分配优先级 21,那么我将不得不调整 21 之后所有测试方法的优先级,包括第 21 个优先级测试用例。

短期:我正在尝试找到一种最简单的方法来单独运行一个测试。有肮脏的方法可以实现这一点。例如,我可以注释掉其他测试用例并重新分配适当的计数值,但这效率太低。

长期:我很想听到意见和建议,以从长远来看改善这一点。我自己有几个长期改进的想法,但我希望从这里得到更有见地的建议。

另外,让我知道是否有任何黑客可以解决添加测试用例而不必重新组织优先级的问题(我已经实施了一个解决方案,我只使用一个更能描述实际测试用例的唯一键)。

巩固这种方法可以看到的一些问题:

  1. 不支持并行执行:构建测试的方式,如果我尝试并行运行它们,整个系统就会崩溃,因为从数据源(在您的例子中为属性文件)获取数据的方法依赖于类中的非线程安全数据成员。
  2. 正如您已经指出的那样,无法轻松添加新测试,也无法灵活地将它们作为独立测试运行。
  3. 测试的重新排序

为了能够独立运行测试,就是能够更改密钥。您的键当前依赖于某个 int 值,该值需要传递给数据源,以便您可以检索它的属性。

我建议您将其更改为开始成为@Test的方法名称。由于您说对于每个测试类,您都将拥有一个属性文件,并且由于Java不允许定义两个具有相同名称的方法(当然方法重载会允许您这样做,但是由于我们正在谈论@Test方法,我们可以方便地忽略该部分),如果您让键依赖于方法名称,那么您的键仍然是唯一的。现在,您也不需要显式引用方法名称。在@Test方法中,如果您调用了callMethodToReadData(),那么您的callMethodToReadData()只需调用org.testng.Reporter.getCurrentTestResult().getMethod().getMethodName()即可轻松检索当前正在运行的@Test方法的名称(请记住,当您从@Test方法中查询线程局部变量Reporter.getCurrentTestResult时,TestNG 可确保存在有效的ITestResult对象)

现在,这将使您摆脱对计数器的依赖,以形成您的密钥。属性文件的可读性要高得多,因为键现在表示方法名称,因此数据属于哪个测试方法更加清晰。

添加新测试时,您也不必更改优先级(当然,如果您真的想更改测试的顺序,则需要调整优先级,因为这就是优先级的用途。soft dependency)

通过构建org.testng.IAnnotationTransformer的实现,您可以根据可以读取的JVM参数随意启用/禁用@Test方法,从而获得更多花哨。因此,从字面上看,您可以随意运行任何@Test方法。如果您使用 maven 作为构建工具,那么您真的不需要转换器,因为 maven surefire 插件本身可以让您做到这一点。

从长远来看,我认为你需要开始关注dataprovider甚至工厂。您可能还想摆脱属性的概念,而是转向复杂的内容,例如 JSON/YAML/XML,或者只是回退到 Excel 电子表格,因为在 excel 电子表格中,您可以通过将每个工作表可视化为一个表,然后让一个表使用键引用另一个表来开始创建一个完整的 RDBMS。然后,您可以构建一个复杂的 excel 数据提供程序,该提供程序能够从电子表格中提取数据并填充 POJO(您需要创建一个,用于对电子表格数据行进行建模)。这就是我们最终构建和开源的内容,作为构建SeLion的一部分。要了解有关我正在谈论的 excel 数据提供程序的更多信息,您可以参考此处

最新更新