繁体   English   中英

TestNG-工厂和数据提供者

[英]TestNG - Factories and Dataproviders

背景故事

我在一家软件公司工作,该公司开发了一个测试自动化框架来替换我们的旧意大利面条缠结系统。

由于我们的系统几乎所有操作都需要登录,因此我决定最好使用@ BeforeMethod,@ DataProvider和@Factory设置测试。 但是,我遇到了一些问题。

样本测试案例

可以说该软件系统是棒球队的名册。 我们要测试以确保用户可以按名称搜索团队成员。

(注意:我知道BeforeMethods不会以任何给定的顺序运行-假设现在已经解决了。)

@BeforeMethod
public void setupSelenium() {
    // login with username & password
    // acknowledge announcements
    // navigate to search page
}

@Test(dataProvider="players")
public void testSearch(String playerName, String searchTerm) {
    // search for "searchTerm"
    // browse through results
        // pass if we find playerName
    // fail (Didn't find the player)
}

该测试用例假定以下条件:

  • 用户已经登录(很可能是在BeforeMethod中)
  • 用户已经导航到搜索页面(方法之前,很简单)
  • 测试的参数与上述登录相关联

问题所在

因此,让我们尝试找出如何处理测试用例的参数。

想法#1

这种方法使我们可以将数据提供者与用户名相关联,并使我们可以将多个用户用于任何特定的测试用例!

@Test(dataProvider="players")
public void testSearch(String user, String pass, String name, String search) {
    // login with user/pass
    // acknowledge announcements
    // navigate to search page
    // ...
}

...但是有很多重复,因为我们必须使每个函数都接受两个额外的参数。 更不用说,我们还在测试确认公告功能,而我们实际上并不想测试。

想法2

因此,让我们使用工厂正确地初始化事物吧!

class BaseTestCase {

    public BaseTestCase(String user, String password, Object[][] data);

}

class SomeTest {

    @Factory
    public void ...

}

这样,我们最终不得不为每个测试用例编写一个工厂...尽管,这确实使我们每个测试用例有多个用户。

结论

我是新主意。 我有另一个想法,我在哪里从XML文件中加载数据,然后从程序中调用方法……但是它变得很愚蠢。

有任何想法吗?

首先,似乎您在每个测试用例中都尝试做太多事情。 例如,如果要搜索某些内容,为什么在搜索过程中需要测试导航?

第二,您的要求似乎不清楚。 您可以创建一个测试,向其发送单个搜索词并返回单个结果吗? 似乎这应该是您的第一个测试。

第三,为什么不能将授权的会话连接/对象作为测试的要求? 从代码的外观来看,您似乎正在通过HTTP进行某种调用。 即使您不是,看起来您也必须使用某种代理将消息发送到您的应用,因为您必须传递用户名并传递每个请求……为什么不自动化整个过程东西放入“授权代理”对象中,该对象为您提供了一种通过预授权连接发送请求的方法?

然后只需将授权代理传递到您的测试中即可处理您的消息传递。 或者更好的方法是,在预测试(BeforeMethods?)函数中设置您的授权代理,并将其用作类成员变量。

我仍然不确定我是否理解您的问题...

您是否对第二次尝试感到不满意,即必须为每个测试用例编写一个@Factory? 那么为什么不将@Factory批注放在基类构造函数上呢? 这样,您所有子类需要做的就是调用super,您就完成了。

您到底想达到什么目标?

Cederic,

我应该从第一天起就注册一个帐户,实际上我不能再编辑旧帖子或回复评论了(此时)。 让我尝试扩展一下。

这是到目前为止我想出的一个例子。 我想我回答了我自己的问题...这可行,但是有点讨厌。

我的问题是,现在我所有的测试都在一个工厂进行。 这有几个原因,这不好。 第一,我必须手动添加它们(或将它们反射地放入)。 第二,我必须将所有内容本质上作为一个套件来运行。 有任何想法吗?

package example2;

import java.lang.reflect.Method;
import java.util.HashMap;
import org.testng.annotations.*;

public class WebTestBase {

  protected String host, username, password;
  protected HashMap<String, Object[][]> dataSet;

  public WebTestBase(String host, String username, String password, HashMap<String, Object[][]> dataSet) {
    this.host = host;
    this.username = username;
    this.password = password;
    this.dataSet = dataSet;
  }

  @DataProvider(name="dataSet")
  public Object[][] dataSet(Method m) {
    return dataSet.get(m.getName());
  }

  @BeforeMethod
  public void login() {
    System.out.println("Logging in to " + host + " with " + username + ":" + password);
  }

  @AfterMethod
  public void logout() {
    System.out.println("Logging out!");
  }
}

package example2;

import java.util.HashMap;

import org.testng.annotations.Factory;

public class WebTestFactory {
  @Factory
  public Object[] factory() {
    HashMap<String, Object[][]> dataSetOne = new HashMap<String, Object[][]>();
    dataSetOne.put("searchRoster", new Object[][] {
          {"mcguire", "McGuire, Mark"},
          {"ruth", "Ruth, Babe"}
        });

    HashMap<String, Object[][]> dataSetTwo = new HashMap<String, Object[][]>();
    dataSetTwo.put("addPlayer", new Object[][] {
          {"Sammy Sosa", 0.273}
        });

    Object[] tests = new Object[] { 
        new SearchTest("localhost", "user", "pass", dataSetOne),
        new AddTest("localhost", "user", "pass", dataSetTwo)
      };

    return tests;
  }
}

package example2;

import java.util.HashMap;
import org.testng.annotations.Test;

public class SearchTest extends WebTestBase {

  public SearchTest(String host, String username, String password,
      HashMap<String, Object[][]> dataSet) {
    super(host, username, password, dataSet);
  }

  @Test(dataProvider="dataSet")
  public void searchRoster(String searchTerm, String playerName) {
    System.out.println("Searching for " + searchTerm);
    System.out.println("I found " + playerName + " in the search results!");
  }

}

package example2;

import java.util.HashMap;

import org.testng.annotations.Test;

public class AddTest extends WebTestBase {

  public AddTest(String host, String username, String password,
      HashMap<String, Object[][]> dataSet) {
    super(host, username, password, dataSet);
  }

  @Test(dataProvider="dataSet")
  public void addPlayer(String playerName, double battingAvg) {
    System.out.println("Adding " + playerName + " with avg " + battingAvg);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM