qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Java Web并發單元測試摘記(1)

            大的web項目開發和運行環境都在服務器容器中進行為主,包括調試過程,也都是單例進過Web觸發進行測試。在Web項目中設計使用Spring、hibernate、JBPM工作流、ehcache各種框架或組件。這些東西在一起配置好一個有效的、覆蓋所有環境的單元測試用例也比較復雜。所有配置好一個可用有效的單元測試環境十分必要。并且面對單元測試對并發要求的不支持,還得加入必要的并發測試組件,滿足測試全面系統白盒測試要求。
            這里總結幾種有效的配置單元測試方式:
            1、直接使用Junit4組件,進行簡單單元測試,在setUp()中初始化各種測試環境如下:
          @Override
          protected void setUp() throws Exception {
          super.setUp();
          String[] paths = { "classpath:applicationContext.xml" };
          ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);
          SpringContextListener.setApplicationContext(ctx);
          // ############模擬servlet容器啟動,手動更改配置文件路徑
          Constant.CURRENT_PROJECT_PATH = "src/";
          // ############直接容器中獲取bean
          userManager = (UserManager) ctx.getBean("userManager");
          userService = (UserService) ctx.getBean("userService");
          }
            2、使用Sprint-test.jar框架,支持事務可注解方式啟動的單元測試:
          @RunWith(SpringJUnit4ClassRunner.class)
          @ContextConfiguration(locations = "classpath:applicationContext.xml")
          @TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false) //true將會回滾所有操作,默認沒有該注解為回滾
          public class JBPMProcessTest2 extends  AbstractTransactionalJUnit4SpringContextTests{
            以上都只能暫時支持簡單功能的單元測試。但是要測試并發和壓力等。需要加入一個常用的框架,支持在單元測試中注入多線程和并發。
            具體參見:http://blog.csdn.net/zhangyaoming2004/article/details/7619489 下面附有Jar包下載 http://yunpan.cn/QUtVay66VnU4T


           我們具體使用的功能不是很多,這些并發測試可以嵌入到上面兩種單元測試方式中:如下:
          /**
          *
          */
          package com.dtsz.model.service.test;
          import net.sourceforge.groboutils.junit.v1.TestRunnable;
          import com.dtsz.model.entity.report.common.InvokeSource;
          import com.dtsz.model.service.ExcelReportLogicService;
          import com.dtsz.model.service.TaskLogicService;
          import com.dtsz.model.util.ExcelReportUtil;
          import com.dtsz.view.vo.authenticator.UserVO;
          import com.dtsz.view.vo.webservice.ExcelReportResult;
          /**
          * 模擬插件端數據上報的并發操作測試
          *
          * @author xiaoli
          *
          */
          public class CreateMulltiTaskReportGroboThread extends TestRunnable {
          TaskLogicService taskLogicService;
          ExcelReportLogicService excelReportLogicService;
          private String reportMap;
          private UserVO user;
          private InvokeSource invokeSource;
          private String bbq;
          public CreateMulltiTaskReportGroboThread(String reportMap, UserVO user, InvokeSource invokeSource,String bbq) {
          super();
          this.reportMap = reportMap;
          this.user = user;
          this.invokeSource = invokeSource;
          this.bbq = bbq;
          init();
          }
          public void init() {
          taskLogicService = (TaskLogicService)ExcelReportUtil.getBean("taskLogicService");
          excelReportLogicService = (ExcelReportLogicService)ExcelReportUtil.getBean("excelReportLogicService");
          }
          /*
          * (non-Javadoc)
          *
          * @see net.sourceforge.groboutils.junit.v1.TestRunnable#runTest()
          */
          @Override
          public void runTest() throws Throwable {
          // TODO Auto-generated method stub
          // ########################模擬當前任務該報表期任務上報
          //保存數據
          ExcelReportResult result = taskLogicService.reportData(reportMap, user, invokeSource);
          excelReportLogicService.saveData(result);
          System.out.println("報表期為:"+this.bbq+"已上報");
          }
          }
            單元測試并發:
          /**
          *
          */
          package com.dtsz.model.service.test;
          import java.sql.SQLException;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          import junit.framework.TestCase;
          import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
          import net.sourceforge.groboutils.junit.v1.TestRunnable;
          import org.junit.Test;
          import org.springframework.context.ApplicationContext;
          import org.springframework.context.support.ClassPathXmlApplicationContext;
          import com.dtsz.model.entity.authenticator.User;
          import com.dtsz.model.entity.report.common.InvokeSource;
          import com.dtsz.model.service.authenticator.UserManager;
          import com.dtsz.model.service.authenticator.UserService;
          import com.dtsz.model.service.exception.BaseAppException;
          import com.dtsz.model.util.BeanUtil2;
          import com.dtsz.model.util.Constant;
          import com.dtsz.model.util.Encryption;
          import com.dtsz.view.util.SpringContextListener;
          import com.dtsz.view.vo.authenticator.UserVO;



          /**
          * 模擬數據上報,這里的初始化數據根據插件端傳入數據組合來的,當前只有根據報表期生成初始化數據
          *
          * @author xiaoli
          *
          */
          public class CreateMultiTaskReportTest3 extends TestCase {
          private UserManager userManager;
          private UserService userService;
          @Override
          protected void setUp() throws Exception {
          super.setUp();
          String[] paths = { "classpath:applicationContext.xml" };
          ApplicationContext ctx = new ClassPathXmlApplicationContext(paths);
          SpringContextListener.setApplicationContext(ctx);
          // ############模擬servlet容器啟動,手動更改配置文件路徑
          Constant.CURRENT_PROJECT_PATH = "src/";
          // ############直接容器中獲取bean
          userManager = (UserManager) ctx.getBean("userManager");
          userService = (UserService) ctx.getBean("userService");
          }
          @Override
          protected void tearDown() throws Exception {
          super.tearDown();
          }
          @Test
          public void test(){
          // ###########自動生成報表期串集合
          List<String> bbqs = new ArrayList<String>();
          UnitTestUtils.imitateCreateMultiBbq(bbqs, 2, "2048", "5");
          // 創建線程
          TestRunnable[] tr = new TestRunnable[bbqs.size()];
          int processCount = 0;
          // ##########對這些數據進行填報
          for (String bbq : bbqs) {
          // 模擬上報數據
          String reportMap = "{taskID:\"402880ee425a92f501425aa75ad50002\",bbq_:\""
          + bbq
          + "\""
          + ",bbhid:\"402855b942099b1b014209b1177e03f5\",approvalFlag:2,reportFlag:False,auditFlag:False,sheetMap:"
          + "[{id:\"402880ee425a92f501425aa75ad60004\",sheetType:\"BASIC\",values:{}}]}";
          // 模擬上報的user
          UserVO user = null;
          try {
          user = checkUser("xl1", "1");
          } catch (BaseAppException e) {
          e.printStackTrace();
          } // 模擬插件端checkUser
          String sessionInfo = "{institutionname:\"南昌分行\",institutioncode:\"A01NC\",username:\"肖力1"
          + "1\",usercode:\"xl1\",rolecode:\"null\",bbhId:\"402855b942099b1b014209b1177e03f5\",bbhcode:\"B01b\",btype:\"BASIC\",taskid:\"402880ee425a92f501425a"
          + "a75ad50002\",bbhname:\"基層財務b\",bbq:\"" + bbq
          + "\",frequency:\"MONTH\",SESSIONDIMENSION:{}}";
          try {
          userService.updateSession(sessionInfo, user);
          } catch (BaseAppException e) {
          e.printStackTrace();
          } catch (SQLException e) {
          e.printStackTrace();
          } // 模擬插件端updateSession
          // 初始化上報方式
          InvokeSource invokeSource = InvokeSource.WSCALL;
          CreateMulltiTaskReportGroboThread reportThread = new CreateMulltiTaskReportGroboThread(reportMap,user, invokeSource,bbq);
          tr[processCount] = reportThread;
          processCount++;
          }
          System.out.println("#######################################計時開始########################");
          long startTime = System.currentTimeMillis();
          // 生成測試線程運行器
          MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(tr);
          // 運行測試線程
          try {
          mttr.runTestRunnables();
          } catch (Throwable e) {
          e.printStackTrace();
          }
          System.out.println("#######################一共耗時:"
          + String.valueOf((System.currentTimeMillis() - startTime) / 1000) + "秒");
          }
          /**
          * xl1 1
          * */
          public UserVO checkUser(String userid,
          String password) throws BaseAppException {
          Map<String, String> paramMap = new HashMap<String, String>();
          paramMap.put("UserName", userid);
          paramMap.put("Password", password);
          List<User> users = userManager.findByCodeCache(userid);
          List<User> needUsers = new ArrayList<User>();
          if (users != null && users.size() > 0) {
          for (User user : users) {
          if (user.getState() && user.getCode().equals(userid)
          && user.getPassword().equals(Encryption.encryption(password))) {
          needUsers.add(user);
          }
          }
          }
          // 通過驗證
          if (needUsers != null && needUsers.size() > 0) {
          User user = needUsers.get(0);
          // 獲取用戶權限,并存放于session中
          // UserVO userVO = userManager.getUserPermission(user.getId());
          String ipAddress = "0.0.0.0";
          UserVO userVO = new UserVO();
          BeanUtil2.copyProperties(user, userVO);
          userVO.setIpAddress(ipAddress);
          return userVO; // 通過驗證
          } else {
          return null;
          }
          }
          }
            真實環境并發和壓力測試不僅僅是在多個線程同時啟動在測,還可能是增量式壓力測試。這些還是要封裝好和處理好。

          posted on 2013-12-04 11:13 順其自然EVO 閱讀(260) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2013年12月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 山东省| 黄浦区| 江都市| 江华| 墨江| 枞阳县| 屏东县| 平顶山市| 涿鹿县| 西林县| 竹北市| 九台市| 蚌埠市| 龙岩市| 沈丘县| 柳江县| 綦江县| 贵定县| 陇川县| 蒙山县| 临沂市| 新建县| 莆田市| 怀柔区| 万盛区| 桐柏县| 准格尔旗| 黑河市| 静宁县| 揭东县| 河西区| 长泰县| 耿马| 梁山县| 奎屯市| 五河县| 开远市| 磴口县| 南陵县| 来凤县| 仁寿县|