接口自動化測試一體式解決方案
前戲叨逼叨:
測試多年工作經(jīng)驗匹层,很少有寫文章极谊、博客之類的東西六敬。
其實我這人不愛去寫博客之類的東西碘赖,更多的是靠腦子的總結(jié)。不是腦子好用外构,其實就一句話:懶普泡!就是懶!I蟊唷撼班!
早在幾年前就有記錄的想法,但當時確實因為工作原因 加上懶垒酬,就借口了自己砰嘁。
好了件炉,如今就要奔三的人,該面對的往往都要面對矮湘。
于是覺得是該寫點東西記錄下斟冕,倒不是說要總結(jié)什么的;只是想讓自己經(jīng)歷過的事情缅阳,通過記錄的形式加強印象磕蛇;與此同時,希望能夠給像自己這樣的小白十办,在遇到類似問題時能夠帶來想法秀撇。
所以,第一次寫類似測試技術(shù)博客向族,獻丑呵燕。看官海涵~
第一篇不談理論件相,實踐篇虏等。
叨逼叨結(jié)束!适肠。
2017.8.17 更新:
- 接口實現(xiàn)輔助類的優(yōu)化霍衫。
- 因單接口用例數(shù)量上升,多接口的 .xml 文件管理混亂問題侯养,進行優(yōu)化敦跌。
無聊的背景
測試工作多年,一路以來一直都會伴隨著服務(wù)端的測試逛揩。
那么首當其沖的肯定是接口測試柠傍, 而接口測試中首先聯(lián)想到的是接口自動化測試。
注意:服務(wù)端測試 != 接口測試 != 接口自動化測試 辩稽。這個公式是不等惧笛!找機會再寫篇文章詳細聊聊...
在經(jīng)歷過多中不同的平臺后,毅然而然的覺得通過碼代碼的用例是最靠譜的逞泄。別相信那些帶UI降低編寫接口自動化用例難度的自動化平臺患整,原因不詳!(不想詳細解釋喷众,入坑后自會明白...)
好了各谚,今天介紹一款接口自動化測試的一體式解決方案。(有點夸張到千,其實吧還真是一體式昌渤。)這是入坑后,個人認為在Java大背景服務(wù)開發(fā)下比較理想的解決方案憔四。
最后膀息,接口自動化測試的框架和平臺形形色色般眉,不用評論哪個好,哪個差潜支。只有最合適項目團隊的才是最好的甸赃。(廢話...)
本文代碼github:https://github.com/Jsir07/TestHub
話不多說,先上Jenkins上自助運行用例毁腿,查看報告流程截圖辑奈。也可結(jié)合持續(xù)集成自動觸發(fā)測試服務(wù)苛茂。
一已烤、方案介紹
①. 選型:Java + Maven + Testng + ExtentReports + Git + Retrofit2 + Jenkins
- 使用Java作為項目編程語言。
- 使用Maven作為項目類型妓羊,方便管理架包胯究。
- 使用TestNG作為項目運行框架,方便執(zhí)行測試用例躁绸,生成測試報告裕循。
- 使用ExtentReports作為代替TestNG報告的報告驅(qū)動,二次美化功能净刮,界面更美觀剥哑,內(nèi)容清晰
- 使用Git作為倉庫管理工具,方便管理項目代碼淹父。
- 使用Retrofit2作為API接口自動化項目底層服務(wù)驅(qū)動框架株婴。
- 使用Jenkins作為自動化持續(xù)集成平臺,方便自動編譯暑认,自動打包困介,自動運行測試腳本,郵件發(fā)送測試報告蘸际,通知等座哩。
②. 功能介紹:
- 實現(xiàn)持續(xù)集成測試,自助式測試粮彤,一站式測試平臺根穷。
- 通過Retrofit2作為等常用接口定義與請求方法壁晒,使用方便簡潔减宣。同時可分離接口定義鸭廷、實現(xiàn)請求互躬、響應(yīng)驗證友扰。
- 參數(shù)化驅(qū)動用例運行方式泌霍,目前使用本地配置文件梆靖;可擴展為造數(shù)據(jù)嵌纲。
- 還有...自己體會...
二闯两、環(huán)境安裝與配置
(一)開發(fā)環(huán)境:
- JDK1.7 及以上
- IDEA 社區(qū)版(壕->pro)
- Maven 不限
- Git 不限
- Jenkins 不限
(二)部分環(huán)境安裝細節(jié):
1. JDK 安裝請查閱褥伴。https://www.cnblogs.com/ottox/p/3313540.html
2. Maven 安裝與配置谅将。
-
setting配置,主要是國內(nèi)鏡像 阿里云重慢。https://blog.csdn.net/liuhui_306/article/details/52822152
- 加速饥臂。<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
-
本地localRepository配置。為什么要配置這個似踱?因為默認是放在C盤的隅熙。
Default: ${user.home}/.m2/repository。
jar 太多核芽、太大囚戚!<localRepository>E:\apache-maven-3.5.3\repository</localRepository>
-
命令配置。https://www.cnblogs.com/eagle6688/p/7838224.html
- 為啥配置這個轧简?因為后面Jenkins如果需要在本地運行的話驰坊,需要用到mvn命令。
3. IDEA 安裝請查閱哮独,下載社區(qū)版本即可拳芙。 https://www.jetbrains.com/idea/
編碼設(shè)置UTF-8:https://blog.csdn.net/frankcheng5143/article/details/50779149
字體設(shè)置:https://blog.csdn.net/qq_35246620/article/details/63253518
模板設(shè)置:https://blog.csdn.net/xiaoliulang0324/article/details/79030752
JDK配置:選擇JDK的存放路徑。
-
maven配置:file->settings->搜索maven->
Maven home deirectory: maven存放地址皮璧。
User settings file: maven的setting路徑舟扎。
Local repository: repository 要存放的路徑。 以上配置最好設(shè)置成默認配置悴务,這樣不用針對每個項目配置睹限。File->Other settings -> Default Settings.
4. Git 安裝。
參考:https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%AE%89%E8%A3%85-Git
5. Jenkins本地安裝惨寿,只要安裝不用創(chuàng)建任務(wù)邦泄,后面會有任務(wù)創(chuàng)建。
參考:https://www.cnblogs.com/c9999/p/6399367.html裂垦。
若遇網(wǎng)站需要翻墻顺囊,具體下載安裝請自行百度。
三蕉拢、框架搭建
(一) 項目基礎(chǔ)工程
搭工程特碳,建立基本工程框架,采用maven結(jié)構(gòu)框架工程晕换。 話不多說午乓,先搭建工程。方式:
1.1 IDEA 上闸准,F(xiàn)ile ->New ->Project -> maven. 選maven后益愈,不選任何模板,直接Next。
1.2 填寫對應(yīng)項目信息后蒸其,next敏释。
1.3 繼續(xù)填寫 對應(yīng)信息后,F(xiàn)inish摸袁。
(二)Maven pom.xml文件配置 與多環(huán)境切換
2.1 依賴配置
需要使用到的依賴有testng钥顽、extentreports、retrofit靠汁、fastjson蜂大、okhttp等..
<dependencies>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/logging-interceptor 日志攔截器-->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>3.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.2</version>
<!--<scope>test</scope>-->
<!--作用范圍,默認是test蝶怔。驗證部分被抽象奶浦,不僅test作用域需使用-->
</dependency>
<!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>3.1.5</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.vimalselvam/testng-extentsreport -->
<dependency>
<groupId>com.vimalselvam</groupId>
<artifactId>testng-extentsreport</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson 對象轉(zhuǎn)換器-->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
2.2 配置多環(huán)境切換部分
采用maven環(huán)境切換方式。
-
2.2.1 先配置pom.xml文件的 build節(jié)點添谊。
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <!--掃描替換參數(shù)的文件路徑--> </resource> </resources> <filters> <filter>src/main/filters/filter-${env}.properties</filter> <!--環(huán)境過濾器的配置方式财喳,回頭需要在該路徑下建立對應(yīng)文件--> </filters> <plugins> <plugin> <!--該插件是解決命令下執(zhí)行mvn test指定testng xxx.xml 文件 的配置--> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.0</version> <configuration> <!--為了解決在jenkins maven執(zhí)行test 報告亂碼問題察迟,編碼格式設(shè)置為UTF-8--> <argLine>-Dfile.encoding=UTF-8</argLine> <encoding>UTF-8</encoding> <!--動態(tài)指定執(zhí)行的xml文件斩狱。${project.basedir}項目目錄,${xmlFileName}maven文件--> <suiteXmlFiles> <suiteXmlFile>${project.basedir}/target/classes/testNg/${xmlFileName}</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> <source>8</source> <target>8</target> </configuration> </plugin> </plugins> </build>
-
2.2.2 在pom.xml文件配置properties為了maven打包編譯時后臺一直輸出警告信息扎瓶。導致構(gòu)建失敗所踊。
<!--為了maven打包編譯時后臺一直輸出警告信息。導致構(gòu)建失敗--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <xmlFileName></xmlFileName> </properties>
-
2.2.3 在pom.xml文件配置Properties環(huán)境概荷。多環(huán)境配置參數(shù)切換秕岛。
<profiles> <!-- 開發(fā)環(huán)境,默認激活 --> <profile> <id>dev</id> <properties> <env>dev</env> </properties> </profile> <!-- 生產(chǎn)環(huán)境 --> <profile> <id>product</id> <properties> <env>product</env> </properties> </profile> <!-- 測試環(huán)境 --> <profile> <id>debug</id> <properties> <env>debug</env> </properties> <activation> <activeByDefault>true</activeByDefault><!--默認啟用的是dev環(huán)境配置--> </activation> </profile> </profiles>
2.3 配置環(huán)境切換-文件部分
- 2.3.1 在src/resource下創(chuàng)建env.properties文件误证。
該文件記錄的信息是跟環(huán)境切換相關(guān)的參數(shù)继薛。
如:接口請求不同環(huán)境的host,mongodb愈捅、mysql數(shù)據(jù)庫等遏考,因不同環(huán)境的信息。
例如:api.post.host=${api.post.host}
- 2.3.2 創(chuàng)建src/main/filters/下創(chuàng)建
filter-debug.properties蓝谨、filter-dev.properties灌具、filter-product.properties
用于環(huán)境信息記錄。
詳細信息譬巫,如:api.post.host=http://apidebug.xxx.com:80/
如圖:
(三) testNg配置部分
3.1. 在src/resources/下創(chuàng)建testNg目錄.
src/resources/testNg 目錄是存放測試集合的目錄咖楣,可根據(jù)測試模塊創(chuàng)建對應(yīng)模塊文件夾。
3.1.1 每個文件夾可以是獨立模塊芦昔,每個模塊下可以有模塊的測試集合诱贿。
- 例如,在src/resources/testNg/下創(chuàng)建測試集合:api/search/search-TestSuite.xml咕缎。配置如下:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > <suite name="search_tags-搜索分類-電影首頁測試集合" verbose="1" preserve-order="true"> <parameter name="report.config" value="src/main/resources/config/report/extent-config.xml"/> <parameter name="system.info" value="reporter.config.MySystemInfo"/> <test name="0100.搜索分類-電影首頁-正常場景" preserve-order="true"> <classes> <class name="com.jxq.douban.SearchTagsTest"> <methods> <include name="testcase1"/> </methods> </class> </classes> </test> <test name="0100.搜索分類-TV首頁-正常場景" preserve-order="true"> <classes> <class name="com.jxq.douban.SearchTagsTest"> <methods> <include name="testcase2"/> </methods> </class> </classes> </test> <listeners> <listener class-name="reporter.Listener.MyExtentTestNgFormatter"/> </listeners> </suite>
3.1.2.為了能夠讓所有接口統(tǒng)一運行測試珠十,需建立一個所有的測試集合咸作,測試集合一般放在src/resources/testNg 目錄下。
型如:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="接口測試集合" verbose="1" preserve-order="true">
<parameter name="report.config" value="src/main/resources/config/report/extent-config.xml"/>
<parameter name="system.info" value="reporter.config.MySystemInfo"/>
<suite-files>
<suite-file path="search/SearchTags-TestSuite.xml"/>
</suite-files>
<listeners>
<listener class-name="reporter.Listener.MyExtentTestNgFormatter"/>
</listeners>
</suite>
3.1.3 說明
- 有同學會問:為什么會有這么多inclde name宵睦?
原因是:test里的name是針對一整個testclass的名稱记罚,為了讓每一個測試名稱都能夠展示。
故此把層級調(diào)整了壳嚎。調(diào)整后的層級對應(yīng)如下:
testng層級 | 接口映射關(guān)系 |
---|---|
test | 接口具體的testcase |
suite | 具體接口所有用例集合 |
總suite | 所有接口測試集合 |
需要說明的是桐智,在testng接口層級管理上,每個項目可以有各自的方式烟馅,只要符合你的是好的说庭。
- 這里添加了parameter、listener郑趁,是用于替換testng默認報告刊驴,使用ExtentReported。關(guān)于ExtentReported后面會有說明寡润。
<parameter name="report.config" value="src/main/resources/config/report/extent-config.xml"/>
<parameter name="system.info" value="reporter.config.MySystemInfo"/>
<listeners>
<listener class-name="reporter.Listener.MyExtentTestNgFormatter"/>
</listeners>
(四) TestCase測試用例
4.1 Test用例類
- 首先捆憎,滿足maven工程結(jié)構(gòu)在src/test目錄下建立對應(yīng)的測試用例類。
- 其次梭纹,測試用例類的命名也滿足maven在單元測試時的規(guī)范躲惰。類名以Test結(jié)尾.
如:SearchTagsTest.java
- 最后,根據(jù)各模塊分類建立對應(yīng)模塊包变抽。
4.2 測試用例怎么寫础拨?
其實網(wǎng)上有很多關(guān)于TestNg的文章,這邊就不做過多介紹了绍载。
官網(wǎng):https://testng.org/doc/index.html
也可查閱:https://www.yiibai.com/testng/
寫接口用例诡宗,不在與形式,形式網(wǎng)上很多击儡。
最重要的是編寫的層次與心得塔沃。回頭有空再整理下曙痘。
(五) extentreports報告
extentreports是什么芳悲?網(wǎng)上有很多關(guān)于使用extentreports替代TestNg自帶報告。原因是什么边坤?
漂亮名扛。先上張圖。
官網(wǎng)很重要:http://extentreports.com/. 其實官網(wǎng)已經(jīng)給了很多demo了茧痒,這里我根據(jù)自己的經(jīng)驗進行了配置肮韧。
testNg原有報告有點丑,信息整理有點亂。ExtentReports是用于替換testNg原有的報告弄企。也可以使用ReportNg超燃,個人偏好ExtentReports樣式。
5.1 強制重寫ExtentTestNgFormatter類
強制重寫EExtentTestNgFormatter類主要是以下兩點原因:
①拘领、為了能夠在報告中展示更多狀態(tài)類型的測試結(jié)果意乓,例如:成功、失敗约素、警告届良、跳過等測試狀態(tài)結(jié)果。
②圣猎、因為不支持cdn.rawgit.com訪問士葫,故替css訪問方式。
方式如下:下載ExtentReportes源碼送悔,找到ExtentTestNgFormatter類慢显。
-
5.1.1 在創(chuàng)建類:src/main/java/reporter/listener路徑下MyExtentTestNgFormatter.java類。
MyExtentTestNgFormatter直接從ExtentTestNgFormatter繼承欠啤。public class MyExtentTestNgFormatter extends ExtentTestNgFormatter {
-
5.1.2 構(gòu)造方法加入
htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
MyExtentTestNgFormatter 類荚藻,代碼如下:public MyExtentTestNgFormatter() { setInstance(this); testRunnerOutput = new ArrayList<>(); String reportPathStr = System.getProperty("reportPath"); File reportPath; try { reportPath = new File(reportPathStr); } catch (NullPointerException e) { reportPath = new File(TestNG.DEFAULT_OUTPUTDIR); } if (!reportPath.exists()) { if (!reportPath.mkdirs()) { throw new RuntimeException("Failed to create output run directory"); } } File reportFile = new File(reportPath, "report.html"); File emailReportFile = new File(reportPath, "emailable-report.html"); htmlReporter = new ExtentHtmlReporter(reportFile); EmailReporter emailReporter = new EmailReporter(emailReportFile); reporter = new ExtentReports(); // 如果cdn.rawgit.com訪問不了,可以設(shè)置為:ResourceCDN.EXTENTREPORTS或者ResourceCDN.GITHUB htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS); reporter.attachReporter(htmlReporter, emailReporter); }
-
5.1.3 接著在onstart方法重寫功能跪妥。
用了很粗暴的方式鞋喇,新建了一個類名為MyReporter声滥,一個靜態(tài)ExtentTest的引用眉撵。-
① reporter.Listener包下MyReporter.java
public class MyReporter { public static ExtentTest report; }
-
② MyExtentTestNgFormatter.java
public void onStart(ITestContext iTestContext) { ISuite iSuite = iTestContext.getSuite(); ExtentTest suite = (ExtentTest) iSuite.getAttribute(SUITE_ATTR); ExtentTest testContext = suite.createNode(iTestContext.getName()); // 將MyReporter.report靜態(tài)引用賦值為testContext。 // testContext是@Test每個測試用例時需要的落塑。report.log可以跟隨具體的測試用例纽疟。另請查閱源碼。 MyReporter.report = testContext; iTestContext.setAttribute("testContext", testContext); }
-
-
5.1.4 順帶提一句憾赁,測試報告默認是在工程根目錄下創(chuàng)建test-output/文件夾下污朽,名為report.html、emailable-report.html龙考◇∷粒可根據(jù)各自需求在構(gòu)造方法中修改。
public MyExtentTestNgFormatter() { setInstance(this); testRunnerOutput = new ArrayList<>(); // reportPath報告路徑 String reportPathStr = System.getProperty("reportPath"); File reportPath; try { reportPath = new File(reportPathStr); } catch (NullPointerException e) { reportPath = new File(TestNG.DEFAULT_OUTPUTDIR); } if (!reportPath.exists()) { if (!reportPath.mkdirs()) { throw new RuntimeException("Failed to create output run directory"); } } // 報告名report.html File reportFile = new File(reportPath, "report.html"); // 郵件報告名emailable-report.html File emailReportFile = new File(reportPath, "emailable-report.html"); htmlReporter = new ExtentHtmlReporter(reportFile); EmailReporter emailReporter = new EmailReporter(emailReportFile); reporter = new ExtentReports(); reporter.attachReporter(htmlReporter, emailReporter); }
-
5.1.5 順帶再提一句晦款,report.log 可以有多種玩法炎功。
// 根據(jù)狀態(tài)不同添加報告。型如警告 MyReporter.report.log(Status.WARNING, "接口耗時(ms):" + String.valueOf(time));
直接從TestClass中運行時會報MyReporter.report的空指針錯誤缓溅,需做個判空即可蛇损。
5.2 導入MyExtentTestNgFormatter監(jiān)聽類
在測試集合.xml文件中導入Listener監(jiān)聽類。
<listeners>
<listener class-name="reporter.Listener.MyExtentTestNgFormatter"/>
</listeners>
5.3 配置報告信息
extent reporters支持報告的配置。目前支持的配置內(nèi)容有title淤齐、主題等股囊。
-
先在src/resources/目錄下添加 config/report/extent-config.xml。
- 配置內(nèi)容
<?xml version="1.0" encoding="UTF-8"?> <extentreports> <configuration> <timeStampFormat>yyyy-MM-dd HH:mm:ss</timeStampFormat> <!-- report theme --> <!-- standard, dark 個人喜好暗色 --> <theme>dark</theme> <!-- document encoding --> <!-- defaults to UTF-8 --> <encoding>UTF-8</encoding> <!-- protocol for script and stylesheets --> <!-- defaults to https --> <protocol>https</protocol> <!-- title of the document --> <documentTitle>QA-接口自動化測試報告</documentTitle> <!-- report name - displayed at top-nav --> <reportName>QA-接口自動化測試報告</reportName> <!-- report headline - displayed at top-nav, after reportHeadline --> <reportHeadline>接口自動化測試報告</reportHeadline> <!-- global date format override --> <!-- defaults to yyyy-MM-dd --> <dateFormat>yyyy-MM-dd</dateFormat> <!-- global time format override --> <!-- defaults to HH:mm:ss --> <timeFormat>HH:mm:ss</timeFormat> <!-- custom javascript --> <scripts> <![CDATA[ $(document).ready(function() { }); ]]> </scripts> <!-- custom styles --> <styles> <![CDATA[ ]]> </styles> </configuration> </extentreports>
5.4 添加系統(tǒng)信息
不多說更啄,上圖稚疹。
可用于添加系統(tǒng)信息,例如:db的配置信息祭务,人員信息贫堰,環(huán)境信息等。根據(jù)項目實際情況添加待牵。
-
在src/main/java/reporter/config目錄下創(chuàng)建MySystemInfo.java類其屏,繼承SystemInfo接口。
public class MySystemInfo implements SystemInfo { @Override public Map<String, String> getSystemInfo() { InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("env.properties"); Properties properties = new Properties(); Map<String, String> systemInfo = new HashMap<>(); try { properties.load(inputStream); systemInfo.put("environment", properties.getProperty("Environment")); systemInfo.put("sqlURL", properties.getProperty("ESsql.URL")); systemInfo.put("redisHost", properties.getProperty("redis.host")); systemInfo.put("redisPort", properties.getProperty("redis.port")); systemInfo.put("mongodbHost", properties.getProperty("mongodb.host")); systemInfo.put("mongodbPort", properties.getProperty("mongodb.port")); systemInfo.put("測試人員", "jxq"); } catch (IOException e) { e.printStackTrace(); } return systemInfo; } }
至此缨该,extentreports美化報告完成偎行。
(六). retrofit2.0--Http接口測試驅(qū)動原力
其實Java的Http客戶端有很多,例如HTTPClient贰拿、OKHttp蛤袒、retrofit等。膨更。妙真。
為什么那么多Http客戶端會選擇retrofit?用一個圖見證他的實力
真正的原因
接口定義與實現(xiàn)分離
retrofit2.0可將Http接口定義與請求實現(xiàn)分離荚守;通過制定interface定義接口珍德。
網(wǎng)上有很多關(guān)于retrofit2.0的教程,這里就不再班門弄斧了矗漾,度娘即可锈候。參考:https://blog.csdn.net/carson_ho/article/details/73732076
附上本項目方式。
6.1 具體Http Api的定義interface敞贡。新建ISearch interface泵琳。
public interface ISearch {
@GET("j/search_tags")
Call<MovieResponseVO> searchTags(@Query("type") String type, @Query("source") String source);
}
6.2 HttpBase基礎(chǔ)類提供原動力。
HttpBase類中提供了Retrofit基礎(chǔ)誊役。
同時获列,我考慮到了日常控制臺和測試報告上都需要看到對應(yīng)請求信息蛔垢,故此在HttpClient中默認加入了日志攔截器击孩;日志攔截器的實現(xiàn)方法里,用Reportes.log記錄到日志中啦桌。
并且溯壶,考慮到實際項目中每個Http請求都會有對應(yīng)類似RequestHeader及皂、RequestBody的加密簽名等,預留了攔截器且改。
可在HttpBase構(gòu)造方法時傳入對應(yīng)攔截器验烧。
對應(yīng)的攔截器可以通過實現(xiàn)接口Interceptor,做對應(yīng)項目需求操作又跛。
先看代碼碍拆。
public class HttpBase {
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private Retrofit retrofit;
private String host;
/**
* 構(gòu)造方法(1個參數(shù))
* 只傳Host,默認沒有使用攔截器慨蓝。
*
* @param host 訪問域名host
*/
public HttpBase(String host) {
init(host, null);
}
/**
* 構(gòu)造方法(2個參數(shù))
* 只傳Host感混,默認使用日志攔截器。
*
* @param host 訪問域名host
* @param interceptor 自定義攔截器
*/
public HttpBase(String host, Interceptor interceptor) {
init(host, interceptor);
}
/**
* 初始化方法
*
* @param host 訪問域名host
* @param interceptor 自定義攔截器
*/
private void init(String host, Interceptor interceptor) {
OkHttpClient.Builder client = getHttpClient(interceptor);
retrofit = new Retrofit.Builder()
.baseUrl(host)
.client(client.build())
.addConverterFactory(RespVoConverterFactory.create())
.build();
}
/**
* 獲取HttpClient.Builder 方法礼烈。
* 默認添加了弧满,基礎(chǔ)日志攔截器
*
* @param interceptor 攔截器
* @return HttpClient.Builder對象
*/
private OkHttpClient.Builder getHttpClient(Interceptor interceptor) {
HttpLoggingInterceptor logging = getHttpLoggingInterceptor();
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true);
if (interceptor != null) {
builder.addInterceptor(interceptor);
}
builder.addInterceptor(logging);
return builder;
}
/**
* 日志攔截器
*
* @return
*/
private HttpLoggingInterceptor getHttpLoggingInterceptor() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Reporter.log("RetrofitLog--> " + message, true);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);//Level中還有其他等級. 設(shè)置打印內(nèi)容級別到Body。
return logging;
}
/**
* retrofit構(gòu)建方法
*
* @param clazz 泛型類
* @param <T> 泛型類
* @return 泛型類
*/
public <T> T create(Class<T> clazz) {
return retrofit.create(clazz);
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
}
6.3 集成HttpBase的Http Api接口請求方法類
這里需要說明下此熬,為什么需要有這個類的存在庭呜?
其實在Retrofit已經(jīng)可以用4行的代碼實現(xiàn)Http請求了,如下:
HttpBase httpBase = new HttpBase(host);
ISearch iSearch = httpBase.create(ISearch.class);
Call<MovieResponseVO> call = iSearch.searchTags(type, source);
Response<MovieResponseVO> response = call.execute();
看了上面的4行代碼犀忱,每次都需要寫也是挺麻煩的募谎。
所以抽出來,讓編寫測試用例驗證更簡潔點阴汇。
抽取后的代碼如下:
public class HttpSearch extends HttpBase {
private ISearch iSearch;
public HttpSearch(String host) {
super(host);
iSearch = super.create(ISearch.class);
}
public Response<MovieResponseVO> searchTags(String type, String source) throws IOException {
Call<MovieResponseVO> call = iSearch.searchTags(type, source);
return call.execute();
}
// 同模塊下数冬,新增的接口可添加到這里。
// public Response<MovieResponseVO> searchTags(String type, String source) throws IOException {
// Call<MovieResponseVO> call = iSearch.searchTags(type, source);
// return call.execute();
// }
}
6.4 使用JsonSchema驗證基礎(chǔ)響應(yīng)體
Http響應(yīng)體非Json格式搀庶,可跳過該步驟拐纱。
這里引入了JsonSchema來做基礎(chǔ)驗證,減少了Http響應(yīng)返回帶來的大量對象基礎(chǔ)驗證地来。
方式如下:
- 6.4.1 pom.xml 依賴引入
<!--json schema start-->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.6</version>
</dependency>
<!--json schema end-->
- 6.4.2 簡單抽象JsonSchemaUtils工具類戳玫。
直接看代碼。
/**
* JsonSchema工具類
*/
public class JsonSchemaUtils {
/**
* 從指定路徑讀取Schema信息
*
* @param filePath Schema路徑
* @return JsonNode型Schema
* @throws IOException 拋出IO異常
*/
private static JsonNode readJSONfile(String filePath) throws IOException {
InputStream stream = JsonSchemaUtils.class.getClassLoader().getResourceAsStream(filePath);
return new JsonNodeReader().fromInputStream(stream);
}
/**
* 將Json的String型轉(zhuǎn)JsonNode類型
*
* @param str 需要轉(zhuǎn)換的Json String對象
* @return 轉(zhuǎn)換JsonNode對象
* @throws IOException 拋出IO異常
*/
private static JsonNode readJSONStr(String str) throws IOException {
return new ObjectMapper().readTree(str);
}
/**
* 將需要驗證的JsonNode 與 JsonSchema標準對象 進行比較
*
* @param schema schema標準對象
* @param data 需要比對的Schema對象
*/
private static void assertJsonSchema(JsonNode schema, JsonNode data) {
ProcessingReport report = JsonSchemaFactory.byDefault().getValidator().validateUnchecked(schema, data);
if (!report.isSuccess()) {
for (ProcessingMessage aReport : report) {
Reporter.log(aReport.getMessage(), true);
}
}
Assert.assertTrue(report.isSuccess());
}
/**
* 將需要驗證的response 與 JsonSchema標準對象 進行比較
*
* @param schemaPath JsonSchema標準的路徑
* @param response 需要驗證的response
* @throws IOException 拋出IO異常
*/
public static void assertResponseJsonSchema(String schemaPath, String response) throws IOException {
JsonNode jsonSchema = readJSONfile(schemaPath);
JsonNode responseJN = readJSONStr(response);
assertJsonSchema(jsonSchema, responseJN);
}
}
這里已經(jīng)將最后抽成簡單方法供使用未斑,只需傳入schemaPath路勁、以及需要驗證的對象币绩。
- 6.4.3 Http響應(yīng)體保存到本地
- ①蜡秽、可以通過客戶端抓包獲取得到Http響應(yīng)體、或者開發(fā)接口定義文檔 等方式缆镣,得到最后Http響應(yīng)體的Json對象芽突。(注意:響應(yīng)體內(nèi)容盡量全面,這樣在驗證時也可以盡可能驗證)
- ②董瞻、將請求響應(yīng)體通過 https://jsonschema.net/ 寞蚌,在線驗證得到JsonSchema信息田巴。
- ③、根據(jù)接口響應(yīng)需求挟秤,做基礎(chǔ)驗證配置壹哺。例如,這里將tags字段認為是必須存在的參數(shù)艘刚。
完整Schema約束文件如下管宵,并將此文件保存到resources目錄對應(yīng)模塊下。
{
"$id": "http://example.com/example.json",
"type": "object",
"properties": {
"tags": {
"$id": "/properties/tags",
"type": "array",
"items": {
"$id": "/properties/tags/items",
"type": "string",
"title": "The 0th Schema ",
"default": "",
"examples": [
"熱門",
"最新"
]
}
}
},
"required": [
"tags"
]
}
6.5 TestCase測試用例編寫攀甚。
public class SearchTagsTest {
private static Properties properties;
private static HttpSearch implSearch;
private static String SCHEMA_PATH = "parameters/search/schema/SearchTagsMovie.json";
@BeforeSuite
public void beforeSuite() throws IOException {
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("env.properties");
properties = new Properties();
properties.load(stream);
String host = properties.getProperty("douban.host");
implSearch = new HttpSearch(host);
stream = this.getClass().getClassLoader().getResourceAsStream("parameters/search/SearchTagsParams.properties");
properties.load(stream);
stream = this.getClass().getClassLoader().getResourceAsStream("");
stream.close();
}
// 注意!!! @Test 注釋內(nèi)加入了description 用于描述該測試用例箩朴,(例如:描述測試目標,對象秋度,參數(shù)炸庞,業(yè)務(wù)流程,測試方法等...)
@Test(description = "電影首頁荚斯。類別:type=movie source=index")
public void testcase1() throws IOException {
String type = properties.getProperty("testcase1.req.type");
String source = properties.getProperty("testcase1.req.source");
Response<MovieResponseVO> response = implSearch.searchTags(type, source);
MovieResponseVO body = response.body();
Assert.assertNotNull(body, "response.body()");
// 響應(yīng)返回內(nèi)容想通過schema標準校驗
JsonSchemaUtils.assertResponseJsonSchema(SCHEMA_PATH, JSONObject.toJSONString(body));
// 再Json化成對象
Assert.assertNotNull(body.getTags(), "tags");
}
@Test(threadPoolSize = 10, invocationCount = 100, invocationTimeOut = 3, description = "Tv首頁燕雁。類別:type=tv source=index")
public void testcase2() throws IOException {
String type = properties.getProperty("testcase2.req.type");
String source = properties.getProperty("testcase2.req.source");
Response<MovieResponseVO> response = implSearch.searchTags(type, source);
MovieResponseVO body = response.body();
Assert.assertNotNull(body, "response.body()");
JsonSchemaUtils.assertResponseJsonSchema(SCHEMA_PATH, JSONObject.toJSONString(body));
Assert.assertNotNull(body.getTags(), "tags");
}
}
至此,TestNg測試用例部分全部完成鲸拥。
四拐格、Jenkins部分配置
Jenkins的安裝上面已有說明,這里不重復刑赶。
(一) Jenkins插件
1.插件列表
需要使用到的插件有:
- Maven Integration plugin
- HTML Publisher plugin
- Dingding[釘釘] Plugin
- TestNG Results
- Groovy
- Parameterized Trigger Plugin
2. Jenkins插件安裝
怎么安裝插件捏浊?
Jenkins-》系統(tǒng)管理-》插件管理-》搜索插件-》安裝即可
3. 插件說明
Maven Integration plugin -必備!
Maven構(gòu)建插件撞叨,使用簡單方便金踪。HTML Publisher plugin -必備!
extentreporets美化報告替換testng就是為了好看牵敷,但要在jenkins中展示必須安裝此插件胡岔。Groovy -必備!
Jenkins不支持異類樣式CSS枷餐,所以Groovy插件是為了解決HTML Publisher plugin在展示extentreporets時能夠正確美麗的作用靶瘸。Dingding[釘釘] Plugin -必備!
測試用例構(gòu)建結(jié)果的通知毛肋。網(wǎng)上很多說用郵件怨咪,說實話使用場景最頻繁高效的應(yīng)該是IM靠譜。這個插件就是解決測試結(jié)果的通知润匙。TestNG Results - 非必備
TestNg測試結(jié)果收集诗眨,統(tǒng)計運行結(jié)果數(shù)據(jù)。Parameterized Trigger Pl ugin - 非必備
依賴構(gòu)建傳參插件孕讳。http://note.youdao.com/noteshare?id=c56333317d3078b36b2479fdf8fe68d7&sub=wcp1530172849180570
(二)Jenkins新建任務(wù)配置
在插件安裝完后匠楚,開始任務(wù)的新建配置巍膘。
-
新建一個maven項目。
(三)General配置
-
丟棄舊的構(gòu)建配置 -可配
該配置根據(jù)需求配置芋簿。
(四) 構(gòu)建配置-maven配置
在Jenkins使用Maven構(gòu)建項目自動化測試前峡懈,先通過本地使用maven測試是否通過。
這里本來要將參數(shù)化構(gòu)建益咬,但參數(shù)化構(gòu)建前先說明下是如何利用maven構(gòu)建測試的逮诲。
-
- 檢查pom.xml配置中指定的suiteXmlFile對象。
<suiteXmlFiles> <!--用于根據(jù)maven傳入的文件幽告,運行maven test測試集合對象梅鹦。 ${xmlFileName}是maven命令替換對象,別忘了添加properties中的xmlFileName--> <suiteXmlFile>${project.basedir}/target/classes/testNg/${xmlFileName}</suiteXmlFile> <!--在IEDA上運行maven test命令時冗锁,可打開該注釋使用完整測試集合--> <!--<suiteXmlFile>${project.basedir}/target/classes/testNg/api/testng.xml</suiteXmlFile>--> </suiteXmlFiles> <properties> <xmlFileName></xmlFileName> </properties>
-
- 先在IDEA上驗證maven test是否生效齐唆?
在
<suiteXmlFile>${project.basedir}/target/classes/testNg/api/testng.xml</suiteXmlFile>
開啟后,使用maven test驗證是否成功冻河。如下圖:
-
- 通過terminal命令驗證maven test是否生效
- 在2.3.1驗證通過后箍邮,pom.xml注釋
<suiteXmlFile>${project.basedir}/target/classes/testNg/api/testng.xml</suiteXmlFile>
. - 打開
<suiteXmlFile>${project.basedir}/target/classes/testNg/${xmlFileName}</suiteXmlFile>
- 進入terminal命令驗證maven test是否生效。在命令行上輸入
mvn clean test -DxmlFileName=testng.xml
- 驗證maven test 是否正確叨叙。
-
- 嘮叨編碼問題
我在執(zhí)行上面的命令時锭弊,maven一直提示警告信息-編碼問題鬓椭;該警告信息原先我本不太在意胧辽,因為配置沒有問題。
可后來疙挺,命令執(zhí)行一直報錯钮呀〗0埃看了報錯信息都指向了非編碼問題。也就把我引向了其他錯誤解決區(qū)域爽醋。
不得不說蚁署,maven的提示還是要重頭到尾認真看。因為真正報錯誤的地方不一定是[error]提示蚂四。
警告信息是: [WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!如何解決該問題呢光戈?在pom.xml上加入如下配置。
// 這個配置由于被誤刪了证杭,導致花費了半天解決田度。。解愤。 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <xmlFileName></xmlFileName> </properties>
(五) 配置構(gòu)建-maven配置信息。
回到Jenkins界面配置maven信息乎莉。
-
5.1 先在Jenkins新建任務(wù)送讲,構(gòu)建模塊奸笤,增加構(gòu)建步驟 - 調(diào)用頂層maven目標。
(需要注意下哼鬓,這里寫的是中文监右,根據(jù)不同的Jenkins版本該名稱可能是英文的)
-
5.2 然后配置信息如下。在目標加入命令信息:clean test -P%env% -DxmlFileName=%xmlFileName%
5.3命令解釋:clean test -P%env% -DxmlFileName=%xmlFileName%
- maven參數(shù)化替換使用的占位符是 %xxx%
- -P%env% 指定maven運行的環(huán)境异希,該環(huán)境信息與pom.xml 配置的信息一直健盒。同時,-P%env% 用于參數(shù)化構(gòu)建傳參使用称簿,后面會有介紹扣癣。
- -DxmlFileName=%xmlFileName% 指定maven test 運行的測試集合對象。用于參數(shù)化構(gòu)建傳參使用憨降,后面介紹父虑。
(六) 參數(shù)化構(gòu)建過程 配置
-
6.1添加參數(shù) 選擇是 【選項參數(shù)】。
-
6.2完整配置信息如下圖授药。
6.3參數(shù)名稱xmlFileName士嚎,對應(yīng)maven構(gòu)建中的-DxmlFileName=%xmlFileName%,再對應(yīng)pom.xml中的
<suiteXmlFile>${project.basedir}/target/classes/testNg/${xmlFileName}</suiteXmlFile>
加入需要運行的集合選項悔叽。6.4 同樣莱衩,env對應(yīng)maven構(gòu)建中的 -P%env% ,再對應(yīng)pom.xml中的build信息娇澎。
加入運行的環(huán)境選項笨蚁。
(七) 源碼管理配置
這個配置網(wǎng)上有很多詳細文檔,這里不重復九火。具體度娘查看赚窃。
(八) 構(gòu)建觸發(fā)器
> 這個配置可根據(jù)實際項目需求配置。個人建議: 接口自動化測試中的自動化最核心的是結(jié)合持續(xù)構(gòu)建岔激。
> 所以建議配置“其他工程構(gòu)建后觸發(fā)”勒极,填入所需測試的服務(wù)端項目名稱即可。當然要在一個Jenkins中虑鼎。
(九) 構(gòu)建信息配置
> 上面已經(jīng)配置了“調(diào)用頂層Maven目標”辱匿,然后還需要配置Groovy script。
> 配置Groovy script的目的是讓Http Reported插件css能用炫彩,同時不用擔心jenkins重啟匾七。
配置Groovy script前保障Groovy 插件已經(jīng)安裝。
-
增加構(gòu)建步驟“Execute system Groovy script” 江兢,選擇Groovy command昨忆,填入
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")
(十) 構(gòu)建后操作信息配置
9.1. publish html reports
加入publish html reports步驟。
- HTML directory to archive: 報告路徑杉允。 填寫extentreports默認輸出路徑:test-output\
- Index page[s] : 報告索引名稱邑贴。填寫extentreports默認報告名稱:report.html
- Keep past HTML reports: 保留報告席里,勾選!不多說拢驾。
9.2 publish html reports
publish testng results 配置奖磁。默認**/testng-results.xml 即可。
為什么要testng默認報告繁疤? 因為需要統(tǒng)計分析時查看咖为。 當然這個是可選的。
9.3. 釘釘通知器配置
怎么玩轉(zhuǎn)釘釘消息稠腊?查看https://blog.csdn.net/workdsz/article/details/77531802
- 填入access token躁染。
4. 構(gòu)建后操作信息配置 釘釘通知器配置 二次開發(fā) - 可選
http://www.51testing.com/html/25/n-3723525.html
(十一) 構(gòu)建測試
-
11.1 build with parameters
-
11.2 構(gòu)建成功后 在 HTML Report上查看
-
11.3 構(gòu)建成功后 在 TestNG Results上查看
-
11.4 構(gòu)建成功后 在 釘釘上查看
五、工程目錄講解 與 接口測試用例編寫步驟
(一) 工程目錄講解
先上圖說明
(二) 接口測試用例編寫步驟
1. 目標:具體Htpp接口定義的熟悉麻养、理解褐啡。
注意:Http 請求行、請求頭鳖昌、請求體备畦;響應(yīng)行、響應(yīng)頭许昨、響應(yīng)體
- 可通過查看開發(fā)wiki文檔懂盐,或者通過抓包等手段達到。
2. 具體Htpp接口的定義 - Host
- 2.1 將不同環(huán)境的Host地址配置在env.properties文件
- 2.2 然后在根據(jù)不同環(huán)境糕档,配置不同properties文件莉恼,中對應(yīng)的host信息。filter-debug.properties速那、filter-dev.properties俐银、filter-product.properties。
3. 具體Htpp接口的定義 - interface
- 3.1 在src/main/java/下com.xxx.api.下新建對應(yīng)模塊端仰,例如article
- 一個模塊文件夾下存放:接口定義的interface捶惜、接口定義的實現(xiàn)類。
- 3.2 在article下新建具體的接口定義interface
public interface IArticle { @POST("article/feed") Call<ResponseBody> articleFeed(@Query("tid") String tid, @Body RequestBody requestBody); }
4. 具體Htpp接口的定義實現(xiàn) - implement
- 4.1 在article下新建具體的接口定義實現(xiàn)
為什么要有這個類荔烧?
原因有1.簡化接口調(diào)用代碼吱七,直接通過靜態(tài)方法調(diào)用。 2. 當遇到接口需要特殊處理時鹤竭,可通過該類進行擴展踊餐。
public class ImplArticle extends HttpBase {
private IArticle iArticle;
public ImplArticle(String host) {
super(host);
iArticle = super.create(IArticle.class);
}
public Response<ResponseBodyVo> articleFeed(String tid, String requestBody) throws IOException {
Call<ResponseBodyVo> call = iArticle.articleFeed(tid, RequestBody.create(HttpBase.JSON, requestBody));
return call.execute();
}
}
5. 編寫測試用例 -xxxTest
-
5.1 在test/java 目錄下新建對應(yīng)測試模塊的文件夾 ,例如:article
- 一個接口用例類臀稚,對應(yīng)一個文件夾吝岭。
-
5.2 在test/java/article 目錄下新建測試用例類。
- 開始編寫接口測試類。
public class ArticleFeedTest { private static String HOST; private static Properties properties; @BeforeSuite public void beforeSuite() throws IOException { InputStream stream = this.getClass().getClassLoader().getResourceAsStream("env.properties"); properties = new Properties(); properties.load(stream); HOST = properties.getProperty("api.newsapi.host"); stream = this.getClass().getClassLoader().getResourceAsStream("parameters/api/article/ArticleFeedParam.properties"); properties.load(stream); stream.close(); } @Test(description = "獲取推薦文章信息流(下拉方式)") public void testcase1() throws IOException { String reques = properties.getProperty("testcase1.requestBody"); String response = ImplArticle.articleFeed(HOST, "tid", reques); ResponseBodyVo responseBodyVo = JSONObject.parseObject(response, ResponseBodyVo.class); assertResponseBody(responseBodyVo); }
// 注解 @Test 中的描述信息苍碟,最后可以在報告中體現(xiàn)酒觅。
@Test(description = "獲取推薦文章信息流(上拉方式)")
public void testcase2() throws IOException {
String reques = properties.getProperty("testcase1.requestBody");
String response = ImplArticle.articleFeed(HOST, "tid", reques);
ResponseBodyVo responseBodyVo = JSONObject.parseObject(response, ResponseBodyVo.class);
assertResponseBody(responseBodyVo);
}
}
##### 6. 具體接口測試用例suite集合制作
- 在testNg/api/article/ArticleFeed-TestSuite.xml下創(chuàng)建suite集合
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="article/feed-接口測試集合" verbose="1" preserve-order="true">
<parameter name="report.config" value="src/main/resources/config/report/extent-config.xml"/>
<parameter name="system.info" value="reporter.config.MySystemInfo"/>
<test name="ArticleFeedTest接口測試集合" preserve-order="true">
<classes>
<class name="com.api.article.ArticleFeedTest"/>
</classes>
</test>
<listeners>
<listener class-name="reporter.Listener.MyExtentTestNgFormatter"/>
</listeners>
</suite>
##### 7. 所有接口測試用例suite集合制作
- 在testNg/api/APICollection-TestSuite.xml下創(chuàng)建suite集合
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="接口測試集合" verbose="1" preserve-order="true">
<parameter name="report.config" value="src/main/resources/config/report/extent-config.xml"/>
<parameter name="system.info" value="reporter.config.MySystemInfo"/>
<suite-files>
<suite-file path="article/ArticleFeed-TestSuite.xml"/>
<suite-file path="post/PostFeed-TestSuite.xml"/>
<suite-file path="push/RegisterToken-TestSuite.xml"/>
<suite-file path="sys/SysGetConfig-TestSuite.xml"/>
<suite-file path="sys/SysGetRegions-TestSuite.xml"/>
<suite-file path="registerDevice/RegisterDevice-TestSuite.xml"/>
</suite-files>
<listeners>
<listener class-name="reporter.Listener.MyExtentTestNgFormatter"/>
</listeners>
</suite>
#### 寫在最后
其實撮执,接口自動化測試平臺的搞起來不難微峰。
推動平臺接入到持續(xù)集成,將測試變成一種服務(wù)抒钱,更快更及時的服務(wù)于項目蜓肆,才是重點。
正所謂:wiki一定谋币,開發(fā)未動仗扬,接口已行。
而蕾额,服務(wù)端測試才挑戰(zhàn)早芭。知識儲備的深度決定了,測試的深度诅蝶。
個人GitHub: https://github.com/Jsir07/TestHub
歡迎Watch + Fork
end...