接口测试 虚拟 DNS 实现实时更换测试环境

天琴圣域 · 2017年01月10日 · 最后由 yu 回复于 2017年01月11日 · 3275 次阅读

序言

起初只是想做到使用 Java 在运行过程中切换 host,刚开始使用 HttpClient,用着还挺顺手,后来公司 HTTPS 迁移,发现很多接口在设置代理 ip 后无法访问了,输出了响应才明白,原来公司是为域名分发的证书,如果直接用 HTTPS 访问 ip 是不可行的。这样可能说不清楚,举个例子:

https://app.api.com.cn/api/test?a=2ip,修改 Windows 的 host 文件当然是可行的(switchhost 软件),但是直接在浏览器中把域名更换为 ip 就不通了,会提示证书不可信,例如 https://192.168.100.1/api/test?a=2,你不能总是要求开发或者运维给你配置。。。直接访问自然是没有问题,有时候我们测试时会有多套环境,这就需要指向对应的

其实 HttpClient 在这里不好使的原因也是如此,它的封装相当于在一个浏览器中把域名更换为 ip 然后点击访问按钮(结果上来看)。

今天偶尔发现一个第三方扩展,可以实现虚拟 DNS,我一看就乐了,熟悉网络的肯定明白,域名的解析就是靠 DNS 这个东东啦。

不啰嗦了,直接上用法,顺便感谢原作者。贴下他们的网站吧,http://leopard.io/

正文

添加 maven 依赖:

<dependency>
        <groupId>io.leopard</groupId>
        <artifactId>javahost</artifactId>
        <version>0.3-SNAPSHOT</version>
</dependency>

在 resource 目录下加入配置文件

就是指定虚拟 DNS 的映射关系咯。
idea 建立的项目可以指定一个 resource 目录,eclipse 的话放在 classpath 下即可。
vdns.properties

app.api.com.cn=192.168.100.1

#多IP设置,域名解析时随机返回其中一个
user.api.com.cn=192.168.100.2,192.168.100.3

启动代码

API 调用永远是很简单啦,不过有兴趣可以看看内部实现。
方法:

import io.leopard.javahost.JavaHost;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Properties;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

public class VirtualDns {

    public static void loadDns() throws IOException {
        Resource resource = new ClassPathResource("/vdns.properties");
        Properties props = PropertiesLoaderUtils.loadProperties(resource);
        JavaHost.updateVirtualDns(props);
    }

}

调用

public class Test {

      public static void main(String[] args) 
        throws Exception {
        VirtualDns.loadDns();
        JavaHost.printAllVirtualDns();// 打印所有虚拟DNS记录
        System.out.println("IP:" + InetAddress.getByName("app.api.com.cn").getHostAddress());// 验证一下解析是否正确
       }

}

实战

当然只是这样是看不出虚拟 DNS 的好处的,比较靠切换 host 方案也可以实现。我这里提出一种场景:现在我在测试环境有个接口,需要测试其返还的数据是否和线上环境完全一致,且 URL 也完全相同,写到脚本里的话就需要在一次执行过程中启用两套环境。

一种办法是写个自定义线程,在需要访问测试环境的数据时,手工切换 host 为测试环境的 host,获取到响应后让线程休眠一段时间,然后手工切换 host 到线上环境,此时线程差不多激活了。。。听着好像有些蛋疼。

另一种办法就是使用虚拟 DNS 了,写两套配置文件,使用哪个环境就用哪个配置文件,demo 如下:

package util;

import io.leopard.javahost.JavaHost;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import java.io.IOException;
import java.util.Properties;

/**
 * Created by Administrator on 2017/1/4.
 * 这里是封装的共用方法
 */
public class VirtualDns {

    private Resource resource;

    public VirtualDns(String path){
        //resource = new ClassPathResource("/dns-test.properties");
        resource = new ClassPathResource(path);
    }

    public void loadDns() throws IOException {
        Properties props = PropertiesLoaderUtils.loadProperties(resource);
        JavaHost.updateVirtualDns(props);
    }
}
package util;

import org.junit.Assert;

import java.io.IOException;

import static io.restassured.RestAssured.*;
import static io.restassured.matcher.RestAssuredMatchers.*;
import static io.restassured.path.json.JsonPath.from;
import static org.hamcrest.Matchers.*;

/**
 * Created by Administrator on 2017/1/10.
 * 这里相当于我们的一个测试用例代码
 */
public class Test {
    public static void main(String[] args) throws IOException {

        //获取测试环境的某个数据
        VirtualDns virtualDnsTest = new VirtualDns("/dns-test.properties");
        virtualDnsTest.loadDns();
        int id_test = get("http://app.api.com.cn/test?a=1").then().extract().path("result.list[0].id");

        //获取线上环境的某个数据
        VirtualDns virtualDnsOnline = new VirtualDns("/dns-online.properties");
        virtualDnsOnline.loadDns();
        int id_online = get("http://app.api.com.cn/test?a=1").then().extract().path("result.list[0].id");

        //对比断言
        Assert.assertEquals(id_online,id_test);
    }
}

其实都挺蛋疼的,要怪就怪世界吧(无奈摊手)。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 3 条回复 时间 点赞

mark。
你既然可以加载不同的配置文件,为何不改下链接地址呀?

估计就是对不可信证书强制信任,然后忽略而已.
访问这样的地址 (https://192.168.100.1/test) ,不通的话,可以让 httpclient 强制信任证书的.
如果测试代码是跑在浏览器上的,必须得动态修改 host 文件

49875183 接口自动化测试框架 中提及了此贴 03月10日 13:10
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册