亚洲好骚综合-亚洲黄色录像-亚洲黄色网址-亚洲黄色网址大全-99久久99久久-99久久99久久精品国产

您的位置:軟件測(cè)試 > 開(kāi)源軟件測(cè)試 > 開(kāi)源單元測(cè)試工具 > junit
JUnit擴(kuò)展:引入新注解Annotation
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2015/4/17 10:48:13 ] 推薦標(biāo)簽:Junit 單元測(cè)試 Annotation

  發(fā)現(xiàn)問(wèn)題
  JUnit提供了Test Suite來(lái)幫助我們組織case,還提供了Category來(lái)幫助我們來(lái)給建立大的Test Set,比如BAT,MAT, Full Testing。 那么什么情況下,這些仍然不能滿足我們的需求,需要進(jìn)行拓展呢?
  閑話不表,直接上需求:
  1. 老板希望能精確的衡量出每個(gè)Sprint寫(xiě)了多少條自動(dòng)化case,或者每個(gè)User Story又設(shè)計(jì)了多少條case來(lái)保證覆蓋率,以此來(lái)對(duì)工作量和效率有數(shù)據(jù)上的直觀表示。
  2. 對(duì)于云服務(wù),通常會(huì)有不同的server來(lái)對(duì)應(yīng)產(chǎn)品不同的開(kāi)發(fā)階段,比如dev的server,這里大家可以隨意上傳代碼,ScrumQA會(huì)測(cè)試每一個(gè)開(kāi)發(fā)提交的Feature -> 然后當(dāng)產(chǎn)品部署到測(cè)試server時(shí),Scrum QA 和 System QA 得對(duì)產(chǎn)品進(jìn)行充分的測(cè)試 -> 甚或者有預(yù)發(fā)布的server,來(lái)模擬真實(shí)產(chǎn)品環(huán)境,這個(gè)server,仍然需要測(cè)試 -> 后產(chǎn)品會(huì)部署到真正的生產(chǎn)環(huán)境上。
  這時(shí)候衍生了測(cè)試代碼版本控制的問(wèn)題,比如當(dāng)我針對(duì)新需求寫(xiě)的自動(dòng)化case所測(cè)得Feature,當(dāng)前只在Dev上部署,還沒(méi)有在其他的server部署,那我的case怎么辦?在其他的server上運(yùn)行一定會(huì)失敗。
  3. 當(dāng)產(chǎn)品足夠復(fù)雜時(shí),我們可能有成千上萬(wàn)條case,這樣全部運(yùn)行這些case,時(shí)間上可能非常耗時(shí)。 而如果使用JUnit的category來(lái)分組可能顆粒度太粗,不靈活,怎么辦?
  解決方案
  綜合考慮,為解決以上需求,我們覺(jué)得必須在Case級(jí)別上做文章,所以結(jié)合JUnit4的功能,我們終引入了新的注解Annotation:Spint, UserStory, 和 Defect。
  名稱                                   描述                                               作用域
  Sprint用來(lái)標(biāo)記這條Case是在什么時(shí)候引進(jìn)的,或者說(shuō)這條Case是哪個(gè)Sprint的加入的功能              方法
  UserStory用來(lái)標(biāo)記這條Case測(cè)試的是哪個(gè)UserStory,或者說(shuō)覆蓋的那個(gè)UserStory,這樣即使過(guò)了很長(zhǎng)時(shí)間,我們也能清晰地知道,我們?yōu)槭裁醇舆@條Case,以及它到底測(cè)的是什么功能              方法
  Defect用來(lái)標(biāo)記這條Case覆蓋的Defect,或者說(shuō)覆蓋的Defect              方法
  在實(shí)際使用時(shí),我們可以這么用:
  @Test
  @Sprint("15.3")
  @UserStory("US30145")
  @Defect(CR = "30775", Title = "[cr30775][p0] xxxx...")
  public void test_AddUserDirectDebitInformation_204_WithoutXXXBefore()
  {
  // Case Body
  }
  那么在運(yùn)行時(shí),根據(jù)這些標(biāo)記,我們可以隨心所欲的Filter出我們需要的Case了:
  只運(yùn)行某個(gè)特定Sprint的case
  運(yùn)行某個(gè)Sprint下的某個(gè)UserStory所屬的Case
  運(yùn)行所有的有Bug的Case,單做回歸測(cè)試
  。。。
  當(dāng)然統(tǒng)計(jì)每個(gè)Sprint的工作量也有了可能。
  代碼實(shí)現(xiàn)
  研究過(guò)類似問(wèn)題的童鞋可能知道,IBM的網(wǎng)站上,有一篇文章,講過(guò)這個(gè)問(wèn)題(地址在文章底有列)。并且他還定義了更多的注解需求, 也給出了部分實(shí)現(xiàn)。這篇文章有個(gè)好處是先從JUnit整體架構(gòu)運(yùn)行流程出發(fā),采用各個(gè)模塊包裝的方法,然后從入口JUnitCore出發(fā)去重新發(fā)起Request來(lái)運(yùn)行我們自定義的Case,我覺(jué)得研究這篇文章可以對(duì)不了解JUnit核心框架的童鞋有一定的幫助。
  這篇文章已經(jīng)給出了自定義Runner部分的代碼,缺了兩塊。第一是IntentObject部分,它把參數(shù)封裝成對(duì)象。第二部分是定義實(shí)現(xiàn)Filter。我這里給出它缺的那部分Filter的實(shí)現(xiàn),Intent這塊直接當(dāng)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;
}

上一頁(yè)123下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd
主站蜘蛛池模板: 69日本人xxxx16-18| 国产日韩精品视频一区二区三区 | 成人男女18免费o | 日本三级香港三级久久99 | 人人干狠狠干 | 成年福利片120秒体验区 | 一级特色大黄美女播放网站 | 黄网址免费 | 曰韩黄色片 | 色视频免费版高清在线观看 | 日本久久精品 | 日韩毛片高清在线看 | 日本在线视频精品 | 日本深夜18免费看片高清网 | 亚洲欧美日韩中文不卡 | 中文字幕精品一区二区日本 | 日韩欧美综合视频 | 国产日韩欧美视频在线观看 | 日日爽夜夜爽 | 老湿影院免费体验区 | 狠狠色噜噜狠狠狠狠97不卡 | 波多野结衣在线观看网址 | 福利网站在线观看 | 757午夜视频国产精品 | 成人精品一区二区www | 中文字幕乱视频 | 亚洲黄v | 日本一区二区中文字幕 | 看三级网站 | 国产精品久久久久久免费 | 国产一级一级一级成人毛片 | 成人免费观看高清在线毛片 | 国产区成人精品视频 | 久久精品国产精品亚洲综合 | 天天骑天天干 | 500福利笫一精品导航 | 男人女人的免费视频网站 | 亚洲性免费 | 日日操夜夜骑 | 欧美视频亚洲视频 | 好男人午夜www视频在线观看 |