JUnit扩展:引入新注解Annotation

发表于:2015-4-16 12:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:大卡    来源:51Testing软件测试网原创

  发现问题
  JUnit提供了Test Suite来帮助我们组织case,还提供了Category来帮助我们来给建立大的Test Set,比如BAT,MAT, Full Testing。 那么什么情况下,这些仍然不能满足我们的需求,需要进行拓展呢?
  闲话不表,直接上需求:
  1. 老板希望能精确的衡量出每个Sprint写了多少条自动化case,或者每个User Story又设计了多少条case来保证覆盖率,以此来对工作量和效率有数据上的直观表示。
  2. 对于云服务,通常会有不同的server来对应产品不同的开发阶段,比如dev的server,这里大家可以随意上传代码,ScrumQA会测试每一个开发提交的Feature -> 然后当产品部署到测试server时,Scrum QA 和 System QA 就得对产品进行充分的测试 -> 甚或者有预发布的server,来模拟真实产品环境,这个server,仍然需要测试 -> 最后产品会部署到真正的生产环境上。
  这时候就衍生了测试代码版本控制的问题,比如当我针对新需求写的自动化case所测得Feature,当前只在Dev上部署,还没有在其他的server部署,那我的case怎么办?在其他的server上运行一定会失败。
  3. 当产品足够复杂时,我们可能就有成千上万条case,这样全部运行这些case,时间上可能就非常耗时。 而如果使用JUnit的category来分组可能颗粒度太粗,不灵活,怎么办?
  解决方案
  综合考虑,为解决以上需求,我们觉得必须在Case级别上做文章,所以结合JUnit4的功能,我们最终引入了新的注解Annotation:Spint, UserStory, 和 Defect。
  名称                                   描述                                               作用域
  Sprint用来标记这条Case是在什么时候引进的,或者说这条Case是哪个Sprint的加入的功能              方法
  UserStory用来标记这条Case测试的是哪个UserStory,或者说覆盖的那个UserStory,这样即使过了很长时间,我们也能清晰地知道,我们为什么加这条Case,以及它到底测的是什么功能              方法
  Defect用来标记这条Case覆盖的Defect,或者说覆盖的Defect              方法
  在实际使用时,我们就可以这么用:
  @Test
  @Sprint("15.3")
  @UserStory("US30145")
  @Defect(CR = "30775", Title = "[cr30775][p0] xxxx...")
  public void test_AddUserDirectDebitInformation_204_WithoutXXXBefore()
  {
  // Case Body
  }
  那么在运行时,根据这些标记,我们就可以随心所欲的Filter出我们需要的Case了:
  只运行某个特定Sprint的case
  运行某个Sprint下的某个UserStory所属的Case
  运行所有的有Bug的Case,单做回归测试
  。。。
  当然统计每个Sprint的工作量也就有了可能。
  代码实现
  研究过类似问题的童鞋可能知道,IBM的网站上,有一篇文章,讲过这个问题(地址在文章底有列)。并且他还定义了更多的注解需求, 也给出了部分实现。这篇文章有个好处就是先从JUnit整体架构运行流程出发,采用各个模块包装的方法,然后从入口JUnitCore出发去重新发起Request来运行我们自定义的Case,我觉得研究这篇文章可以对不了解JUnit核心框架的童鞋有一定的帮助。
  这篇文章已经给出了自定义Runner部分的代码,缺了两块。第一是IntentObject部分,它把参数封装成对象。第二部分就是定义实现Filter。我这里给出它缺的那部分Filter的实现,Intent这块直接当String处理就可以了。
public class FilterFactory
{
public static final String REGEX_COMMA = ",";
public static final String ANNOTATION_PREFIX = "com.junit.extension.annotations."; // 包名的前缀
public static final String REGEX_EQUAL = "=";
public static List<Filter> filters = new ArrayList<Filter>();
public static List<Filter> getFilters()
{
return filters;
}
// This is a special toggle served {@link Sprint}
public static String FILTER_RUN_CASE_ISONLY_TOGGLE = "isOnly";
private static FilterSprint fSprint = null;
private static FilterUserStory fUserStory = null;
private static FilterDefect fDefect = null;
public static List<Filter> createFilters(String intention) throws ClassNotFoundException
{
String[] splits = intention.split(REGEX_COMMA);
for(String split : splits)
{
String[] pair = split.split(REGEX_EQUAL);
if(pair != null && pair.length == 2)
{
if(pair[0].trim().equalsIgnoreCase(FILTER_RUN_CASE_ISONLY_TOGGLE))
{
if(fSprint == null)
{
fSprint = new FilterSprint();
}
fSprint.setIsOnly(Boolean.parseBoolean(pair[1].trim()));
}
else
{
Class<?> annotation = Class.forName(ANNOTATION_PREFIX + pair[0].trim());
if(annotation.isAssignableFrom(Sprint.class))
{
fSprint = new FilterSprint(pair[1].trim());
}
else if(annotation.isAssignableFrom(UserStory.class))
{
fUserStory = new FilterUserStory(pair[1].trim());
filters.add(fUserStory);
}
else if(annotation.isAssignableFrom(Defect.class))
{
fDefect = new FilterDefect(pair[1].trim());
filters.add(fDefect);
}
}
if(fSprint != null)
{
filters.add(fSprint);
}
}
}
return filters;
}
31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号