Java 利用现有测试体系结构的TestNG的困难
下面是我的类结构的一个简单(最小)表示,请注意,结构中只有一个与TestNG的集成点(抽象类上的@Test注释) 现在,下面是一个测试用例的示例,它可以很好地使用上述结构Java 利用现有测试体系结构的TestNG的困难,java,selenium-webdriver,testng,Java,Selenium Webdriver,Testng,下面是我的类结构的一个简单(最小)表示,请注意,结构中只有一个与TestNG的集成点(抽象类上的@Test注释) 现在,下面是一个测试用例的示例,它可以很好地使用上述结构 public class sampletest extends AbstractValidator2{ public sampletest() { super("www.google.com", null); } @Override public boolean validate
public class sampletest extends AbstractValidator2{
public sampletest() {
super("www.google.com", null);
}
@Override
public boolean validate() {
return true;
}
}
由于上面有一个无参数构造函数,所以它很容易与TestNG一起使用。我可以将其包含在任何测试xml文件中,并配置它以任何方式运行。太好了,生活是美好的
下面的下一个测试是与TestNG的集成
public class sampletest2 extends AbstractValidator2{
Date date;
public sampletest2(String url, Date date) {
super(url, null);
date = date;
}
@Override
public boolean validate() {
driver.get(url);
Utils.wait(5000);
return false;
}
}
在本例中,我需要为构造函数提供参数。我还需要为我要测试的每个测试用例提供一个新实例。这就排除了单独使用数据提供者的可能性。为了增加复杂性,我还需要并行运行。工厂确实在工作,但有一个问题。在使用工厂时,我似乎不可能选择单个用例(我必须在不更改代码的情况下运行所有用例)。每天我都喜欢单独运行用例
我提出的解决方案如下
public class sampletest2suite {
@Test
public void sampletest2google(){
new sampletest2("https://www.google.com/", null).run();
}
@Test
public void sampletest3bing(){
new sampletest2("https://www.bing.com/", null).run();
}
}
然而,这种结构使我瘫痪,并创建了一种阻止我利用Testng的许多强大功能的结构。我的目标是利用testng的xml配置,以便从java类结构中删除重复的代码和配置
public class sampletest extends AbstractValidator2{
public sampletest() {
super("www.google.com", null);
}
@Override
public boolean validate() {
return true;
}
}
我还提出了另一个解决办法。这个解决方案滥用继承性并生成子类的唯一原因是为了与testng兼容而提供一个无参数构造函数。关于为什么这是一个坏模式,您可以看到以下stackexchange问题:
鉴于目前的问题,有没有人有什么建议可以让你重新走上更健康的道路。我认为TestNG有一些功能,如果使用的话,会让你的生活更轻松
setup()
和tearDown()
应在*之前和之后适当地添加@注释。这将触发它们在适当的时间运行,而不必在一些run()
方法中调用它们。实例化驱动程序应该在setup()
中。最佳做法是创建一个浏览器实例,将其用于一个测试,然后销毁它。这样可以保持每次运行的独立性,避免运行的交叉污染(一次运行变差,并扰乱后续运行等)
下面是一个简单的示例,我希望它能帮助您理解如何使用带有TestNG的数据提供程序来完成您想要的事情
public class TestNg
{
private WebDriver driver;
@Test(dataProvider = "getData")
public void test(String url, String title)
{
driver.navigate().to(url);
assertEquals(driver.getTitle(), title, "Verify title");
}
@BeforeMethod
public void setup()
{
String chromeDriverPath = "C:\\path\\to\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
driver = new ChromeDriver();
}
@AfterMethod
public void tearDown()
{
driver.close();
driver.quit();
}
@DataProvider
public Object[][] getData()
{
return new Object[][] { { "http://www.google.com", "Google" }, { "http://www.bing.com", "Bing" } };
}
}
有很多方法可以使用TestNG来实现数据提供程序。这只是其中之一。你会更好地知道哪种方法可能适合你的需要,并且可以调查官方文件并选择适合你的方法。这里有一种解决问题的方法
成分:
表示要注入到每个测试中的参数的自定义注释
每个测试变量都有一个基类(或者,您甚至可以有一个只处理对象的通用基类)
在基类中实现IHookable
实现,在确定要注入的正确参数后,该实现将扮演修补测试调用的角色
一个对象工厂(如果需要的话),负责创建要实例化到测试中的对象(类似于Spring所做的)
这是样品
注释
import java.lang.annotation.Retention;
导入java.lang.annotation.Target;
导入静态java.lang.annotation.ElementType.METHOD;
导入静态java.lang.annotation.ElementType.TYPE;
@保留(java.lang.annotation.RetentionPolicy.RUNTIME)
@目标({方法,类型})
公共@接口参数{
字符串url()默认为“”;
字符串getComplexClass()默认为“testngImplementation.acomplexclass”;
}
测试将从中扩展的基类
import org.testng.IHookCallBack;
导入org.testng.IHookable;
导入org.testng.ITestResult;
导入org.testng.internal.ClassHelper;
导入java.util.ArrayList;
导入java.util.List;
公共类抽象验证器实现IHookable{
公共抽象验证器(){
//更常见的设置报告、selenium、实用程序等。。。
}
public void setup(){}
public void拆卸(){}
@凌驾
公共无效运行(IHookCallBack回调、ITestResult testResult){
println(“我们让它在抽象验证器2上运行”);
设置();
Object[]parameters=callBack.getParameters();
对象[]已注入=getParametersToInject(testResult);
if(parameters.length==injected.length){
数组复制(注入,0,参数,0,参数,长度);
}
runTestMethod(testResult);
撕裂();
}
私有对象[]getParametersToInject(ITestResult testResult){
列表参数=新的ArrayList();
注射参数=
测试结果
.getMethod()
.getConstructorMethod()
.getMethod()
.getAnnotation(InjectParameters.class);
如果(toInject!=null){
add(toInject.url());
add(ClassHelper.newInstance(ClassHelper.forName(toInject.getComplexClass()));
}
返回参数.toArray(新对象[0]);
}
}
样本测试类
公共类TestCreation扩展了AbstractValidator{
@试验
@内射参数(url=”https://www.google.com/")
//@Parameters在这里用作占位符。为了防止触发TestNG
//验证表明该参数是必需的,但未提供。我认为这将是固定的
//作为修复的一部分https://github.com/cbeust/testng/issues/564 这将在
//TestNG 7.0.0
@参数({“url”,“a”})
public void sampletest2google(@Optional String url,@Optional acomplexclass a){
系统
public class TestNg
{
private WebDriver driver;
@Test(dataProvider = "getData")
public void test(String url, String title)
{
driver.navigate().to(url);
assertEquals(driver.getTitle(), title, "Verify title");
}
@BeforeMethod
public void setup()
{
String chromeDriverPath = "C:\\path\\to\\chromedriver.exe";
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
driver = new ChromeDriver();
}
@AfterMethod
public void tearDown()
{
driver.close();
driver.quit();
}
@DataProvider
public Object[][] getData()
{
return new Object[][] { { "http://www.google.com", "Google" }, { "http://www.bing.com", "Bing" } };
}
}