41

你如何自动化集成测试?我使用 JUnit 进行其中一些测试。这是解决方案之一还是完全错误?你有什么建议?

4

10 回答 10

46

我使用 JUnit 进行了很多集成测试。当然,集成测试可能意味着许多不同的东西。对于更多的系统级集成测试,我更喜欢让脚本从外部驱动我的测试过程。

对于使用 http 和数据库的应用程序,这是一种非常适合我的方法,我想验证整个堆栈:

  1. Hypersonic or H2在内存模式下使用作为数据库的替代品(这对 ORM 最有效)
  2. 初始化数据库@BeforeSuite或等价物(再次:使用 ORM 最简单)
  3. 使用 Jetty 启动进程内 Web 服务器。
  4. @Before每次测试,清除数据库并使用必要的数据进行初始化
  5. 用于JWebUnit向 Jetty 执行 HTTP 请求

这为您提供了无需任何数据库或应用程序服务器设置即可运行的集成测试,并且可以从 http 向下运行堆栈。由于它不依赖于外部资源,因此该测试在构建服务器上运行良好。

这是我使用的一些代码:

@BeforeClass
public static void startServer() throws Exception {
    System.setProperty("hibernate.hbm2ddl.auto", "create");
    System.setProperty("hibernate.dialect", "...");
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setJdbcUrl("jdbc:hsqldb:mem:mytest");
    new org.mortbay.jetty.plus.naming.Resource(
             "jdbc/primaryDs", dataSource);


    Server server = new Server(0);
    WebAppContext webAppContext = new WebAppContext("src/main/webapp", "/");
    server.addHandler(webAppContext);
    server.start();
    webServerPort = server.getConnectors()[0].getLocalPort();
}

// From JWebUnit
private WebTestCase tester = new WebTestCase();

@Before
public void createTestContext() {
    tester.getTestContext().setBaseUrl("http://localhost:" + webServerPort + "/");
    dao.deleteAll(dao.find(Product.class));
    dao.flushChanges();
}

@Test
public void createNewProduct() throws Exception {
    String productName = uniqueName("product");
    int price = 54222;

    tester.beginAt("/products/new.html");
    tester.setTextField("productName", productName);
    tester.setTextField("price", Integer.toString(price));
    tester.submit("Create");

    Collection<Product> products = dao.find(Product.class);
    assertEquals(1, products.size());
    Product product = products.iterator().next();
    assertEquals(productName, product.getProductName());
    assertEquals(price, product.getPrice());
}

对于那些想了解更多的人,我在 Java.net 上写了一篇关于使用 Jetty 和 JWebUnit 进行嵌入式集成测试的文章。

于 2008-11-12T20:42:46.373 回答
19

JUnit 工作。没有任何限制将其限制为仅作为单元测试。我们使用 JUnit、Maven 和 CruiseControl 来做 CI。

可能有专门用于集成测试的工具,但我认为它们的有用性取决于您要集成的系统组件类型。JUnit 适用于非 UI 类型测试。

于 2008-11-12T18:27:35.040 回答
5

在使用 Maven 构建项目时,我对TestNG的运气稍微好一点,因为它具有@BeforeSuite@AfterSuite操作性。这很有用,因为如果任何集成测试失败,Maven 将不会执行“集成后测试”。Ant没有问题,所以我只是出于偏好而使用jUnit。

在任何一种情况下,像 TestNG 和 jUnit 那样分割测试也有助于集成测试。

于 2008-11-12T18:28:03.667 回答
2

在我们的工作中,我们的集成测试解决方案包含三个主要部分:

  1. CruiseControl是我们持续集成方法的基础。
  2. 我们的 CruiseControl 配置在任何人签入Subversion后 3 分钟内启动快速测试构建。这里发生的测试是“一切都还在编译吗?” 和“单元测试都通过了吗?”。 JUnit显然是回答第二个问题的主要促进者。
  3. 每小时,它都会启动一个更大的构建,构建我们在各种部署平台上使用的在线帮助和安装程序。这一步验证了“我们的每个目标平台是否还有可部署的产品?”这样更大的问题。

最终结果是这里的大多数人从不担心集成测试:它只是发生了。另一方面,单元测试是每个人的首要任务。JUnit 使构建测试变得容易,尽管好的测试总是需要思考和开发时间。

于 2008-11-12T20:22:42.937 回答
1

是的,您可以使用 junit 进行集成测试,但这取决于您需要的集成测试类型。

测试一个 servlet:

  • 设置 servlet 上下文和配置
  • 使用模拟 servlet 请求进行测试(Spring 对此提供支持,但您也可以使用 EasyMock 或您自己的模拟)

测试弹簧应用程序:

  • 使用 AbstractDependencyInjectionSpringContextTests 设置上下文
  • 测试有线 bean
  • 在使用数据库进行测试时,还有支持事务处理的 AbstractDependencyInjectionSpringContextTests 的子类。

但纯粹的 Junit 也有其局限性。测试用户界面是一个典型案例。您可以将 selenium 用于 Web 应用程序,将 soapui 用于 Web 服务或其他适当的工具。

但无论您使用什么,都应该可以将其集成到您的持续构建中(巡航控制、团队城市或其他)。

于 2008-11-12T18:30:07.860 回答
0

确实!我们使用 JUnit、ANT 任务的组合来运行它们,并使用Hudson进行持续集成测试。奇迹般有效。

于 2008-11-12T18:18:06.400 回答
0

该建议取决于您的应用程序和您的目标。

我在 JUnit 中编写过集成测试,但我也看到人们使用 HtmlUnit(JUnit 扩展)、Selenium、Watir、Fit/Fitness,甚至像 WinRunner 和 Silk 这样的商业工具。

因此,请告诉我们更多有关您的领域和测试目标的信息,您可能会得到更好的答案。

于 2008-11-13T08:35:30.897 回答
0

JUnit 有一个很好的扩展,叫做 Jitr。

Jitr 是一个 JUnit 集成测试运行器,它允许您的 Web 应用程序集成测试轻松地在与您的测试相同的 JVM 中针对轻量级 Web 容器运行。

有关详细信息,请参见他们的网站:http ://www.jitr.org/

于 2009-12-04T04:39:33.647 回答
0

2012 年更新:虽然可以使用 JUnit(并且受益于 CI 支持),但 JWebUnit 和 Selenium 似乎正在占据集成测试的份额。

于 2012-02-01T01:13:25.780 回答
0

我认为自动化和集成测试不能很好地结合在一起。最基本的问题是每次测试前的环境设置。需要更多集成类型的测试更大的设置。

我对集成层测试自动化的看法:http: //blog.aplikacja.info/2012/03/whats-wrong-with-automated-integration-tests/

于 2012-09-18T21:05:20.143 回答