diff --git a/db/update12.2.sql b/db/update12.2.sql index 9dc8463878..90fdfb7c3e 100644 --- a/db/update12.2.sql +++ b/db/update12.2.sql @@ -1 +1,2 @@ ALTER TABLE `zt_job` ADD `frame` varchar(20) COLLATE 'utf8_general_ci' NOT NULL AFTER `repo`; +ALTER TABLE `zt_compile` ADD `testtask` mediumint unsigned NULL AFTER `atTime`; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 060ecdc628..26e34c9e84 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -300,7 +300,7 @@ $lang->testtask = new stdclass(); $lang->testtask->menu = new stdclass(); $lang->testtask->menu->bug = array('link' => 'Bug|bug|browse|productID=%s'); $lang->testtask->menu->testcase = array('link' => '用例|testcase|browse|productID=%s'); -$lang->testtask->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report'); +$lang->testtask->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s', 'subModule' => 'testtask', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report'); $lang->testtask->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s'); $lang->testtask->menu->report = array('link' => '报告|testreport|browse|productID=%s'); $lang->testtask->menu->caselib = array('link' => '用例库|caselib|browse'); diff --git a/module/job/js/edit.js b/module/job/js/edit.js index 39eb2c1558..2a1bd472a9 100644 --- a/module/job/js/edit.js +++ b/module/job/js/edit.js @@ -78,7 +78,11 @@ $('#triggerType').change(function() var repoID = $('#repo').val(); var type = 'Git'; if(typeof(repoTypes[repoID]) != 'undefined') type = repoTypes[repoID]; - if(type == 'Subversion') $('.svn-fields').removeClass('hidden'); + if(type == 'Subversion') + { + $('.svn-fields').removeClass('hidden'); + if($('.svn-fields td .input-group select').length == 0) $('#repo').change(); + } } }); diff --git a/module/job/view/edit.html.php b/module/job/view/edit.html.php index 19119aabff..a19da86983 100644 --- a/module/job/view/edit.html.php +++ b/module/job/view/edit.html.php @@ -54,7 +54,8 @@ if($repoType == 'Subversion' and $job->svnDir) { $path = ''; - $svnDirs = empty(trim($job->svnDir, '/')) ? '' : $job->svnDir; + $svnDirs = trim($job->svnDir, '/'); + $svnDirs = empty($svnDirs) ? '' : $job->svnDir; $svnDirs = explode('/', $svnDirs); foreach($svnDirs as $i => $svnDir) { diff --git a/module/testtask/config.php b/module/testtask/config.php index 56e201e186..4e3cd708a1 100644 --- a/module/testtask/config.php +++ b/module/testtask/config.php @@ -1,18 +1,25 @@ testtask = new stdclass(); -$config->testtask->create = new stdclass(); -$config->testtask->edit = new stdclass(); -$config->testtask->create->requiredFields = 'project,build,begin,end,name'; -$config->testtask->edit->requiredFields = 'project,build,begin,end,name'; +$config->testtask->create = new stdclass(); +$config->testtask->importunit = new stdclass(); +$config->testtask->edit = new stdclass(); +$config->testtask->create->requiredFields = 'project,build,begin,end,name'; +$config->testtask->importunit->requiredFields = 'project,build,begin,end,name,resultFile'; +$config->testtask->edit->requiredFields = 'project,build,begin,end,name'; $config->testtask->editor = new stdclass(); -$config->testtask->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); -$config->testtask->editor->edit = array('id' => 'desc,report,comment', 'tools' => 'simpleTools'); -$config->testtask->editor->view = array('id' => 'lastComment', 'tools' => 'simpleTools'); -$config->testtask->editor->start = array('id' => 'comment', 'tools' => 'simpleTools'); -$config->testtask->editor->close = array('id' => 'report,comment', 'tools' => 'simpleTools'); -$config->testtask->editor->block = array('id' => 'comment', 'tools' => 'simpleTools'); -$config->testtask->editor->activate= array('id' => 'comment', 'tools' => 'simpleTools'); +$config->testtask->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->testtask->editor->edit = array('id' => 'desc,report,comment', 'tools' => 'simpleTools'); +$config->testtask->editor->view = array('id' => 'lastComment', 'tools' => 'simpleTools'); +$config->testtask->editor->start = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->testtask->editor->close = array('id' => 'report,comment', 'tools' => 'simpleTools'); +$config->testtask->editor->block = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->testtask->editor->activate = array('id' => 'comment', 'tools' => 'simpleTools'); +$config->testtask->editor->importunit = array('id' => 'desc', 'tools' => 'simpleTools'); $config->testtask->datatable = new stdclass(); $config->testtask->datatable->defaultField = array('id', 'pri', 'title', 'type', 'assignedTo', 'lastRunner', 'lastRunDate', 'lastRunResult', 'status', 'bugs', 'results', 'stepNumber','actions'); + +$config->testtask->unitFormat = new stdclass(); +$config->testtask->unitFormat->common = array('path' => array('testsuite/testcase', 'testcase'), 'name' => array('classname', 'name'), 'failure' => 'failure'); +$config->testtask->unitFormat->phpunit = array('path' => array('test', 'testsuite/testcase', 'testcase'), 'name' => array('className', 'methodName'), 'failure' => 'failure'); diff --git a/module/testtask/control.php b/module/testtask/control.php index 9e187bfd1a..1256ade2dc 100644 --- a/module/testtask/control.php +++ b/module/testtask/control.php @@ -1023,4 +1023,53 @@ class testtask extends control ->exec(); die(js::locate($this->session->caseList, 'parent')); } + + /** + * Import unit results. + * + * @param int $productID + * @access public + * @return void + */ + public function importUnit($productID) + { + if($_POST) + { + $file = $this->loadModel('file')->getUpload('resultFile'); + $file = $file[0]; + + $fileName = $this->file->savePath . $this->file->getSaveName($file['pathname']); + move_uploaded_file($file['tmpname'], $fileName); + $this->session->set('resultFile', $fileName); + + $taskID = $this->testtask->importUnit($productID); + 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')); + } + + $this->testtask->setMenu($this->products, $productID); + + $this->app->loadLang('job'); + $projects = $this->dao->select('t2.id, t2.name')->from(TABLE_PROJECTPRODUCT) + ->alias('t1')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') + ->where('t1.product')->eq((int)$productID) + ->andWhere('t2.deleted')->eq(0) + ->beginIF('0')->andWhere('t1.branch')->in('0')->fi() + ->beginIF(!$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->projects)->fi() + ->andWhere('t2.type')->ne('ops') + ->orderBy('t1.project desc') + ->fetchPairs('id', 'name'); + + $this->view->title = $this->products[$productID] . $this->lang->colon . $this->lang->testtask->importUnit; + $this->view->position[] = html::a($this->createLink('testtask', 'browse', "productID=$productID"), $this->products[$productID]); + $this->view->position[] = $this->lang->testtask->importUnit; + + $this->view->projects = array('' => '') + $projects; + $this->view->builds = $this->loadModel('build')->getProductBuildPairs($productID, 0, 'notrunk'); + $this->view->users = $this->loadModel('user')->getPairs('noletter|nodeleted|noclosed'); + $this->view->productID = $productID; + $this->display(); + } } diff --git a/module/testtask/js/common.js b/module/testtask/js/common.js index 1c67ebf668..95f00b00ab 100644 --- a/module/testtask/js/common.js +++ b/module/testtask/js/common.js @@ -44,3 +44,54 @@ function createBug(obj) window.open(createLink('bug', 'create', params + ',stepIdList=' + stepIdList), '_blank'); config.onlybody = onlybody; } + +function loadProjectRelated(projectID) +{ + loadProjectBuilds(projectID); +} + +function loadProjectBuilds(projectID) +{ + selectedBuild = $('#build').val(); + if(!selectedBuild) selectedBuild = 0; + link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild); + if(projectID == 0) link = createLink('build', 'ajaxGetProductBuilds', 'productID=' + $('#product').val() + '&varName=resolvedBuild&build=' + selectedBuild); + $('#buildBox').load(link, function() + { + $('#resolvedBuild').attr('id', 'build').attr('name', 'build').find('option[value=trunk]').remove(); + $('#build').chosen(); + }); +} + +/** + * when begin date input change and end date input is null + * change end date input to begin's after day + * + * @access public + * @return void + */ +function suitEndDate() +{ + beginDate = $('#begin').val(); + if(!beginDate) return; + endDate = $('#end').val(); + if(endDate) return; + + endDate = convertStringToDate(beginDate).addDays(1).toString('yyyy-MM-dd'); + $('#end').val(endDate); +} + +/** + * Convert a date string like 2011-11-11 to date object in js. + * + * @param string $date + * @access public + * @return date + */ +function convertStringToDate(dateString) +{ + dateString = dateString.split('-'); + dateString = dateString[1] + '/' + dateString[2] + '/' + dateString[0]; + + return Date.parse(dateString); +} diff --git a/module/testtask/js/create.js b/module/testtask/js/create.js index 6187212348..435254b2d4 100755 --- a/module/testtask/js/create.js +++ b/module/testtask/js/create.js @@ -9,66 +9,6 @@ function loadProductRelated() loadProjectBuilds(parseInt($('#project').val())); } -/** - * Load project related builds - * - * @param int $projectID - * @access public - * @return void - */ -function loadProjectRelated(projectID) -{ - loadProjectBuilds(projectID); -} - -/** - * Load project builds. - * - * @param int $projectID - * @access public - * @return void - */ -function loadProjectBuilds(projectID) -{ - selectedBuild = $('#build').val(); - if(!selectedBuild) selectedBuild = 0; - link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild); - $('#buildBox').load(link, function(){$('#build').chosen();}); -} - -/** - * Convert a date string like 2011-11-11 to date object in js. - * - * @param string $date - * @access public - * @return date - */ -function convertStringToDate(dateString) -{ - dateString = dateString.split('-'); - dateString = dateString[1] + '/' + dateString[2] + '/' + dateString[0]; - - return Date.parse(dateString); -} - -/** - * when begin date input change and end date input is null - * change end date input to begin's after day - * - * @access public - * @return void - */ -function suitEndDate() -{ - beginDate = $('#begin').val(); - if(!beginDate) return; - endDate = $('#end').val(); - if(endDate) return; - - endDate = convertStringToDate(beginDate).addDays(1).toString('yyyy-MM-dd'); - $('#end').val(endDate); -} - /* If the mouse hover over the manage contacts button, give tip. */ $(function() { diff --git a/module/testtask/js/edit.js b/module/testtask/js/edit.js index 5c108bcadd..c60cf07c54 100755 --- a/module/testtask/js/edit.js +++ b/module/testtask/js/edit.js @@ -1,30 +1,3 @@ -/** - * Load project related builds - * - * @param int $projectID - * @access public - * @return void - */ -function loadProjectRelated(projectID) -{ - loadProjectBuilds(projectID); -} - -/** - * Load project builds. - * - * @param int $projectID - * @access public - * @return void - */ -function loadProjectBuilds(projectID) -{ - selectedBuild = $('#build').val(); - if(!selectedBuild) selectedBuild = 0; - link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + $('#product').val() + '&varName=testTaskBuild&build=' + selectedBuild); - $('#buildBox').load(link, function(){$('#build').chosen();}); -} - $(function() { adjustPriBoxWidth(); diff --git a/module/testtask/lang/zh-cn.php b/module/testtask/lang/zh-cn.php index c486fce084..5f21b0ab24 100644 --- a/module/testtask/lang/zh-cn.php +++ b/module/testtask/lang/zh-cn.php @@ -14,6 +14,7 @@ $lang->testtask->create = "提交测试"; $lang->testtask->reportChart = '报表统计'; $lang->testtask->reportAction = '用例报表统计'; $lang->testtask->delete = "删除测试单"; +$lang->testtask->importUnit = "导入测试结果"; $lang->testtask->view = "概况"; $lang->testtask->edit = "编辑测试单"; $lang->testtask->browse = "测试单列表"; @@ -79,6 +80,7 @@ $lang->testtask->lastRunner = '最后执行人'; $lang->testtask->lastRunDate = '最后执行时间'; $lang->testtask->date = '测试时间'; $lang->testtask->deleted = "已删除"; +$lang->testtask->resultFile = "测试结果"; $lang->testtask->beginAndEnd = '起止时间'; $lang->testtask->to = '至'; diff --git a/module/testtask/model.php b/module/testtask/model.php index bef9dfd338..2b3fc4c4ee 100644 --- a/module/testtask/model.php +++ b/module/testtask/model.php @@ -1493,4 +1493,127 @@ class testtaskModel extends model } return array($toList, $ccList); } + + /** + * Import unit results. + * + * @param int $productID + * @access public + * @return string + */ + public function importUnit($productID) + { + $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']; + foreach($matchPaths as $matchPath) + { + $matchNodes = $parsedXML->xpath($matchPath); + if(count($matchNodes) != 0) break; + } + + /* Get cases and results by parsed node. */ + $now = helper::now(); + $cases = array(); + $titles = array(); + $results = array(); + foreach($matchNodes as $i => $matchNode) + { + $case = new stdclass(); + $case->product = $productID; + $case->title = ''; + $case->pri = 3; + $case->type = 'feature'; + $case->stage = 'unittest'; + $case->status = 'normal'; + $case->openedBy = $this->app->user->account; + $case->openedDate = $now; + $case->version = 1; + + $attributes = $matchNode->attributes(); + foreach($nameFields as $field) $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; + + $titles[] = $case->title; + $cases[$i] = $case; + $results[$i] = $result; + } + + /* Create task. */ + $testtaskID = $this->create(); + unlink($fileName); + if(dao::isError()) return false; + + /* Import cases and link task and insert result. */ + $existCases = $this->dao->select('*')->from(TABLE_CASE)->where('title')->in($titles)->andWhere('stage')->eq('unittest')->andWhere('deleted')->eq(0)->fetchPairs('title', 'id'); + $this->loadModel('action'); + foreach($cases as $i => $case) + { + if(!isset($existCases[$case->title])) + { + $this->dao->insert(TABLE_CASE)->data($case)->exec(); + $caseID = $this->dao->lastInsertID(); + $this->action->create('case', $caseID, 'Opened'); + } + else + { + $caseID = $existCases[$case->title]; + } + + $testrun = new stdclass(); + $testrun->task = $testtaskID; + $testrun->case = $caseID; + $testrun->version = $case->version; + $testrun->lastRunner = $case->lastRunner; + $testrun->lastRunDate = $case->lastRunDate; + $testrun->lastRunResult = $case->lastRunResult; + $testrun->status = 'done'; + + $this->dao->replace(TABLE_TESTRUN)->data($testrun)->exec(); + $runID = $this->dao->lastInsertID(); + + $testresult = $results[$i]; + $testresult->run = $runID; + $testresult->case = $caseID; + $this->dao->insert(TABLE_TESTRESULT)->data($testresult)->exec(); + } + + return $testtaskID; + } } diff --git a/module/testtask/view/browse.html.php b/module/testtask/view/browse.html.php index f6d11336a8..449ec7e573 100644 --- a/module/testtask/view/browse.html.php +++ b/module/testtask/view/browse.html.php @@ -46,7 +46,10 @@ $status = $this->session->testTaskVersionStatus;
- +