代码之家  ›  专栏  ›  技术社区  ›  Synesso

什么是Java敏捷集成测试DAO->数据库的良好实践?

  •  3
  • Synesso  · 技术社区  · 14 年前

    目前DAOS的敏捷集成测试与Java景观中的真实数据库模式有什么好的实践?

    (我所说的“敏捷”是指对这个问题最简化、最自动化和最简单的解决方案)。

    我希望实现自动化测试,证明数据访问层与实际运行的数据库实例无缝集成。我们必须针对特定的供应商DBS测试我们的自定义SQL。也就是说,如果我们编写T-SQL,我们希望对SQL Server进行测试。

    一个数据库应该专用于所有正在运行的测试,但不需要提交吗?或者每个测试环境都应该有一个专用的数据库?

    人们如何处理设置和拆卸?DBUnit还在流行吗?春天有什么帮助?

    4 回复  |  直到 7 年前
        1
  •  3
  •   Arthur Ronald    14 年前

    重要的是,我们要针对特定的供应商DBS测试我们的自定义SQL

    因此,您应该为每个供应商数据库创建一套测试

    @RunWith(Suite.class)
    @Suite.SuiteClasses({})
    public class SQLServerTestSuite {
    
        @BeforeClass
        public static void setUpClass() throws Exception {
    
        }
    
        @AfterClass
        public static void tearDownClass() throws Exception {
            // clean database
        }
    
    }
    

    一个数据库应该专用于所有正在运行的测试,但不需要提交吗?

    建议您执行SQL命令 但使用回滚命令 因为如果使用提交,您可以更改当前测试的状态,也可以更改其他测试的状态。否则,您可以处理意外行为。

    对于每个开发人员,建议 database sandbox . 这允许每个用户以他们认为合适的任何方式修改数据库,并使用测试来运行应用程序。 不用担心他们的测试和其他用户的测试之间的任何交互

    人们如何处理设置和拆卸?

    public class PersonTest {
    
        @Before
        public void setUp() {
            // set up state to run the test
        }
    
        @After
        public void teardown() {
           // Transaction rollback
        }
    
    }
    

    关于 Transaction rollback pattern 是吗? 它使数据库保持与我们开始测试时完全相同的状态 不管我们对数据库内容做了什么更改

    DBUnit还在流行吗?

    dbunit用于将数据库表与包含 预期值。您应该记住dbunit处理手工编码的设置。然而,尽管这种方法更为彻底 开发和维护这些测试是极其繁琐的 . 此外,测试不会检测到新添加字段或属性的丢失映射。

    春天有什么帮助?

    Spring内置了对事务回滚模式的支持,并支持命名参数( SqlParameterSource )例如,它允许您在多行和可读的XML文件中为每个供应商数据库外部化纯JDBC查询。

    <?xml version="1.0" encoding="UTF-8"?>
    <queries>
        <query name="PERSON_BY_ID">
            <![CDATA[
                select 
                    *
                from 
                    PERSON
                where
                    PERSON.ID = :integerId
            ]]>
        </query>
    </queries>
    

    注意查询参数。它遵循JavaScript代码样式,在这里您将参数类型声明为前缀。现在,您可以创建一个类,在其中定义一组命名查询

    public class SQLServerQuery {
    
        public static final String PERSON_BY_ID = "PERSON_BY_ID";
    
    }
    

    对于一般查询, 通常重要的是检测查询逻辑中的错误,例如使用<而不是<。= . 要捕获这些类型的错误,我们需要编写用测试数据填充数据库的测试,执行查询,并验证它是否返回预期的对象。不幸的是,这些类型的测试在写入和执行时都很耗时。

        2
  •  3
  •   Christopher Hunt    14 年前

    我想说的是,DAO的集成测试只需要确保ORM的SQL(如HQL或JDBCSQL)是有效的。我认为有理由假定查询语言本身已经针对多个驱动程序/数据库进行了彻底的测试。接下来,使用“内存”数据库(如hsqldb)是合理的。

    “Spring测试”的目标是集成测试,它非常适合于设置IOC上下文、提供事务、设置数据库会话、创建模式,然后在测试后删除它、在测试后回滚事务…如此之多以至于我坐在围栏上,将我的一些数据库测试标记为集成测试(我个人认为,只要单元测试不跨越过程边界,并且它们的设置是无摩擦的,它们就构成了一个合理的单元测试)。

    另一方面,一些好的系统测试应该测试您的系统端到端以及所有目标数据库。在设置系统测试时总是要付出大量的努力,而且,因为您是在测试系统本身,所以在框架和工具包方面有很多适用的帮助。

        3
  •  1
  •   Ankit Bansal    14 年前

    我认为只要确保在测试开始时删除设置的数据,每个开发人员都可以使用一个数据库。如果您不依赖任何初始数据集,那么只需清理表即可。在这种情况下,dbunit是一个很好的解决方案。

    有时,您依赖于一些初始数据集,而不是所有测试,而是主要用于选择查询的少数测试。如果您依赖于某些数据集,则会变得很棘手。您仍然可以通过在每个测试开始之前运行种子数据并在结束时关闭来管理dbunit,但它会使测试运行更长的时间。

    在这种情况下,我发现更好的方法是创建一个简单的实用程序类,以保留在测试开始时创建的任何新数据的ID,并在最后将其删除。

        4
  •  0
  •   sjt    14 年前

    也许我不理解您试图做什么的目的,或者为什么选择这个测试方法,但是您考虑过使用模拟对象吗?您可以使用模拟对象编写JUnits测试,并将其与Hudson集成以实现自动化。您可以模拟DAO、准备语句、连接、结果集等。

    DAO是经过验证的模式。JDBC或者其他你可能用来接口的东西也是如此。你想证明它是有效的吗?或者您真的打算测试DAO方法中的查询或SQL吗?