互联网软件测试软件测试软件测试职业探索

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

2017-04-12  本文已影响54人  professorLea

引言

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

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

需求偏于口头传述

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

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

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

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

在项目中的具体实践

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

鉴于目前接触到的大多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

那么各有什么用处:

这里就可以大致知道,之前所有<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>

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

2.png 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>

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

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

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

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

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

了解一些关键注释的意思,比如@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

<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战斗力,需要开拓新思路。提出Think as developer,以及Do as developer在某一类项目中的一些具体技巧。为读者提供另外一种思维方式。

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

引自 链接

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

上一篇 下一篇

猜你喜欢

热点阅读