使用Profile和Resources Filter隔离测试环境

Maven能够帮我们很好的管理测试,我们可以在 src/test/java src/test/resources 下面使用JUnit或者TestNG 编写单元测试和集成测试,然后在命令行运行 mvn test ,测试就会自动运行,同时产生详细的测试报告。对只有一两个人的项目来说,不会碰到本文将提到的问题。

 

我们考虑以下场景(这也是我在实际项目中碰到的问题):有一个大概30人团队的项目,其中一半在美国,另一半在中国,要知道两个地方的网络连接速度不是很快,也就是说从地球的一端连接地球另一端的数据库十分耗时。中国的团队开发了一些模块,也很积极的编写了大量单元测试和集成测试(我这里说的单元测试使指不对外部任何环境有依赖),这些代码完全由Maven管理,所以在中国团队这里,持续集成服务器上只有简单的一条 mvn clean install 命令,一切都很好!但是,当美国团队签出同样的源代码,运行同样的命令时,问题出现了,测试在他们那里总是过不去,经过检查,发现代码中有太多的硬编码的数据库链接,以及其它的对外部环境的依赖。于是他们抱怨:How can you hardcode database link? 中国的同事很委屈:我们已经从代码里把这些东西抽取到配置文件里了,这不算Hardcode吧。大家暂时没办法,于是只能在build命令后加上-Dtest -DfailIfNoTests ,build可以过了,但是美国团队心里总是不舒服,尤其是当他们代码把测试弄坏时,他们经常不知道。

 

问题总是要解决的,更何况现在的问题也不小。让我们看看Maven为我们提供了什么,大家首先会想到的肯定是Profile,通过Profile,我们可以通过Maven传入一些个性化变量。考虑一下我们的情况下什么需要个性化?也就是说什么东西在不同的地方值是不一样的?答案是src/test/resources 下的一些资源文件,如JPA用到的 persistence.xml ,其中包含了这样的内容:

 

    <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>

    <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/test"/>

    <property name="hibernate.connection.username" value="test"/>

    <property name="hibernate.connection.password" value="test"/>

 


我们看到这个资源文件绑定到了本机的mysql数据库上,我们需要从Maven传入这些参数,包括url, username和password。可问题是,通过Profile传输的个性化变量,我们能在pom.xml里面引用,我们如何在src/test /resources 下的资源文件里引用它们呢?


先别急,先让我们把Profile定义好,这里我选择在%M2_HOME%/conf 下的settings.xml 里定义全局的Profile,因为数据库链接是很多模块的测试都会用到的,定义如下:

 

<profiles>

  <profile>

    <id>myProfile</id>

    <properties>

      <mysql.url>jdbc:mysql://localhost:3306</mysql.url>

      <mysql.username>test</mysql.username>

      <mysql.password>test</mysql.password>

      <mysql.dbname>test</mysql.dbname>

    </properties>

  </profile>

</profiles>

<activeProfiles>

  <activeProfile>myProfile</activeProfile>

</activeProfiles>

 

此外,修改资源文件如下:

 

    <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>

    <property name="hibernate.connection.url" value="jdbc:mysql://${mysql.url}/${mysql.dbname}"/>

    <property name="hibernate.connection.username" value="${mysql.username}"/>

    <property name="hibernate.connection.password" value="${mysql.password}"/>

 

至此,我们已经把环境相关的变量隔离开了,每个用户都有自己的settings.xml 文件,所以每个人都能配置自己的settings.xml 来使用他想要使用的数据库。针对我们上面的场景,美国的团队只要在本地配置一个数据库,他们也就可以运行测试了,皆大欢喜!

 

最后,不要忘了配置 Maven Resources 插件让它开启 filtering 功能:

 

      [...]
      <resource>
        <directory>src/test/resources</directory>
        <filtering>true</filtering>
      </resource>
      [...]
 

至此,运行 mvn install ,Maven 会让 Resources 插件首先根据 setttings.xml 文件中的值填充测试资源文件中的变量,然后再运行测试。这种解决方案不仅仅适用于数据库,任何外部环境配置都可以使用该方案,如对消息服务器的依赖。尽情享受Maven给你带来的便利吧!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过使用 Mavenprofiles 和构建参数来实现多个 pom 文件分别打包测试环境和生产环境。 首先,你可以创建两个独立的 pom 文件,分别用于测试环境和生产环境的打包。在这两个 pom 文件中,你可以定义不同的构建配置,如依赖、插件和资源文件等。 接下来,你可以为每个 pom 文件创建一个对应的 profile。在每个 profile 中,你可以指定特定的构建参数,如环境变量、属性值等。这将帮助 Maven 根据不同的 profile 来选择正确的 pom 文件进行构建。 下面是一个示例: 首先,在根目录下创建两个 pom 文件,分别为 pom-test.xml 和 pom-prod.xml。这两个文件可以拥有不同的依赖和插件配置。 然后,在根目录的 pom.xml 文件中添加以下内容: ```xml <profiles> <profile> <id>test</id> <activation> <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <!-- 配置 test profile 的构建插件 --> </plugins> </build> </profile> <profile> <id>prod</id> <build> <plugins> <!-- 配置 prod profile 的构建插件 --> </plugins> </build> </profile> </profiles> ``` 在以上示例中,test profile 被设置为默认激活的 profile,这意味着如果没有指定 profile,则会使用 test profile 进行构建。你可以根据需要修改这个设置。 最后,你可以使用以下命令来选择不同的 profile 进行构建: ```shell mvn package -P test # 使用 test profile 进行构建 mvn package -P prod # 使用 prod profile 进行构建 ``` 使用上述命令的时候,Maven 将会根据指定的 profile 来选择对应的 pom 文件进行构建,并且应用相应的配置。 希望这个例子能对你有所帮助!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值