引言
這篇文章主要介紹筆者從經(jīng)歷過的項目中琼掠,看到自己或者項目組QA在產(chǎn)品迭代中的軟肋拒垃。認(rèn)為可以通過另外一種思路來改善這些弱點。希望能夠有助于QA最大化的做好質(zhì)量保障工作瓷蛙。
產(chǎn)品迭代中QA自身的Bug(軟肋)是什么悼瓮?
需求偏于口頭傳述
產(chǎn)品的快速迭代,可以迅速滿足用戶需求艰猬,然而卻也有一些后遺癥谤牡,比如部分需求描述偏向于口頭傳述,文檔后于實現(xiàn)姥宝,會給QA工作造成比較大的困難翅萤。所以在堅守一些固有可靠的測試流程之外,我們需要想一些新的辦法腊满。
需求和實現(xiàn)銜接不能達(dá)到無縫連接
測試的起點是明確測試的需求套么,然而有些很具體的問題,需要幫助開發(fā)定位問題的時候碳蛋,需求只定義了一些比較粗的業(yè)務(wù)目標(biāo)胚泌,然而具體實現(xiàn)由開發(fā)掌握。這里的銜接過程肃弟,QA是袖手旁觀呢玷室,還是參與其中。筆者認(rèn)為后者可能可以更深入的接近實現(xiàn)笤受,達(dá)到最大化的質(zhì)量保障穷缤。
是時候開拓一種新思路了。Think as developer箩兽,從閱讀并深入理解業(yè)務(wù)實現(xiàn)框架開始吧津肛。即使代碼并不是出自QA手,用到的開源或者內(nèi)部框架并不熟悉汗贫,那么也要嘗試開始跳出QA的舒適區(qū)身坐,開始更貼合的去理解業(yè)務(wù)邏輯及代碼實現(xiàn)細(xì)節(jié)秸脱。這個過程,QA要重新定位自己部蛇,重新定位質(zhì)量保障的核心競爭力摊唇。
在項目中的具體實踐
有了Think as developer這樣的思路,那么如何具體到 Do as developer涯鲁?筆者在下面2個項目中進(jìn)行了實踐:
- 某運維監(jiān)控系統(tǒng)Web巷查、API及Task模塊源碼閱讀
- 某智能語音項目Java層源碼閱讀
鑒于目前接觸到的大多PC端的項目,大多是war包形式走的Tomcat撮竿。所以這篇文章主要是面向這類產(chǎn)品的一些閱讀方法和技巧總結(jié)進(jìn)行的一些實踐活動吮便。
也提煉出來了下面3個具體的閱讀技巧,可以更快速有效的作為理解業(yè)務(wù)實現(xiàn)框架的切入點:
下面的篇幅,來具體談?wù)勥@3個閱讀技巧房蝉。
<span id="jump1">一個Web項目的容器啟動的入口是什么僚匆?</span>
記得最早的時候開始研究Java Web的時候,記得看到一個人寫的一句話:
“初學(xué) Java Web 開發(fā)搭幻,請遠(yuǎn)離各種框架咧擂,從 Servlet 開發(fā)”
Java Web開發(fā)離不開Servlet松申,Servlet的生命周期是有Tomcat/Jetty這樣的Web容器接管,那么web.xml
就是所有開始的入口俯逾。這里會配置Servlet贸桶,Filter這樣的組件。
Servlet:通過doGet doPost方法處理請求桌肴,這個方法里有傳統(tǒng)的兩個入?yún)ⅲ?em>HttpServletRequest皇筛,HttpServletResponse來分別處理請求和響應(yīng)。
Filter:在請求被容器發(fā)到servlet之前坠七,會先經(jīng)過配置的filter水醋。所以一般情況下,filter都是做一些白名單驗證彪置,特定的uri要通過openid拄踪,doFilter方法在做。
這個時候web.xml
里應(yīng)該會有很多<servlet>
和<filter>
標(biāo)簽悉稠,雜亂無章
加入的SpringMVC框架后宫蛆,web.xml
就變得簡化無比(只是web.xml),需要關(guān)注的有下面這些:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-context-web.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
以及Servlet的配置:
<servlet>
<servlet-name>sentry</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
又出來了兩個配置文件:spring-context-web.xml & spring-mvc-config.xml
一個是通用上下文的猛,一個是初始化MVC上下文耀盗。如下圖
那么各有什么用處:
- ContextLoaderListener初始化的上下文加載的Bean是對于整個應(yīng)用程序共享的,不管是使用什么表現(xiàn)層技術(shù)卦尊,一般如DAO層叛拷、Service層Bean;
- DispatcherServlet初始化的上下文加載的Bean是只對Spring Web MVC有效的Bean岂却,如Controller忿薇、HandlerMapping、HandlerAdapter等等躏哩,該初始化上下文應(yīng)該只加載Web相關(guān)組件署浩。
這里就可以大致知道,之前所有<servlet>
需要做的事情扫尺,都被Spring的Dispatcher servlet統(tǒng)一接管筋栋,可以理解為一個虛擬的路由器,將請求轉(zhuǎn)發(fā)給所有的@Controller
正驻。
這里碰見過一個事情:我有個外部的服務(wù)需要初始化弊攘,初始化如下:
<bean id="qaService" class="com.xxx.utils.qa.qaServiceImpl">
<constructor-arg index="0" value="${baseURL}" />
<constructor-arg index="1" value="${token}" />
</bean>
我用它的地方是在一個Controller里面,然而放在spring-mvc-config.xml就編譯失敗姑曙,說找不到這個Bean襟交。放在spring-context-web.xml就可以。
<span id="jump2">深入Spring MVC + Mybatis的一些成熟的工程架構(gòu)如何配置伤靠?</span>
你的項目目錄應(yīng)該是這樣的:
-
/main/:
controller層捣域,service層及DAO層,以及filter:
-
/Resources:
使用MyBatis的話宴合,這些mapper文件放在這里焕梅,并使用和DAO層一樣的包名。
然后根據(jù)不同的開發(fā)形纺,測試丘侠,線上環(huán)境放入不同的配置文件。
至于配置文件如何讀取逐样,一方面Maven編譯打包的時候resource目錄下的文件都會拷貝出來蜗字。另外一方面,區(qū)分環(huán)境變量脂新,在pom.xml
的<profile>
配置即可挪捕,然后通過mvn的 -P參數(shù)來區(qū)分,如圖:
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/resources/dev</directory>
</resource>
<resource>
<directory>src/main/resources/common</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>test</id>
/* 同上 */
<directory>src/main/resources/test</directory>
</profile>
<profile>
<id>online</id>
...
<directory>src/main/resources/online</directory>
...
/* 同上 */
</profile>
- 請求如何到達(dá)Controller
這里有個關(guān)鍵注釋:<mvc:annotation-driven/>
因為之前肯定是通過<context:component-scan/>
掃描過所有的Controller争便,但是他們只是Bean被構(gòu)造级零,需要通過<mvc:annotation-driven/>
標(biāo)簽告訴SpringMVC,請求的處理者。
出處:spring-mvc-difference-between-contextcomponent-scan-and-annotation-driven
- 請求返回:FTL返回及JSON返回
這里要在spring_mvc_config.xml中配置一個bean:ContentNegotiatingViewResolver奏纪,有兩個屬性:
<property name="defaultContentType" value="application/json" />
.....
<property name="viewResolvers">
.....
<property name="defaultViews">
這兩個resolver的好處在于:Controller的函數(shù)處理鉴嗤,返回String就默認(rèn)是FTL的路徑(也就是前端的路徑),返回void序调,就是json醉锅。不需要@RequestBody
注解。
- Controller 怎么看发绢,怎么寫
了解一些關(guān)鍵注釋的意思硬耍,比如@RequestMapping
, @RequestParam
, @RequestHeader
边酒,@PathVariable
经柴, 至于ResponseBody
,經(jīng)過上面的講解墩朦,應(yīng)該就不需用了坯认。別的話,多看代碼介杆,多實踐鹃操,不缺這樣的資料。
- 前端的配置
前端這里有兩個關(guān)鍵配置:
<mvc:resources mapping="/views/**" location="/views/"/>`
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/views"/>`
因為Servlet被Spring整體接管之后春哨,所有的請求都被接管荆隘。那么靜態(tài)文件呢?他們又沒有Controller的處理赴背,肯定會404 not found椰拒。
- 第一個注釋就是解決了這個問題,配置了靜態(tài)文件的本地路徑
/views/
凰荚,這里根目錄是webapp燃观, 那么所有的CSS,JS便瑟,PNG, 都將在來這里找缆毁。 - 第二個注釋其實就是配置FreeMarker的模版路徑,一般工程也都放在webapp的
/views/
下到涂。
<span id="jump3">Spring 和SpringMVC是兩件事</span>
這里碰見過一個事情:我有個外部的服務(wù)需要初始化脊框,初始化如下:
<bean id="qaService" class="com.xxx.utils.qa.qaServiceImpl">
<constructor-arg index="0" value="${baseURL}" />
<constructor-arg index="1" value="${token}" />
</bean>
我用它的地方是在一個Controller里面,然而放在spring-mvc-config.xml就編譯失敗践啄,說找不到這個Bean浇雹。具體為啥,可以參考上一節(jié)屿讽。因為這些Bean并不是有SpringMVC通過@Service
標(biāo)簽來統(tǒng)一注入管理昭灵。那么它的初始化過程應(yīng)該要放入spring-context-web.xml,在SpringMVC介入之間就需要實例化。否則當(dāng)然只是一個接口烂完。
所以到這里為止试疙,相信已經(jīng)對此種類型的項目有了一個基本的閱讀技巧。下一章窜护,來說一下筆者在這些基礎(chǔ)之上效斑,實踐得到的一些感悟非春。
<span id="jump">實踐所得</span>
-
能夠迅速上手項目柱徙,并快速理解項目基本邏輯及架構(gòu)。
在我新接手的一個某智能語音機(jī)器人項目中奇昙,在沒有任何需求設(shè)計接口文檔的情況下护侮,要開展測試工作,只能先從源碼開始储耐,之前的經(jīng)驗幫助了我羊初,理清楚了所有接口的處理邏輯(畢竟是半路接手項目,只能先解決問題為先)什湘〕ぴ蓿基本上一兩天功夫就可以把源碼大體邏輯以及框架讀懂(當(dāng)然,大型的項目要花更長的時間)闽撤。當(dāng)時的幾個思維導(dǎo)圖之一如下:
然后就開始?xì)g快的寫接口測試用例得哆。
- QA不僅僅要整體業(yè)務(wù)上有宏觀把控。出現(xiàn)微觀上bug哟旗,也能做出Root Cause的前瞻分析贩据,能夠迅速定位問題。**
- 略深入理解Spring及SpringMVC闸餐。
- 找到快速融入研發(fā)團(tuán)隊的切入點饱亮。其實似乎是沒法量化的,然而個人在團(tuán)隊中起到的化學(xué)反應(yīng)相信都能感受到舍沙。
結(jié)語
筆者認(rèn)為在項目質(zhì)量保障過程中近上,提升QA戰(zhàn)斗力,需要開拓新思路拂铡。提出Think as developer壹无,以及Do as developer在某一類項目中的一些具體技巧。為讀者提供另外一種思維方式和媳。
所以白盒與黑盒不是測試手段格遭,而是測試思維。過度關(guān)注開發(fā)細(xì)節(jié)的白盒測試沒有意義留瞳,從需求出發(fā)更加的符合實際中的測試拒迅。
引自 鏈接
業(yè)務(wù)理解第一,業(yè)務(wù)理解第一,業(yè)務(wù)理解第一璧微。