接口测试

软件工程术语

接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。

简介
接口测试是测试系统组件间接口的一种测试,主要用于测试系统与外部其他系统之间的接口,以及系统内部各个子模块之间的接口。测试的重点是要检查接口参数传递的正确性,接口功能实现的正确性,输出结果的正确性,以及对各种异常情况的容错处理的完整性和合理性。针对软件接口的分类一般有如下几种情况:
1)系统与系统之间的调用,如微信向用户提供统一的对外接口,程序员调用接口完成基于微信的小程序等;
2)同一系统内部上层服务对下层服务的调用,如一个软件程序一般分为表示层,业务层和数据层,表示层调用业务层的接口来完成自己的工作,而业务层又会调用数据层的接口来实现相应的业务等。
其以保证系统的正确和稳定为核心,重要性主要体现为以下几个方面:
(1)能够提早发现 bug,符合质量控制前移的理念。
(2)接口测试低成本高效益,因为接口测试可以自动化并且是持续集成的。
(3)接口测试从用户的角度对系统接口进行全面检测。实际项目中,接口测试会覆盖一定程度的业务逻辑。
接口测试的用例设计
接口测试的用例设计与单元测试有相似之处。都需要用到如:边界值法,等价类法等基本测试方法。
首先,设计接口测试用例的出发点是要验证接口实现的功能与性能指标与接口设计文档的一致性,同时测试接口具有良好的容错机制,能在接收到各种异常输入数据时做到:返回对错误定位具有良好参考意义的错误码,屏蔽底层错误信息,同时接口测试用例需要暴露接口代码更多的代码缺陷,以这个出发点为导向。
其次,选择合适的测试对象。对一个系统做接口测试,识别出合理的测试对象才能保证接口测试达到预期效果,甚至能达到事半功倍的效果。一个系统可能有很多的层次结构,也就有了不同层级的许多接口,如果对每个接口分别进行测试,时间和人力消耗较大,且用例数量大,用例的维护成本很大。分析出系统的关键模块和核心接口,并对其进行完整的测试,能以最小的测试投入,达到最好的测试效果。接口测试用例的内容应该包括:
输入参数组合、预期结果、实际运行结果以及备注的其他相关信息,如:测试功能点说明,测试环境说明等。其中,预期结果包括接口返回值以及接口的输出参数的内容。输入参数的组合应遵循等价类法和边界值法等常用用例设计方法,以最少的用例数量覆盖所有典型参数组合,做到每条用例覆盖不同的测试点,且每条用例都不可被取代。另外,接口测试用例设计时,需要注意的是以下几点:
(1)每一条用例需要有完善的初始化操作和结束操作。在每条用例开始时,由于不确定上一条用例的执行结果对测试环境的影响,因此需要把涉及到此条用例的相关数据进行初始化,比如:测试创建文件的接口,需要把已存在的文件全部删除,然后在用例中创建相应数量的文件,才能准确的在验证点中写明,调用创建文件接口以后,设备上存在几个文件,如果不进行初始化操作,有可能上一条用例产生的文件依然存在,那验证点中写明的文件个数就与实际情况不符,该条用例运行结果就是失败,但这个结果实际上是因为没有进行用例数据初始化造成的。同样接口的结束操作也是为了尽可能不影响后续用例的测试环境和执行结果,比如:该条用例创建的文件夹和文件,分配的内存空间等等,都需要在用例执行结束时将其删除或释放空间。我们知道,不管是内存,还是磁盘空间或者是其他资源都不是无限的,如果不在使用完毕后及时释放,就会出现意想不到的测试结果,比如相关资源被耗尽导致接口调用失败,文件数达到上限,内存被耗尽等,尤其是在 API 接口的性能测试和稳定性测试中出现此类问题,会严重影响测试结果的正确性,由于需要排查到底是接口本身的 bug还是测试脚本或用例的 bug 引发的不通过的测试结果,增大了测试难度,也增加了测试的时间成本。
(2)接口的初始化操作和结束操作通常是通过调用其他接口来完成的,部分初始化操作和结束操作的接口调用时,不用判断其接口调用返回值就可以直接往下执行。原因有两点,一是用于初始化和结束操作的接口往往是比较简单的或是基础性的接口,这类接口往往是最先被测试并已通过测试的,因此我们假定这些接口都是被正确实现了,不需要通过判定其返回值来确认该操作是否成功,二是此类接口的调用结果往往既可能成功也可能失败,但就算失败了,也不影响接口测试本身,因此不需要判定其返回值。举个例子,如果我在调用创建文件接口前,为了初始化测试环境调用了删除文件接口,那么它的执行结果有两个,成功或失败。如果执行成功,则证明之前的测试环境中残留有其他用例创建的文件,删除操作有效,如果执行失败,则确认了该测试环境中已无影响测试的其他数据,可以顺利进行下一步接口调用,因此无论初始化接口调用结果为成功或失败,都确保了测试环境与预期一致,不需要对初始化接口进行调用结果判断。不需要对结束清理接口进行结果判断的原因类似,被测接口创建文件的执行结果可能为成功或失败,两种结果会导致测试环境中数据的不同变化,因此统一调用删除文件操作并不判断其调用返回值是简单有效的清理数据的方法。
因为接口测试的依据往往是需求规格说明书等软件设计文档,测试手段是把接口内的程序逻辑看作一个黑盒,只根据接口定义来编写测试代码,相当于把一个接口当作一个函数来进行测试,为了确保测试的覆盖率,可能会使用到单元测试的用例设计方法。具体的测试用例设计描述如下:
(1)正常用例的设计方法。
具体是指根据该接口实现的功能分析出该接口的正常用例包括哪几种输入参数的组合,从而在用例中构造相应的参数组合来覆盖所有的正常分支。输入参数分为两种类型,一种是可以直接赋值的,这种参数直接赋值即可,另一种参数是其他接口调用的输出参数,无法直接给出,这种参数就需要在调用被测接口前先调用其他接口,将其输出参数作为被测接口所需要的输入参数传入,或者事先将所需要的参数数据写入文件中,通过读取文件的方式获取输入参数的数据。对接口输入参数的组合,一是需要根据自然逻辑进行排列组合,排除无效的组合,以及将可以划分等价类的组合进行合并同类项,控制用例总数,避免冗余重复的用例耗费测试资源。
同时还应从业务上分析有没有特殊的组合是没有考虑到的,此类用例往往不止涉及单一接口,而是涉及到根据某个特定业务流程而产生的接口调用流程,通过接口调用的方式模拟关键业务流程,可以在不用搭建辅助测试环境的情况下单纯的测试被测接口,去除测试环境复杂性对测试结果的影响,极大提升测试效率。比如,要测试该接口涉及到的某个特定关键业务流程,有两种方式覆盖测试,第一种方式是搭建真实的测试环境,将该业务流程涉及到的所有模块,设备,软件全部准备到位,然后进行业务流程测试,此种测试的优点是最大程度还原了用户真实业务使用场景,缺点是出现异常极难定位问题原因到底是出在被测接口上,还是其他陪测设备或软件上,或者是几者之间的衔接出了问题。第二种方式则是刚才提到的通过调用接口模拟业务流程来覆盖业务测试的方式,这种方式不需要额外搭建测试环境,只需要通过编写脚本的方式进行接口调用,来测试业务流程即可,虽然会花费一些人力成本编写脚本代码,但测试结果直观,出现问题后便于定位解决。
还有一种情况会明显体现出这种业务测试方法的优势,就是不同型号的设备或软件都有类似业务流程,测试该接口只需保证接口的业务流程测试通过,就可判断如果实际业务流程出问题,多半是出在其他产品或者产品之间的衔接上,错误定位成本可控。一个完整的用例,除了输入参数的组合,还包括接口执行结果的预期值,预期值也包括两部分,一个是接口调用本身的返回值,该返回值反映了该接口调用结果是成功还是失败,一般来说,结果为0表示执行成功,非0则表示执行失败。非 0 的值一般是事先定义好的错误码,提示接口调用失败的原因,便于用户进行故障诊断。大部分接口的参数除了输入参数外,还包括输出参数,对于正常用例的输出参数也需要在用例中明确写出预期值,作为用例是否成功执行的依据。
(2)异常用例的设计方法。
异常用例的设计一般采用以下方法。选取一条正常用例的数据作为基础数据,然后遍历所有的输入参数,针对每一个输入参数,分别使用等价类法,边界值法等用例设计方法枚举出该参数的所有异常值,该用例除了该参数为异常外,其余参数均保持正常值不变,以保证测试结果仅由异常的那一个参数导致。当所有输入参数都使用上述方法设计了对应的异常用例之后,进一步补充不方便在用例文件中输入的异常参数到测试脚本中,通过 switch 分支判断,在测试脚本中将无法通过文件读取的异常输入值(如:错误指针等),直接赋值给接口的输入参数,测试某些指针类型的数据错误是否被及时捕获并返回正确无歧义的错误码。
异常用例的设计需要注意的是以下几点:
首先,接口应在任何时候都返回错误码,而不能存在未经处理,直接导致调用接口的程序异常退出,或者将底层错误信息直接返回给上一层调用程序。调用程序异常退出会给用户非常不好的用户体验,同时,无法进行故障诊断和错误定位,而未经处理的底层错误信息直接返回给调用程序,有可能将不应被用户知晓的数据信息返回给用户,比如数据库相关信息,造成可能被攻击的漏洞或安全隐患。
其次,错误码的准确性很重要。错误码的准确性对接口调用失败原因的定位有非常重要的意义,将极大降低后续维护成本,错误码的设置应当准确,无歧义,一种错误类型一个错误码,尽量将错误码编得更细,更有利于错误排查。比如:参数长度错误和参数类型错误应当为不同的错误码,而不应该是统一的参数错误的错误码。同时,错误码应当在接口设计文档中有明确定义,并且在不同接口中保持一致。
一个很好的测试用例设计过程应该是建立在前期深入的需求分析和文档设计的基础之上。需求分析得越深入全面、文档描述越详细清晰,则设计的接口测试用例就会越全面,越能暴露出接口的缺陷,从而提供出高质量的服务接口。并且在后续接口维护过程中,有详尽的接口设计文档作为支撑,也可以降低维护成本。
自动化测试的基本理论
由于产品的不断版本迭代,针对同一产品的不同时期版本测试时,由于核心功能保持相对稳定的状态,因此对核心功能验证的大部分工作都是重复的工作,通过计算机程序来完成这类工作既高效又可靠。软件自动化测试通常是通过开发所需的软件测试工具以实现自动化。理想的自动化水平应该达到一种程度,就是它能够根据时间和成本的需求选取最适用于该系统的自动化测试方案。以此为指导思想实现的自动化程度越高,测试过程就越有效,越高效。因此只要选择的测试自动化工具是适合的,并且被正确地实现,自动化测试就能极大的发挥作用,提高测试效率,改进测试质量。自动化测试的目的是将测试人员从重复繁琐的手工操作中解放出来,把精力和时间投入到测试需求分析,测试用例设计和测试结果分析上,提高测试效率和质量。可以实施自动化测试场景有如下几类:
(1)回归测试
回归测试是在软件产品发布新版本时,在旧版本已经测试完毕的情况下,在新版本中执行和旧版本一样的测试用例,用于确认代码缺陷是否已经成功被修复,并且没有因此引入其他代码缺陷。我们知道,只要有代码的修改,就有可能引入新的缺陷,哪怕出现新缺陷的功能点与此次修改内容看似无关。因此,确认 bug已被正确的修复,并且没有因此引入新的bug,是保证版本质量的关键,由此可见回归测试的重要性。但由于回归测试需要对该版本的产品功能进行比较全面的覆盖,而产品开发周期时间有限,如果依靠手工来进行回归测试,效率低下且容易出错,产品质量得不到保证。引入自动化测试代替手工的回归测试则可以很好的解决上述问题,既提高测试效率,又能保证测试的可靠性,避免因为人为因素导致的测试结果不准确。
(2)非功能性测试
对于一些非功能性的测试来说,手工测试很难做到,比如容量测试,压力测试、并发测试等。在使用自动化测试工具之前,手工测试很难模拟各种性能测试的场景,也很难达到理想的测试效果。自动化测试可以在无需专人干预的非工作时间进行,比如晚上或周末进行,充分利用时间和有限的资源,缩短测试过程中回归测试的周期,从而缩短项目整体研发周期。同时,由于自动化测试的用例已经固化,且测试执行是由自动化测试工具来执行,排除了人为因素,使测试结果更可靠,应用在版本迭代频繁的产品上,能高效的发现新版本的问题,保证产品质量,在回归测试中也能更高效的完成任务,大大节省人力和时间,提高测试效率。
(3)增量开发,持续集成的项目。
此类项目一般具有自动编译,自动发布的特点,且GUI 风格变化较小,使用自动化测试代替手工测试能显著提高测试效率和质量。一个规范的软件测试流程包括以下基本步骤:
1、测试计划拟制;
2、测试方案编写;
3、测试用例设计;
4、测试执行;
5、生成软件问题报告。
要想充分利用自动化测试来改进测试质量,提高测试效率,必须有效地利用科学规范的测试流程将自动化测试的优点发挥到极致。总的来说,是否需要进行自动化测试,以下准则可以参考:
1、项目在时间安排上比较充裕;
2、具有明确的测试计划和内容且不会频繁变更需求,你从很早以前就知道要测试的具体内容,且在你进行自动化测试实践过程中,测试内容不会频繁变更;
3、多平台环境需要被测试,手工重复工作量大;虽然自动化测试在导入前期的人力和时间投资比较大,但一旦自动化测试平台搭建起来,测试效率的提升是相当明显的,对于一个需求变化不大的长线产品来说,更是如此。一般,自动化测试有以下优点:
1、测试人员有更多的时间和精力进行深入测试,进行更加深入全面的测试需求分析,测试用例设计,更多时间进行创造性的手工测试,覆盖更多的测试类型,从而提高测试的质量;
2、测试结果更加可靠:使用机器和程序来重复执行人的手工操作,比由人来手工执行,执行出错的几率大大降低,测试结果的可信度更高,而且省时省力;
3、提升测试效率:测试能够在多个平台上同时运行,且执行速度相对于手工测试大大提高,在需求变化不大的情况下,用例和脚本复用率高,大大提升测试效率;
4、更好的测试评估,对测试进度和使用的时间有更精准的把控;关于自动化测试,有以下两点认识需要明确;
自动化测试不能代替手工测试。自动化测试只能执行测试人员手工设计的测试用例,只能发现手工测试发现过的缺陷,不能指望自动化测试发现手工测试没有发现过的新问题,测试专家 James Bach总结:
八成以上的代码缺陷靠手工测试发现,而自动化测试只能发现剩下不到两成的代码缺陷。因为程序是人写的,程序本身没有创造力,程序不能代替人脑的思考。因此,自动化测试大量应用于产品回归测试这种重复性的测试过程,保证经过测试人员手工测试过的功能点不因为代码改动而引入新的缺陷;
自动化测试的可行性分析很重要。测试自动化不会减轻工作负担,相反,推进自动化测试需要投入大量的人力和时间,因此需要结合多方面因素权衡,根据投入产出比判断是否有必要进行自动化测试,应该对哪些被测对象进行自动化测试。同时,推行自动化测试可能会遇很多阻力和困难,如组织不够重视导致的资源和时间分配不足、当前技术水平或产品本身的特点达不到自动化测试的要求,产品不具有延续性,长期投入可能性不大等等问题都必须考虑,因此,进行自动化测试前,进行充分全面的可行性分析是关系到自动化测试能否成功的关键。
使用范围
接口测试一般会用于多系统间交互开发,或者拥有多个子系统的应用系统开发的测试。接口测试适用于为其他系统提供服务的底层框架系统和中心服务系统,主要测试这些系统对外部提供的接口,验证其正确性和稳定性。接口测试同样适用于一个上层系统中的服务层接口,越往上层,其测试的难度越大。接口测试在淘宝的应用是一个自下而上的发展过程。
接口测试实施在多系统多平台的构架下,有着极为高效的成本收益比,接口测试天生为高复杂性的平台带来高效的缺陷监测和质量监督能力。平台越复杂,系统越庞大,接口测试的效果越明显。
接口测试的目的是测试接口,尤其是那些与系统相关联的外部接口,测试的重点是要检查数据的交换,传递和控制管理过程,还包括处理的次数。外部接口测试一般是作为系统测试来看待的。
不是所有的团队都可以在一个隔离的测试环境中进行测试工作的,因此使得对外部接口的测试显得困难。我们应该确保较早地与相关的组织协调好并确定进行外部接口测试的方案。有时候相关的组织只是人工的静态的审阅一次数据而并不真正的用这些数据来测试。等等这些都增加了实际测试执行中遇到的风险,但有些时候是可以避免的。
全国各地天气预报查询

上海市

  • 市辖区
  • 云南省

  • 临沧市
  • 云南省

  • 丽江市
  • 云南省

  • 保山市
  • 云南省

  • 大理白族自治州
  • 云南省

  • 德宏傣族景颇族自治州
  • 云南省

  • 怒江傈僳族自治州
  • 云南省

  • 文山壮族苗族自治州
  • 云南省

  • 昆明市
  • 云南省

  • 昭通市
  • 云南省

  • 普洱市
  • 云南省

  • 曲靖市
  • 云南省

  • 楚雄彝族自治州
  • 云南省

  • 玉溪市
  • 云南省

  • 红河哈尼族彝族自治州
  • 云南省

  • 西双版纳傣族自治州
  • 云南省

  • 迪庆藏族自治州
  • 内蒙古自治区

  • 乌兰察布市
  • 内蒙古自治区

  • 乌海市
  • 内蒙古自治区

  • 兴安盟
  • 内蒙古自治区

  • 包头市
  • 内蒙古自治区

  • 呼伦贝尔市
  • 内蒙古自治区

  • 呼和浩特市
  • 内蒙古自治区

  • 巴彦淖尔市
  • 内蒙古自治区

  • 赤峰市
  • 内蒙古自治区

  • 通辽市
  • 内蒙古自治区

  • 鄂尔多斯市
  • 内蒙古自治区

  • 锡林郭勒盟
  • 内蒙古自治区

  • 阿拉善盟
  • 北京市

  • 市辖区
  • 吉林省

  • 吉林市
  • 吉林省

  • 四平市
  • 吉林省

  • 延边朝鲜族自治州
  • 吉林省

  • 松原市
  • 吉林省

  • 白城市
  • 吉林省

  • 白山市
  • 吉林省

  • 辽源市
  • 吉林省

  • 通化市
  • 吉林省

  • 长春市
  • 四川省

  • 乐山市
  • 四川省

  • 内江市
  • 四川省

  • 凉山彝族自治州
  • 四川省

  • 南充市
  • 四川省

  • 宜宾市
  • 四川省

  • 巴中市
  • 四川省

  • 广元市
  • 四川省

  • 广安市
  • 四川省

  • 德阳市
  • 四川省

  • 成都市
  • 四川省

  • 攀枝花市
  • 四川省

  • 泸州市
  • 四川省

  • 甘孜藏族自治州
  • 四川省

  • 眉山市
  • 四川省

  • 绵阳市
  • 四川省

  • 自贡市
  • 四川省

  • 资阳市
  • 四川省

  • 达州市
  • 四川省

  • 遂宁市
  • 四川省

  • 阿坝藏族羌族自治州
  • 四川省

  • 雅安市
  • 天津市

  • 市辖区
  • 宁夏回族自治区

  • 中卫市
  • 宁夏回族自治区

  • 吴忠市
  • 宁夏回族自治区

  • 固原市
  • 宁夏回族自治区

  • 石嘴山市
  • 宁夏回族自治区

  • 银川市
  • 安徽省

  • 亳州市
  • 安徽省

  • 六安市
  • 安徽省

  • 合肥市
  • 安徽省

  • 安庆市
  • 安徽省

  • 宣城市
  • 安徽省

  • 宿州市
  • 安徽省

  • 池州市
  • 安徽省

  • 淮北市
  • 安徽省

  • 淮南市
  • 安徽省

  • 滁州市
  • 安徽省

  • 芜湖市
  • 安徽省

  • 蚌埠市
  • 安徽省

  • 铜陵市
  • 安徽省

  • 阜阳市
  • 安徽省

  • 马鞍山市
  • 安徽省

  • 黄山市
  • 山东省

  • 东营市
  • 山东省

  • 临沂市
  • 山东省

  • 威海市
  • 山东省

  • 德州市
  • 山东省

  • 日照市
  • 山东省

  • 枣庄市
  • 山东省

  • 泰安市
  • 山东省

  • 济南市
  • 山东省

  • 济宁市
  • 山东省

  • 淄博市
  • 山东省

  • 滨州市
  • 山东省

  • 潍坊市
  • 山东省

  • 烟台市
  • 山东省

  • 聊城市
  • 山东省

  • 菏泽市
  • 山东省

  • 青岛市
  • 山西省

  • 临汾市
  • 山西省

  • 吕梁市
  • 山西省

  • 大同市
  • 山西省

  • 太原市
  • 山西省

  • 忻州市
  • 山西省

  • 晋中市
  • 山西省

  • 晋城市
  • 山西省

  • 朔州市
  • 山西省

  • 运城市
  • 山西省

  • 长治市
  • 山西省

  • 阳泉市
  • 广东省

  • 东莞市
  • 广东省

  • 中山市
  • 广东省

  • 云浮市
  • 广东省

  • 佛山市
  • 广东省

  • 广州市
  • 广东省

  • 惠州市
  • 广东省

  • 揭阳市
  • 广东省

  • 梅州市
  • 广东省

  • 汕头市
  • 广东省

  • 汕尾市
  • 广东省

  • 江门市
  • 广东省

  • 河源市
  • 广东省

  • 深圳市
  • 广东省

  • 清远市
  • 广东省

  • 湛江市
  • 广东省

  • 潮州市
  • 广东省

  • 珠海市
  • 广东省

  • 肇庆市
  • 广东省

  • 茂名市
  • 广东省

  • 阳江市
  • 广东省

  • 韶关市
  • 广西壮族自治区

  • 北海市
  • 广西壮族自治区

  • 南宁市
  • 广西壮族自治区

  • 崇左市
  • 广西壮族自治区

  • 来宾市
  • 广西壮族自治区

  • 柳州市
  • 广西壮族自治区

  • 桂林市
  • 广西壮族自治区

  • 梧州市
  • 广西壮族自治区

  • 河池市
  • 广西壮族自治区

  • 玉林市
  • 广西壮族自治区

  • 百色市
  • 广西壮族自治区

  • 贵港市
  • 广西壮族自治区

  • 贺州市
  • 广西壮族自治区

  • 钦州市
  • 广西壮族自治区

  • 防城港市
  • 新疆维吾尔自治区

  • 乌鲁木齐市
  • 新疆维吾尔自治区

  • 伊犁哈萨克自治州
  • 新疆维吾尔自治区

  • 克孜勒苏柯尔克孜自治州
  • 新疆维吾尔自治区

  • 克拉玛依市
  • 新疆维吾尔自治区

  • 博尔塔拉蒙古自治州
  • 新疆维吾尔自治区

  • 吐鲁番市
  • 新疆维吾尔自治区

  • 和田地区
  • 新疆维吾尔自治区

  • 哈密市
  • 新疆维吾尔自治区

  • 喀什地区
  • 新疆维吾尔自治区

  • 塔城地区
  • 新疆维吾尔自治区

  • 巴音郭楞蒙古自治州
  • 新疆维吾尔自治区

  • 昌吉回族自治州
  • 新疆维吾尔自治区

  • 自治区直辖县级行政区划
  • 新疆维吾尔自治区

  • 阿克苏地区
  • 新疆维吾尔自治区

  • 阿勒泰地区
  • 江苏省

  • 南京市
  • 江苏省

  • 南通市
  • 江苏省

  • 宿迁市
  • 江苏省

  • 常州市
  • 江苏省

  • 徐州市
  • 江苏省

  • 扬州市
  • 江苏省

  • 无锡市
  • 江苏省

  • 泰州市
  • 江苏省

  • 淮安市
  • 江苏省

  • 盐城市
  • 江苏省

  • 苏州市
  • 江苏省

  • 连云港市
  • 江苏省

  • 镇江市
  • 江西省

  • 上饶市
  • 江西省

  • 九江市
  • 江西省

  • 南昌市
  • 江西省

  • 吉安市
  • 江西省

  • 宜春市
  • 江西省

  • 抚州市
  • 江西省

  • 新余市
  • 江西省

  • 景德镇市
  • 江西省

  • 萍乡市
  • 江西省

  • 赣州市
  • 江西省

  • 鹰潭市
  • 河北省

  • 保定市
  • 河北省

  • 唐山市
  • 河北省

  • 廊坊市
  • 河北省

  • 张家口市
  • 河北省

  • 承德市
  • 河北省

  • 沧州市
  • 河北省

  • 石家庄市
  • 河北省

  • 秦皇岛市
  • 河北省

  • 衡水市
  • 河北省

  • 邢台市
  • 河北省

  • 邯郸市
  • 河南省

  • 三门峡市
  • 河南省

  • 信阳市
  • 河南省

  • 南阳市
  • 河南省

  • 周口市
  • 河南省

  • 商丘市
  • 河南省

  • 安阳市
  • 河南省

  • 平顶山市
  • 河南省

  • 开封市
  • 河南省

  • 新乡市
  • 河南省

  • 洛阳市
  • 河南省

  • 漯河市
  • 河南省

  • 濮阳市
  • 河南省

  • 焦作市
  • 河南省

  • 省直辖县级行政区划
  • 河南省

  • 许昌市
  • 河南省

  • 郑州市
  • 河南省

  • 驻马店市
  • 河南省

  • 鹤壁市
  • 浙江省

  • 丽水市
  • 浙江省

  • 台州市
  • 浙江省

  • 嘉兴市
  • 浙江省

  • 宁波市
  • 浙江省

  • 杭州市
  • 浙江省

  • 温州市
  • 浙江省

  • 湖州市
  • 浙江省

  • 绍兴市
  • 浙江省

  • 舟山市
  • 浙江省

  • 衢州市
  • 浙江省

  • 金华市
  • 海南省

  • 三亚市
  • 海南省

  • 三沙市
  • 海南省

  • 儋州市
  • 海南省

  • 海口市
  • 海南省

  • 省直辖县级行政区划
  • 湖北省

  • 十堰市
  • 湖北省

  • 咸宁市
  • 湖北省

  • 孝感市
  • 湖北省

  • 宜昌市
  • 湖北省

  • 恩施土家族苗族自治州
  • 湖北省

  • 武汉市
  • 湖北省

  • 省直辖县级行政区划
  • 湖北省

  • 荆州市
  • 湖北省

  • 荆门市
  • 湖北省

  • 襄阳市
  • 湖北省

  • 鄂州市
  • 湖北省

  • 随州市
  • 湖北省

  • 黄冈市
  • 湖北省

  • 黄石市
  • 湖南省

  • 娄底市
  • 湖南省

  • 岳阳市
  • 湖南省

  • 常德市
  • 湖南省

  • 张家界市
  • 湖南省

  • 怀化市
  • 湖南省

  • 株洲市
  • 湖南省

  • 永州市
  • 湖南省

  • 湘潭市
  • 湖南省

  • 湘西土家族苗族自治州
  • 湖南省

  • 益阳市
  • 湖南省

  • 衡阳市
  • 湖南省

  • 邵阳市
  • 湖南省

  • 郴州市
  • 湖南省

  • 长沙市
  • 甘肃省

  • 临夏回族自治州
  • 甘肃省

  • 兰州市
  • 甘肃省

  • 嘉峪关市
  • 甘肃省

  • 天水市
  • 甘肃省

  • 定西市
  • 甘肃省

  • 平凉市
  • 甘肃省

  • 庆阳市
  • 甘肃省

  • 张掖市
  • 甘肃省

  • 武威市
  • 甘肃省

  • 甘南藏族自治州
  • 甘肃省

  • 白银市
  • 甘肃省

  • 酒泉市
  • 甘肃省

  • 金昌市
  • 甘肃省

  • 陇南市
  • 福建省

  • 三明市
  • 福建省

  • 南平市
  • 福建省

  • 厦门市
  • 福建省

  • 宁德市
  • 福建省

  • 泉州市
  • 福建省

  • 漳州市
  • 福建省

  • 福州市
  • 福建省

  • 莆田市
  • 福建省

  • 龙岩市
  • 西藏自治区

  • 山南市
  • 西藏自治区

  • 拉萨市
  • 西藏自治区

  • 日喀则市
  • 西藏自治区

  • 昌都市
  • 西藏自治区

  • 林芝市
  • 西藏自治区

  • 那曲市
  • 西藏自治区

  • 阿里地区
  • 贵州省

  • 六盘水市
  • 贵州省

  • 安顺市
  • 贵州省

  • 毕节市
  • 贵州省

  • 贵阳市
  • 贵州省

  • 遵义市
  • 贵州省

  • 铜仁市
  • 贵州省

  • 黔东南苗族侗族自治州
  • 贵州省

  • 黔南布依族苗族自治州
  • 贵州省

  • 黔西南布依族苗族自治州
  • 辽宁省

  • 丹东市
  • 辽宁省

  • 大连市
  • 辽宁省

  • 抚顺市
  • 辽宁省

  • 朝阳市
  • 辽宁省

  • 本溪市
  • 辽宁省

  • 沈阳市
  • 辽宁省

  • 盘锦市
  • 辽宁省

  • 营口市
  • 辽宁省

  • 葫芦岛市
  • 辽宁省

  • 辽阳市
  • 辽宁省

  • 铁岭市
  • 辽宁省

  • 锦州市
  • 辽宁省

  • 阜新市
  • 辽宁省

  • 鞍山市
  • 重庆市

  • 重庆市

  • 市辖区
  • 陕西省

  • 咸阳市
  • 陕西省

  • 商洛市
  • 陕西省

  • 安康市
  • 陕西省

  • 宝鸡市
  • 陕西省

  • 延安市
  • 陕西省

  • 榆林市
  • 陕西省

  • 汉中市
  • 陕西省

  • 渭南市
  • 陕西省

  • 西安市
  • 陕西省

  • 铜川市
  • 青海省

  • 果洛藏族自治州
  • 青海省

  • 海东市
  • 青海省

  • 海北藏族自治州
  • 青海省

  • 海南藏族自治州
  • 青海省

  • 海西蒙古族藏族自治州
  • 青海省

  • 玉树藏族自治州
  • 青海省

  • 西宁市
  • 青海省

  • 黄南藏族自治州
  • 黑龙江省

  • 七台河市
  • 黑龙江省

  • 伊春市
  • 黑龙江省

  • 佳木斯市
  • 黑龙江省

  • 双鸭山市
  • 黑龙江省

  • 哈尔滨市
  • 黑龙江省

  • 大兴安岭地区
  • 黑龙江省

  • 大庆市
  • 黑龙江省

  • 牡丹江市
  • 黑龙江省

  • 绥化市
  • 黑龙江省

  • 鸡西市
  • 黑龙江省

  • 鹤岗市
  • 黑龙江省

  • 黑河市
  • 黑龙江省

  • 齐齐哈尔市