From d649cbcbaaf1c14a057e1a687519c501ef17099b Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 2 Apr 2020 16:50:43 +0800 Subject: [PATCH] * adjust for show unit. --- db/update12.2.sql | 3 + module/ci/control.php | 2 + module/common/lang/zh-cn.php | 2 +- module/compile/control.php | 8 +- module/compile/lang/zh-cn.php | 1 + module/compile/model.php | 2 +- module/compile/view/browse.html.php | 14 +- module/testcase/control.php | 59 --- module/testcase/model.php | 12 +- module/testsuite/model.php | 23 - module/testtask/control.php | 129 +++++- module/testtask/css/browseunit.css | 2 + module/testtask/css/units.css | 2 + module/testtask/lang/zh-cn.php | 13 + module/testtask/model.php | 419 +++++++++++++----- module/testtask/view/results.html.php | 4 + .../view/units.html.php} | 95 +--- 17 files changed, 496 insertions(+), 294 deletions(-) create mode 100644 module/testtask/css/browseunit.css create mode 100644 module/testtask/css/units.css rename module/{testcase/view/unit.html.php => testtask/view/units.html.php} (54%) diff --git a/db/update12.2.sql b/db/update12.2.sql index ba9caa25a9..71da84ecc6 100644 --- a/db/update12.2.sql +++ b/db/update12.2.sql @@ -5,3 +5,6 @@ ALTER TABLE `zt_case` ADD `frame` varchar(10) COLLATE 'utf8_general_ci' NOT NULL ALTER TABLE `zt_testresult` ADD `job` mediumint unsigned NOT NULL AFTER `version`; ALTER TABLE `zt_testresult` ADD `compile` mediumint unsigned NOT NULL AFTER `job`; ALTER TABLE `zt_job` ADD `product` mediumint(8) unsigned NOT NULL AFTER `repo`; +ALTER TABLE `zt_testtask` ADD `auto` varchar(10) COLLATE 'utf8_general_ci' NOT NULL DEFAULT 'no' AFTER `status`; +ALTER TABLE `zt_testresult` ADD `duration` float NOT NULL AFTER `date`; +ALTER TABLE `zt_testresult` ADD `xml` text NOT NULL AFTER `duration`; diff --git a/module/ci/control.php b/module/ci/control.php index 3bf187a78f..bdd993a56d 100644 --- a/module/ci/control.php +++ b/module/ci/control.php @@ -119,6 +119,7 @@ class ci extends control if(!empty($taskID)) { $testtask = $this->testtask->getById($taskID); + $this->dao->update(TABLE_TESTTASK)->set('auto')->eq(strtolower($testType))->where('id')->eq($taskID)->exec(); $productID = $testtask->product; } else @@ -137,6 +138,7 @@ class ci extends control $testtask->owner = $this->app->user->account; $testtask->project = $lastProject; $testtask->build = 'trunk'; + $testtask->auto = strtolower($testType); $testtask->begin = date('Y-m-d'); $testtask->end = date('Y-m-d', time() + 24 * 3600); $testtask->status = 'done'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index d4a008d3d9..ba79b0fd02 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -280,7 +280,7 @@ $lang->qa->menu->caselib = array('link' => '用例库|caselib|browse'); $lang->qa->subMenu = new stdclass(); $lang->qa->subMenu->testcase = new stdclass(); $lang->qa->subMenu->testcase->feature = array('link' => '功能测试|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree,story'); -$lang->qa->subMenu->testcase->unit = array('link' => '单元测试|testcase|unit|productID=%s'); +$lang->qa->subMenu->testcase->unit = array('link' => '单元测试|testtask|browseUnit|productID=%s'); $lang->bug = new stdclass(); $lang->bug->menu = new stdclass(); diff --git a/module/compile/control.php b/module/compile/control.php index 25dc9c93df..e51931baa9 100644 --- a/module/compile/control.php +++ b/module/compile/control.php @@ -46,10 +46,10 @@ class compile extends control $this->view->position[] = $this->lang->compile->browse; $this->app->loadLang('job'); - $this->view->jobID = $jobID; - $this->view->buildList = $this->compile->getList($jobID, $orderBy, $pager); - $this->view->orderBy = $orderBy; - $this->view->pager = $pager; + $this->view->jobID = $jobID; + $this->view->buildList = $this->compile->getList($jobID, $orderBy, $pager); + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; $this->display(); } diff --git a/module/compile/lang/zh-cn.php b/module/compile/lang/zh-cn.php index 28702a44b0..4814769834 100644 --- a/module/compile/lang/zh-cn.php +++ b/module/compile/lang/zh-cn.php @@ -7,6 +7,7 @@ $lang->compile->id = 'ID'; $lang->compile->name = '构建名称'; $lang->compile->status = '构建状态'; $lang->compile->time = '构建时间'; +$lang->compile->result = '构建结果'; $lang->compile->statusList['success'] = '成功'; $lang->compile->statusList['failure'] = '失败'; diff --git a/module/compile/model.php b/module/compile/model.php index 9afbc234ad..cf55ffaaf1 100644 --- a/module/compile/model.php +++ b/module/compile/model.php @@ -34,7 +34,7 @@ class compileModel extends model */ public function getList($jobID, $orderBy = 'id_desc', $pager = null) { - return $this->dao->select('t1.id, t1.name, t1.status, t1.createdDate, t2.jkJob,t2.triggerType,t2.comment,t2.atDay,t2.atTime, t3.name as repoName, t4.name as jenkinsName')->from(TABLE_COMPILE)->alias('t1') + return $this->dao->select('t1.id, t1.name, t1.status, t1.createdDate,t1.testtask, t2.jkJob,t2.triggerType,t2.comment,t2.atDay,t2.atTime, t3.name as repoName, t4.name as jenkinsName')->from(TABLE_COMPILE)->alias('t1') ->leftJoin(TABLE_JOB)->alias('t2')->on('t1.job=t2.id') ->leftJoin(TABLE_REPO)->alias('t3')->on('t2.repo=t3.id') ->leftJoin(TABLE_JENKINS)->alias('t4')->on('t2.jkHost=t4.id') diff --git a/module/compile/view/browse.html.php b/module/compile/view/browse.html.php index 9f3462a977..f6df664031 100644 --- a/module/compile/view/browse.html.php +++ b/module/compile/view/browse.html.php @@ -33,7 +33,7 @@ job->triggerType;?> compile->status);?> compile->time);?> - actions;?> + actions;?> @@ -50,7 +50,17 @@ createdDate;?> - compile->logs);?> + compile->logs); + if($build->testtask) + { + common::printIcon('testtask', 'units', "taskID=$build->testtask", '', 'list', 'list-alt', '', '', '', '', $lang->compile->result); + } + else + { + echo html::a('###', "", '', "class='btn disabled' title='{$lang->compile->result}'"); + } + ?> diff --git a/module/testcase/control.php b/module/testcase/control.php index 803b926d37..4ff0d1634d 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -141,65 +141,6 @@ class testcase extends control $this->display(); } - /** - * Browse unit cases. - * - * @param int $productID - * @param string $branch - * @access public - * @return void - */ - public function unit($productID = 0, $branch = '') - { - /* Set browseType, productID, moduleID and queryID. */ - $productID = $this->product->saveState($productID, $this->products); - $branch = ($branch === '') ? (int)$this->cookie->preBranch : (int)$branch; - - /* Set menu, save session. */ - $this->testcase->setMenu($this->products, $productID, $branch); - $this->session->set('caseList', $this->app->getURI(true)); - - /* Load lang. */ - $this->app->loadLang('testtask'); - $this->app->loadLang('project'); - - /* Get test cases. */ - $cases = $this->loadModel('testsuite')->getProductSuiteCases($productID, $branch, 'suite,id_desc', 'unit'); - - /* save session .*/ - $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false); - - $groupCases = array(); - foreach($cases as $case) $groupCases[(int)$case->suite][$case->id] = $case; - - $suites = $this->loadModel('testsuite')->getUnit($productID); - - /* Process case for check story changed. */ - $cases = $this->loadModel('story')->checkNeedConfirm($cases); - $cases = $this->testcase->appendData($cases); - - $showModule = !empty($this->config->datatable->testcaseBrowse->showModule) ? $this->config->datatable->testcaseBrowse->showModule : ''; - $this->view->modulePairs = $showModule ? $this->tree->getModulePairs($productID, 'case', $showModule) : array(); - - /* Assign. */ - $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common; - $this->view->position[] = html::a($this->createLink('testcase', 'unit', "productID=$productID&branch=$branch"), $this->products[$productID]); - $this->view->position[] = $this->lang->testcase->common; - - $this->view->productID = $productID; - $this->view->product = $this->product->getById($productID); - $this->view->productName = $this->products[$productID]; - $this->view->summary = $this->testcase->summary($cases); - $this->view->users = $this->user->getPairs('noletter'); - $this->view->groupCases = $groupCases; - $this->view->branch = $branch; - $this->view->branches = $this->loadModel('branch')->getPairs($productID); - $this->view->suites = $suites; - $this->view->setModule = true; - - $this->display(); - } - /** * Group case. * diff --git a/module/testcase/model.php b/module/testcase/model.php index 774bd11323..3bb9f654cc 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -350,8 +350,8 @@ class testcaseModel extends model ->beginIF($branch)->andWhere('t1.branch')->eq($branch)->fi() ->beginIF($moduleIdList)->andWhere('t1.module')->in($moduleIdList)->fi() ->beginIF($browseType == 'wait')->andWhere('t1.status')->eq($browseType)->fi() - ->beginIF($type == 'nounit')->andWhere('t1.type')->ne('unit')->fi() - ->beginIF($type == 'unit')->andWhere('t1.type')->eq('unit')->fi() + ->beginIF($type == 'nounit')->andWhere('t1.auto')->eq('no')->fi() + ->beginIF($type == 'unit')->andWhere('t1.auto')->ne('no')->fi() ->andWhere('t1.deleted')->eq('0') ->orderBy($orderBy)->page($pager)->fetchAll('id'); } @@ -466,8 +466,8 @@ class testcaseModel extends model ->andWhere('t1.product')->eq($productID) ->beginIF($branch)->andWhere('t1.branch')->eq($branch)->fi() ->beginIF($modules)->andWhere('t1.module')->in($modules)->fi() - ->beginIF($type == 'nounit')->andWhere('t1.type')->ne('unit')->fi() - ->beginIF($type == 'unit')->andWhere('t1.type')->eq('unit')->fi() + ->beginIF($type == 'nounit')->andWhere('t1.auto')->eq('no')->fi() + ->beginIF($type == 'unit')->andWhere('t1.auto')->ne('no')->fi() ->orderBy($sort) ->page($pager) ->fetchAll(); @@ -534,8 +534,8 @@ class testcaseModel extends model $cases = $this->dao->select('*')->from(TABLE_CASE)->where($caseQuery) ->beginIF($queryProductID != 'all')->andWhere('product')->eq($productID)->fi() - ->beginIF($type == 'nounit')->andWhere('t1.type')->ne('unit')->fi() - ->beginIF($type == 'unit')->andWhere('t1.type')->eq('unit')->fi() + ->beginIF($type == 'nounit')->andWhere('t1.auto')->eq('no')->fi() + ->beginIF($type == 'unit')->andWhere('t1.auto')->ne('no')->fi() ->andWhere('deleted')->eq(0) ->orderBy($orderBy)->page($pager)->fetchAll('id'); diff --git a/module/testsuite/model.php b/module/testsuite/model.php index 80c3f464b5..b3fc36a491 100644 --- a/module/testsuite/model.php +++ b/module/testsuite/model.php @@ -183,29 +183,6 @@ class testsuiteModel extends model return $suite; } - /** - * Get product suite cases. - * - * @param int $productID - * @param int $branch - * @param string $orderBy - * @param string $type nounit|unit - * @access public - * @return array - */ - public function getProductSuiteCases($productID, $branch = 0, $orderBy = 'id_desc', $type = 'nounit') - { - return $this->dao->select('t1.*,t2.suite')->from(TABLE_CASE)->alias('t1') - ->leftJoin(TABLE_SUITECASE)->alias('t2')->on('t1.id=t2.case') - ->where('t1.product')->eq((int)$productID) - ->beginIF($branch)->andWhere('t1.branch')->eq($branch)->fi() - ->beginIF($type == 'nounit')->andWhere('t1.type')->ne('unit')->fi() - ->beginIF($type == 'unit')->andWhere('t1.type')->eq('unit')->fi() - ->andWhere('t1.deleted')->eq('0') - ->orderBy($orderBy) - ->fetchAll('id'); - } - /** * Update a test suite. * diff --git a/module/testtask/control.php b/module/testtask/control.php index 1256ade2dc..b680fb0d3a 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -91,6 +91,52 @@ class testtask extends control $this->display(); } + /** + * Browse unit task. + * + * @param int $productID + * @param string $browseType + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function browseUnit($productID = 0, $browseType = 'newest', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + /* Save session. */ + $this->session->set('testtaskList', $this->app->getURI(true)); + + /* Set menu. */ + $productID = $this->product->saveState($productID, $this->products); + $this->lang->testtask->menu = $this->lang->testcase->menu; + $this->lang->testtask->menuOrder = $this->lang->testcase->menuOrder; + $this->lang->testtask->subMenu->testcase->unit['subModule'] = 'testtask'; + $this->loadModel('testtask')->setUnitMenu($this->products, $productID); + + /* Load pager. */ + if($browseType == 'newest') $recPerPage = '10'; + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + /* Append id for secend sort. */ + $sort = $this->loadModel('common')->appendOrder($orderBy); + + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->common; + $this->view->position[] = html::a($this->createLink('testtask', 'browseUnit', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = $this->lang->testtask->common; + $this->view->productID = $productID; + $this->view->productName = $this->products[$productID]; + $this->view->orderBy = $orderBy; + $this->view->browseType = $browseType; + $this->view->tasks = $this->testtask->getProductUnitTasks($productID, $browseType, $sort, $pager); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->view->pager = $pager; + + $this->display(); + } + /** * Create a test task. * @@ -233,6 +279,87 @@ class testtask extends control $this->display(); } + /** + * Browse unit cases. + * + * @param int $taskID + * @param string $orderBy + * @access public + * @return void + */ + public function units($taskID, $orderBy = 'id_desc') + { + $task = $this->testtask->getById($taskID); + + /* Set browseType, productID, moduleID and queryID. */ + $productID = $this->product->saveState($task->product, $this->products); + + /* Set menu, save session. */ + $this->lang->testtask->menu = $this->lang->testcase->menu; + $this->lang->testtask->menuOrder = $this->lang->testcase->menuOrder; + $this->lang->testtask->subMenu->testcase->unit['subModule'] = 'testtask'; + $this->loadModel('testtask')->setUnitMenu($this->products, $productID, 0, $taskID); + $this->session->set('caseList', $this->app->getURI(true)); + + /* Load lang. */ + $this->app->loadLang('testtask'); + $this->app->loadLang('project'); + + /* Get test cases. */ + $runs = $this->testtask->getRuns($taskID, 0, $orderBy); + + /* save session .*/ + $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'testcase', false); + + $cases = array(); + $runs = $this->loadModel('testcase')->appendData($runs, 'testrun'); + foreach($runs as $run) $cases[$run->case] = $run; + + $results = $this->dao->select('*')->from(TABLE_TESTRESULT)->where('`case`')->in(array_keys($cases))->andWhere('run')->in(array_keys($runs))->fetchAll('run'); + foreach($results as $result) + { + $runs[$result->run]->caseResult = $result->caseResult; + $runs[$result->run]->xml = $result->xml; + $runs[$result->run]->duration = $result->duration; + } + + $groupCases = $this->dao->select('*')->from(TABLE_SUITECASE)->where('`case`')->in(array_keys($cases))->orderBy('case')->fetchGroup('suite', 'case'); + $summary = array(); + foreach($groupCases as $suiteID => $groupCase) + { + $caseNum = 0; + $failNum = 0; + $duration = 0; + foreach($groupCase as $caseID => $suitecase) + { + $case = $cases[$caseID]; + $groupCases[$suiteID][$caseID] = $case; + $duration += $case->duration; + $caseNum ++; + if($case->caseResult == 'fail') $failNum ++; + } + $summary[$suiteID] = sprintf($this->lang->testtask->unitSummary, $caseNum, $failNum, $duration); + } + + $suites = $this->loadModel('testsuite')->getUnit($productID); + + /* Assign. */ + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testcase->common; + $this->view->position[] = html::a($this->createLink('testcase', 'browseUnit', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = $this->lang->testcase->common; + + $this->view->productID = $productID; + $this->view->product = $this->product->getById($productID); + $this->view->productName = $this->products[$productID]; + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + $this->view->groupCases = $groupCases; + $this->view->suites = $suites; + $this->view->summary = $summary; + $this->view->taskID = $taskID; + + $this->display(); + } + /** * Browse cases of a test task. * @@ -1046,7 +1173,7 @@ class testtask extends control if(dao::isError()) die(js::error(dao::getError())); $this->loadModel('action')->create('testtask', $taskID, 'opened'); - die(js::locate($this->createLink('testtask', 'cases', "taskID=$taskID"), 'parent')); + die(js::locate($this->createLink('testtask', 'units', "taskID=$taskID"), 'parent')); } $this->testtask->setMenu($this->products, $productID); diff --git a/module/testtask/css/browseunit.css b/module/testtask/css/browseunit.css new file mode 100644 index 0000000000..fdfebcc2dc --- /dev/null +++ b/module/testtask/css/browseunit.css @@ -0,0 +1,2 @@ +td.pass{background-color:unset !important;border-color:unset !important;border-bottom: 1px solid #eee !important; color:green} +td.fail{background-color:unset !important;border-color:unset !important;border-bottom: 1px solid #eee !important; color:red} diff --git a/module/testtask/css/units.css b/module/testtask/css/units.css new file mode 100644 index 0000000000..af9f40e521 --- /dev/null +++ b/module/testtask/css/units.css @@ -0,0 +1,2 @@ +td.pass{color:green} +td.fail{color:red} diff --git a/module/testtask/lang/zh-cn.php b/module/testtask/lang/zh-cn.php index a1b54ac3e0..6467a9668d 100644 --- a/module/testtask/lang/zh-cn.php +++ b/module/testtask/lang/zh-cn.php @@ -57,6 +57,8 @@ $lang->testtask->product = '所属' . $lang->productCommon; $lang->testtask->project = '所属' . $lang->projectCommon; $lang->testtask->build = '版本'; $lang->testtask->owner = '负责人'; +$lang->testtask->executor = '执行人'; +$lang->testtask->execTime = '执行时间'; $lang->testtask->pri = '优先级'; $lang->testtask->name = '名称'; $lang->testtask->begin = '开始日期'; @@ -81,6 +83,10 @@ $lang->testtask->lastRunDate = '最后执行时间'; $lang->testtask->date = '测试时间'; $lang->testtask->deleted = "已删除"; $lang->testtask->resultFile = "测试结果"; +$lang->testtask->caseNum = '用例数'; +$lang->testtask->passNum = '成功'; +$lang->testtask->failNum = '失败'; +$lang->testtask->unitSummary = '有%s个用例,失败%s个,耗时%s。'; $lang->testtask->beginAndEnd = '起止时间'; $lang->testtask->to = '至'; @@ -175,3 +181,10 @@ $lang->testtask->featureBar['browse']['wait'] = $lang->testtask->wait; $lang->testtask->featureBar['browse']['doing'] = $lang->testtask->testing; $lang->testtask->featureBar['browse']['blocked'] = $lang->testtask->blocked; $lang->testtask->featureBar['browse']['done'] = $lang->testtask->done; + +$lang->testtask->unitTag['all'] = '所有'; +$lang->testtask->unitTag['newest'] = '最近'; +$lang->testtask->unitTag['thisWeek'] = '本周'; +$lang->testtask->unitTag['lastWeek'] = '上周'; +$lang->testtask->unitTag['thisMonth'] = '本月'; +$lang->testtask->unitTag['lastMonth'] = '上月'; diff --git a/module/testtask/model.php b/module/testtask/model.php index 22c3a798a9..a3b6bc87a7 100644 --- a/module/testtask/model.php +++ b/module/testtask/model.php @@ -115,6 +115,75 @@ class testtaskModel extends model } } + /** + * Set unit menu. + * + * @param array $products + * @param int $productID + * @param int $branch + * @param int $testtask + * @access public + * @return void + */ + public function setUnitMenu($products, $productID, $branch = 0, $testtask = 0) + { + $this->loadModel('product')->setMenu($products, $productID, $branch); + $selectHtml = $this->product->select($products, $productID, 'testtask', 'browseUnit', '', $branch); + + if($testtask and $this->app->viewType != 'mhtml') + { + $testtasks = $this->getProductUnitTasks($productID, 'all', 'id_desc'); + if(!isset($testtasks[$testtask])) $testtasks[$testtask] = $this->getById($testtask); + + $selectHtml .= "
"; + $selectHtml .= "
"; + $selectHtml .= "" . $testtasks[$testtask]->name . " "; + $selectHtml .= ""; + $selectHtml .= "
"; + $selectHtml .= "
"; + } + + $this->app->loadLang('qa'); + $productIndex = '
' . html::a(helper::createLink('qa', 'index', 'locate=no'), $this->lang->qa->index, '', "class='btn'") . '
'; + $productIndex .= $selectHtml; + + $pageNav = ''; + $pageActions = ''; + $isMobile = $this->app->viewType == 'mhtml'; + if($isMobile) + { + $this->app->loadLang('qa'); + $pageNav = html::a(helper::createLink('qa', 'index'), $this->lang->qa->index) . $this->lang->colon; + } + else + { + if($this->config->global->flow == 'full') + { + $this->app->loadLang('qa'); + $pageNav = '
' . html::a(helper::createLink('qa', 'index', 'locate=no'), $this->lang->qa->index, '', "class='btn'") . '
'; + } + } + $pageNav .= $selectHtml; + + $this->lang->modulePageNav = $pageNav; + $this->lang->modulePageActions = $pageActions; + foreach($this->lang->testtask->menu as $key => $value) + { + $this->loadModel('qa')->setSubMenu('testtask', $key, $productID); + if($this->config->global->flow != 'onlyTest') + { + $replace = ($key == 'product') ? $selectHtml : $productID; + } + else + { + if($key == 'product') $replace = $selectHtml; + } + common::setMenuVars($this->lang->testtask->menu, $key, $replace); + } + } + /** * Create a test task. * @@ -167,6 +236,7 @@ class testtaskModel extends model ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') ->leftJoin(TABLE_BUILD)->alias('t4')->on('t1.build = t4.id') ->where('t1.deleted')->eq(0) + ->andWhere('t1.auto')->eq('no') ->beginIF($scopeAndStatus[0] == 'local')->andWhere('t1.product')->eq((int)$productID)->fi() ->beginIF($scopeAndStatus[0] == 'all')->andWhere('t1.product')->in($products)->fi() ->beginIF($scopeAndStatus[1] == 'totalStatus')->andWhere('t1.status')->in(('blocked,doing,wait,done'))->fi() @@ -186,6 +256,7 @@ class testtaskModel extends model ->leftJoin(TABLE_PROJECTPRODUCT)->alias('t5')->on('t1.project = t5.project and t1.product = t5.product') ->where('t1.deleted')->eq(0) + ->andWhere('t1.auto')->eq('no') ->andWhere('t3.id')->in($this->app->user->view->projects) ->beginIF($scopeAndStatus[0] == 'local')->andWhere('t1.product')->eq((int)$productID)->fi() ->beginIF($scopeAndStatus[0] == 'all')->andWhere('t1.product')->in($products)->fi() @@ -200,6 +271,77 @@ class testtaskModel extends model } } + /** + * Get product unit tasks. + * + * @param int $productID + * @param string $browseType + * @param string $orderBy + * @param int $pager + * @access public + * @return void + */ + public function getProductUnitTasks($productID, $browseType = '', $orderBy = 'id_desc', $pager = null) + { + $beginAndEnd = $this->loadModel('action')->computeBeginAndEnd($browseType); + if($browseType == 'newest') $orderBy = 'end_desc,' . $orderBy; + if($this->config->global->flow == 'onlyTest') + { + $tasks = $this->dao->select("t1.*, t2.name AS productName,t4.name AS buildName") + ->from(TABLE_TESTTASK)->alias('t1') + ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') + ->leftJoin(TABLE_BUILD)->alias('t4')->on('t1.build = t4.id') + ->where('t1.deleted')->eq(0) + ->andWhere('t1.product')->eq($productID) + ->andWhere('t1.auto')->ne('no') + ->beginIF($browseType != 'all' and $browseType != 'newest' and $beginAndEnd) + ->andWhere('t1.end')->ge($beginAndEnd['begin']) + ->andWhere('t1.end')->le($beginAndEnd['end']) + ->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + } + else + { + $tasks = $this->dao->select("t1.*, t2.name AS productName, t3.name AS projectName, t4.name AS buildName") + ->from(TABLE_TESTTASK)->alias('t1') + ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id') + ->leftJoin(TABLE_PROJECT)->alias('t3')->on('t1.project = t3.id') + ->leftJoin(TABLE_BUILD)->alias('t4')->on('t1.build = t4.id') + ->where('t1.deleted')->eq(0) + ->andWhere('t1.product')->eq($productID) + ->andWhere('t1.auto')->ne('no') + ->beginIF($browseType != 'all' and $browseType != 'newest' and $beginAndEnd) + ->andWhere('t1.end')->ge($beginAndEnd['begin']) + ->andWhere('t1.end')->le($beginAndEnd['end']) + ->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + } + $resultGroups = $this->dao->select('t1.task, t2.*')->from(TABLE_TESTRUN)->alias('t1') + ->leftJoin(TABLE_TESTRESULT)->alias('t2')->on('t1.id=t2.run') + ->where('t1.task')->in(array_keys($tasks)) + ->fetchGroup('task', 'run'); + + foreach($tasks as $taskID => $task) + { + $results = zget($resultGroups, $taskID, array()); + + $task->caseNum = count($results); + $task->passNum = 0; + $task->failNum = 0; + foreach($results as $result) + { + if($result->caseResult == 'pass') $task->passNum ++; + if($result->caseResult == 'fail') $task->failNum ++; + } + } + + return $tasks; + } + /** * Get test tasks of a project. * @@ -215,6 +357,7 @@ class testtaskModel extends model ->from(TABLE_TESTTASK)->alias('t1') ->leftJoin(TABLE_BUILD)->alias('t2')->on('t1.build = t2.id') ->where('t1.project')->eq((int)$projectID) + ->andWhere('t1.auto')->eq('no') ->andWhere('t1.deleted')->eq(0) ->orderBy($orderBy) ->page($pager) @@ -286,6 +429,7 @@ class testtaskModel extends model ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') ->leftJoin(TABLE_BUILD)->alias('t3')->on('t1.build = t3.id') ->where('t1.deleted')->eq(0) + ->andWhere('t1.auto')->eq('no') ->andWhere('t1.owner')->eq($account) ->andWhere('t2.id')->in($this->app->user->view->projects) ->beginIF($type == 'wait')->andWhere('t1.status')->ne('done')->fi() @@ -486,6 +630,7 @@ class testtaskModel extends model return $this->dao->select('id, name')->from(TABLE_TESTTASK) ->where('product')->eq($productID) + ->andWhere('auto')->eq('no') ->beginIF($beginDate)->andWhere('begin')->le($beginDate)->fi() ->andWhere('deleted')->eq('0') ->andWhere('id')->notin($testTaskID) @@ -1507,119 +1652,18 @@ class testtaskModel extends model $frame = $this->post->frame; unset($_POST['frame']); - /* Parse result xml. */ - $unitFormat = zget($this->config->testtask->unitFormat, $frame, $this->config->testtask->unitFormat->common); - $fileName = $this->session->resultFile; - $parsedXML = simplexml_load_file($fileName); - - /* Get testcase node. */ - $matchPaths = $unitFormat['path']; - $nameFields = $unitFormat['name']; - $failure = $unitFormat['failure']; - $matchNodes = array(); - foreach($matchPaths as $matchPath) - { - $matchNodes = $parsedXML->xpath($matchPath); - if(count($matchNodes) != 0) break; - } - if(count($matchNodes) == 0) die(js::alert($this->lang->testtask->noImportData)); - - $parentPath = ''; - $caseNode = $matchPath; - $parentNodes = array($parsedXML); - if(strpos($matchPath, '/') !== false) - { - $explodedPath = explode('/', $matchPath); - $caseNode = array_pop($explodedPath); - $parentPath = implode('/', $explodedPath); - $parentNodes = $parsedXML->xpath($parentPath); - } - - /* Get cases and results by parsed node. */ - $now = helper::now(); - $cases = array(); - $results = array(); - $suites = array(); - $caseTitles = array(); - $suiteNames = array(); - foreach($parentNodes as $suiteIndex => $parentNode) - { - $attributes = $parentNode->attributes(); - $suite = ''; - if(isset($attributes['name'])) - { - $suite = new stdclass(); - $suite->product = $productID; - $suite->name = (string)$attributes['name']; - $suite->type = 'unit'; - $suite->addedBy = $this->app->user->account; - $suite->addedDate = $now; - $suiteNames[] = $suite->name; - } - $suites[$suiteIndex] = $suite; - - foreach($parentNode->xpath($caseNode) as $caseIndex => $matchNode) - { - $case = new stdclass(); - $case->product = $productID; - $case->title = ''; - $case->pri = 3; - $case->type = 'unit'; - $case->stage = 'unittest'; - $case->status = 'normal'; - $case->openedBy = $this->app->user->account; - $case->openedDate = $now; - $case->version = 1; - $case->auto = 'unit'; - $case->frame = 'junit'; - - $attributes = $matchNode->attributes(); - foreach($nameFields as $field) - { - if(!isset($attributes[$field])) continue; - $case->title .= (string)$attributes[$field] . ' '; - } - $case->title = trim($case->title); - - $result = new stdclass(); - $result->case = 0; - $result->version = 1; - $result->caseResult = 'pass'; - $result->lastRunner = $this->app->user->account; - $result->date = $now; - $result->stepResults[0]['result'] = 'pass'; - $result->stepResults[0]['real'] = ''; - if(isset($matchNode->$failure)) - { - $result->caseResult = 'fail'; - $result->stepResults[0]['result'] = 'fail'; - if(is_string($matchNode->$failure)) - { - $result->stepResults[0]['real'] = (string)$matchNode->$failure; - } - else - { - $failureAttrs = $matchNode->$failure->attributes(); - $result->stepResults[0]['real'] = (string)$failureAttrs['message']; - } - } - $result->stepResults = serialize($result->stepResults); - $case->lastRunner = $this->app->user->account; - $case->lastRunDate = $now; - $case->lastRunResult = $result->caseResult; - - $caseTitles[$suiteIndex][] = $case->title; - $cases[$suiteIndex][$caseIndex] = $case; - $results[$suiteIndex][$caseIndex] = $result; - } - } + $fileName = $this->session->resultFile; + $data = $this->buildDataFromXML($fileName, $productID, $frame); /* Create task. */ + $this->post->set('auto', 'unit'); $testtaskID = $this->create(); + unlink($fileName); + unset($_SESSION['resultFile']); if(dao::isError()) return false; - return $this->saveUnit($testtaskID, $productID, $suites, $cases, $results, $suiteNames, $caseTitles); + return $this->saveUnit($testtaskID, $productID, $data['suites'], $data['cases'], $data['results'], $data['suiteNames'], $data['caseTitles']); } /** @@ -1690,16 +1734,6 @@ class testtaskModel extends model $caseID = $existCases[$case->title]; } - if($suiteID) - { - $suitecase = new stdclass(); - $suitecase->suite = $suiteID; - $suitecase->case = $caseID; - $suitecase->version = $case->version; - $suitecase->product = $case->product; - $this->dao->replace(TABLE_SUITECASE)->data($suitecase)->exec(); - } - $testrun = new stdclass(); $testrun->task = $testtaskID; $testrun->case = $caseID; @@ -1712,6 +1746,17 @@ class testtaskModel extends model $this->dao->replace(TABLE_TESTRUN)->data($testrun)->exec(); $runID = $this->dao->lastInsertID(); + if($suiteID) + { + $suitecase = new stdclass(); + $suitecase->suite = $suiteID; + $suitecase->run = $runID; + $suitecase->case = $caseID; + $suitecase->version = $case->version; + $suitecase->product = $case->product; + $this->dao->replace(TABLE_SUITECASE)->data($suitecase)->exec(); + } + $testresult = $results[$suiteIndex][$i]; $testresult->run = $runID; $testresult->case = $caseID; @@ -1722,6 +1767,143 @@ class testtaskModel extends model return $testtaskID; } + /** + * buildDataFromXML + * + * @param string $fileName + * @param int $productID + * @param string $frame + * @access public + * @return array + */ + public function buildDataFromXML($fileName, $productID, $frame) + { + /* Parse result xml. */ + $unitFormat = zget($this->config->testtask->unitFormat, $frame, $this->config->testtask->unitFormat->common); + $parsedXML = simplexml_load_file($fileName); + + /* Get testcase node. */ + $matchPaths = $unitFormat['path']; + $nameFields = $unitFormat['name']; + $failure = $unitFormat['failure']; + $matchNodes = array(); + foreach($matchPaths as $matchPath) + { + $matchNodes = $parsedXML->xpath($matchPath); + if(count($matchNodes) != 0) break; + } + if(count($matchNodes) == 0) die(js::alert($this->lang->testtask->noImportData)); + + $parentPath = ''; + $caseNode = $matchPath; + $parentNodes = array($parsedXML); + if(strpos($matchPath, '/') !== false) + { + $explodedPath = explode('/', $matchPath); + $caseNode = array_pop($explodedPath); + $parentPath = implode('/', $explodedPath); + $parentNodes = $parsedXML->xpath($parentPath); + } + + /* Get cases and results by parsed node. */ + $now = helper::now(); + $cases = array(); + $results = array(); + $suites = array(); + $caseTitles = array(); + $suiteNames = array(); + foreach($parentNodes as $suiteIndex => $parentNode) + { + $caseNodes = $parentNode->xpath($caseNode); + $attributes = $parentNode->attributes(); + $suite = ''; + if(isset($attributes['name'])) + { + $suite = new stdclass(); + $suite->product = $productID; + $suite->name = (string)$attributes['name']; + $suite->type = 'unit'; + $suite->addedBy = $this->app->user->account; + $suite->addedDate = $now; + $suiteNames[] = $suite->name; + } + else + { + $attributes = $caseNodes[0]->attributes(); + if(isset($attributes['classname'])) + { + $suite = new stdclass(); + $suite->product = $productID; + $suite->name = (string)$attributes['classname']; + $suite->type = 'unit'; + $suite->addedBy = $this->app->user->account; + $suite->addedDate = $now; + $suiteNames[] = $suite->name; + } + } + $suites[$suiteIndex] = $suite; + + foreach($caseNodes as $caseIndex => $matchNode) + { + $case = new stdclass(); + $case->product = $productID; + $case->title = ''; + $case->pri = 3; + $case->type = 'unit'; + $case->stage = 'unittest'; + $case->status = 'normal'; + $case->openedBy = $this->app->user->account; + $case->openedDate = $now; + $case->version = 1; + $case->auto = 'unit'; + $case->frame = $frame ? $frame : 'junit'; + + $attributes = $matchNode->attributes(); + foreach($nameFields as $field) + { + if(!isset($attributes[$field])) continue; + $case->title .= (string)$attributes[$field] . ' '; + } + $case->title = trim($case->title); + + $result = new stdclass(); + $result->case = 0; + $result->version = 1; + $result->caseResult = 'pass'; + $result->lastRunner = $this->app->user->account; + $result->date = $now; + $result->duration = (float)$attributes['time']; + $result->xml = $matchNode->asXML(); + $result->stepResults[0]['result'] = 'pass'; + $result->stepResults[0]['real'] = ''; + if(isset($matchNode->$failure)) + { + $result->caseResult = 'fail'; + $result->stepResults[0]['result'] = 'fail'; + if(is_string($matchNode->$failure)) + { + $result->stepResults[0]['real'] = (string)$matchNode->$failure; + } + else + { + $failureAttrs = $matchNode->$failure->attributes(); + $result->stepResults[0]['real'] = (string)$failureAttrs['message']; + } + } + $result->stepResults = serialize($result->stepResults); + $case->lastRunner = $this->app->user->account; + $case->lastRunDate = $now; + $case->lastRunResult = $result->caseResult; + + $caseTitles[$suiteIndex][] = $case->title; + $cases[$suiteIndex][$caseIndex] = $case; + $results[$suiteIndex][$caseIndex] = $result; + } + } + + return array('suites' => $suites, 'cases' => $cases, 'results' => $results, 'suiteNames' => $suiteNames, 'caseTitles' => $caseTitles); + } + /** * Build data from unit. * @@ -1761,7 +1943,7 @@ class testtaskModel extends model $case = new stdclass(); $case->product = $productID; - $case->title = $caseResult->TestSuite . ' ' . $caseResult->Title; + $case->title = $caseResult->Title; $case->pri = 3; $case->type = 'unit'; $case->stage = 'unittest'; @@ -1780,6 +1962,7 @@ class testtaskModel extends model $result->job = $jobID; $result->compile = $compileID; $result->date = $now; + $result->duration = $caseResult->Duration; $result->stepResults[0]['result'] = 'pass'; $result->stepResults[0]['real'] = ''; if(!empty($caseResult->Failure)) diff --git a/module/testtask/view/results.html.php b/module/testtask/view/results.html.php index 271d8e373b..420909dec5 100644 --- a/module/testtask/view/results.html.php +++ b/module/testtask/view/results.html.php @@ -20,16 +20,20 @@
+ auto == 'no'):?>
testcase->precondition;?>
precondition;?>
+
+ auto == 'no'):?> + global->flow); -if(!isset($branch)) $branch = 0; ?> global->flow == 'full'):?> @@ -87,9 +41,6 @@ if(!isset($branch)) $branch = 0;

testcase->noCase;?> - - createLink('testcase', 'create', "productID=$productID&branch=$branch&moduleID=$initModule"), " " . $lang->testcase->create, '', "class='btn btn-info'");?> -

@@ -105,15 +56,13 @@ if(!isset($branch)) $branch = 0; - - - + @@ -123,51 +72,33 @@ if(!isset($branch)) $branch = 0; $suite = zget($suites, $suiteID, ''); $groupName = $suite ? $suite->name : ''; ?> - + $case):?> > - + - - + - - - + + - @@ -175,4 +106,10 @@ if(!isset($branch)) $branch = 0;
testcase->result?>   testtask->showResult, $count)?>
idAB;?> priAB;?> testcase->title;?> typeAB;?> testtask->lastRunAccount;?> testtask->lastRunTime;?> testtask->lastRunResult;?> testcase->status;?> testcase->bugsAB;?> testcase->resultsAB;?> testcase->stepNumberAB;?> actions;?> actions;?>
$groupName", '', "class='text-primary'");?>
+
id);?> pri;?>' title='testcase->priList, $case->pri, $case->pri);?>'>testcase->priList, $case->pri, $case->pri);?>id", $case->title)) echo $case->title;?>case->typeList, $case->type, '');?>case&version={$case->version}&from=testtask&task=$taskID", $case->title)) echo $case->title;?> lastRunner);?> lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?> lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?> - needconfirm) - { - echo "({$lang->story->changed} "; - echo html::a(helper::createLink('testcase', 'confirmStoryChange', "caseID=$case->id"), $lang->confirm, 'hiddenwin'); - echo ")"; - } - else - { - echo ""; - echo $this->processStatus('testcase', $case); - echo ''; - } - ?> - bugs) ? html::a(inlink('bugs', "runID=0&caseID={$case->id}"), $case->bugs, '', "class='iframe'") : $case->bugs;?>results) ? html::a($this->createLink('testtask', 'results', "runID=0&caseID={$case->id}"), $case->results, '', "class='iframe'") : $case->results;?>bugs) ? html::a($this->createLink('testcase', 'bugs', "runID={$case->id}&caseID={$case->case}"), $case->bugs, '', "class='iframe'") : $case->bugs;?>results) ? html::a($this->createLink('testtask', 'results', "runID={$case->id}&caseID={$case->case}"), $case->results, '', "class='iframe'") : $case->results;?> stepNumber;?> - id", $case, 'list', '', '', 'iframe', true, "data-width='95%'");?> - id", '', 'list');?> - id", '', 'list', '', 'hiddenwin');?> + id&caseID=$case->case", $case, 'list', '', '', 'iframe', true, "data-width='95%'");?>
+