本文介绍了集成测试所需的数据库数据;通过 API 调用或使用导入的数据创建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题或多或少与编程语言无关.但是,由于这些天我主要使用 Java,这就是我将从中提取示例的地方.我也在考虑 OOP 的情况,所以如果你想测试一个方法,你需要一个该方法类的实例.

This question is more or less programming language agnostic. However as I'm mostly into Java these days that's where I'll draw my examples from. I'm also thinking about the OOP case, so if you want to test a method you need an instance of that methods class.

用于单元测试核心规则strong> 是它们应该是自治的,这可以通过将类与其依赖项隔离来实现.有几种方法可以做到这一点,这取决于您是否使用 IoC(在Java 世界,我们有 Spring、EJB3 和其他提供注入功能的框架/平台)和/或如果您模拟对象(对于 Java,您有 JMockEasyMock) 将被测试的类与其依赖项分开.

A core rule for unit tests is that they should be autonomous, and that can be achieved by isolating a class from its dependencies. There are several ways to do it and it depends on if you inject your dependencies using IoC (in the Java world we have Spring, EJB3 and other frameworks/platforms which provide injection capabilities) and/or if you mock objects (for Java you have JMock and EasyMock) to separate a class being tested from its dependencies.

如果我们需要测试不同类*中的方法组并看到它们很好地集成,我们编写集成测试.这是我的问题!

If we need to test groups of methods in different classes* and see that they are well integration, we write integration tests. And here is my question!

  • 至少在 Web 应用程序中,状态通常会持久保存到数据库中.我们可以使用与单元测试相同的工具来实现独立于数据库.但在我的拙见中,我认为在某些情况下,不使用数据库进行集成测试是在嘲笑太多(但请随意反对;根本不使用数据库,永远,也是一个有效的答案,因为它使问题变得无关紧要).
  • 当您使用数据库进行集成测试时,您如何用数据填充该数据库?我可以看到两种方法:
    • 存储集成测试的数据库内容并在开始测试之前加载它.如果将其存储为 SQL 转储、数据库文件、XML 或其他内容,将会很有趣.
    • 通过 API 调用创建必要的数据库结构.这些调用可能会在您的测试代码中拆分为多个方法,并且这些方法中的每一个都可能失败.可以将其视为您的集成测试依赖于其他测试.
    • At least in web applications, state is often persisted to a database. We could use the same tools as for unit tests to achieve independence from the database. But in my humble opinion I think that there are cases when not using a database for integration tests is mocking too much (but feel free to disagree; not using a database at all, ever, is also a valid answer as it makes the question irrelevant).
    • When you use a database for integration tests, how do you fill that database with data? I can see two approaches:
      • Store the database contents for the integration test and load it before starting the test. If it's stored as an SQL dump, a database file, XML or something else would be interesting to know.
      • Create the necessary database structures by API calls. These calls are probably split up into several methods in your test code and each of these methods may fail. It could be seen as your integration test having dependencies on other tests.

      您如何确定测试所需的数据库数据在您需要时是否存在?你为什么选择你选择的方法?

      How are you making certain that database data needed for tests is there when you need it? And why did you choose the method you choose?

      请提供带有动机的答案,因为有趣的部分在于动机.请记住,只需说这是最佳实践!"不是真正的动机,它只是重复你从某人那里读到或听到的东西.对于这种情况,请解释为什么这是最佳做法.

      Please provide an answer with a motivation, as it's in the motivation the interesting part lies. Remember that just saying "It's best practice!" isn't a real motivation, it's just re-iterating something you've read or heard from someone. For that case please explain why it's best practice.

      *我在我的单元测试定义中包含了一种调用同一类(相同或其他)实例中的其他方法的方法,即使它在技术上可能不正确.随时纠正我,但让我们把它作为一个附带问题.

      *I'm including one method calling other methods in (the same or other) instances of the same class in my definition of unit test, even though it might technically not be correct. Feel free to correct me, but let's keep it as a side issue.

      推荐答案

      我更喜欢使用 API 调用创建测试数据.

      I prefer creating the test data using API calls.

      在测试开始时,您创建一个空数据库(内存中或生产中使用的数据库),运行安装脚本以对其进行初始化,然后创建数据库使用的任何测试数据.例如,可以使用 Object Mother 模式组织测试数据的创建,以便相同的数据可以在许多测试中重复使用,可能会有细微的变化.

      In the beginning of the test, you create an empty database (in-memory or the same that is used in production), run the install script to initialize it, and then create whatever test data used by the database. Creation of the test data may be organized for example with the Object Mother pattern, so that the same data can be reused in many tests, possibly with minor variations.

      您希望在每次测试之前使数据库处于已知状态,以便进行可重复的测试而不会产生副作用.所以当一个测试结束时,你应该删除测试数据库或回滚事务,以便下一个测试可以始终以相同的方式重新创建测试数据,无论之前的测试是否通过或失败.

      You want to have the database in a known state before every test, in order to have reproducable tests without side effects. So when a test ends, you should drop the test database or roll back the transaction, so that the next test could recreate the test data always the same way, regardless of whether the previous tests passed or failed.

      我避免导入数据库转储(或类似的)的原因是它将测试数据与数据库模式耦合.当数据库架构发生变化时,您还需要更改或重新创建测试数据,这可能需要手动工作.

      The reason why I would avoid importing database dumps (or similar), is that it will couple the test data with the database schema. When the database schema changes, you would also need to change or recreate the test data, which may require manual work.

      如果测试数据是在代码中指定的,那么您将拥有 IDE 重构工具的强大功能.当您进行影响数据库架构的更改时,它可能也会影响 API 调用,因此您无论如何都需要使用 API 重构代码.通过几乎相同的努力,您还可以重构测试数据的创建 - 特别是如果重构可以自动化(重命名、引入参数等).但是如果测试依赖于数据库转储,除了重构使用 API 的代码之外,您还需要手动重构数据库转储.

      If the test data is specified in code, you will have the power of your IDE's refactoring tools at your hand. When you make a change which affects the database schema, it will probably also affect the API calls, so you will anyways need to refactor the code using the API. With nearly the same effort you can also refactor the creation of the test data - especially if the refactoring can be automated (renames, introducing parameters etc.). But if the tests rely on a database dump, you would need to manually refactor the database dump in addition to refactoring the code which uses the API.

      与集成测试数据库相关的另一件事是测试从以前的数据库模式升级是否正常工作.为此,您可能需要阅读这本书 重构数据库:进化数据库设计 或这篇文章:http://martinfowler.com/articles/evodb.html

      Another thing related to integration testing the database, is testing that upgrading from a previous database schema works right. For that you might want to read the book Refactoring Databases: Evolutionary Database Design or this article: http://martinfowler.com/articles/evodb.html

      这篇关于集成测试所需的数据库数据;通过 API 调用或使用导入的数据创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 18:55