Think as developer,从深入理解业务实现框架开始

引言

这篇文章主要介绍笔者从经历过的项目中,看到自己或者项目组QA在产品迭代中的软肋。认为可以通过另外一种思路来改善这些弱点。希望能够有助于QA最大化的做好质量保障工作。

产品迭代中QA自身的Bug(软肋)是什么?

需求偏于口头传述

产品的快速迭代,可以迅速满足用户需求,然而却也有一些后遗症,比如部分需求描述偏向于口头传述,文档后于实现,会给QA工作造成比较大的困难。所以在坚守一些固有可靠的测试流程之外,我们需要想一些新的办法。

需求和实现衔接不能达到无缝连接

测试的起点是明确测试的需求,然而有些很具体的问题,需要帮助开发定位问题的时候,需求只定义了一些比较粗的业务目标,然而具体实现由开发掌握。这里的衔接过程,QA是袖手旁观呢,还是参与其中。笔者认为后者可能可以更深入的接近实现,达到最大化的质量保障。

是时候开拓一种新思路了。Think as developer,从阅读并深入理解业务实现框架开始吧。即使代码并不是出自QA手,用到的开源或者内部框架并不熟悉,那么也要尝试开始跳出QA的舒适区,开始更贴合的去理解业务逻辑及代码实现细节。这个过程,QA要重新定位自己,重新定位质量保障的核心竞争力。

在项目中的具体实践

有了Think as developer这样的思路,那么如何具体到 Do as developer?笔者在下面2个项目中进行了实践:

  • 某运维监控系统WebAPITask模块源码阅读
  • 某智能语音项目Java层源码阅读

鉴于目前接触到的大多PC端的项目,大多是war包形式走的Tomcat。所以这篇文章主要是面向这类产品的一些阅读方法和技巧总结进行的一些实践活动。

也提炼出来了下面3个具体的阅读技巧,可以更快速有效的作为理解业务实现框架的切入点:

下面的篇幅,来具体谈谈这3个阅读技巧。

<span id="jump1">一个Web项目的容器启动的入口是什么?</span>

记得最早的时候开始研究Java Web的时候,记得看到一个人写的一句话:
“初学 Java Web 开发,请远离各种框架,从 Servlet 开发”

初学 Java Web 开发,请远离各种框架,从 Servlet 开发

Java Web开发离不开ServletServlet的生命周期是有Tomcat/Jetty这样的Web容器接管,那么web.xml就是所有开始的入口。这里会配置ServletFilter这样的组件。

Servlet:通过doGet doPost方法处理请求,这个方法里有传统的两个入参:HttpServletRequest,HttpServletResponse来分别处理请求和响应。

Filter:在请求被容器发到servlet之前,会先经过配置的filter。所以一般情况下,filter都是做一些白名单验证,特定的uri要通过openiddoFilter方法在做。
这个时候web.xml里应该会有很多<servlet><filter>标签,杂乱无章

加入的SpringMVC框架后,web.xml就变得简化无比(只是web.xml),需要关注的有下面这些:

    <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上下文。如下图

1.png

那么各有什么用处:

  • ContextLoaderListener初始化的上下文加载的Bean是对于整个应用程序共享的,不管是使用什么表现层技术,一般如DAO层、Service层Bean;
  • DispatcherServlet初始化的上下文加载的Bean是只对Spring Web MVC有效的Bean,如ControllerHandlerMappingHandlerAdapter等等,该初始化上下文应该只加载Web相关组件。

这里就可以大致知道,之前所有<servlet>需要做的事情,都被SpringDispatcher servlet统一接管,可以理解为一个虚拟的路由器,将请求转发给所有的@Controller

这里碰见过一个事情:我有个外部的服务需要初始化,初始化如下:

    <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的一些成熟的工程架构如何配置?</span>

你的项目目录应该是这样的:

  • /main/
    controller层,service层及DAO层,以及filter
2.png
  • /Resources
    使用MyBatis的话,这些mapper文件放在这里,并使用和DAO层一样的包名。
    然后根据不同的开发,测试,线上环境放入不同的配置文件。
3.png

至于配置文件如何读取,一方面Maven编译打包的时候resource目录下的文件都会拷贝出来。另外一方面,区分环境变量,在pom.xml<profile>配置即可,然后通过mvn的 -P参数来区分,如图:

        <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>
  • 请求如何到达Controller

这里有个关键注释:<mvc:annotation-driven/>
因为之前肯定是通过<context:component-scan/>扫描过所有的Controller,但是他们只是Bean被构造,需要通过<mvc:annotation-driven/>标签告诉SpringMVC,请求的处理者。

出处:spring-mvc-difference-between-contextcomponent-scan-and-annotation-driven

  • 请求返回FTL返回及JSON返回

这里要在spring_mvc_config.xml中配置一个beanContentNegotiatingViewResolver,有两个属性:

<property name="defaultContentType" value="application/json" />
.....
<property name="viewResolvers">
.....
<property name="defaultViews">

这两个resolver的好处在于:Controller的函数处理,返回String就默认是FTL的路径(也就是前端的路径),返回void,就是json。不需要@RequestBody注解。

  • Controller 怎么看,怎么写

了解一些关键注释的意思,比如@RequestMapping@RequestParam, @RequestHeader@PathVariable, 至于ResponseBody,经过上面的讲解,应该就不需用了。别的话,多看代码,多实践,不缺这样的资料。

  • 前端的配置

前端这里有两个关键配置:

<mvc:resources mapping="/views/**" location="/views/"/>`
<bean
            class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="/views"/>`

因为ServletSpring整体接管之后,所有的请求都被接管。那么静态文件呢?他们又没有Controller的处理,肯定会404 not found

  • 第一个注释就是解决了这个问题,配置了静态文件的本地路径/views/,这里根目录是webapp, 那么所有的CSS,JS,PNG, 都将在来这里找。
  • 第二个注释其实就是配置FreeMarker的模版路径,一般工程也都放在webapp/views/下。

<span id="jump3">Spring 和SpringMVC是两件事</span>

这里碰见过一个事情:我有个外部的服务需要初始化,初始化如下:

    <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。具体为啥,可以参考上一节。因为这些Bean并不是有SpringMVC通过@Service标签来统一注入管理。那么它的初始化过程应该要放入spring-context-web.xml,在SpringMVC介入之间就需要实例化。否则当然只是一个接口。

所以到这里为止,相信已经对此种类型的项目有了一个基本的阅读技巧。下一章,来说一下笔者在这些基础之上,实践得到的一些感悟。

<span id="jump">实践所得</span>

  • 能够迅速上手项目,并快速理解项目基本逻辑及架构。
    在我新接手的一个某智能语音机器人项目中,在没有任何需求设计接口文档的情况下,要开展测试工作,只能先从源码开始,之前的经验帮助了我,理清楚了所有接口的处理逻辑(毕竟是半路接手项目,只能先解决问题为先)。基本上一两天功夫就可以把源码大体逻辑以及框架读懂(当然,大型的项目要花更长的时间)。当时的几个思维导图之一如下:
4.png

然后就开始欢快的写接口测试用例。

  • QA不仅仅要整体业务上有宏观把控。出现微观上bug,也能做出Root Cause的前瞻分析,能够迅速定位问题。**
  • 略深入理解SpringSpringMVC
  • 找到快速融入研发团队的切入点。其实似乎是没法量化的,然而个人在团队中起到的化学反应相信都能感受到。

结语

笔者认为在项目质量保障过程中,提升QA战斗力,需要开拓新思路。提出Think as developer,以及Do as developer在某一类项目中的一些具体技巧。为读者提供另外一种思维方式。

所以白盒与黑盒不是测试手段,而是测试思维。过度关注开发细节的白盒测试没有意义,从需求出发更加的符合实际中的测试。

引自 链接

业务理解第一,业务理解第一,业务理解第一。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,590评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,726评论 6 342
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,562评论 18 399
  • spring官方文档:http://docs.spring.io/spring/docs/current/spri...
    牛马风情阅读 1,647评论 0 3
  • 总是需要温暖 哪怕是一点点自以为是的纪念
    我是ko杨凯伦的原配阅读 126评论 0 0