2

背景故事

我在一家软件公司工作,正在开发一个测试自动化框架来取代我们旧的意大利面条纠缠不清的系统。

由于我们的系统几乎要求我们所做的所有事情都需要登录,因此我决定最好使用@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 文件加载数据,然后从程序中调用方法……但它变得愚蠢。

有任何想法吗?

4

3 回答 3

2

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

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

你到底想达到什么目的?

于 2010-06-01T20:55:28.127 回答
2

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

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

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

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

于 2010-06-01T18:36:04.613 回答
1

塞德里克,

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

这是我迄今为止提出的一个例子。我想我回答了我自己的问题......这行得通,但它有点讨厌。

我现在的问题是,我在一家工厂进行了所有测试。这不好有几个原因。一,我必须手动添加它们(或将它们放入反思中)。第二,我必须将所有东西基本上作为一个套件运行。有任何想法吗?

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);
  }
}
于 2010-06-03T15:27:54.523 回答