gitList();
+cid=1
+pid=1
+
+获取GiLlab列表 >> 1
+
+*/
+
+$gitlab = new gitlabTest();
+
+$orderBy = 'id_desc';
+r($gitlab->getList($orderBy)) && p('id') && e('1'); // 获取GitLab列表
+
+system("./ztest init");
diff --git a/module/gitlab/test/model/getpairs.php b/module/gitlab/test/model/getpairs.php
new file mode 100755
index 0000000000..aa1f6be05a
--- /dev/null
+++ b/module/gitlab/test/model/getpairs.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+gitPairs();
+cid=1
+pid=1
+
+获取GitLab >> 1
+
+*/
+
+$gitlab = new gitlabTest();
+
+r($gitlab->getPairs()) && p() && e('1'); // 获取GitLab
+
+system("./ztest init");
diff --git a/module/gitlab/test/model/getversion.php b/module/gitlab/test/model/getversion.php
new file mode 100755
index 0000000000..f3bf5d5f7a
--- /dev/null
+++ b/module/gitlab/test/model/getversion.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+> success
+通过正确的host,错误的token获取api权限 >> return false
+通过错误或低版本的的host,token获取api权限 >> return false
+
+*/
+
+$gitlab = $tester->loadModel('gitlab');
+
+$gitlabID = 1;
+$gitlabServer = $tester->loadModel('pipeline')->getByID($gitlabID);
+
+$result = $gitlab->getVersion($gitlabServer->url, $gitlabServer->token);
+if(isset($result->version)) $result = 'success';
+r($result) && p() && e('success'); //通过host,token检验api权限
+
+$result = $gitlab->getVersion($gitlabServer->url, $gitlabServer->token . 'a');
+if(!isset($result->version)) $result = 'return false';
+r($result) && p() && e('return false'); //通过正确的host,错误的token获取api权限
+
+$result = $gitlab->getVersion($gitlabServer->url . '1', $gitlabServer->token);
+if(!isset($result->version)) $result = 'return false';
+r($result) && p() && e('return false'); //通过错误或低版本的的host,token获取api权限
\ No newline at end of file
diff --git a/module/gitlab/test/model/managebranchprivs.php b/module/gitlab/test/model/managebranchprivs.php
new file mode 100755
index 0000000000..aa8846dc21
--- /dev/null
+++ b/module/gitlab/test/model/managebranchprivs.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+manageBranchPrivs();
+cid=1
+pid=1
+
+维护已存在的保护分支 >> fail
+使用错误的gitlabID维护保护分支 >> success
+使用错误的项目ID维护保护分支 >> success
+
+*/
+
+$gitlab = new gitlabTest();
+
+$_POST['branches'][0] = '1227';
+$_POST['mergeLevels'][0] = 40;
+$_POST['pushLevels'][0] = 40;
+
+$result1 = $gitlab->manageBranchPrivsTest(1, 1569);
+$result2 = $gitlab->manageBranchPrivsTest(0, 1569);
+$result3 = $gitlab->manageBranchPrivsTest(1, 0);
+
+r($result1) && p('') && e('fail'); // 维护已存在的保护分支
+r($result2) && p('') && e('success'); // 使用错误的gitlabID维护保护分支
+r($result3) && p('') && e('success'); // 使用错误的项目ID维护保护分支
diff --git a/module/gitlab/test/model/managetagprivs.php b/module/gitlab/test/model/managetagprivs.php
new file mode 100755
index 0000000000..b075a6fcc6
--- /dev/null
+++ b/module/gitlab/test/model/managetagprivs.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+manageTagPrivs();
+cid=1
+pid=1
+
+维护已存在的保护标签 >> fail
+使用错误的gitlabID维护保护标签 >> success
+使用错误的项目ID维护保护标签 >> success
+
+*/
+
+$gitlab = new gitlabTest();
+
+$_POST['tags'][0] = '1230';
+$_POST['createLevels'][0] = 40;
+
+$result1 = $gitlab->manageTagPrivsTest(1, 1569);
+$result2 = $gitlab->manageTagPrivsTest(0, 1569);
+$result3 = $gitlab->manageTagPrivsTest(1, 0);
+
+r($result1) && p('') && e('fail'); // 维护正常的保护标签
+r($result2) && p('') && e('success'); // 使用错误的gitlabID维护保护标签
+r($result3) && p('') && e('success'); // 使用错误的项目ID维护保护标签
diff --git a/module/gitlab/test/model/update.php b/module/gitlab/test/model/update.php
new file mode 100644
index 0000000000..658f4eb8a9
--- /dev/null
+++ b/module/gitlab/test/model/update.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+GitLab名称为空 >> name
+服务器地址为空 >> url
+正确GitLab数据 >> Changed GitLab
+
+*/
+
+$gitlab = new gitlabTest();
+
+$gitlabID = 3;
+
+$_POST = array();
+$_POST['name'] = '';
+$_POST['url'] = 'http://10.0.7.242:9980';
+$_POST['account'] = 'admin';
+$_POST['token'] = 'y2UBqwPPzaLxsniy8R6A';
+$_POST['password'] = '';
+
+r($gitlab->update($gitlabID)) && p() && e('name'); // GitLab名称为空
+
+$_POST['name'] = 'Changed GitLab';
+$_POST['url'] = '';
+r($gitlab->update($gitlabID)) && p() && e('url'); // 服务器地址为空
+
+$_POST['url'] = 'http://10.0.7.242:9980';
+r($gitlab->update($gitlabID)) && p('name') && e('Changed GitLab'); // 正确GitLab数据
+
+system("./ztest init");
diff --git a/module/gogs/test/gogs.class.php b/module/gogs/test/gogs.class.php
new file mode 100644
index 0000000000..68d7c74435
--- /dev/null
+++ b/module/gogs/test/gogs.class.php
@@ -0,0 +1,88 @@
+tester = $tester;
+ $this->gogs = $this->tester->loadModel('gogs');
+ }
+
+ /**
+ * Get by id.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByID($id)
+ {
+ $gogs = $this->gogs->getByID($id);
+ if(empty($gogs)) return 0;
+ return $gogs;
+ }
+
+ /**
+ * Get gogs list.
+ *
+ * @param string $orderBy
+ * @access public
+ * @return object
+ */
+ public function getList($orderBy = 'id_desc')
+ {
+ $gogs = $this->gogs->getList($orderBy);
+ if(empty($gogs)) return 0;
+ return array_shift($gogs);
+ }
+
+ /**
+ * Get gogs pairs
+ *
+ * @return string
+ */
+ public function getPairs()
+ {
+ $pairs = $this->gogs->getPairs();
+ return key($pairs);
+ }
+
+ /**
+ * Create a gogs.
+ *
+ * @access public
+ * @return object|string
+ */
+ public function create()
+ {
+ $gogsID = $this->gogs->create();
+ if(dao::isError())
+ {
+ $errors = dao::getError();
+ return key($errors);
+ }
+
+ return $this->gogs->getById($gogsID);
+ }
+
+ /**
+ * Update a gogs.
+ *
+ * @param int $id
+ * @access public
+ * @return object|string
+ */
+ public function update($id)
+ {
+ $this->gogs->update($id);
+ if(dao::isError())
+ {
+ $errors = dao::getError();
+ return key($errors);
+ }
+
+ return $this->gogs->getById($id);
+ }
+}
diff --git a/module/gogs/test/model/checktokenaccess.php b/module/gogs/test/model/checktokenaccess.php
new file mode 100644
index 0000000000..a16bb2e1bd
--- /dev/null
+++ b/module/gogs/test/model/checktokenaccess.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+loadModel('gogs');
+
+$host = '';
+$token = '';
+
+$result = $gogs->checkTokenAccess($host, $token);
+if($result === false) $result = 'return false';
+r($result) && p() && e('return false'); //使用空的数据验证token权限
+
+$host = 'http://10.0.7.242:9021';
+$result = $gogs->checkTokenAccess($host, $token);
+if(!$result) $result = 'return false';
+r($result) && p() && e('return false'); //使用错误的host验证token权限
+
+$host = 'http://10.0.7.242:9021';
+$result = $gogs->checkTokenAccess($host, $token);
+if(empty($result)) $result = 'return null';
+r($result) && p() && e('return null'); //使用正确的host,错误的token验证token权限
+
+$token = '9ff43f9d1a369465bcf0781a3785f46bcef782d1';
+$result = $gogs->checkTokenAccess($host, $token);
+if(isset($result->id)) $result = 'success';
+r($result) && p() && e('1'); //通过host,token验证token权限
+
+$token = 'wVFHE6NZA-cJy-3U2y2J';
+$result = $gogs->checkTokenAccess($host, $token);
+if(!isset($result->id)) $result = 'no access';
+r($result) && p() && e('no access'); //通过host,权限不足的token验证token权限
diff --git a/module/gogs/test/model/create.php b/module/gogs/test/model/create.php
new file mode 100644
index 0000000000..ed581a2b4a
--- /dev/null
+++ b/module/gogs/test/model/create.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+Gogs名称为空 >> name
+服务器地址为空 >> url
+正确Gogs数据 >> Gogs,http://10.0.7.242:9021,9ff43f9d1a369465bcf0781a3785f46bcef782d1
+
+*/
+
+$gogs = new gogsTest();
+
+$_POST = array();
+$_POST['name'] = '';
+$_POST['url'] = 'http://10.0.7.242:9021';
+$_POST['token'] = '9ff43f9d1a369465bcf0781a3785f46bcef782d1';
+
+r($gogs->create()) && p() && e('name'); // Gogs名称为空
+
+$_POST['name'] = 'Gogs';
+$_POST['url'] = '';
+r($gogs->create()) && p() && e('url'); // 服务器地址为空
+
+$_POST['url'] = 'http://10.0.7.242:9021';
+r($gogs->create()) && p('name,url,token') && e('Gogs,http://10.0.7.242:9021,9ff43f9d1a369465bcf0781a3785f46bcef782d1'); // 正确Gogs数据
+
diff --git a/module/gogs/test/model/getbyid.php b/module/gogs/test/model/getbyid.php
new file mode 100755
index 0000000000..c6065ad0f3
--- /dev/null
+++ b/module/gogs/test/model/getbyid.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+gitById();
+cid=1
+pid=1
+
+使用存在的ID >> 5
+使用空的ID >> 0
+使用不存在的ID >> 0
+
+*/
+
+$gogs = new gogsTest();
+
+$gogsID = 5;
+r($gogs->getById($gogsID)) && p('id') && e('5'); // 使用存在的ID
+
+$gogsID = 0;
+r($gogs->getById($gogsID)) && p() && e(0); // 使用空的ID
+
+$gogsID = 111;
+r($gogs->getById($gogsID)) && p() && e(0); // 使用不存在的ID
+
diff --git a/module/gogs/test/model/getgogslistbyaccount.php b/module/gogs/test/model/getgogslistbyaccount.php
new file mode 100644
index 0000000000..afadf914eb
--- /dev/null
+++ b/module/gogs/test/model/getgogslistbyaccount.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+loadModel('gogs');
+
+r(count($gogs->getGogsListByAccount())) && p() && e('0'); //默认admin用户查询绑定的gogs服务器
+r(count($gogs->getGogsListByAccount('user4'))) && p() && e('1'); //使用已绑定一个gogs服务器的用户查询
+r(count($gogs->getGogsListByAccount('test1'))) && p() && e('0'); //使用未绑定gogs服务器的用户查询
diff --git a/module/gogs/test/model/getlist.php b/module/gogs/test/model/getlist.php
new file mode 100755
index 0000000000..99eb522143
--- /dev/null
+++ b/module/gogs/test/model/getlist.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+gitList();
+cid=1
+pid=1
+
+获取Gogs列表 >> 5
+
+*/
+
+$gogs = new gogsTest();
+
+$orderBy = 'id_desc';
+r($gogs->getList($orderBy)) && p('id') && e('5'); // 获取Gogs列表
+
diff --git a/module/gogs/test/model/getpairs.php b/module/gogs/test/model/getpairs.php
new file mode 100755
index 0000000000..cecd063eb5
--- /dev/null
+++ b/module/gogs/test/model/getpairs.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+gitPairs();
+cid=1
+pid=1
+
+获取Gogs >> 5
+
+*/
+
+$gogs = new gogsTest();
+
+r($gogs->getPairs()) && p() && e('5'); // 获取Gogs
+
diff --git a/module/gogs/test/model/update.php b/module/gogs/test/model/update.php
new file mode 100644
index 0000000000..acdf70bbaf
--- /dev/null
+++ b/module/gogs/test/model/update.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+Gogs名称为空 >> name
+服务器地址为空 >> url
+正确Gogs数据 >> Changed Gogs
+
+*/
+
+$gogs = new gogsTest();
+
+$gogsID = 3;
+
+$_POST = array();
+$_POST['name'] = '';
+$_POST['url'] = 'http://10.0.7.242:9021';
+$_POST['token'] = '9ff43f9d1a369465bcf0781a3785f46bcef782d1';
+
+r($gogs->update($gogsID)) && p() && e('name'); // Gogs名称为空
+
+$_POST['name'] = 'Changed Gogs';
+$_POST['url'] = '';
+r($gogs->update($gogsID)) && p() && e('url'); // 服务器地址为空
+
+$_POST['url'] = 'http://10.0.7.242:9021';
+r($gogs->update($gogsID)) && p('name') && e('Changed Gogs'); // 正确Gogs数据
+
diff --git a/module/group/test/group.class.php b/module/group/test/group.class.php
new file mode 100755
index 0000000000..a9837417d0
--- /dev/null
+++ b/module/group/test/group.class.php
@@ -0,0 +1,473 @@
+objectModel = $tester->loadModel('group');
+ }
+
+ /**
+ * Test create a group.
+ *
+ * @param mixed $param
+ * @access public
+ * @return object
+ */
+ public function createObject($param)
+ {
+ foreach($param as $k => $v) $_POST[$k] = $v;
+
+ $groupID = $this->objectModel->create();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getById($groupID);
+
+ return $object;
+ }
+
+ /**
+ * Update a group.
+ *
+ * @param int $groupID
+ * @access public
+ * @return void
+ */
+ public function updateTest($groupID, $param)
+ {
+ foreach($param as $k => $v) $_POST[$k] = $v;
+
+ $object = $this->objectModel->update($groupID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($groupID);
+
+ return $object;
+ }
+
+ /**
+ * Copy a group.
+ *
+ * @param int $groupID
+ * @access public
+ * @return void
+ */
+ public function copyTest($groupID, $param)
+ {
+ foreach($param as $k => $v) $_POST[$k] = $v;
+
+ $objects = $this->objectModel->copy($groupID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $newGroupID = $this->objectModel->dao->lastInsertID();
+ $object = $this->objectModel->getByID($newGroupID);
+
+ $this->objectModel->delete($newGroupID);
+ return $object;
+ }
+
+ /**
+ * Copy privileges.
+ *
+ * @param string $fromGroup
+ * @param string $toGroup
+ * @access public
+ * @return void
+ */
+ public function copyPrivTest($fromGroup, $toGroup)
+ {
+ $objects = $this->objectModel->copyPriv($fromGroup, $toGroup);
+
+ if(dao::isError()) return dao::getError();
+
+ $fromPrivs = $this->objectModel->getPrivs($fromGroup);
+ $toPrivs = $this->objectModel->getPrivs($toGroup);
+
+ $result = true;
+ foreach($fromPrivs as $group => $privs)
+ {
+ foreach($privs as $key => $priv)
+ {
+ if(!isset($toPrivs[$group][$key]) or $toPrivs[$group][$key] != $fromPrivs[$group][$key])
+ {
+ $result = false;
+ break;
+ }
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Copy user.
+ *
+ * @param string $fromGroup
+ * @param string $toGroup
+ * @access public
+ * @return void
+ */
+ public function copyUserTest($fromGroup, $toGroup)
+ {
+ $objects = $this->objectModel->copyUser($fromGroup, $toGroup);
+
+ if(dao::isError()) return dao::getError();
+
+ $fromUsers = $this->objectModel->getUserPairs($fromGroup);
+ $toUsers = $this->objectModel->getUserPairs($toGroup);
+
+ $result = true;
+ foreach($fromUsers as $account => $name)
+ {
+ if(!isset($toUsers[$account]) or $toUsers[$account] != $fromUsers[$account])
+ {
+ $result = false;
+ break;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Get group lists.
+ *
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getListTest($projectID = 0)
+ {
+ $objects = $this->objectModel->getList($projectID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get group pairs.
+ *
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getPairsTest($projectID = 0)
+ {
+ $objects = $this->objectModel->getPairs($projectID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get group by id.
+ *
+ * @param int $groupID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($groupID)
+ {
+ $objects = $this->objectModel->getByID($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get group by account.
+ *
+ * @param string $account
+ * @access public
+ * @return array
+ */
+ public function getByAccountTest($account)
+ {
+ $objects = $this->objectModel->getByAccount($account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get groups by accounts.
+ *
+ * @param array $accounts
+ * @access public
+ * @return array
+ */
+ public function getByAccountsTest($accounts)
+ {
+ $objects = $this->objectModel->getByAccounts($accounts);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get the account number in the group.
+ *
+ * @param array $groupIdList
+ * @access public
+ * @return array
+ */
+ public function getGroupAccountsTest($groupIdList)
+ {
+ $objects = $this->objectModel->getGroupAccounts($groupIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get privileges of a groups.
+ *
+ * @param int $groupID
+ * @access public
+ * @return array
+ */
+ public function getPrivsTest($groupID)
+ {
+ $objects = $this->objectModel->getPrivs($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get user pairs of a group.
+ *
+ * @param int $groupID
+ * @access public
+ * @return array
+ */
+ public function getUserPairsTest($groupID)
+ {
+ $objects = $this->objectModel->getUserPairs($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get user programs of a group.
+ *
+ * @param int $groupID
+ * @access public
+ * @return array
+ */
+ public function getUserProgramsTest($groupID)
+ {
+ $objects = $this->objectModel->getUserPrograms($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get the ID of the group that has access to the program.
+ *
+ * @access public
+ * @return array
+ */
+ public function getAccessProgramGroupTest()
+ {
+ $objects = $this->objectModel->getAccessProgramGroup();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete a group.
+ *
+ * @param int $groupID
+ * @param null $null compatible with that of model::delete()
+ * @access public
+ * @return void
+ */
+ public function deleteTest($groupID, $null = null)
+ {
+ $this->objectModel->delete($groupID, $null = null);
+
+ if(dao::isError()) return dao::getError();
+
+ return true;
+ }
+
+ /**
+ * Update privilege of a group.
+ *
+ * @param int $groupID
+ * @access public
+ * @return bool
+ */
+ public function updatePrivByGroupTest($groupID, $menu, $version)
+ {
+ $objects = $this->objectModel->updatePrivByGroup($groupID, $menu, $version);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Update privilege by module.
+ *
+ * @access public
+ * @return void
+ */
+ public function updatePrivByModuleTest()
+ {
+ $objects = $this->objectModel->updatePrivByModule();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Update users.
+ *
+ * @param int $groupID
+ * @access public
+ * @return void
+ */
+ public function updateUserTest($groupID)
+ {
+ $objects = $this->objectModel->updateUser($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Update project admins.
+ *
+ * @param int $groupID
+ * @access public
+ * @return void
+ */
+ public function updateProjectAdminTest($groupID)
+ {
+ $objects = $this->objectModel->updateProjectAdmin($groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Sort resource.
+ *
+ * @access public
+ * @return void
+ */
+ public function sortResourceTest()
+ {
+ $objects = $this->objectModel->sortResource();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Check menu have module
+ *
+ * @param string $menu
+ * @param string $moduleName
+ * @access public
+ * @return void
+ */
+ public function checkMenuModuleTest($menu, $moduleName)
+ {
+ $objects = $this->objectModel->checkMenuModule($menu, $moduleName);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get modules in menu
+ *
+ * @param string $menu
+ * @access public
+ * @return void
+ */
+ public function getMenuModulesTest($menu)
+ {
+ $objects = $this->objectModel->getMenuModules($menu);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+
+
+
+
+ /**
+ * 获取一条权限的基本信息
+ *
+ * @param int $privID
+ * @param string $lang
+ * @access public
+ * @return void
+ */
+ public function getPrivInfoTest($priv, $lang)
+ {
+ $object = $this->objectModel->getPrivInfo($priv, $lang);
+ if(dao::isError()) return dao::getError();
+ return $object;
+ }
+
+
+
+
+
+ /**
+ * 获取模块和权限包option
+ *
+ * @access public
+ * @return array
+ */
+ public function getModuleAndPackageTreeTest()
+ {
+ return $this->objectModel->getModuleAndPackageTree();
+ }
+
+
+ /**
+ * 更新权限
+ *
+ * @access public
+ * @return void
+ */
+ public function updatePrivTest($privID,$lang)
+ {
+ $this->objectModel->updatePrivLang($privID,$lang);
+ if(dao::isError())
+ {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/module/group/test/model/checkModuleAndPackageTree.php b/module/group/test/model/checkModuleAndPackageTree.php
new file mode 100644
index 0000000000..876a6b2c02
--- /dev/null
+++ b/module/group/test/model/checkModuleAndPackageTree.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getModuleAndPackageTree();
+cid=1
+pid=1
+
+
+*/
+$group = new groupTest();
+var_dump($group->getModuleAndPackageTreeTest());
+r($group->getModuleAndPackageTreeTest()) && p() && e("获取数据");
+
diff --git a/module/group/test/model/checkmenumodule.php b/module/group/test/model/checkmenumodule.php
new file mode 100755
index 0000000000..923878fffb
--- /dev/null
+++ b/module/group/test/model/checkmenumodule.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+checkMenuModule();
+cid=1
+pid=1
+
+
+
+*/
+
+$group = new groupTest();
+
+r($group->checkMenuModuleTest('','index')) && p('') && e(1); // 测试获取 '','index' 的返回结果
+r($group->checkMenuModuleTest('my','tree')) && p('') && e(''); // 测试获取 'my','tree' 的返回结果
+r($group->checkMenuModuleTest('none','tree')) && p('') && e(''); // 测试获取 'none','tree' 的返回结果
\ No newline at end of file
diff --git a/module/group/test/model/copy.php b/module/group/test/model/copy.php
new file mode 100755
index 0000000000..d210a77b5b
--- /dev/null
+++ b/module/group/test/model/copy.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+copy();
+cid=1
+pid=1
+
+这是一个复制的分组 >> 这是一个复制的分组
+『分组名称』已经有『我是一个分组』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。 >> 『分组名称』已经有『我是一个分组』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+$groupID = 2;
+
+$data = array('name' => '这是一个复制的分组');
+$existData = array('name' => '我是一个分组');
+
+$group = new groupTest();
+r($group->copyTest($groupID, $data)) && p('name') && e('这是一个复制的分组'); // 这是一个复制的分组
+r($group->copyTest($groupID, $existData)) && p('name:0') && e('『分组名称』已经有『我是一个分组』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 『分组名称』已经有『我是一个分组』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
\ No newline at end of file
diff --git a/module/group/test/model/copypriv.php b/module/group/test/model/copypriv.php
new file mode 100755
index 0000000000..84865246ad
--- /dev/null
+++ b/module/group/test/model/copypriv.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+copyPriv();
+cid=1
+pid=1
+
+复制分组6权限到分组7 >> 1
+
+*/
+
+$fromGroup = 6;
+$toGroup = 7;
+
+$group = new groupTest();
+r($group->copyPrivTest($fromGroup, $toGroup)) && p() && e('1'); // 复制分组6权限到分组7
\ No newline at end of file
diff --git a/module/group/test/model/copyuser.php b/module/group/test/model/copyuser.php
new file mode 100755
index 0000000000..a2feda664b
--- /dev/null
+++ b/module/group/test/model/copyuser.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+copyUser();
+cid=1
+pid=1
+
+复制分组6用户到分组7 >> 1
+
+*/
+
+$fromGroup = 6;
+$toGroup = 7;
+
+$group = new groupTest();
+
+r($group->copyUserTest($fromGroup, $toGroup)) && p() && e('1'); // 复制分组6用户到分组7
diff --git a/module/group/test/model/create.php b/module/group/test/model/create.php
new file mode 100755
index 0000000000..6fa98da4bd
--- /dev/null
+++ b/module/group/test/model/create.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试正常创建分组的名称 >> 我是一个分组
+测试创建受限用户组分组 >> limited
+
+*/
+
+$limited = array('0' => 0);
+
+$t_name = array('name' => '我是一个分组', 'desc' => '');
+$t_limited = array('name' => '我是一个分组', 'desc' => '', 'limited' => $limited);
+
+$group = new groupTest();
+
+r($group->createObject($t_name)) && p('name') && e('我是一个分组'); // 测试正常创建分组的名称
+r($group->createObject($t_limited)) && p('role') && e('limited'); // 测试创建受限用户组分组
+
diff --git a/module/group/test/model/delete.php b/module/group/test/model/delete.php
new file mode 100755
index 0000000000..4c82e38562
--- /dev/null
+++ b/module/group/test/model/delete.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+delete();
+cid=1
+pid=1
+
+删除id为10的组 >> 1
+删除id为0的组 >> 1
+
+*/
+
+$groupID = 10;
+
+$group = new groupTest();
+r($group->deleteTest($groupID)) && p() && e('1'); // 删除id为10的组
+r($group->deleteTest(0)) && p() && e('1'); // 删除id为0的组
diff --git a/module/group/test/model/editpriv.php b/module/group/test/model/editpriv.php
new file mode 100644
index 0000000000..52581e3678
--- /dev/null
+++ b/module/group/test/model/editpriv.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getPrivInfo();
+ *
+ * cid=1
+ * pid=1
+ *
+ */
+
+$group = new groupTest();
+
+$_POST['name'] = '修改test';
+$_POST['desc'] = '描述描述描述';
+$_POST['module'] = 'webhook';
+r($group->updatePrivTest(3324,'zh-cn')) && p('priv') && e("这是获取到的一条权限");
+
+//测试获取 id为3324的权限信息
diff --git a/module/group/test/model/getaccessprogramgroup.php b/module/group/test/model/getaccessprogramgroup.php
new file mode 100755
index 0000000000..60b3d2a9f8
--- /dev/null
+++ b/module/group/test/model/getaccessprogramgroup.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getAccessProgramGroup();
+cid=1
+pid=1
+
+测试获取group中用户个数 >> 14
+
+*/
+
+$group = new groupTest();
+$AccessProgramGroup = $group->getAccessProgramGroupTest();
+
+r(count($AccessProgramGroup)) && p('') && e('14'); //测试获取group中用户个数
\ No newline at end of file
diff --git a/module/group/test/model/getbyaccount.php b/module/group/test/model/getbyaccount.php
new file mode 100755
index 0000000000..ef6cb5505b
--- /dev/null
+++ b/module/group/test/model/getbyaccount.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getByAccount();
+cid=1
+pid=1
+
+测试获取test2 的信息 >> 3,测试,qa
+测试获取dev2 的信息 >> 2,研发,dev
+测试获取po48 的信息 >> 2,研发,dev
+测试获取td2 的信息 >> 2,研发,dev
+测试获取pd2 的信息 >> 3,测试,qa
+
+*/
+
+$group = new groupTest();
+r($group->getByAccountTest('test2')) && p('3:id,name,role') && e('3,测试,qa'); //测试获取test2 的信息
+r($group->getByAccountTest('dev2')) && p('2:id,name,role') && e('2,研发,dev'); //测试获取dev2 的信息
+r($group->getByAccountTest('po48')) && p('2:id,name,role') && e('2,研发,dev'); //测试获取po48 的信息
+r($group->getByAccountTest('td2')) && p('2:id,name,role') && e('2,研发,dev'); //测试获取td2 的信息
+r($group->getByAccountTest('pd2')) && p('3:id,name,role') && e('3,测试,qa'); //测试获取pd2 的信息
\ No newline at end of file
diff --git a/module/group/test/model/getbyaccounts.php b/module/group/test/model/getbyaccounts.php
new file mode 100755
index 0000000000..c8c39f4111
--- /dev/null
+++ b/module/group/test/model/getbyaccounts.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getByAccounts();
+cid=1
+pid=1
+
+测试获取用户 outside3 的权限分组信息 >> outside3
+测试获取用户 top2 的权限分组信息 >> top2
+测试获取用户 pd2 的权限分组信息 >> pd2
+测试获取用户 td1 的权限分组信息 >> td1
+测试获取用户 pm1 的权限分组信息 >> pm1
+测试获取用户 po48 的权限分组信息 >> po48
+测试获取用户 dev100 的权限分组信息 >> dev100
+测试获取用户 test2 的权限分组信息 >> test2
+
+*/
+
+$accountList = array();
+$accountList[0] = array('outside3', 'top2');
+$accountList[1] = array('td1', 'pd2');
+$accountList[2] = array('po48', 'pm1');
+$accountList[3] = array('dev100', 'test2');
+
+$group = new groupTest();
+$groups0 = $group->getByAccountsTest($accountList[0]);
+$groups1 = $group->getByAccountsTest($accountList[1]);
+$groups2 = $group->getByAccountsTest($accountList[2]);
+$groups3 = $group->getByAccountsTest($accountList[3]);
+
+r($groups0['outside3']) && p('0:account') && e('outside3'); //测试获取用户 outside3 的权限分组信息
+r($groups0['top2']) && p('0:account') && e('top2'); //测试获取用户 top2 的权限分组信息
+r($groups1['pd2']) && p('0:account') && e('pd2'); //测试获取用户 pd2 的权限分组信息
+r($groups1['td1']) && p('0:account') && e('td1'); //测试获取用户 td1 的权限分组信息
+r($groups2['pm1']) && p('0:account') && e('pm1'); //测试获取用户 pm1 的权限分组信息
+r($groups2['po48']) && p('0:account') && e('po48'); //测试获取用户 po48 的权限分组信息
+r($groups3['dev100']) && p('0:account') && e('dev100'); //测试获取用户 dev100 的权限分组信息
+r($groups3['test2']) && p('0:account') && e('test2'); //测试获取用户 test2 的权限分组信息
\ No newline at end of file
diff --git a/module/group/test/model/getbyid.php b/module/group/test/model/getbyid.php
new file mode 100755
index 0000000000..37e8627657
--- /dev/null
+++ b/module/group/test/model/getbyid.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+测试获取ID为 1 的权限分组信息 >> 管理员,admin,系统管理员
+测试获取ID为 2 的权限分组信息 >> 研发,dev,研发人员
+测试获取ID为 3 的权限分组信息 >> 测试,qa,测试人员
+测试获取ID为 4 的权限分组信息 >> 项目经理,pm,项目经理
+测试获取ID为 5 的权限分组信息 >> 产品经理,po,产品经理
+
+*/
+$groupIDList = array(1, 2, 3, 4, 5);
+
+$group = new groupTest();
+
+r($group->getByIDTest($groupIDList[0])) && p('name,role,desc') && e('管理员,admin,系统管理员'); //测试获取ID为 1 的权限分组信息
+r($group->getByIDTest($groupIDList[1])) && p('name,role,desc') && e('研发,dev,研发人员'); //测试获取ID为 2 的权限分组信息
+r($group->getByIDTest($groupIDList[2])) && p('name,role,desc') && e('测试,qa,测试人员'); //测试获取ID为 3 的权限分组信息
+r($group->getByIDTest($groupIDList[3])) && p('name,role,desc') && e('项目经理,pm,项目经理'); //测试获取ID为 4 的权限分组信息
+r($group->getByIDTest($groupIDList[4])) && p('name,role,desc') && e('产品经理,po,产品经理'); //测试获取ID为 5 的权限分组信息
\ No newline at end of file
diff --git a/module/group/test/model/getgroupaccounts.php b/module/group/test/model/getgroupaccounts.php
new file mode 100755
index 0000000000..0699415d24
--- /dev/null
+++ b/module/group/test/model/getgroupaccounts.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getGroupAccounts();
+cid=1
+pid=1
+
+测试获取 group 的 account td79 >> td79
+测试获取 group 的 account pm1 >> pm1
+测试获取 group 的 account po75 >> po75
+测试获取 group 的 account top88 >> top88
+
+*/
+
+$group = new groupTest();
+$groupIdList = array(1,9,2,12);
+
+r($group->getGroupAccountsTest($groupIdList)) && p('td79') && e('td79'); //测试获取 group 的 account td79
+r($group->getGroupAccountsTest($groupIdList)) && p('pm1') && e('pm1'); //测试获取 group 的 account pm1
+r($group->getGroupAccountsTest($groupIdList)) && p('po75') && e('po75'); //测试获取 group 的 account po75
+r($group->getGroupAccountsTest($groupIdList)) && p('top88') && e('top88'); //测试获取 group 的 account top88
\ No newline at end of file
diff --git a/module/group/test/model/getlist.php b/module/group/test/model/getlist.php
new file mode 100755
index 0000000000..766fb0e581
--- /dev/null
+++ b/module/group/test/model/getlist.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+测试获取 groupList 的信息 >> 其他,others,其他
+测试获取 groupList 的信息 >> guest,guest,For guest
+测试获取 groupList 的信息 >> 项目管理员,projectAdmin,项目管理员可以维护项目的权限
+
+*/
+
+$group = new groupTest();
+
+r($group->getListTest()) && p('9:name,role,desc') && e('其他,others,其他'); // 测试获取 groupList 的信息
+r($group->getListTest()) && p('10:name,role,desc') && e('guest,guest,For guest'); // 测试获取 groupList 的信息
+r($group->getListTest()) && p('12:name,role,desc') && e('项目管理员,projectAdmin,项目管理员可以维护项目的权限'); // 测试获取 groupList 的信息
\ No newline at end of file
diff --git a/module/group/test/model/getmenumodules.php b/module/group/test/model/getmenumodules.php
new file mode 100755
index 0000000000..05984a22d9
--- /dev/null
+++ b/module/group/test/model/getmenumodules.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getMenuModules();
+cid=1
+pid=1
+
+测试查询 product 菜单的模块 >> product,branch,story
+测试查询 my 菜单的模块 >> my,todo
+测试查询 qa 菜单的模块 >> qa,bug,caselib
+测试查询 project 菜单的模块 >> design,projectbuild,projectstory
+
+*/
+
+$group = new groupTest();
+
+r($group->getMenuModulesTest('product')) && p('0,1,2') && e('product,branch,story'); // 测试查询 product 菜单的模块
+r($group->getMenuModulesTest('my')) && p('0,1') && e('my,todo'); // 测试查询 my 菜单的模块
+r($group->getMenuModulesTest('qa')) && p('0,1,6') && e('qa,bug,caselib'); // 测试查询 qa 菜单的模块
+r($group->getMenuModulesTest('project')) && p('0,3,4') && e('design,projectbuild,projectstory'); // 测试查询 project 菜单的模块
\ No newline at end of file
diff --git a/module/group/test/model/getpairs.php b/module/group/test/model/getpairs.php
new file mode 100755
index 0000000000..9e01ab00ff
--- /dev/null
+++ b/module/group/test/model/getpairs.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试查询产品 1 的权限分组 2 的信息 >> 研发
+测试查询产品 194 的权限分组 3 的信息 >> 测试
+测试查询产品 284 的权限分组 4 的信息 >> 项目经理
+测试查询产品 346 的权限分组 5 的信息 >> 产品经理
+测试查询产品 493 的权限分组 6 的信息 >> 研发主管
+测试查询产品 519 的权限分组 7 的信息 >> 产品主管
+
+*/
+
+$group = new groupTest();
+
+r($group->getPairsTest(1)) && p('2') && e('研发'); // 测试查询产品 1 的权限分组 2 的信息
+r($group->getPairsTest(194)) && p('3') && e('测试'); // 测试查询产品 194 的权限分组 3 的信息
+r($group->getPairsTest(284)) && p('4') && e('项目经理'); // 测试查询产品 284 的权限分组 4 的信息
+r($group->getPairsTest(346)) && p('5') && e('产品经理'); // 测试查询产品 346 的权限分组 5 的信息
+r($group->getPairsTest(493)) && p('6') && e('研发主管'); // 测试查询产品 493 的权限分组 6 的信息
+r($group->getPairsTest(519)) && p('7') && e('产品主管'); // 测试查询产品 519 的权限分组 7 的信息
\ No newline at end of file
diff --git a/module/group/test/model/getpriv.php b/module/group/test/model/getpriv.php
new file mode 100644
index 0000000000..61fbdb7dfd
--- /dev/null
+++ b/module/group/test/model/getpriv.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getPrivInfo();
+ *
+ * cid=1
+ * pid=1
+ *
+ */
+
+$group = new groupTest();
+
+
+r($group->getPrivInfoTest(3324,'zh-cn')) && p('priv') && e("这是获取到的一条权限");
+
+//测试获取 id为3324的权限信息
diff --git a/module/group/test/model/getprivs.php b/module/group/test/model/getprivs.php
new file mode 100755
index 0000000000..93ab4d3eaf
--- /dev/null
+++ b/module/group/test/model/getprivs.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPrivs();
+cid=1
+pid=1
+
+测试查询分组 10 是否具有 action 模块 editComment 的权限 >> editComment
+测试查询分组 10 是否具有 user 模块 bug 的权限 >> bug
+测试查询分组 10 是否具有 trainplan 模块 view 的权限 >> view
+测试查询分组 2 是否具有 trainplan 模块 create 的权限 >> create
+测试查询分组 2 是否具有 todo 模块 activate 的权限 >> activate
+
+*/
+
+$group = new groupTest();
+
+r($group->getPrivsTest(100)) && p('action:editComment') && e(0); //测试查询不存在的分组是否具有 action 模块 editComment 的权限
+r($group->getPrivsTest(10)) && p('action:editComment') && e('editComment'); //测试查询分组 10 是否具有 action 模块 editComment 的权限
+r($group->getPrivsTest(10)) && p('user:bug') && e('bug'); //测试查询分组 10 是否具有 user 模块 bug 的权限
+r($group->getPrivsTest(10)) && p('trainplan:view') && e('view'); //测试查询分组 10 是否具有 trainplan 模块 view 的权限
+r($group->getPrivsTest(10)) && p('trainplan:create') && e(''); //测试查询分组 10 是否具有 trainplan 模块 create 的权限
+r($group->getPrivsTest(2)) && p('trainplan:create') && e('create'); //测试查询分组 2 是否具有 trainplan 模块 create 的权限
+r($group->getPrivsTest(2)) && p('todo:activate') && e('activate'); //测试查询分组 2 是否具有 todo 模块 activate 的权限
\ No newline at end of file
diff --git a/module/group/test/model/getuserpairs.php b/module/group/test/model/getuserpairs.php
new file mode 100755
index 0000000000..f7f7ecb3b1
--- /dev/null
+++ b/module/group/test/model/getuserpairs.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getUserPairs();
+cid=1
+pid=1
+
+测试查询权限分组 3 的用户id和name >> 高层管理2
+测试查询权限分组 3 的用户id和name >> 用户20
+测试查询权限分组 3 的用户id和name >> 开发1
+测试查询权限分组 6 的用户id和name >> 产品主管68
+测试查询权限分组 6 的用户id和name >> 产品主管69
+测试查询权限分组 5 的用户id和name >> 产品主管59
+
+*/
+$groupList = array(3,6,5);
+
+$group = new groupTest();
+
+r($group->getUserPairsTest($groupList[0])) && p('top2') && e('高层管理2'); // 测试查询权限分组 3 的用户id和name
+r($group->getUserPairsTest($groupList[0])) && p('top20') && e('用户20'); // 测试查询权限分组 3 的用户id和name
+r($group->getUserPairsTest($groupList[0])) && p('dev1') && e('开发1'); // 测试查询权限分组 3 的用户id和name
+r($group->getUserPairsTest($groupList[1])) && p('td68') && e('产品主管68'); // 测试查询权限分组 6 的用户id和name
+r($group->getUserPairsTest($groupList[1])) && p('td69') && e('产品主管69'); // 测试查询权限分组 6 的用户id和name
+r($group->getUserPairsTest($groupList[2])) && p('td59') && e('产品主管59'); // 测试查询权限分组 5 的用户id和name
+r($group->getUserPairsTest($groupList[2])) && p('td80') && e(''); // 测试查询权限分组 5 的用户id和name
\ No newline at end of file
diff --git a/module/group/test/model/getuserprograms.php b/module/group/test/model/getuserprograms.php
new file mode 100755
index 0000000000..69ea5badd5
--- /dev/null
+++ b/module/group/test/model/getuserprograms.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getUserPrograms();
+cid=1
+pid=1
+
+
+
+*/
+
+$groupList = array(1,2,3,4,5);
+$userIDList = array('td81','dev100','pd10','td50','td64');
+$resultList = array(74,29,13,43,57);
+
+$group = new groupTest();
+
+r($group->getUserProgramsTest($groupList[0])) && p($userIDList[0]) && e(74); //检查权限分组 1 的用户项目信息
+r($group->getUserProgramsTest($groupList[1])) && p($userIDList[1]) && e(29); //检查权限分组 2 的用户项目信息
+r($group->getUserProgramsTest($groupList[2])) && p($userIDList[2]) && e(13); //检查权限分组 3 的用户项目信息
+r($group->getUserProgramsTest($groupList[3])) && p($userIDList[3]) && e(43); //检查权限分组 4 的用户项目信息
+r($group->getUserProgramsTest($groupList[4])) && p($userIDList[4]) && e(57); //检查权限分组 5 的用户项目信息
\ No newline at end of file
diff --git a/module/group/test/model/update.php b/module/group/test/model/update.php
new file mode 100755
index 0000000000..21190e6823
--- /dev/null
+++ b/module/group/test/model/update.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新分组id为2的分组 >> 我是一个分组
+测试更新分组2为受限用户分组 >> 这是一个分组
+
+*/
+$t_name = array('name' => '我是一个分组', 'desc' => '');
+$t_desc = array('name' => '我是一个分组', 'desc' => '这是一个分组');
+
+$group = new groupTest();
+a($group->updateTest(2, $t_name));
+
+r($group->updateTest(2, $t_name)) && p('name') && e('我是一个分组'); //测试更新分组id为2的分组
+r($group->updateTest(2, $t_desc)) && p('desc') && e('这是一个分组'); //测试更新分组2为受限用户分组
+
diff --git a/module/group/test/model/updateprivbygroup.php b/module/group/test/model/updateprivbygroup.php
new file mode 100755
index 0000000000..2fab6deadd
--- /dev/null
+++ b/module/group/test/model/updateprivbygroup.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+updatePrivByGroup();
+cid=1
+pid=1
+
+
+
+*/
+
+$group = new groupTest();
+
+r($group->updatePrivByGroupTest()) && p() && e();
\ No newline at end of file
diff --git a/module/group/test/model/updateprivbymodule.php b/module/group/test/model/updateprivbymodule.php
new file mode 100755
index 0000000000..84d14f39e6
--- /dev/null
+++ b/module/group/test/model/updateprivbymodule.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+updatePrivByModule();
+cid=1
+pid=1
+
+
+
+*/
+
+$group = new groupTest();
+
+r($group->updatePrivByModuleTest()) && p() && e();
\ No newline at end of file
diff --git a/module/group/test/model/updateprojectadmin.php b/module/group/test/model/updateprojectadmin.php
new file mode 100755
index 0000000000..5474fa5241
--- /dev/null
+++ b/module/group/test/model/updateprojectadmin.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+updateProjectAdmin();
+cid=1
+pid=1
+
+
+
+*/
+
+$group = new groupTest();
+
+r($group->updateProjectAdminTest()) && p() && e();
\ No newline at end of file
diff --git a/module/group/test/model/updateuser.php b/module/group/test/model/updateuser.php
new file mode 100755
index 0000000000..67389eea07
--- /dev/null
+++ b/module/group/test/model/updateuser.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+updateUser();
+cid=1
+pid=1
+
+
+
+*/
+
+$group = new groupTest();
+
+r($group->updateUserTest()) && p() && e();
\ No newline at end of file
diff --git a/module/group/test/model/updateview.php b/module/group/test/model/updateview.php
new file mode 100755
index 0000000000..d32dfb8416
--- /dev/null
+++ b/module/group/test/model/updateview.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+updateView();
+cid=1
+pid=1
+
+针对ID为1的权限分组,设置全选权限,查看返回的数据元素数量 >> 2
+针对ID为1的权限分组,设置任务创建权限,查看返回的数据元素数量 >> 3
+针对ID为1的权限分组,设置任务创建权限,查看是否有创建方法 >> create
+
+*/
+
+global $tester;
+$tester->loadModel('group');
+
+$_POST['allchecker'] = 1;
+$tester->group->updateView(1);
+$group1 = $tester->group->getByID(1);
+
+$_POST['actions']['task']['create'] = 'create';
+$tester->group->updateView(1);
+$group2 = $tester->group->getByID(1);
+
+r(count($group1->acl)) && p() && e('2'); // 针对ID为1的权限分组,设置全选权限,查看返回的数据元素数量
+r(count($group2->acl)) && p() && e('3'); // 针对ID为1的权限分组,设置任务创建权限,查看返回的数据元素数量
+r($group2->acl) && p('task:create') && e('create'); // 针对ID为1的权限分组,设置任务创建权限,查看是否有创建方法
+
diff --git a/module/holiday/test/holiday.class.php b/module/holiday/test/holiday.class.php
new file mode 100644
index 0000000000..5b2fcccdcc
--- /dev/null
+++ b/module/holiday/test/holiday.class.php
@@ -0,0 +1,320 @@
+objectModel = $tester->loadModel('holiday');
+ }
+
+ /**
+ * Test getById method.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($id)
+ {
+ $objects = $this->objectModel->getById($id);
+
+ if($objects === false) return 'Object not found';
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test getList method.
+ *
+ * @param string $year
+ * @param string $type
+ * @access public
+ * @return object
+ */
+ public function getListTest($year = '', $type = 'all')
+ {
+ $objects = $this->objectModel->getList($year, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test getYearPairs method.
+ *
+ * @access public
+ * @return int
+ */
+ public function getYearPairsTest()
+ {
+ $objects = $this->objectModel->getYearPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test create method.
+ *
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createTest($param = array())
+ {
+ $defaultParam['type'] = 'holiday';
+ $defaultParam['begin'] = '2022-01-01';
+ $defaultParam['end'] = '2022-02-01';
+ $defaultParam['name'] = '测试创建holiday';
+ $defaultParam['desc'] = '默认的holiday';
+
+ foreach($defaultParam as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $lastInsertID = $this->objectModel->create();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getByID($lastInsertID);
+ return $object;
+ }
+ }
+
+ /**
+ * Test update method.
+ *
+ * @param int $holidayID
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function updateTest($holidayID, $param = array())
+ {
+ global $tester;
+ $object = $tester->dbh->query("SELECT * FROM " . TABLE_HOLIDAY ." WHERE id = $holidayID")->fetch();
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $noError = $this->objectModel->update($bugID);
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return 'true';
+ }
+ }
+
+ /**
+ * Test getHolidays method.
+ *
+ * @param string $begin
+ * @param string $end
+ * @access public
+ * @return object
+ */
+ public function getHolidaysTest($begin, $end)
+ {
+ $objects = $this->objectModel->getHolidays($begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test getWorkingDays method.
+ *
+ * @param string $begin
+ * @param string $end
+ * @access public
+ * @return int
+ */
+ public function getWorkingDaysTest($begin = '', $end = '')
+ {
+ $objects = $this->objectModel->getWorkingDays($begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test getActualWorkingDays method.
+ *
+ * @param string $begin
+ * @param string $end
+ * @access public
+ * @return int
+ */
+ public function getActualWorkingDaysTest($begin, $end)
+ {
+ $objects = $this->objectModel->getActualWorkingDays($begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test getDaysBetweenTest method.
+ *
+ * @param string $begin
+ * @param string $end
+ * @access public
+ * @return int
+ */
+ public function getDaysBetweenTest($begin, $end)
+ {
+ $objects = $this->objectModel->getDaysBetween($begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test isHoliday method.
+ *
+ * @param string $date
+ * @access public
+ * @return object
+ */
+ public function isHolidayTest($date)
+ {
+ $objects = $this->objectModel->isHoliday($date);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects === true ? "It is a holiday" : "It is not a holiday";
+ }
+
+ /**
+ * Test isWorkingDay method.
+ *
+ * @param string $date
+ * @access public
+ * @return object
+ */
+ public function isWorkingDayTest($date)
+ {
+ $objects = $this->objectModel->isWorkingDay($date);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test updateProgramPlanDuration method.
+ *
+ * @param int $testProjectID
+ * @param object $holiday
+ * @access public
+ * @return int
+ */
+ public function updateProgramPlanDurationTest($testProjectID, $holidayID)
+ {
+ global $tester;
+
+ $holiday = $tester->dao->select('*')->from(TABLE_HOLIDAY)->where('id')->eq($holidayID)->fetch();
+
+ $this->objectModel->updateProgramPlanDuration($holiday->begin, $holiday->end);
+
+ $project = $tester->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($testProjectID)->fetch();
+
+ if(dao::isError()) return dao::getError();
+
+ return $project->planDuration;
+ }
+
+ /**
+ * Test updateProjectRealDuration method.
+ *
+ * @param int $testProjectID
+ * @param object $holiday
+ * @access public
+ * @return int
+ */
+ public function updateProjectRealDurationTest($testProjectID, $holidayID)
+ {
+ global $tester;
+
+ $holiday = $tester->dao->select('*')->from(TABLE_HOLIDAY)->where('id')->eq($holidayID)->fetch();
+
+ $this->objectModel->updateProjectRealDuration($holiday->begin, $holiday->end);
+
+ $project = $tester->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($testProjectID)->fetch();
+
+ if(dao::isError()) return dao::getError();
+
+ return $project->realDuration;
+ }
+
+ /**
+ * Test updateTaskPlanDuration method.
+ *
+ * @param int $testTaskID
+ * @param object $holiday
+ * @access public
+ * @return int
+ */
+ public function updateTaskPlanDurationTest($testTaskID, $holidayID)
+ {
+ global $tester;
+
+ $holiday = $tester->dao->select('*')->from(TABLE_HOLIDAY)->where('id')->eq($holidayID)->fetch();
+
+ $this->objectModel->updateTaskPlanDuration($holiday->begin, $holiday->end);
+
+ $task = $tester->dao->select('*')->from(TABLE_TASK)->where('id')->eq($testTaskID)->fetch();
+
+ if(dao::isError()) return dao::getError();
+
+ return $task->planDuration;
+ }
+
+ /**
+ * Test updateTaskRealDuration method.
+ *
+ * @param int $testTaskID
+ * @param object $holiday
+ * @access public
+ * @return int
+ */
+ public function updateTaskRealDurationTest($testTaskID, $holidayID)
+ {
+ global $tester;
+
+ $holiday = $tester->dao->select('*')->from(TABLE_HOLIDAY)->where('id')->eq($holidayID)->fetch();
+
+ $this->objectModel->updateTaskRealDuration($holiday->begin, $holiday->end);
+
+ $task = $tester->dao->select('*')->from(TABLE_TASK)->where('id')->eq($testTaskID)->fetch();
+
+ if(dao::isError()) return dao::getError();
+
+ return $task->realDuration;
+ }
+}
diff --git a/module/holiday/test/model/create.php b/module/holiday/test/model/create.php
new file mode 100755
index 0000000000..8c430ffc38
--- /dev/null
+++ b/module/holiday/test/model/create.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试创建holiday >> 101,测试创建holiday,holiday
+测试创建working >> 102,测试创建working,working
+测试不传入必填项开始日期 >> 『开始日期』不能为空。
+测试不传入必填项结束日期 >> 『结束日期』不能为空。
+测试不传入必填项名称 >> 『名称』不能为空。
+测试传入小于开始日期的结束日期 >> 『结束日期』应当不小于『2022-01-10』。
+
+*/
+
+$holiday = new holidayTest();
+
+$createHoliday = array('name' => '测试创建holiday', 'type' => 'holiday');
+$createWorking = array('name' => '测试创建working', 'type' => 'working');
+$createNoBegin = array('name' => '不传入开始日期', 'type' => 'holiday', 'begin' => '');
+$createNoEnd = array('name' => '不传入结束日期', 'type' => 'holiday', 'end' => '' );
+$createNoName = array('name' => '', 'type' => 'holiday');
+$createErrorDate = array('begin' => '2022-01-10', 'end' => '2022-01-01');
+
+r($holiday->createTest($createHoliday)) && p('id,name,type') && e('101,测试创建holiday,holiday'); //测试创建holiday
+r($holiday->createTest($createWorking)) && p('id,name,type') && e('102,测试创建working,working'); //测试创建working
+r($holiday->createTest($createNoBegin)) && p('begin:0') && e('『开始日期』不能为空。'); //测试不传入必填项开始日期
+r($holiday->createTest($createNoEnd)) && p('end:0') && e('『结束日期』不能为空。'); //测试不传入必填项结束日期
+r($holiday->createTest($createNoName)) && p('name:0') && e('『名称』不能为空。'); //测试不传入必填项名称
+r($holiday->createTest($createErrorDate)) && p('end:0') && e('『结束日期』应当不小于『2022-01-10』。'); //测试传入小于开始日期的结束日期
+
diff --git a/module/holiday/test/model/getactualworkingdays.php b/module/holiday/test/model/getactualworkingdays.php
new file mode 100755
index 0000000000..a14540cd44
--- /dev/null
+++ b/module/holiday/test/model/getactualworkingdays.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getActualWorkingDays();
+cid=1
+pid=1
+
+查询2022-04-01到2022-04-10的实际工作日 >> 8
+查询2022-04-06到2022-04-12的实际工作日 >> 7
+查询2022-05-10到2022-05-10的实际工作日 >> 9
+查询2022-05-10到2022-05-10的实际工作日 >> 1
+查询2022-05-13到2022-05-13的实际工作日 >> 1
+查询2022-05-14到2022-05-14的实际工作日 >> 0
+测试传入0000-00-00的情况 >> 0
+
+*/
+
+$holiday = new holidayTest();
+
+r($holiday->getActualWorkingDaysTest('2022-04-01', '2022-04-10')) && p() && e('8'); //查询2022-04-01到2022-04-10的实际工作日
+r($holiday->getActualWorkingDaysTest('2022-04-06', '2022-04-12')) && p() && e('7'); //查询2022-04-06到2022-04-12的实际工作日
+r($holiday->getActualWorkingDaysTest('2022-05-10', '2022-05-20')) && p() && e('9'); //查询2022-05-10到2022-05-10的实际工作日
+r($holiday->getActualWorkingDaysTest('2022-04-06', '2022-04-06')) && p() && e('1'); //查询2022-05-10到2022-05-10的实际工作日
+r($holiday->getActualWorkingDaysTest('2022-05-13', '2022-05-13')) && p() && e('1'); //查询2022-05-13到2022-05-13的实际工作日
+r($holiday->getActualWorkingDaysTest('2022-05-14', '2022-05-14')) && p() && e('0'); //查询2022-05-14到2022-05-14的实际工作日
+r($holiday->getActualWorkingDaysTest('0000-00-00', '0000-00-00')) && p() && e('0'); //测试传入0000-00-00的情况
\ No newline at end of file
diff --git a/module/holiday/test/model/getbyid.php b/module/holiday/test/model/getbyid.php
new file mode 100755
index 0000000000..b50d6aefaa
--- /dev/null
+++ b/module/holiday/test/model/getbyid.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+查询id为1的holiday >> 这是一个节假日1,holiday,这个是节假日的描述1
+查询id为5的holiday >> 这是一个节假日5,holiday,这个是节假日的描述5
+查询id为10的holiday >> 这是一个节假日10,working,这个是节假日的描述10
+查询不存在的holiday >> Object not found
+
+*/
+$holidayIDList = array('1', '5', '10', '1001');
+
+$holiday = new holidayTest();
+
+r($holiday->getByIdTest($holidayIDList[0])) && p('name,type,desc') && e('这是一个节假日1,holiday,这个是节假日的描述1'); //查询id为1的holiday
+r($holiday->getByIdTest($holidayIDList[1])) && p('name,type,desc') && e('这是一个节假日5,holiday,这个是节假日的描述5'); //查询id为5的holiday
+r($holiday->getByIdTest($holidayIDList[2])) && p('name,type,desc') && e('这是一个节假日10,working,这个是节假日的描述10'); //查询id为10的holiday
+r($holiday->getByIdTest($holidayIDList[3])) && p() && e('Object not found'); //查询不存在的holiday
\ No newline at end of file
diff --git a/module/holiday/test/model/getdaysbetween.php b/module/holiday/test/model/getdaysbetween.php
new file mode 100755
index 0000000000..b3352e46df
--- /dev/null
+++ b/module/holiday/test/model/getdaysbetween.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getDaysBetween();
+cid=1
+pid=1
+
+返回2022-04-01到2022-04-21之间的天数 >> 21
+返回2022-05-23到2022-05-30之间的天数 >> 8
+测试传入一间隔一整年的两天 >> 366
+返回2022-05-07到2022-05-08之间的天数 >> 2
+测试传入同一天的情况 >> 1
+
+*/
+
+$holiday = new holidayTest();
+
+r($holiday->getDaysBetweenTest('2022-04-01', '2022-04-21')) && p() && e('21'); //返回2022-04-01到2022-04-21之间的天数
+r($holiday->getDaysBetweenTest('2022-05-23', '2022-05-30')) && p() && e('8'); //返回2022-05-23到2022-05-30之间的天数
+r($holiday->getDaysBetweenTest('2021-01-01', '2022-01-01')) && p() && e('366'); //测试传入一间隔一整年的两天
+r($holiday->getDaysBetweenTest('2022-05-07', '2022-05-08')) && p() && e('2'); //返回2022-05-07到2022-05-08之间的天数
+r($holiday->getDaysBetweenTest('2022-05-07', '2022-05-07')) && p() && e('1'); //测试传入同一天的情况
\ No newline at end of file
diff --git a/module/holiday/test/model/getholidays.php b/module/holiday/test/model/getholidays.php
new file mode 100755
index 0000000000..0e8e6d4349
--- /dev/null
+++ b/module/holiday/test/model/getholidays.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getHolidays();
+cid=1
+pid=1
+
+返回处于2022-3-3到2022-4-7之间的休假日期。 >> 1
+返回处于2022-3-3到2022-4-8之间的休假日期。 >> 2
+测试当结束日期大于开始日期时。 >> 0
+返回处于2022-4-7到2022-4-8之间的休假日期。 >> 2
+测试当数据库没有休假记录时。 >> 0
+
+*/
+
+$holiday = new holidayTest();
+$begin = array('2022-03-03', '2022-04-07');
+$end = array('2022-04-07', '2022-04-08', '2022-03-05');
+
+r($holiday->getHolidaysTest($begin[0], $end[0])) && p() && e('1'); //返回处于2022-3-3到2022-4-7之间的休假日期。
+r($holiday->getHolidaysTest($begin[0], $end[1])) && p() && e('2'); //返回处于2022-3-3到2022-4-8之间的休假日期。
+r($holiday->getHolidaysTest($begin[1], $end[2])) && p() && e('0'); //测试当结束日期大于开始日期时。
+r($holiday->getHolidaysTest($begin[1], $end[1])) && p() && e('2'); //返回处于2022-4-7到2022-4-8之间的休假日期。
+r($holiday->getHolidaysTest($begin[0], $end[2])) && p() && e('0'); //测试当数据库没有休假记录时。
\ No newline at end of file
diff --git a/module/holiday/test/model/getlist.php b/module/holiday/test/model/getlist.php
new file mode 100755
index 0000000000..b45dfbd662
--- /dev/null
+++ b/module/holiday/test/model/getlist.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+返回2022年的holiday list >> 100
+返回2022年2月的holiday list >> 0
+返回2022年5月的holiday list >> 100
+返回2002年的holiday list >> 0
+返回2022年所有类型的holiday list >> 100
+返回2022年类型为holiday的holiday list >> 50
+返回2022年类型为working的holiday list >> 50
+返回2022年类型为空holiday list >> 100
+
+*/
+
+$holiday = new holidayTest();
+$t_numyear = array('2022', '2022-02', '2022-05', '2002', '');
+$t_type = array('all', 'holiday', 'working', '');
+
+r($holiday->getListTest($t_numyear[0])) && p() && e('100'); // 返回2022年的holiday list
+r($holiday->getListTest($t_numyear[1])) && p() && e('0'); // 返回2022年2月的holiday list
+r($holiday->getListTest($t_numyear[2])) && p() && e('100'); // 返回2022年5月的holiday list
+r($holiday->getListTest($t_numyear[3])) && p() && e('0'); // 返回2002年的holiday list
+r($holiday->getListTest($t_numyear[0], $t_type[0])) && p() && e('100'); // 返回2022年所有类型的holiday list
+r($holiday->getListTest($t_numyear[0], $t_type[1])) && p() && e('50'); // 返回2022年类型为holiday的holiday list
+r($holiday->getListTest($t_numyear[0], $t_type[2])) && p() && e('50'); // 返回2022年类型为working的holiday list
+r($holiday->getListTest($t_numyear[0], $t_type[3])) && p() && e('100'); // 返回2022年类型为空holiday list
\ No newline at end of file
diff --git a/module/holiday/test/model/getworkingdays.php b/module/holiday/test/model/getworkingdays.php
new file mode 100755
index 0000000000..32d0314e86
--- /dev/null
+++ b/module/holiday/test/model/getworkingdays.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getWorkingDays();
+cid=1
+pid=1
+
+返回处于2022-3-3到2022-4-6之间的工作日。 >> 0
+返回处于2022-3-3到2022-4-8之间的工作日。 >> 2
+测试当结束日期大于开始日期时。 >> 0
+返回处于2022-4-6到2022-4-8之间的工作日。 >> 2
+测试当数据库没有工作日记录时。 >> 0
+
+*/
+
+$holiday = new holidayTest();
+
+$begin = array('2022-03-03', '2022-04-07');
+$end = array('2022-04-06', '2022-04-08', '2022-03-05');
+
+r($holiday->getWorkingDaysTest($begin[0], $end[0])) && p() && e('0'); //返回处于2022-3-3到2022-4-6之间的工作日。
+r($holiday->getWorkingDaysTest($begin[0], $end[1])) && p() && e('2'); //返回处于2022-3-3到2022-4-8之间的工作日。
+r($holiday->getWorkingDaysTest($begin[1], $end[0])) && p() && e('0'); //测试当结束日期大于开始日期时。
+r($holiday->getWorkingDaysTest($begin[1], $end[1])) && p() && e('2'); //返回处于2022-4-6到2022-4-8之间的工作日。
+r($holiday->getWorkingDaysTest($begin[0], $end[2])) && p() && e('0'); //测试当数据库没有工作日记录时。
\ No newline at end of file
diff --git a/module/holiday/test/model/getyearpairs.php b/module/holiday/test/model/getyearpairs.php
new file mode 100755
index 0000000000..8f8817ec7d
--- /dev/null
+++ b/module/holiday/test/model/getyearpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getYearPairs();
+cid=1
+pid=1
+
+测试getYearPairsTest方法 >> 1
+
+*/
+
+$holiday = new holidayTest();
+
+r($holiday->getYearPairsTest()) && p() && e('1'); //测试getYearPairsTest方法
\ No newline at end of file
diff --git a/module/holiday/test/model/isholiday.php b/module/holiday/test/model/isholiday.php
new file mode 100755
index 0000000000..28f90ab2d8
--- /dev/null
+++ b/module/holiday/test/model/isholiday.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+isHoliday();
+cid=1
+pid=1
+
+测试节假日2022年4月10日 >> It is a holiday
+测试节假日2022年4月16日 >> It is a holiday
+测试补班2022年5月7日 >> It is not a holiday
+测试补班2022年5月13日 >> It is not a holiday
+
+*/
+$holidays = array('2022-04-10', '2022-04-16');
+$workingDays = array('2022-05-07', '2022-05-13');
+
+$holiday = new holidayTest();
+
+r($holiday->isHolidayTest($holidays[0])) && p() && e('It is a holiday'); // 测试节假日2022年4月10日
+r($holiday->isHolidayTest($holidays[1])) && p() && e('It is a holiday'); // 测试节假日2022年4月16日
+r($holiday->isHolidayTest($workingDays[0])) && p() && e('It is not a holiday'); // 测试补班2022年5月7日
+r($holiday->isHolidayTest($workingDays[1])) && p() && e('It is not a holiday'); // 测试补班2022年5月13日
\ No newline at end of file
diff --git a/module/holiday/test/model/isworkingday.php b/module/holiday/test/model/isworkingday.php
new file mode 100755
index 0000000000..935c3b518d
--- /dev/null
+++ b/module/holiday/test/model/isworkingday.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+isWorkingDay();
+cid=1
+pid=1
+
+测试不是工作日 >> 0
+测试是工作日 >> 1
+测试日期格式不对 >> 0
+
+*/
+
+$holiday = new holidayTest();
+$date = array('2022-03-01', '2022-04-09', '2002-2-2');
+
+r($holiday->isWorkingDayTest($date[0])) && p() && e('0'); // 测试不是工作日
+r($holiday->isWorkingDayTest($date[1])) && p() && e('1'); // 测试是工作日
+r($holiday->isWorkingDayTest($date[2])) && p() && e('0'); // 测试日期格式不对
\ No newline at end of file
diff --git a/module/holiday/test/model/update.php b/module/holiday/test/model/update.php
new file mode 100755
index 0000000000..b9afbb6165
--- /dev/null
+++ b/module/holiday/test/model/update.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试修改类型 >> true
+测试修改名称 >> true
+测试修改描述 >> true
+测试将必填项名称置空 >> 『名称』不能为空。
+测试将必填项开始日期置空 >> 『开始日期』应当为合法的日期。
+测试将必填项结束日期置空 >> 『结束日期』应当为合法的日期。
+测试输入大于开始日期的结束日期 >> 『结束日期』应当不小于
+
+*/
+
+$holidayIDList = array('1', '2');
+
+$holiday = new holidayTest();
+
+$updateType = array('type' => 'working');
+$updateName = array('name' => '修改holiday的名字');
+$updateDesc = array('desc' => '一些描述');
+$noName = array('name' => '');
+$noBegin = array('begin' => '');
+$noEnd = array('end' => '');
+$endltBegin = array('begin' => '2022-05-08', 'end' => '2022-05-01');
+
+r($holiday->updateTest($holidayIDList[0], $updateType)) && p() && e('true'); //测试修改类型
+r($holiday->updateTest($holidayIDList[0], $updateName)) && p() && e('true'); //测试修改名称
+r($holiday->updateTest($holidayIDList[0], $updateDesc)) && p() && e('true'); //测试修改描述
+r($holiday->updateTest($holidayIDList[0], $noName)) && p('name:0') && e('『名称』不能为空。'); //测试将必填项名称置空
+r($holiday->updateTest($holidayIDList[0], $noBegin)) && p('begin:0') && e('『开始日期』应当为合法的日期。'); //测试将必填项开始日期置空
+r($holiday->updateTest($holidayIDList[0], $noEnd)) && p('end:0') && e('『结束日期』应当为合法的日期。'); //测试将必填项结束日期置空
+r($holiday->updateTest($holidayIDList[0], $endltBegin)) && p('end:0') && e('『结束日期』应当不小于'); //测试输入大于开始日期的结束日期
+
diff --git a/module/holiday/test/model/updateprogramplanduration.php b/module/holiday/test/model/updateprogramplanduration.php
new file mode 100755
index 0000000000..da4515ea2a
--- /dev/null
+++ b/module/holiday/test/model/updateprogramplanduration.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+updateProgramPlanDuration();
+cid=1
+pid=1
+
+测试插入id为1的节假日时迭代101项目的planDuration >> 59
+测试插入id为3的节假日时迭代101项目的planDuration >> 59
+测试插入id为1的节假日时迭代102项目的planDuration >> 58
+测试插入id为3的节假日时迭代102项目的planDuration >> 58
+测试插入id为1的节假日时迭代750项目的planDuration >> 58
+测试插入id为3的节假日时迭代750项目的planDuration >> 58
+测试插入id为1的节假日时迭代1项目的planDuration >> 59
+测试插入id为3的节假日时迭代1项目的planDuration >> 59
+测试插入id为1的节假日时迭代11项目的planDuration >> 59
+测试插入id为3的节假日时迭代11项目的planDuration >> 59
+
+*/
+$holidayIDList = array('1', '3', '99', '100');
+
+$holiday = new holidayTest();
+
+r($holiday->updateProgramPlanDurationTest(101, $holidayIDList[0])) && p() && e('59'); //测试插入id为1的节假日时迭代101项目的planDuration
+r($holiday->updateProgramPlanDurationTest(101, $holidayIDList[1])) && p() && e('59'); //测试插入id为3的节假日时迭代101项目的planDuration
+r($holiday->updateProgramPlanDurationTest(102, $holidayIDList[0])) && p() && e('58'); //测试插入id为1的节假日时迭代102项目的planDuration
+r($holiday->updateProgramPlanDurationTest(102, $holidayIDList[1])) && p() && e('58'); //测试插入id为3的节假日时迭代102项目的planDuration
+r($holiday->updateProgramPlanDurationTest(750, $holidayIDList[0])) && p() && e('58'); //测试插入id为1的节假日时迭代750项目的planDuration
+r($holiday->updateProgramPlanDurationTest(750, $holidayIDList[1])) && p() && e('58'); //测试插入id为3的节假日时迭代750项目的planDuration
+r($holiday->updateProgramPlanDurationTest(1, $holidayIDList[0])) && p() && e('59'); //测试插入id为1的节假日时迭代1项目的planDuration
+r($holiday->updateProgramPlanDurationTest(1, $holidayIDList[1])) && p() && e('59'); //测试插入id为3的节假日时迭代1项目的planDuration
+r($holiday->updateProgramPlanDurationTest(11, $holidayIDList[0])) && p() && e('59'); //测试插入id为1的节假日时迭代11项目的planDuration
+r($holiday->updateProgramPlanDurationTest(11, $holidayIDList[1])) && p() && e('59'); //测试插入id为3的节假日时迭代11项目的planDuration
+
diff --git a/module/holiday/test/model/updateprojectrealduration.php b/module/holiday/test/model/updateprojectrealduration.php
new file mode 100755
index 0000000000..8ec31465ff
--- /dev/null
+++ b/module/holiday/test/model/updateprojectrealduration.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+updateProjectRealDuration();
+cid=1
+pid=1
+
+测试新插入holiday1时项目的realDuration字段 >> 29
+测试新插入holiday3时项目的realDuration字段 >> 29
+测试新插入holiday99时项目的realDuration字段 >> 29
+测试新插入holiday100时项目的realDuration字段 >> 29
+
+*/
+
+$project = new Project();
+
+$insertNewProject = array(
+ 'parent' => 1,
+ 'name' => '用于测试holiday的项目',
+ 'budget' => '',
+ 'budgetUnit' => 'CNY',
+ 'begin' => '2022-03-07',
+ 'end' => '2022-03-10',
+ 'realBegan' => '2022-04-01',
+ 'realEnd' => '2022-05-01',
+ 'desc' => '测试项目描述',
+ 'acl' => 'private',
+ 'whitelist' => '',
+ 'PM' => '',
+ 'products' => array(1),
+);
+
+$newProject = $project->create($insertNewProject);
+$newProjectID = $newProject->id;
+
+$holidayIDList = array('1', '3', '99', '100');
+
+$holiday = new holidayTest();
+
+r($holiday->updateProjectRealDurationTest($newProjectID, $holidayIDList[0])) && p() && e('29'); //测试新插入holiday1时项目的realDuration字段
+r($holiday->updateProjectRealDurationTest($newProjectID, $holidayIDList[1])) && p() && e('29'); //测试新插入holiday3时项目的realDuration字段
+r($holiday->updateProjectRealDurationTest($newProjectID, $holidayIDList[2])) && p() && e('29'); //测试新插入holiday99时项目的realDuration字段
+r($holiday->updateProjectRealDurationTest($newProjectID, $holidayIDList[3])) && p() && e('29'); //测试新插入holiday100时项目的realDuration字段
+
diff --git a/module/holiday/test/model/updatetaskplanduration.php b/module/holiday/test/model/updatetaskplanduration.php
new file mode 100755
index 0000000000..3c433e66bb
--- /dev/null
+++ b/module/holiday/test/model/updatetaskplanduration.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+updateTaskPlanDurationTest();
+cid=1
+pid=1
+
+测试插入id为1的holiday时任务1的planDuration >> 6
+测试插入id为3的holiday时任务1的planDuration >> 6
+测试插入id为1的holiday时任务2的planDuration >> 6
+测试插入id为3的holiday时任务2的planDuration >> 6
+测试插入id为1的holiday时任务11的planDuration >> 0
+测试插入id为3的holiday时任务11的planDuration >> 0
+
+*/
+$holidayIDList = array('1', '3', '99', '100');
+
+$holiday = new holidayTest();
+
+r($holiday->updateTaskPlanDurationTest(1, $holidayIDList[0])) && p() && e('6'); //测试插入id为1的holiday时任务1的planDuration
+r($holiday->updateTaskPlanDurationTest(1, $holidayIDList[1])) && p() && e('6'); //测试插入id为3的holiday时任务1的planDuration
+r($holiday->updateTaskPlanDurationTest(2, $holidayIDList[0])) && p() && e('6'); //测试插入id为1的holiday时任务2的planDuration
+r($holiday->updateTaskPlanDurationTest(2, $holidayIDList[1])) && p() && e('6'); //测试插入id为3的holiday时任务2的planDuration
+r($holiday->updateTaskPlanDurationTest(11, $holidayIDList[0])) && p() && e('0'); //测试插入id为1的holiday时任务11的planDuration
+r($holiday->updateTaskPlanDurationTest(11, $holidayIDList[1])) && p() && e('0'); //测试插入id为3的holiday时任务11的planDuration
\ No newline at end of file
diff --git a/module/jenkins/test/jenkins.class.php b/module/jenkins/test/jenkins.class.php
new file mode 100644
index 0000000000..7d75f0c5f1
--- /dev/null
+++ b/module/jenkins/test/jenkins.class.php
@@ -0,0 +1,102 @@
+tester = $tester;
+ $this->jenkins = $this->tester->loadModel('jenkins');
+ }
+
+ /**
+ * Get by id.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByID($id)
+ {
+ $jenkins = $this->jenkins->getByID($id);
+ if(empty($jenkins)) return 0;
+ return $jenkins;
+ }
+
+ /**
+ * Get jenkins list.
+ *
+ * @param string $orderBy
+ * @access public
+ * @return object
+ */
+ public function getList($orderBy = 'id_desc')
+ {
+ $jenkins = $this->jenkins->getList($orderBy);
+ if(empty($jenkins)) return 0;
+ return array_shift($jenkins);
+ }
+
+ /**
+ * Get jenkins pairs
+ *
+ * @return string
+ */
+ public function getPairs()
+ {
+ $pairs = $this->jenkins->getPairs();
+ return key($pairs);
+ }
+
+ /**
+ * Get jenkins tasks.
+ *
+ * @param int $id
+ * @access public
+ * @return array
+ */
+ public function getTasks($id)
+ {
+ $tasks = $this->jenkins->getTasks($id);
+ if(empty($tasks)) return 0;
+ return $tasks;
+ }
+
+ /**
+ * Create a jenkins.
+ *
+ * @access public
+ * @return object|string
+ */
+ public function create()
+ {
+ $jenkinsID = $this->jenkins->create();
+ if(dao::isError())
+ {
+ $errors = dao::getError();
+ return key($errors);
+ }
+
+ return $this->jenkins->getById($jenkinsID);
+ }
+
+ /**
+ * Update a jenkins.
+ *
+ * @param int $id
+ * @access public
+ * @return object|string
+ */
+ public function update($id)
+ {
+ $this->jenkins->update($id);
+ if(dao::isError())
+ {
+ $errors = dao::getError();
+ return key($errors);
+ }
+
+ return $this->jenkins->getById($id);
+ }
+}
diff --git a/module/jenkins/test/model/create.php b/module/jenkins/test/model/create.php
new file mode 100755
index 0000000000..5a6d2d2fab
--- /dev/null
+++ b/module/jenkins/test/model/create.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+*/
+
+$jenkins = new jenkinsTest();
+
+$_POST = array();
+$_POST['name'] = '';
+$_POST['url'] = 'http://10.0.7.242:9580';
+$_POST['account'] = 'admin';
+$_POST['token'] = '1196c85ba525a268570df9da627e3a7b2d';
+$_POST['password'] = '';
+
+r($jenkins->create()) && p() && e('name'); // Jenkins名称为空
+
+$_POST['name'] = 'Jenkins';
+$_POST['url'] = '';
+r($jenkins->create()) && p() && e('url'); // 服务器地址为空
+
+$_POST['url'] = 'http://10.0.7.242:9580';
+r($jenkins->create()) && p('name,url,token') && e('Jenkins,http://10.0.7.242:9580,1196c85ba525a268570df9da627e3a7b2d'); // 正确Jenkins数据
+
diff --git a/module/jenkins/test/model/getbyid.php b/module/jenkins/test/model/getbyid.php
new file mode 100755
index 0000000000..a786986423
--- /dev/null
+++ b/module/jenkins/test/model/getbyid.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+gitById();
+cid=1
+pid=1
+
+使用存在的ID >> 3
+
+*/
+
+$jenkins = new jenkinsTest();
+
+$jenkinsID = 3;
+r($jenkins->getById($jenkinsID)) && p('id') && e('3'); // 使用存在的ID
+
+$jenkinsID = 0;
+r($jenkins->getById($jenkinsID)) && p() && e(0); // 使用空的ID
+
+$jenkinsID = 111;
+r($jenkins->getById($jenkinsID)) && p() && e(0); // 使用不存在的ID
+
diff --git a/module/jenkins/test/model/getlist.php b/module/jenkins/test/model/getlist.php
new file mode 100755
index 0000000000..d9c883d70e
--- /dev/null
+++ b/module/jenkins/test/model/getlist.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+gitList();
+cid=1
+pid=1
+
+获取Jenkins列表 >> 3
+
+*/
+
+$jenkins = new jenkinsTest();
+
+$orderBy = 'id_desc';
+r($jenkins->getList($orderBy)) && p('id') && e('3'); // 获取Jenkins列表
+
diff --git a/module/jenkins/test/model/getpairs.php b/module/jenkins/test/model/getpairs.php
new file mode 100755
index 0000000000..30311a22a8
--- /dev/null
+++ b/module/jenkins/test/model/getpairs.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+gitPairs();
+cid=1
+pid=1
+
+获取Jenkins >> 3
+
+*/
+
+$jenkins = new jenkinsTest();
+
+r($jenkins->getPairs()) && p() && e('3'); // 获取Jenkins
+
diff --git a/module/jenkins/test/model/gettasks.php b/module/jenkins/test/model/gettasks.php
new file mode 100755
index 0000000000..83141f4454
--- /dev/null
+++ b/module/jenkins/test/model/gettasks.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+gitTasks();
+cid=1
+pid=1
+
+使用存在的Jenkins >> zentao-test
+使用空的Jenkins >> 0
+使用不存在的Jenkins >> 0
+
+*/
+
+$jenkins = new jenkinsTest();
+
+$id = 3;
+r($jenkins->getTasks($id)) && p('zentao-test') && e('zentao-test'); // 使用存在的Jenkins
+
+$id = 0;
+r($jenkins->getTasks($id)) && p() && e('0'); // 使用空的Jenkins
+
+$id = 111;
+r($jenkins->getTasks($id)) && p() && e('0'); // 使用不存在的Jenkins
+
diff --git a/module/jenkins/test/model/update.php b/module/jenkins/test/model/update.php
new file mode 100755
index 0000000000..0740538e82
--- /dev/null
+++ b/module/jenkins/test/model/update.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+Jenkins名称为空 >> name
+服务器地址为空 >> url
+正确Jenkins数据 >> Changed Jenkins
+
+*/
+
+$jenkins = new jenkinsTest();
+
+$jenkinsID = 3;
+
+$_POST = array();
+$_POST['name'] = '';
+$_POST['url'] = 'http://10.0.7.242:9580';
+$_POST['account'] = 'admin';
+$_POST['token'] = '1196c85ba525a268570df9da627e3a7b2d';
+$_POST['password'] = '';
+
+r($jenkins->update($jenkinsID)) && p() && e('name'); // Jenkins名称为空
+
+$_POST['name'] = 'Changed Jenkins';
+$_POST['url'] = '';
+r($jenkins->update($jenkinsID)) && p() && e('url'); // 服务器地址为空
+
+$_POST['url'] = 'http://10.0.7.242:9580';
+r($jenkins->update($jenkinsID)) && p('name') && e('Changed Jenkins'); // 正确Jenkins数据
+
diff --git a/module/job/test/job.class.php b/module/job/test/job.class.php
new file mode 100644
index 0000000000..b7636392f5
--- /dev/null
+++ b/module/job/test/job.class.php
@@ -0,0 +1,305 @@
+objectModel = $tester->loadModel('job');
+ }
+
+ /**
+ * Test get job by id.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($id)
+ {
+ $object = $this->objectModel->getById($id);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get job list.
+ *
+ * @param string $orderBy
+ * @param int $pager
+ * @access public
+ * @return object
+ */
+ public function getListTest($orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getList($orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get list by repo id.
+ *
+ * @param int $repoID
+ * @access public
+ * @return object
+ */
+ public function getListByRepoIDTest($repoID)
+ {
+ return $this->objectModel->getListByRepoID($repoID);
+ }
+
+ /**
+ * Test get job pairs.
+ *
+ * @param int $repoID
+ * @param string $engine
+ * @access public
+ * @return object
+ */
+ public function getPairsTest($repoID, $engine = '')
+ {
+ $objects = $this->objectModel->getPairs($repoID, $engine);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get job list by trigger type.
+ *
+ * @param string $triggerType
+ * @param array $repoIdList
+ * @access public
+ * @return object
+ */
+ public function getListByTriggerTypeTest($triggerType, $repoIdList = array())
+ {
+ $objects = $this->objectModel->getListByTriggerType($triggerType, $repoIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get trigger config.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getTriggerConfigTest($id)
+ {
+
+ $job = $this->objectModel->getById($id);
+
+ $object = $this->objectModel->getTriggerConfig($job);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get trigger group.
+ *
+ * @param string $triggerType
+ * @param array $repoIdList
+ * @access public
+ * @return array
+ */
+ public function getTriggerGroupTest($triggerType, $repoIdList)
+ {
+ $array = $this->objectModel->getTriggerGroup($triggerType, $repoIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ $group = array();
+ if($triggerType == 'tag') $group = isset($array[1]) ? $array[1] : array();
+ if($triggerType == 'commit') $group = isset($array[2]) ? $array[2] : array();
+
+ return $group;
+ }
+
+ /**
+ * Test create object.
+ *
+ * @param array $params
+ * @access public
+ * @return object
+ */
+ public function createObject($params)
+ {
+ $createFields['name'] = '这是一个JOB3';
+ $createFields['engine'] = 'gitlab';
+ $createFields['repo'] = '1';
+ $createFields['reference'] = 'test_case';
+ $createFields['product'] = '1';
+ $createFields['frame'] = 'phpunit';
+ $createFields['triggerType'] = 'commit';
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($params as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create();
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test update object.
+ *
+ * @param int $jobId
+ * @param array $params
+ * @access public
+ * @return string
+ */
+ public function updateObject($jobId, $params = array())
+ {
+ global $tester;
+ $object = $tester->dbh->query("SELECT * FROM " . TABLE_JOB ." WHERE id = $jobId")->fetch();
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($params)))
+ {
+ $_POST[$field] = $params[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+ $_POST['jkServer'] = 3;
+ $_POST['jkTask'] = 'dave';
+
+ $result = $this->objectModel->update($jobId);
+ unset($_POST);
+ if(dao::isError()) return dao::getError()[0];
+
+ return $result ? 'Job更新成功' : 'Job更新失败';
+ }
+
+ /**
+ * Test exec job.
+ *
+ * @param int $id
+ * @param array $extraParam
+ * @access public
+ * @return object
+ */
+ public function execTest($id, $extraParam = array())
+ {
+ $object = $this->objectModel->exec($id, $extraParam);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test exec jenkins pipeline.
+ *
+ * @param int $jobID
+ * @param object $repo
+ * @param int $compileID
+ * @param array $extraParam
+ * @access public
+ * @return object
+ */
+ public function execJenkinsPipelineTest($jobID, $repo, $compileID, $extraParam = array())
+ {
+ $job = $this->objectModel->getById($jobID);
+
+ $object = $this->objectModel->execJenkinsPipeline($job, $repo, $compileID, $extraParam);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test exec gitlab pipeline.
+ *
+ * @param int $jobID
+ * @access public
+ * @return object
+ */
+ public function execGitlabPipelineTest($jobID)
+ {
+ $job = $this->objectModel->getById($jobID);
+
+ $object = $this->objectModel->execGitlabPipeline($job);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get last tag by repo.
+ *
+ * @param int $repoId
+ * @param int $jobId
+ * @access public
+ * @return string
+ */
+ public function getLastTagByRepoTest($jobId)
+ {
+ global $tester;
+ $job = $this->objectModel->getById($jobId);
+ $repo = $tester->loadModel('repo')->getRepoById($job->repo);
+ $object = $this->objectModel->getLastTagByRepo($repo, $job);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get sonarqube by RepoID.
+ *
+ * @param array $repoIDList
+ * @param int $jobID
+ * @param bool $showDeleted
+ * @access public
+ * @return array
+ */
+ public function getSonarqubeByRepoTest($repoIDList, $jobID = 0, $showDeleted = false)
+ {
+ $array = $this->objectModel->getSonarqubeByRepo($repoIDList, $jobID, $showDeleted);
+
+ if(dao::isError()) return dao::getError();
+
+ return $array;
+ }
+
+ /**
+ * Test get job pairs by sonarqube projectkeys.
+ *
+ * @param int $sonarqubeID
+ * @param array $projectKeys
+ * @param bool $emptyShowAll
+ * @param bool $showDeleted
+ * @access public
+ * @return array
+ */
+ public function getJobBySonarqubeProjectTest($sonarqubeID, $projectKeys = array(), $emptyShowAll = false, $showDeleted = false)
+ {
+ $array = $this->objectModel->getJobBySonarqubeProject($sonarqubeID, $projectKeys, $emptyShowAll, $showDeleted);
+
+ if(dao::isError()) return dao::getError();
+
+ return $array;
+ }
+
+}
diff --git a/module/job/test/model/create.php b/module/job/test/model/create.php
new file mode 100755
index 0000000000..f1cf212452
--- /dev/null
+++ b/module/job/test/model/create.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试创建job name为空的情况 >> 『名称』不能为空。
+测试创建job engine为空的情况 >> 『构建引擎』不能为空。
+测试创建job triggerType为空的情况 >> 『触发方式』不能为空
+测试创建job name为《这是一个job007》的情况 >> 这是一个job007
+测试创建job engine为gitlab的情况 >> gitlab
+测试创建job triggerType为tag的情况 >> tag
+
+*/
+
+$job_name = array('name' => '这是一个job007');
+$job_engine = array('engine' => 'gitlab');
+$job_triggerType = array('triggerType' => 'tag');
+$job_name_blank = array('name' => '');
+$job_engine_blank = array('engine' => '');
+$job_triggerType_blank = array('triggerType' => '');
+
+$job = new jobTest();
+
+r($job->createObject($job_name_blank)) && p('name:0') && e('『名称』不能为空。'); // 测试创建job name为空的情况
+r($job->createObject($job_engine_blank)) && p('engine:0') && e('『构建引擎』不能为空。'); // 测试创建job engine为空的情况
+r($job->createObject($job_triggerType_blank)) && p('triggerType:0') && e('『触发方式』不能为空'); // 测试创建job triggerType为空的情况
+r($job->createObject($job_name)) && p('name') && e('这是一个job007'); // 测试创建job name为《这是一个job007》的情况
+r($job->createObject($job_engine)) && p('engine') && e('gitlab'); // 测试创建job engine为gitlab的情况
+r($job->createObject($job_triggerType)) && p('triggerType') && e('tag'); // 测试创建job triggerType为tag的情况
diff --git a/module/job/test/model/exec.php b/module/job/test/model/exec.php
new file mode 100755
index 0000000000..309c709a78
--- /dev/null
+++ b/module/job/test/model/exec.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试执行job id为1的情况 >> 1
+
+*/
+
+$jobID = 1;
+$job = new jobTest();
+r($job->execTest($jobID)) && p('id')&& e('1'); // 测试执行job id为1的情况
diff --git a/module/job/test/model/getbyid.php b/module/job/test/model/getbyid.php
new file mode 100755
index 0000000000..860ba258e3
--- /dev/null
+++ b/module/job/test/model/getbyid.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+查询id为1的job的engine >> jenkins
+查询id为1的job的frame >> sonarqube
+
+*/
+
+$jobIDList = array('1', '1000001');
+
+$job = new jobTest();
+
+r($job->getByIdTest($jobIDList[0])) && p('engine') && e('jenkins'); // 查询id为1的job的engine
+r($job->getByIdTest($jobIDList[0])) && p('frame') && e('sonarqube'); // 查询id为1的job的frame
+r($job->getByIdTest($jobIDList[1])) && p('engine') && e(NULL); // 查询id为1000001的job的name
+r($job->getByIdTest($jobIDList[1])) && p('frame') && e(NULL); // 查询id为1000001的job的account
diff --git a/module/job/test/model/getjobbysonarqubeproject.php b/module/job/test/model/getjobbysonarqubeproject.php
new file mode 100755
index 0000000000..f29311349a
--- /dev/null
+++ b/module/job/test/model/getjobbysonarqubeproject.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getJobBySonarqubeProject();
+cid=1
+pid=1
+
+根据sonarqube project查询job >> 1
+
+*/
+
+$sonarqubeID = 2;
+$projectKeys = array('zentaopms');
+
+$job = new jobTest();
+r($job->getJobBySonarqubeProjectTest($sonarqubeID, $projectKeys)) && p('zentaopms') && e('1'); // 根据sonarqube project查询job
diff --git a/module/job/test/model/getlasttagbyrepo.php b/module/job/test/model/getlasttagbyrepo.php
new file mode 100755
index 0000000000..d91d91dc1a
--- /dev/null
+++ b/module/job/test/model/getlasttagbyrepo.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getLastTagByRepo();
+cid=1
+pid=1
+
+查询id为1的job的last tag >> tag_test1
+
+*/
+
+$jobID = 1;
+$job = new jobTest();
+r($job->getLastTagByRepoTest($jobID)) && p() && e('tag_test1'); // 查询id为1的job的last tag
diff --git a/module/job/test/model/getlist.php b/module/job/test/model/getlist.php
new file mode 100755
index 0000000000..85bf05ce97
--- /dev/null
+++ b/module/job/test/model/getlist.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+测试获取列表的个数,目前只有两个 >> 2
+测试获取列表某个job的名称信息 >> 这是一个Job1
+
+*/
+
+$job = new jobTest();
+$list = $job->getListTest();
+
+r(count($list)) && p() && e('2'); //测试获取列表的个数,目前只有两个
+r($list) && p('1:name') && e('这是一个Job1'); //测试获取列表某个job的名称信息
diff --git a/module/job/test/model/getlistbyrepoid.php b/module/job/test/model/getlistbyrepoid.php
new file mode 100755
index 0000000000..582bbca283
--- /dev/null
+++ b/module/job/test/model/getlistbyrepoid.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 这是一个Job1
+获取repo为100001的name >> 0
+
+*/
+$job = new jobTest();
+
+$repoIdList = array('1', '100001');
+
+r($job->getListByRepoIDTest($repoIdList[0])) && p('1:name') && e('这是一个Job1'); // 获取repo为1的name
+r($job->getListByRepoIDTest($repoIdList[1])) && p('100001:name') && e('0'); // 获取repo为100001的name
diff --git a/module/job/test/model/getlistbytriggertype.php b/module/job/test/model/getlistbytriggertype.php
new file mode 100755
index 0000000000..debc35c064
--- /dev/null
+++ b/module/job/test/model/getlistbytriggertype.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 这是一个Job1
+获取trigger type为commit的repo为2的name >> 这是一个Job2
+
+*/
+$job = new jobTest();
+
+$triggerType = array('tag', 'commit');
+$repoIdList = array('1', '2', '100001');
+
+r($job->getListByTriggerTypeTest($triggerType[0], $repoIdList)) && p('1:name') && e('这是一个Job1'); // 获取trigger type为tag的repo为1的name
+r($job->getListByTriggerTypeTest($triggerType[1], $repoIdList)) && p('2:name') && e('这是一个Job2'); // 获取trigger type为commit的repo为2的name
diff --git a/module/job/test/model/getparis.php b/module/job/test/model/getparis.php
new file mode 100755
index 0000000000..63b6170fee
--- /dev/null
+++ b/module/job/test/model/getparis.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+> 这是一个Job1
+
+*/
+$job = new jobTest();
+
+$repoID = '1';
+$engine = 'jenkins';
+
+r($job->getPairsTest($repoID, $engine)) && p('1') && e('这是一个Job1'); // 获取repo为1且engine为jenkins的name
diff --git a/module/job/test/model/getsonarqubebyrepo.php b/module/job/test/model/getsonarqubebyrepo.php
new file mode 100755
index 0000000000..f205e3ffcd
--- /dev/null
+++ b/module/job/test/model/getsonarqubebyrepo.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getSonarqubeByRepo();
+cid=1
+pid=1
+
+根据repo查询sonarqube >> 这是一个Job1
+
+*/
+
+$repoIDList = array('1', '2');
+
+$job = new jobTest();
+r($job->getSonarqubeByRepoTest($repoIDList)) && p('1:name') && e('这是一个Job1'); // 根据repo查询sonarqube
diff --git a/module/job/test/model/gettriggerconfig.php b/module/job/test/model/gettriggerconfig.php
new file mode 100755
index 0000000000..073be0fbf6
--- /dev/null
+++ b/module/job/test/model/gettriggerconfig.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 目录改动(/module/caselib)
+获取job为100001的trigger config >> 0
+
+*/
+$job = new jobTest();
+
+$jobIdList = array('1', '100001');
+
+r($job->getTriggerConfigTest($jobIdList[0])) && p() && e('目录改动(/module/caselib)'); // 获取job为1的trigger config
+r($job->getTriggerConfigTest($jobIdList[1])) && p() && e('0'); // 获取job为100001的trigger config
diff --git a/module/job/test/model/gettriggergroup.php b/module/job/test/model/gettriggergroup.php
new file mode 100755
index 0000000000..8fc8869290
--- /dev/null
+++ b/module/job/test/model/gettriggergroup.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 这是一个Job1
+获取trigger type为commit且repo id为2的name >> 这是一个Job2
+
+*/
+$job = new jobTest();
+
+$triggerTypeList = array('tag', 'commit');
+$repoIdList = array('1', '2');
+
+r($job->getTriggerGroupTest($triggerTypeList['0'], $repoIdList)) && p('1:name') && e('这是一个Job1'); // 获取trigger type为tag且repo id为1的name
+r($job->getTriggerGroupTest($triggerTypeList['1'], $repoIdList)) && p('2:name') && e('这是一个Job2'); // 获取trigger type为commit且repo id为2的name
diff --git a/module/job/test/model/update.php b/module/job/test/model/update.php
new file mode 100755
index 0000000000..ecf25b9d82
--- /dev/null
+++ b/module/job/test/model/update.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新job名称 >> Job更新成功
+测试更新job引擎异常 >> SonarQube工具/框架仅在构建引擎为JenKins的情况下使用
+
+*/
+
+$jobID = 1;
+
+$job_upName = array('name' => '这是一个job11');
+$job_upEngine = array('engine' => 'gitlab');
+
+$job = new jobTest();
+
+r($job->updateObject($jobID, $job_upName)) && p() && e('Job更新成功'); //测试更新job名称
+r($job->updateObject($jobID, $job_upEngine)) && p() && e('SonarQube工具/框架仅在构建引擎为JenKins的情况下使用'); //测试更新job引擎异常
diff --git a/module/kanban/test/kanban.class.php b/module/kanban/test/kanban.class.php
new file mode 100644
index 0000000000..a3bb5b49b7
--- /dev/null
+++ b/module/kanban/test/kanban.class.php
@@ -0,0 +1,1797 @@
+objectModel = $tester->loadModel('kanban');
+ }
+
+ /**
+ * Test create a kanban group.
+ *
+ * @param int $kanbanID
+ * @param int $regionID
+ * @access public
+ * @return object
+ */
+ public function createGroupTest($kanbanID, $regionID)
+ {
+ $objectID = $this->objectModel->createGroup($kanbanID, $regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->findByID($objectID)->from(TABLE_KANBANGROUP)->fetch();
+ return $object;
+ }
+
+ /**
+ * Test create a default kanban region.
+ *
+ * @param int $kanbanID
+ * @access public
+ * @return object
+ */
+ public function createDefaultRegionTest($kanban)
+ {
+ $objectID = $this->objectModel->createDefaultRegion($kanban);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getRegionByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test create a region.
+ *
+ * @param object $kanban
+ * @param object $region
+ * @param int $copyRegionID
+ * @access public
+ * @return object
+ */
+ public function createRegionTest($kanban, $region = null, $copyRegionID = 0)
+ {
+ if(!is_null($region))
+ {
+ if(empty($copyRegionID))
+ {
+ foreach($region as $key => $value) $_POST[$key] = $value;
+ $region = null;
+ }
+
+ $objectID = $this->objectModel->createRegion($kanban, $region, $copyRegionID);
+ }
+ else
+ {
+ $objectID = $this->objectModel->createDefaultRegion($kanban);
+ }
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getRegionByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test create default kanban lanes.
+ *
+ * @param int $regionID
+ * @param int $groupID
+ * @access public
+ * @return object
+ */
+ public function createDefaultLaneTest($regionID, $groupID)
+ {
+ $objectID = $this->objectModel->createDefaultLane(null, $regionID, $groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getLaneByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test create default kanban columns.
+ *
+ * @param int $regionID
+ * @param int $groupID
+ * @access public
+ * @return int
+ */
+ public function createDefaultColumnsTest($regionID, $groupID)
+ {
+ $this->objectModel->createDefaultColumns(null, $regionID, $groupID);
+
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`region`')->eq($regionID)->andWhere('`group`')->eq($groupID)->andWhere('`type`')->like('column%')->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test create a column.
+ *
+ * @param object $param
+ * @access public
+ * @return object
+ */
+ public function createColumnTest($param)
+ {
+ $regionID = 1;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->createColumn($regionID, null, 0, $param->parent);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getColumnByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test split column.
+ *
+ * @param int $columnID
+ * @param array $param
+ * @access public
+ * @return int
+ */
+ public function splitColumnTest($columnID, $param)
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->splitColumn($columnID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $childs = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`parent`')->eq($columnID)->fetchAll();
+ return count($childs);
+ }
+
+ /**
+ * Test create a card.
+ *
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createCardTest($param)
+ {
+ $kanbanID = 1;
+ $regionID = 1;
+ $groupID = 1;
+ $columnID = 1;
+
+ $_POST['lane'] = 1;
+ $_POST['begin'] = date('Y-m-d', strtotime("-3 day"));
+ $_POST['end'] = date('Y-m-d', strtotime("+3 day"));
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->createCard($kanbanID, $regionID, $groupID, $columnID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getCardByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test import card.
+ *
+ * @param int $kanbanID
+ * @param int $regionID
+ * @param int $groupID
+ * @param int $columnID
+ * @param array $cards
+ * @param int $targetLane
+ * @access public
+ * @return object
+ */
+ public function importCardTest($kanbanID, $regionID, $groupID, $columnID, $cards, $targetLane)
+ {
+ $_POST['cards'] = $cards;
+ $_POST['targetLane'] = $targetLane;
+
+ $this->objectModel->importCard($kanbanID, $regionID, $groupID, $columnID);
+
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('`lane`')->eq($targetLane)->andWhere('`column`')->eq($columnID)->andWhere('kanban')->eq($kanbanID)->andWhere('type')->eq('common')->fetch();
+ return $object;
+ }
+
+ /**
+ * Test import object.
+ *
+ * @param int $kanbanID
+ * @param int $regionID
+ * @param int $groupID
+ * @param int $columnID
+ * @param string $objectType
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function importObjectTest($kanbanID, $regionID, $groupID, $columnID, $objectType, $param)
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->importObject($kanbanID, $regionID, $groupID, $columnID, $objectType);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('`lane`')->eq($param['targetLane'])->andWhere('`column`')->eq($columnID)->andWhere('kanban')->eq($kanbanID)->andWhere('type')->eq('common')->fetch();
+ return $object;
+ }
+
+ /**
+ * Test batch create kanban cards.
+ *
+ * @param array $param
+ * @param bool $endLtBegin
+ * @access public
+ * @return object
+ */
+ public function batchCreateCardTest($param = array(), $endLtBegin = false)
+ {
+ $kanbanID = 1;
+ $regionID = 1;
+ $groupID = 1;
+ $columnID = 1;
+ $batchCreateFields['name'] = array('0' => '批量创建卡片1', '1' => '批量创建卡片2', '2' => '批量创建卡片3', '3' => '批量创建卡片4');
+ $batchCreateFields['lane'] = array('0' => '1', '1' => 'ditto', '2' => 'ditto', '3' => 'ditto');
+ $batchCreateFields['assignedTo'] = array();
+ $batchCreateFields['estimate'] = array('0' => '1', '1' => '2', '2' => '3', '3' => '4');
+ $batchCreateFields['begin'] = array('0' => date('Y-m-d', time()), '1' => date('Y-m-d', time()), '2' => '', '3' => '');
+ $batchCreateFields['end'] = !$endLtBegin ? array('0' => date('Y-m-d', time()), '1' => '', '2' => '', '3' => '') : array('0' => date('Y-m-d', strtotime("-1 day")), '1' => date('Y-m-d', strtotime("-1 day")), '2' => date('Y-m-d', strtotime("-2 day")), '3' => date('Y-m-d', strtotime("-3 day")));
+ $batchCreateFields['desc'] = array('0' => '描述1', '1' => '描述2', '2' => '描述3', '3' => '描述4');
+ $batchCreateFields['pri'] = array('0' => '1', '1' => '2', '2' => '3', '3' => '4');
+ $batchCreateFields['beginDitto'] = array('1' => 'on', '2' => 'on', '3' => 'on', '4' => 'on');
+ $batchCreateFields['endDitto'] = array('1' => 'on', '2' => 'on', '3' => 'on', '4' => 'on');
+
+ foreach($batchCreateFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->batchCreateCard($kanbanID, $regionID, $groupID, $columnID);
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->eq($kanbanID)->andWhere('lane')->eq(1)->andWhere('`column`')->eq($columnID)->andWhere('type')->eq('common')->fetch();
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError()[0];
+
+ return $object;
+ }
+
+ /**
+ * Test get kanban by id.
+ *
+ * @param int $kanbanID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($kanbanID)
+ {
+ $object = $this->objectModel->getByID($kanbanID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get kanban data.
+ *
+ * @param int $kanbanID
+ * @access public
+ * @return string
+ */
+ public function getKanbanDataTest($kanbanID)
+ {
+ $objects = $this->objectModel->getKanbanData($kanbanID);
+
+ if(dao::isError()) return dao::getError();
+
+ $columnCount = 0;
+ $laneCount = 0;
+ $cardCount = 0;
+ foreach($objects as $regions)
+ {
+ foreach($regions->groups as $group)
+ {
+ foreach($group->lanes as $lane) $cardCount += count($lane->items);
+
+ $columnCount += count($group->columns);
+ $laneCount += count($group->lanes);
+ }
+ }
+ return 'columns:' . $columnCount . ', lanes:' . $laneCount . ', cards:' . $cardCount;
+ }
+
+ /**
+ * Test get plan kanban.
+ *
+ * @param int $productID
+ * @param int $branchID
+ * @access public
+ * @return string
+ */
+ public function getPlanKanbanTest($productID, $branchID = 0)
+ {
+ global $tester;
+ $product = $tester->loadModel('product')->getByID($productID);
+
+ $tester->loadModel('productplan');
+ $planGroup = $product->type == 'normal' ? $tester->productplan->getList($product->id, 0, 'all', '', 'begin_desc', 'skipparent') : $tester->productplan->getGroupByProduct($product->id, 'skipParent', '', 'begin_desc');
+
+ $objects = $this->objectModel->getPlanKanban($product, $branchID, $planGroup);
+
+ if(dao::isError()) return dao::getError();
+
+ $laneCount = 0;
+ $cardCount = 0;
+ foreach($objects->lanes as $lane)
+ {
+ foreach($lane->items as $item) $cardCount += count($item);
+ }
+ return 'lanes:' . count($objects->lanes) . ', cards:' . $cardCount;
+ }
+
+ /**
+ * Test get a RD kanban data.
+ *
+ * @param int $executionID
+ * @param string $browseType
+ * @param int $regionID
+ * @access public
+ * @return string
+ */
+ public function getRDKanbanTest($executionID, $browseType = 'all', $regionID = 0)
+ {
+ $objects = $this->objectModel->getRDKanban($executionID, $browseType, 'id_desc', $regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ $columnCount = 0;
+ $laneCount = 0;
+ $cardCount = 0;
+ foreach($objects as $regions)
+ {
+ foreach($regions->groups as $group)
+ {
+ $columnCount += count($group->columns);
+ $laneCount += count($group->lanes);
+ foreach($group->lanes as $lane)
+ {
+ foreach($lane->items as $item) $cardCount += count($item);
+ }
+ }
+ }
+ return 'columns:' . $columnCount . ', lanes:' . $laneCount . ', cards:' . $cardCount;
+ }
+
+ /**
+ * Test get region by id.
+ *
+ * @param int $regionID
+ * @access public
+ * @return object
+ */
+ public function getRegionByIDTest($regionID)
+ {
+ $object = $this->objectModel->getRegionByID($regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get ordered region pairs.
+ *
+ * @param int $kanbanID
+ * @param int $regionID
+ * @param string $from
+ * @access public
+ * @return array
+ */
+ public function getRegionPairsTest($kanbanID, $regionID = 0, $from = 'kanban')
+ {
+ $objects = $this->objectModel->getRegionPairs($kanbanID, $regionID, $from);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get kanban id by region id.
+ *
+ * @param int $regionID
+ * @access public
+ * @return int
+ */
+ public function getKanbanIDByRegionTest($regionID)
+ {
+ $object = $this->objectModel->getKanbanIDByRegion($regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get kanban group by regions.
+ *
+ * @param string $regions
+ * @access public
+ * @return int
+ */
+ public function getGroupGroupByRegionsTest($regions)
+ {
+ $objects = $this->objectModel->getGroupGroupByRegions($regions);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ foreach($objects as $object) $count += count($object);
+
+ return $count;
+ }
+
+ public function getLaneGroupByRegionsTest($regions, $browseType = 'all')
+ {
+ $objects = $this->objectModel->getLaneGroupByRegions($regions, $browseType);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ foreach($objects as $object) $count += count($object);
+ return $count;
+ }
+
+ /**
+ * Test get lane pairs by group id.
+ *
+ * @param int $groupID
+ * @param string $orderBy
+ * @access public
+ * @return string
+ */
+ public function getLanePairsByGroupTest($groupID, $orderBy = '`order`_asc')
+ {
+ $objects = $this->objectModel->getLanePairsByGroup($groupID, $orderBy = '`order`_asc');
+
+ if(dao::isError()) return dao::getError();
+
+ $names = implode(',', $objects);
+ return $names;
+ }
+
+ public function getColumnGroupByRegionsTest($regions, $order = 'order')
+ {
+ $objects = $this->objectModel->getColumnGroupByRegions($regions, $order = 'order');
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ foreach($objects as $object) $count += count($object);
+ return $count;
+ }
+
+ /**
+ * Test get card group by kanban id.
+ *
+ * @param int $kanbanID
+ * @access public
+ * @return int
+ */
+ public function getCardGroupByKanbanTest($kanbanID)
+ {
+ $objects = $this->objectModel->getCardGroupByKanban($kanbanID);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get imported cards.
+ *
+ * @param int $kanbanID
+ * @param string $fromType
+ * @param int $archived
+ * @param int $regionID
+ * @access public
+ * @return string
+ */
+ public function getImportedCardsTest($kanbanID, $fromType, $archived = 0, $regionID = 0)
+ {
+ global $tester;
+ $cards = $tester->dao->select('*')->from(TABLE_KANBANCARD)
+ ->where('deleted')->eq(0)
+ ->andWhere('kanban')->eq($kanbanID)
+ ->andWhere('archived')->eq($archived)
+ ->andWhere('fromID')->eq(0)
+ ->beginIF($regionID)->andWhere('region')->eq($regionID)->fi()
+ ->fetchAll('id');
+
+ $objects = $this->objectModel->getImportedCards($kanbanID, $cards, $fromType, $archived, $regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object->id;
+ return $ids;
+ }
+
+ /**
+ * Test get RD column group by regions.
+ *
+ * @param int $regions
+ * @param array $groupIDList
+ * @access public
+ * @return int
+ */
+ public function getRDColumnGroupByRegionsTest($regions, $groupIDList = array())
+ {
+ $objects = $this->objectModel->getRDColumnGroupByRegions($regions, $groupIDList);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ foreach($objects as $object) $count += count($object);
+ return $count;
+ }
+
+ /**
+ * Test get card group by execution id.
+ *
+ * @param int $executionID
+ * @param string $browseType
+ * @param string $orderBy
+ * @access public
+ * @return int
+ */
+ public function getCardGroupByExecutionTest($executionID, $browseType = 'all')
+ {
+ $objects = $this->objectModel->getCardGroupByExecution($executionID, $browseType);
+
+ if(dao::isError()) return dao::getError();
+
+ $cardCount = 0;
+ foreach($objects as $lane)
+ {
+ foreach($lane as $type) $cardCount += count($type);
+ }
+ return $cardCount;
+ }
+
+ /**
+ * Test get Kanban by execution id.
+ *
+ * @param int $executionID
+ * @param string $browseType
+ * @param string $groupBy
+ * @access public
+ * @return string
+ */
+ public function getExecutionKanbanTest($executionID, $browseType = 'all', $groupBy = 'default')
+ {
+ $objects = $this->objectModel->getExecutionKanban($executionID, $browseType, $groupBy);
+
+ if(empty($objects))
+ {
+ $this->objectModel->createExecutionLane($executionID, $browseType, $groupBy);
+ $objects = $this->objectModel->getExecutionKanban($executionID, $browseType, $groupBy);
+ }
+
+ if(dao::isError()) return dao::getError();
+
+ $columnCount = 0;
+ $laneCount = 0;
+ $cardCount = 0;
+ foreach($objects as $types)
+ {
+ foreach($types['lanes'] as $lane)
+ {
+ foreach($lane['cards'] as $card) $cardCount += count($card);
+ }
+ $columnCount += count($types['columns']);
+ $laneCount += count($types['lanes']);
+ }
+ return 'columns:' . $columnCount . ', lanes:' . $laneCount . ', cards:' . $cardCount;
+ }
+
+ /**
+ * Test get kanban for group view.
+ *
+ * @param int $executionID
+ * @param string $browseType
+ * @param string $groupBy
+ * @access public
+ * @return int
+ */
+ public function getKanban4GroupTest($executionID, $browseType, $groupBy)
+ {
+ $objects = $this->objectModel->getKanban4Group($executionID, $browseType, $groupBy);
+
+ if(empty($objects))
+ {
+ $this->objectModel->createExecutionLane($executionID, $browseType, $groupBy);
+ $objects = $this->objectModel->getKanban4Group($executionID, $browseType, $groupBy);
+ }
+
+ if(dao::isError()) return dao::getError();
+
+ $laneCount = 0;
+ foreach($objects as $types) $laneCount += count($types['lanes']);
+
+ return 'lanes:' . $laneCount;
+ }
+
+ /**
+ * Test get kanban for group view.
+ *
+ * @param int $executionID
+ * @param string $browseType
+ * @param string $groupBy
+ * @access public
+ * @return void
+ */
+ public function getLanes4GroupTest($executionID, $browseType, $groupBy)
+ {
+ global $tester;
+ /* Get group objects. */
+ if($browseType == 'story') $cardList = $tester->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
+ if($browseType == 'bug') $cardList = $tester->loadModel('bug')->getExecutionBugs($executionID);
+ if($browseType == 'task') $cardList = $tester->loadModel('execution')->getKanbanTasks($executionID, "id");
+ $objects = $this->objectModel->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
+
+ if(empty($objects))
+ {
+ $this->objectModel->createExecutionLane($executionID, $browseType, $groupBy);
+ $objects = $this->objectModel->getLanes4Group($executionID, $browseType, $groupBy);
+ }
+
+ if(dao::isError()) return dao::getError();
+
+ $names = '';
+ foreach($objects as $object) $names .= ',' . $object->name;
+ return $names;
+ }
+
+ /**
+ * Test get space list.
+ *
+ * @param string $user
+ * @param string $browseType
+ * @access public
+ * @return int
+ */
+ public function getSpaceListTest($user, $browseType)
+ {
+ su($user);
+ $objects = $this->objectModel->getSpaceList($browseType);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get space pairs.
+ *
+ * @param int $user
+ * @param string $browseType
+ * @access public
+ * @return int
+ */
+ public function getSpacePairsTest($user, $browseType = 'private')
+ {
+ su($user);
+ $objects = $this->objectModel->getSpacePairs($browseType);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get Kanban pairs.
+ *
+ * @param string $user
+ * @access public
+ * @return int
+ */
+ public function getKanbanPairsTest($user)
+ {
+ su($user);
+ $objects = $this->objectModel->getKanbanPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get can view objects.
+ *
+ * @param string $user
+ * @param string $objectType
+ * @param string $param
+ * @access public
+ * @return void
+ */
+ public function getCanViewObjectsTest($user, $objectType = 'kanban', $param = '')
+ {
+ su($user);
+ $objects = $this->objectModel->getCanViewObjects($objectType, $param);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test create a space.
+ *
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createSpaceTest($param)
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->createSpace();
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getSpaceByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test update a space.
+ *
+ * @param int $spaceID
+ * @param string $type
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateSpaceTest($spaceID, $type = '', $param = array())
+ {
+ global $tester;
+ $object = $tester->dao->select('`type`,`name`,`owner`,`team`,`desc`,`whitelist`')->from(TABLE_KANBANSPACE)->where('`id`')->eq($spaceID)->fetch();
+ $object->team = explode(',', $object->team);
+ $object->whitelist = explode(',', $object->whitelist);
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $this->objectModel->updateSpace($spaceID, $type);
+ if($change == array()) $change = '没有数据更新';
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test get lane pairs by region id.
+ *
+ * @param int $regionID
+ * @param string $type
+ * @access public
+ * @return string
+ */
+ public function getLanePairsByRegionTest($regionID, $type = 'all')
+ {
+ global $tester;
+
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->getLanePairsByRegion($regionID, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ $names = implode(',', $objects);
+ return $names;
+ }
+
+ /**
+ * Test get lane group by regionid.
+ *
+ * @param int $regionID
+ * @param string $type
+ * @access public
+ * @return int
+ */
+ public function getLaneGroupByRegionTest($regionID, $type = 'all')
+ {
+ $objects = $this->objectModel->getLaneGroupByRegion($regionID, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects[$regionID]);
+ }
+
+ /**
+ * Test create a lane.
+ *
+ * @param object $object
+ * @param int $kanbanID
+ * @param int $regionID
+ * @access public
+ * @return object
+ */
+ public function createLaneTest($object, $kanbanID, $regionID)
+ {
+ $lane = isset($object->id) ? $this->objectModel->getLaneByID($object->id) : null;
+ unset($object->id);
+ unset($lane->id);
+
+ foreach($object as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->createLane($kanbanID, $regionID, $lane);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getLaneByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test create a kanban.
+ *
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createTest($param = array())
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create();
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($objectID);
+ return $object;
+ }
+
+ /**
+ * Test update a kanban.
+ *
+ * @param int $kanbanID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateTest($kanbanID, $param)
+ {
+ global $tester;
+ $object = $tester->dao->select('`space`,`name`,`owner`,`team`,`desc`')->from(TABLE_KANBAN)->where('`id`')->eq($kanbanID)->fetch();
+ $object->team = explode(',', $object->team);
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $this->objectModel->update($kanbanID);
+ if($change == array()) $change = '没有数据更新';
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test add execution Kanban lanes and columns.
+ *
+ * @param int $executionID
+ * @param string $type
+ * @param string $groupBy
+ * @access public
+ * @return int
+ */
+ public function createExecutionLaneTest($executionID, $type = 'all', $groupBy = 'default')
+ {
+ $this->objectModel->createExecutionLane($executionID, $type, $groupBy);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANLANE)
+ ->where('execution')->eq($executionID)
+ ->beginIF($type != 'all')->andWhere('type')->eq($type)->fi()
+ ->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test create execution columns.
+ *
+ * @param int $laneID
+ * @param string $type
+ * @param int $executionID
+ * @access public
+ * @return int
+ */
+ public function createExecutionColumnsTest($laneID, $type, $executionID)
+ {
+ $this->objectModel->createExecutionColumns($laneID, $type, $executionID);
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)
+ ->where('kanban')->eq($executionID)
+ ->andWhere('lane')->eq($laneID)
+ ->andWhere('type')->eq($type)
+ ->fetchAll();
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test add kanban cell.
+ *
+ * @param int $kanbanID
+ * @param int $laneID
+ * @param int $colID
+ * @param int $type
+ * @param int $cardID
+ * @access public
+ * @return object
+ */
+ public function addKanbanCellTest($kanbanID, $laneID, $colID, $type, $cardID = 0)
+ {
+ $this->objectModel->addKanbanCell($kanbanID, $laneID, $colID, $type, $cardID);
+
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->eq($kanbanID)->andWhere('lane')->eq($laneID)->andWhere('`column`')->eq($colID)->andWhere('type')->eq($type)->fetch();
+ return $object;
+ }
+
+ /**
+ * Test remove kanban cell.
+ *
+ * @param string $type
+ * @param int $removeCardID
+ * @param array $kanbanList
+ * @access public
+ * @return string
+ */
+ public function removeKanbanCellTest($type, $removeCardID, $kanbanList)
+ {
+ $this->objectModel->removeKanbanCell($type, $removeCardID, $kanbanList);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->in($kanbanList)->andWhere('type')->eq($type)->fetchAll();
+ $cards = '';
+ foreach($objects as $object) $cards .= $object->id . ':' . $object->cards . '; ';
+ $cards = trim($cards, '; ');
+ $cards = str_replace(':,', ':', $cards);
+ $cards = str_replace(':;', ';', $cards);
+ return $cards;
+ }
+
+ /**
+ * Test create rd kanban.
+ *
+ * @param object $execution
+ * @access public
+ * @return string
+ */
+ public function createRDKanbanTest($execution)
+ {
+ $this->objectModel->createRDKanban($execution);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $regions = $tester->dao->select('*')->from(TABLE_KANBANREGION)->where('`kanban`')->eq($execution->id)->fetchAll('id');
+ $lanes = $tester->dao->select('*')->from(TABLE_KANBANLANE)->where('`execution`')->eq($execution->id)->andWhere('`type`')->ne('common')->fetchAll('id');
+ $regionIDList = implode($regions, ',');
+ $columns = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`region`')->in($regionIDList)->fetchAll('id');
+ return count($regions) . ',' . count($lanes) . ',' . count($columns);
+ }
+
+ /**
+ * Test create default RD region.
+ *
+ * @param object $execution
+ * @access public
+ * @return object
+ */
+ public function createRDRegionTest($execution)
+ {
+ $objectID = $this->objectModel->createRDRegion($execution);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getRegionByID($objectID);
+ return $object;
+ }
+
+ /**
+ *
+ * Test create default RD lanes.
+ *
+ * @param int $executionID
+ * @param int $regionID
+ * @access public
+ * @return int
+ */
+ public function createRDLaneTest($executionID, $regionID)
+ {
+ $this->objectModel->createRDLane($executionID, $regionID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANLANE)->where('`region`')->eq($regionID)->andWhere('`execution`')->eq($executionID)->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test create default RD columns.
+ *
+ * @param int $regionID
+ * @param int $groupID
+ * @param int $laneID
+ * @param string $laneType
+ * @param int $executionID
+ * @access public
+ * @return int
+ */
+ public function createRDColumnTest($regionID, $groupID, $laneID, $laneType, $executionID)
+ {
+ $this->objectModel->createRDColumn($regionID, $groupID, $laneID, $laneType, $executionID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`region`')->eq($regionID)->andWhere('`group`')->eq($groupID)->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test update a region.
+ *
+ * @param int $regionID
+ * @param string $name
+ * @access public
+ * @return array
+ */
+ public function updateRegionTest($regionID, $name)
+ {
+ $_POST['name'] = $name;
+
+ $change = $this->objectModel->updateRegion($regionID);
+ if($change == array()) $change = '没有数据更新';
+
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test update kanban lane.
+ *
+ * @param int $executionID
+ * @param string $laneType
+ * @param int $cardID
+ * @access public
+ * @return string
+ */
+ public function updateLaneTest($executionID, $laneType, $cardID = 0)
+ {
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANLANE)->where('type')->ne('common')->andWhere('execution')->eq($executionID)->fetch();
+ if(empty($objects)) $this->objectModel->createExecutionLane($executionID);
+
+ $this->objectModel->updateLane($executionID, $laneType, $cardID);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('kanban')->eq($executionID)->andWhere('type')->eq($laneType)->fetchAll();
+ $cards = '';
+ foreach($objects as $object) $cards .= $object->cards;
+ $cards = preg_replace('#,+#', ',', $cards);
+ return $cards;
+ }
+
+ /**
+ * Test refresh column cards.
+ *
+ * @param int $laneID
+ * @access public
+ * @return string
+ */
+ public function refreshCardsTest($laneID)
+ {
+ $lane = $this->objectModel->getLaneByID($laneID);
+ $this->objectModel->refreshCards($lane);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('`lane`')->eq($laneID)->fetchAll();
+
+ $cards = '';
+ foreach($objects as $object) $cards .= $object->id . ':' . $object->cards . '; ';
+ $cards = trim($cards, '; ');
+ $cards = str_replace(':,', ':', $cards);
+ $cards = str_replace(':;', ';', $cards);
+ return $cards;
+ }
+
+ /**
+ * Test update a column.
+ *
+ * @param int $columnID
+ * @param string $name
+ * @param string $color
+ * @access public
+ * @return array
+ */
+ public function updateLaneColumnTest($columnID, $name, $color)
+ {
+ $_POST['name'] = $name;
+ $_POST['color'] = $color;
+
+ $column = $this->objectModel->getColumnByID($columnID);
+ $change = $this->objectModel->updateLaneColumn($columnID, $column);
+ if($change == array()) $change = '没有数据更新';
+
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test activate a card.
+ *
+ * @param int $cardID
+ * @param int $progress
+ * @access public
+ * @return object
+ */
+ public function activateCardTest($cardID, $progress)
+ {
+ global $tester;
+ $tester->post->progress = $progress;
+
+ $this->objectModel->activateCard($cardID);
+
+ unset($this->post);
+
+ if(dao::isError()) return dao::getError()[0];
+
+ $object = $this->objectModel->getCardByID($cardID);
+ return $object;
+ }
+
+ /**
+ * Test update a card.
+ *
+ * @param int $cardID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateCardTest($cardID, $param)
+ {
+ global $tester;
+ $object = $tester->dao->select('`name`,`desc`,`assignedTo`,`begin`,`end`,`pri`,`estimate`, `progress`')->from(TABLE_KANBANCARD)->where('`id`')->eq($cardID)->fetch();
+ $object->assignedTo = explode(',', $object->assignedTo);
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $this->objectModel->updateCard($cardID);
+ if($change == array()) $change = '没有数据更新';
+ unset($_POST);
+
+
+ if(dao::isError()) return dao::getError()[0];
+
+ return $change;
+ }
+
+ /**
+ * Test set WIP.
+ *
+ * @param int $columnID
+ * @param int $limit
+ * @param int $WIPCount
+ * @access public
+ * @return object
+ */
+ public function setWIPTest($columnID, $limit, $WIPCount)
+ {
+ $_POST['limit'] = $limit;
+ if($WIPCount == '-1') $_POST['WIPCount'] = $WIPCount;
+ if($WIPCount == '-1') $_POST['noLimit'] = $WIPCount;
+
+ $this->objectModel->setWIP($columnID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getColumnByID($columnID);
+ return $object;
+ }
+
+ /**
+ * Test set a lane.
+ *
+ * @param int $laneID
+ * @access public
+ * @return object
+ */
+ public function setLaneTest($laneID, $name, $color)
+ {
+ $_POST['name'] = $name;
+ $_POST['color'] = $color;
+
+ $this->objectModel->setLane($laneID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getLaneByID($laneID);
+ return $object;
+ }
+
+ /**
+ * Test set kanban lane height.
+ *
+ * @param int $kanbanID
+ * @param string $heightType
+ * @param int $displayCards
+ * @param string $from
+ * @access public
+ * @return object
+ */
+ public function setLaneHeightTest($kanbanID, $heightType, $displayCards, $from = 'kanban')
+ {
+ $_POST['heightType'] = $heightType;
+ $_POST['displayCards'] = $displayCards;
+
+ $this->objectModel->setLaneHeight($kanbanID, $from);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $table = $tester->config->objectTables[$from];
+ $object = $tester->dao->select('*')->from($table)->where('id')->eq($kanbanID)->fetch();
+ return $object;
+ }
+
+ /**
+ * Test set column width.
+ *
+ * @param int $kanbanID
+ * @param string $from
+ * @access public
+ * @return object
+ */
+ public function setColumnWidthTest($kanbanID, $fluidBoard, $from = 'kanban')
+ {
+ $_POST['fluidBoard'] = $fluidBoard;
+
+ $this->objectModel->setColumnWidth($kanbanID, $from);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $table = $tester->config->objectTables[$from];
+ $object = $tester->dao->select('*')->from($table)->where('id')->eq($kanbanID)->fetch();
+ return $object;
+ }
+
+ /**
+ * Test sort kanban group;
+ *
+ * @param int $region
+ * @param array $groups
+ * @access public
+ * @return string
+ */
+ public function sortGroupTest($region, $groups)
+ {
+ $this->objectModel->sortGroup($region, $groups);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANGROUP)->where('region')->eq($region)->orderBy('order_asc')->fetchAll('id');
+ return implode(array_keys($objects), ',');
+ }
+
+ /**
+ * Test move a card.
+ *
+ * @param int $cardID
+ * @param int $fromColID
+ * @param int $toColID
+ * @param int $fromLaneID
+ * @param int $toLaneID
+ * @param int $kanbanID
+ * @access public
+ * @return object
+ */
+ public function moveCardTest($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID = 0)
+ {
+ $objects = $this->objectModel->moveCard($cardID, $fromColID, $toColID, $fromLaneID, $toLaneID, $kanbanID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('`lane`')->eq($toLaneID)->andWhere('`column`')->eq($toColID)->andWhere('`type`')->eq('common')->fetch();
+ return $object;
+ }
+
+ /**
+ * Test update a card's color.
+ *
+ * @param int $cardID
+ * @param string $color
+ * @access public
+ * @return object
+ */
+ public function updateCardColorTest($cardID, $color)
+ {
+ $this->objectModel->updateCardColor($cardID, $color);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getCardByID($cardID);
+ return $object;
+ }
+
+ /**
+ * Test archive a column.
+ *
+ * @param int $columnID
+ * @access public
+ * @return array
+ */
+ public function archiveColumnTest($columnID)
+ {
+ $this->objectModel->archiveColumn($columnID);
+
+ $object = $this->objectModel->getColumnByID($columnID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test restore a column.
+ *
+ * @param int $columnID
+ * @access public
+ * @return object
+ */
+ public function restoreColumnTest($columnID)
+ {
+ $this->objectModel->restoreColumn($columnID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $object = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`id`')->eq($columnID)->fetch();
+ return $object;
+ }
+
+ /**
+ * Test archive a card.
+ *
+ * @param int $cardID
+ * @access public
+ * @return array
+ */
+ public function archiveCardTest($cardID)
+ {
+ $changes = $this->objectModel->archiveCard($cardID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $changes;
+ }
+
+ /**
+ * Test restore a card.
+ *
+ * @param int $cardID
+ * @access public
+ * @return array
+ */
+ public function restoreCardTest($cardID)
+ {
+ $objects = $this->objectModel->restoreCard($cardID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function processCardsTest($columnID)
+ {
+ $column = $this->objectModel->getColumnByID($columnID);
+ $this->objectModel->processCards($column);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $nodes = $tester->dao->select('*')->from(TABLE_KANBANCOLUMN)->where('`parent`')->eq($column->parent)->andWhere('`id`')->ne($columnID)->fetchAll('id');
+ $objects = $tester->dao->select('*')->from(TABLE_KANBANCELL)->where('`column`')->in(array_keys($nodes))->fetchAll();
+
+ $cards = '';
+ foreach($objects as $object) $cards .= $object->id . ':' . $object->cards . '; ';
+ $cards = trim($cards, '; ');
+ return $cards;
+ }
+
+ /**
+ * Test get space by id.
+ *
+ * @param int $spaceID
+ * @access public
+ * @return object
+ */
+ public function getSpaceByIdTest($spaceID)
+ {
+ $object = $this->objectModel->getSpaceById($spaceID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get kanban group by space id list.
+ *
+ * @param string $spaceIdList
+ * @param string $kanbanIdList
+ * @access public
+ * @return int
+ */
+ public function getGroupBySpaceListTest($spaceIdList, $kanbanIdList = '')
+ {
+ $objects = $this->objectModel->getGroupBySpaceList($spaceIdList, $kanbanIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ if(empty($kanbanIdList))
+ {
+ foreach($objects as $object) $count += count($object);
+ }
+ else
+ {
+ $count += count($objects);
+ }
+ return $count;
+ }
+
+ /**
+ * Test get group list by region id.
+ *
+ * @param int $region
+ * @access public
+ * @return object
+ */
+ public function getGroupListTest($region)
+ {
+ $objects = $this->objectModel->getGroupList($region);
+
+ if(dao::isError()) return dao::getError();
+
+ $kanban = '';
+ foreach($objects as $object) $kanban .= ',' . $object->kanban;
+ return $kanban;
+ }
+
+ /**
+ * Test get column by id.
+ *
+ * @param int $columnID
+ * @access public
+ * @return object
+ */
+ public function getColumnByIDTest($columnID)
+ {
+ $object = $this->objectModel->getColumnByID($columnID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get columns by object id.
+ *
+ * @param string $objectType
+ * @param int $objectID
+ * @param int $archived
+ * @param string $deleted
+ * @access public
+ * @return int
+ */
+ public function getColumnsByObjectTest($objectType = '', $objectID = 0, $archived = 0, $deleted = '0')
+ {
+ $objects = $this->objectModel->getColumnsByObject($objectType, $objectID, $archived, $deleted);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get column ID by lane ID.
+ *
+ * @param int $laneID
+ * @param string $columnType
+ * @access public
+ * @return string
+ */
+ public function getColumnIDByLaneIDTest($laneID, $columnType)
+ {
+ $object = $this->objectModel->getColumnIDByLaneID($laneID, $columnType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get lane by id.
+ *
+ * @param int $laneID
+ * @access public
+ * @return object
+ */
+ public function getLaneByIdTest($laneID)
+ {
+ $object = $this->objectModel->getLaneById($laneID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get object group list.
+ *
+ * @param int $executionID
+ * @param string $type
+ * @param string $groupBy
+ * @access public
+ * @return array
+ */
+ public function getObjectGroupTest($executionID, $type, $groupBy)
+ {
+ $objects = $this->objectModel->getObjectGroup($executionID, $type, $groupBy);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = implode(',', $objects);
+ return $objects;
+ }
+
+ /**
+ * Test get card by id.
+ *
+ * @param int $cardID
+ * @access public
+ * @return object
+ */
+ public function getCardByIDTest($cardID)
+ {
+ $object = $this->objectModel->getCardByID($cardID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get cards by object id.
+ *
+ * @param string $objectType
+ * @param int $objectID
+ * @param string $archived
+ * @param string $deleted
+ * @access public
+ * @return int
+ */
+ public function getCardsByObjectTest($objectType = '', $objectID = 0, $archived = '0', $deleted = '0')
+ {
+ $objects = $this->objectModel->getCardsByObject($objectType, $objectID, $archived, $deleted);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get cards to import.
+ *
+ * @param int $kanbanID
+ * @param int $excludedID
+ * @param object $pager
+ * @access public
+ * @return int
+ */
+ public function getCards2ImportTest($kanbanID = 0, $excludedID = 0, $pager = null)
+ {
+ $objects = $this->objectModel->getCards2Import($kanbanID, $excludedID, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get Kanban cards menus by execution id.
+ *
+ * @param int $executionID
+ * @param string $objecType
+ * @access public
+ * @return int
+ */
+ public function getKanbanCardMenuTest($executionID, $objecType)
+ {
+ global $tester;
+ /* Get group objects. */
+ if($objecType == 'story') $objectGroup['story'] = $tester->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
+ if($objecType == 'bug') $objectGroup['bug'] = $tester->loadModel('bug')->getExecutionBugs($executionID);
+ if($objecType == 'task') $objectGroup['task'] = $tester->loadModel('execution')->getKanbanTasks($executionID, "id");
+
+ $objects = array();
+ /* Get objects cards menus. */
+ if($objecType == 'story') $objects = $this->objectModel->getKanbanCardMenu($executionID, $objectGroup['story'], 'story');
+ if($objecType == 'bug') $objects = $this->objectModel->getKanbanCardMenu($executionID, $objectGroup['bug'], 'bug');
+ if($objecType == 'task') $objects = $this->objectModel->getKanbanCardMenu($executionID, $objectGroup['task'], 'task');
+
+ if(dao::isError()) return dao::getError();
+
+ $count = 0;
+ foreach($objects as $object) $count += count($object);
+ return $count;
+ }
+
+ /**
+ * Get toList and ccList.
+ *
+ * @param object $card
+ * @access public
+ * @return array
+ */
+ public function getToAndCcListTest($card)
+ {
+ $objects = $this->objectModel->getToAndCcList($card);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check if user can execute an action.
+ *
+ * @param string $objectType
+ * @param int $objectID
+ * @param string $action
+ * @access public
+ * @return int
+ */
+ public function isClickableTest($objectType, $objectID, $action)
+ {
+ $functionName = 'get' . $objectType . 'ById';
+ $object = $this->objectModel->$functionName($objectID);
+
+ $result = $this->objectModel->isClickable($object, $action);
+
+ if(dao::isError()) return dao::getError();
+
+ return $result ? 1 : 2;
+ }
+
+ /**
+ * Test import.
+ *
+ * @param int $kanbanID
+ * @access public
+ * @return object
+ */
+ public function importTest($kanbanID, $import, $importObjectList)
+ {
+ $_POST['import'] = $import;
+ $_POST['importObjectList'] = $importObjectList;
+
+ $this->objectModel->import($kanbanID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($kanbanID);
+ $object->object = !empty($object->object) ? $object->object : 0;
+ return $object;
+ }
+}
diff --git a/module/kanban/test/model/activatecard.php b/module/kanban/test/model/activatecard.php
new file mode 100755
index 0000000000..0f11e1f3b0
--- /dev/null
+++ b/module/kanban/test/model/activatecard.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+activateCard();
+cid=1
+pid=1
+
+测试激活卡片1,进度0 >> 1,卡片1,doing,0
+测试激活卡片1,进度50 >> 1,卡片1,doing,50
+测试激活卡片1,进度100 >> 请输入正确的进度
+测试激活卡片1,进度101 >> 请输入正确的进度
+测试激活卡片1,进度-1 >> 请输入正确的进度
+测试激活卡片2,进度0 >> 2,卡片2,doing,0
+测试激活卡片3,进度0 >> 3,卡片3,doing,50
+测试激活卡片4,进度0 >> 4,卡片4,doing,0
+测试激活卡片5,进度0 >> 5,卡片5,doing,50
+测试激活不存在的卡片,进度0 >> 0
+
+*/
+
+$cardIDList = array('1', '2', '3', '4', '5', '100001');
+$progressList = array('0', '50', '100', '101', '-1');
+
+$kanban = new kanbanTest();
+
+r($kanban->activateCardTest($cardIDList[0], $progressList[0])) && p('id,name,status,progress') && e('1,卡片1,doing,0'); // 测试激活卡片1,进度0
+r($kanban->activateCardTest($cardIDList[0], $progressList[1])) && p('id,name,status,progress') && e('1,卡片1,doing,50'); // 测试激活卡片1,进度50
+r($kanban->activateCardTest($cardIDList[0], $progressList[2])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度100
+r($kanban->activateCardTest($cardIDList[0], $progressList[3])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度101
+r($kanban->activateCardTest($cardIDList[0], $progressList[4])) && p('0:') && e('请输入正确的进度'); // 测试激活卡片1,进度-1
+r($kanban->activateCardTest($cardIDList[1], $progressList[0])) && p('id,name,status,progress') && e('2,卡片2,doing,0'); // 测试激活卡片2,进度0
+r($kanban->activateCardTest($cardIDList[2], $progressList[1])) && p('id,name,status,progress') && e('3,卡片3,doing,50'); // 测试激活卡片3,进度0
+r($kanban->activateCardTest($cardIDList[3], $progressList[0])) && p('id,name,status,progress') && e('4,卡片4,doing,0'); // 测试激活卡片4,进度0
+r($kanban->activateCardTest($cardIDList[4], $progressList[1])) && p('id,name,status,progress') && e('5,卡片5,doing,50'); // 测试激活卡片5,进度0
+r($kanban->activateCardTest($cardIDList[5], $progressList[0])) && p('id,name,status,progress') && e('0'); // 测试激活不存在的卡片,进度0
diff --git a/module/kanban/test/model/addkanbancell.php b/module/kanban/test/model/addkanbancell.php
new file mode 100755
index 0000000000..1297d43e41
--- /dev/null
+++ b/module/kanban/test/model/addkanbancell.php
@@ -0,0 +1,55 @@
+#!/usr/bin/env php
+addKanbanCell();
+cid=1
+pid=1
+
+更新类型为common的kanbancell >> common,,0,1,2,
+更新类型为common的kanbancell 有cardID >> common,,3,0,1,2,
+插入类型为common的kanbancell >> common,
+插入类型为common的kanbancell 有cardID >> common,,3,
+更新类型为story的kanbancell >> story,,0,
+更新类型为story的kanbancell 有cardID >> story,,3,0,
+插入类型为story的kanbancell >> story,
+插入类型为story的kanbancell 有cardID >> story,,3,
+更新类型为bug的kanbancell >> bug,,0,
+更新类型为bug的kanbancell 有cardID >> bug,,3,0,
+插入类型为bug的kanbancell >> bug,
+插入类型为bug的kanbancell 有cardID >> bug,,3,
+更新类型为task的kanbancell >> task,,0,
+更新类型为task的kanbancell 有cardID >> task,,3,0,
+插入类型为task的kanbancell >> task,
+插入类型为task的kanbancell 有cardID >> task,,3,
+
+*/
+
+$kanban = new kanbanTest();
+
+$kanbanIDList = array('1', '161');
+$laneIDList = array('1', '101', '102', '103');
+$columnIDList = array('1', '408', '412', '421');
+$typeList = array('common', 'story', 'bug', 'task');
+$cardID = '3';
+
+r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[0], $columnIDList[0], $typeList[0])) && p('type,cards') && e('common,,0,1,2,'); // 更新类型为common的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[0], $columnIDList[0], $typeList[0], $cardID)) && p('type,cards') && e('common,,3,0,1,2,'); // 更新类型为common的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[1], $columnIDList[0], $typeList[0])) && p('type,cards') && e('common,'); // 插入类型为common的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[0], $laneIDList[1], $columnIDList[0], $typeList[0], $cardID)) && p('type,cards') && e('common,,3,'); // 插入类型为common的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[1], $typeList[1])) && p('type,cards') && e('story,,0,'); // 更新类型为story的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[1], $typeList[1], $cardID)) && p('type,cards') && e('story,,3,0,'); // 更新类型为story的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[2], $typeList[1])) && p('type,cards') && e('story,'); // 插入类型为story的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[1], $columnIDList[2], $typeList[1], $cardID)) && p('type,cards') && e('story,,3,'); // 插入类型为story的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[2], $typeList[2])) && p('type,cards') && e('bug,,0,'); // 更新类型为bug的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[2], $typeList[2], $cardID)) && p('type,cards') && e('bug,,3,0,'); // 更新类型为bug的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[3], $typeList[2])) && p('type,cards') && e('bug,'); // 插入类型为bug的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[2], $columnIDList[3], $typeList[2], $cardID)) && p('type,cards') && e('bug,,3,'); // 插入类型为bug的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[3], $typeList[3])) && p('type,cards') && e('task,,0,'); // 更新类型为task的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[3], $typeList[3], $cardID)) && p('type,cards') && e('task,,3,0,'); // 更新类型为task的kanbancell 有cardID
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[0], $typeList[3])) && p('type,cards') && e('task,'); // 插入类型为task的kanbancell
+r($kanban->addKanbanCellTest($kanbanIDList[1], $laneIDList[3], $columnIDList[0], $typeList[3], $cardID)) && p('type,cards') && e('task,,3,'); // 插入类型为task的kanbancell 有cardID
diff --git a/module/kanban/test/model/archivecard.php b/module/kanban/test/model/archivecard.php
new file mode 100755
index 0000000000..eed8a3445a
--- /dev/null
+++ b/module/kanban/test/model/archivecard.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+archiveCard();
+cid=1
+pid=1
+
+测试归档卡片1 >> archived,0,1
+测试归档卡片2 >> archived,0,1
+测试归档卡片3 >> archived,0,1
+测试归档卡片4 >> archived,0,1
+测试归档卡片5 >> archived,0,1
+
+*/
+
+$cardIDList = array('1', '2', '3', '4', '5');
+
+$kanban = new kanbanTest();
+
+r($kanban->archiveCardTest($cardIDList[0])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片1
+r($kanban->archiveCardTest($cardIDList[1])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片2
+r($kanban->archiveCardTest($cardIDList[2])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片3
+r($kanban->archiveCardTest($cardIDList[3])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片4
+r($kanban->archiveCardTest($cardIDList[4])) && p('0:field,old,new') && e('archived,0,1'); // 测试归档卡片5
diff --git a/module/kanban/test/model/archivecolumn.php b/module/kanban/test/model/archivecolumn.php
new file mode 100755
index 0000000000..a262f05b07
--- /dev/null
+++ b/module/kanban/test/model/archivecolumn.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+archiveColumn();
+cid=1
+pid=1
+
+测试归档列1 >> 1,1
+测试归档列2 >> 2,1
+测试归档列3 >> 3,1
+测试归档列4 >> 4,1
+测试归档列5 >> 5,1
+测试归档不存在的列 >> 0
+
+*/
+
+$columnIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->archiveColumnTest($columnIDList[0])) && p('id,archived') && e('1,1'); // 测试归档列1
+r($kanban->archiveColumnTest($columnIDList[1])) && p('id,archived') && e('2,1'); // 测试归档列2
+r($kanban->archiveColumnTest($columnIDList[2])) && p('id,archived') && e('3,1'); // 测试归档列3
+r($kanban->archiveColumnTest($columnIDList[3])) && p('id,archived') && e('4,1'); // 测试归档列4
+r($kanban->archiveColumnTest($columnIDList[4])) && p('id,archived') && e('5,1'); // 测试归档列5
+r($kanban->archiveColumnTest($columnIDList[5])) && p() && e('0'); // 测试归档不存在的列
diff --git a/module/kanban/test/model/batchcreatecard.php b/module/kanban/test/model/batchcreatecard.php
new file mode 100755
index 0000000000..98e7894469
--- /dev/null
+++ b/module/kanban/test/model/batchcreatecard.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+batchCreateCard();
+cid=1
+pid=1
+
+批量创建卡片 其中一个没有名称 >> 1,1,1,common,,1003,1002,1001,1,2,801,
+批量创建卡片 预计为负数 >> 预计不能为负数!
+批量创建看板 截止日期小于开始日期 >> "截止日期"不能小于"预计开始"!
+批量创建看板 >> 1,1,1,common,,1010,1009,1008,1007,1004,1003,1002,1001,1,2,801,
+
+*/
+
+$no_name = array('0' => '', '1' => '批量创建的卡片2', '2' => '批量创建的卡片3', '3' => '批量创建的卡片4');
+$estimate = array('0' => '1', '1' => '-1', '2' => '-2', '3' => '-3');
+$endDitto = array('1' => 'off', '2' => 'off', '3' => 'off', '4' => 'off');
+
+$kanban = new kanbanTest();
+
+r($kanban->batchCreateCardTest(array('name' => $no_name))) && p('kanban,column,lane,type,cards') && e('1,1,1,common,,1003,1002,1001,1,2,801,'); // 批量创建卡片 其中一个没有名称
+r($kanban->batchCreateCardTest(array('estimate' => $estimate))) && p() && e('预计不能为负数!'); // 批量创建卡片 预计为负数
+r($kanban->batchCreateCardTest(array(), true)) && p() && e('"截止日期"不能小于"预计开始"!'); // 批量创建看板 截止日期小于开始日期
+r($kanban->batchCreateCardTest()) && p('kanban,column,lane,type,cards') && e('1,1,1,common,,1010,1009,1008,1007,1004,1003,1002,1001,1,2,801,'); // 批量创建看板
diff --git a/module/kanban/test/model/create.php b/module/kanban/test/model/create.php
new file mode 100755
index 0000000000..e6f743631c
--- /dev/null
+++ b/module/kanban/test/model/create.php
@@ -0,0 +1,77 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+创建协同空间 >> 测试创建协作看板,1,,po15,
+创建私人空间 >> 测试创建私人看板,2,,admin,,user4
+创建公共空间 >> 测试创建公共看板,3,,po17,
+创建没有名字的公共空间 >> 『看板名称』不能为空。
+创建没有空间公共空间 >> 『所属空间』不能为空。
+创建重名公共空间 >> 『看板名称』已经有『测试创建公共看板』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+$kanban1 = new stdclass();
+$kanban1->type = 'cooperation';
+$kanban1->space = 1;
+$kanban1->name = '测试创建协作看板';
+$kanban1->owner = 'po15';
+$kanban1->team = array('', 'user3');
+$kanban1->desc = '测试创建协作看板的描述';
+
+$kanban2 = new stdclass();
+$kanban2->type = 'private';
+$kanban2->space = 2;
+$kanban2->name = '测试创建私人看板';
+$kanban2->owner = 'po16';
+$kanban2->whitelist = array('', 'user4');
+$kanban2->desc = '测试创建私人看板的描述';
+
+$kanban3 = new stdclass();
+$kanban3->type = 'open';
+$kanban3->space = 3;
+$kanban3->name = '测试创建公共看板';
+$kanban3->owner = 'po17';
+$kanban3->team = array('', 'user5');
+$kanban3->desc = '测试创建公共看板的描述';
+
+$kanban4 = new stdclass();
+$kanban4->type = 'open';
+$kanban4->space = 3;
+$kanban4->name = '';
+$kanban4->owner = 'po17';
+$kanban4->team = array('', 'user5');
+$kanban4->desc = '测试创建没有名字看板的描述';
+
+$kanban5 = new stdclass();
+$kanban5->type = 'open';
+$kanban5->space = 0;
+$kanban5->name = '测试创建没有空间的公共看板';
+$kanban5->owner = 'po17';
+$kanban5->team = array('', 'user5');
+$kanban5->desc = '测试创建没有空间的公共看板的描述';
+
+$kanban6 = new stdclass();
+$kanban6->type = 'open';
+$kanban6->space = 3;
+$kanban6->name = '测试创建公共看板';
+$kanban6->owner = 'po17';
+$kanban6->team = array('', 'user5');
+$kanban6->desc = '测试创建重名的公共看板的描述';
+
+$kanban = new kanbanTest();
+
+r($kanban->createTest($kanban1)) && p('name,space,type,owner,whitelist') && e('测试创建协作看板,1,,po15,'); // 创建协同空间
+r($kanban->createTest($kanban2)) && p('name,space,type,owner,whitelist') && e('测试创建私人看板,2,,admin,,user4'); // 创建私人空间
+r($kanban->createTest($kanban3)) && p('name,space,type,owner,whitelist') && e('测试创建公共看板,3,,po17,'); // 创建公共空间
+r($kanban->createTest($kanban4)) && p('name:0') && e('『看板名称』不能为空。'); // 创建没有名字的公共空间
+r($kanban->createTest($kanban5)) && p('space:0') && e('『所属空间』不能为空。'); // 创建没有空间公共空间
+r($kanban->createTest($kanban6)) && p('name:0') && e('『看板名称』已经有『测试创建公共看板』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 创建重名公共空间
diff --git a/module/kanban/test/model/createcard.php b/module/kanban/test/model/createcard.php
new file mode 100755
index 0000000000..a24b57d427
--- /dev/null
+++ b/module/kanban/test/model/createcard.php
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+createCard();
+cid=1
+pid=1
+
+测试创建卡片1 >> 测试创建卡片1,1,1,测试创建卡片1的卡片描述
+测试创建卡片2 >> 测试创建卡片2,2,2,测试创建卡片2的卡片描述
+测试创建预计小于0的卡片 >> 预计不能为负数!
+测试创建结束小于开始日期的卡片 >> "截止日期"不能小于"预计开始"!
+测试创建没有名字的卡片 >> 『卡片名称』不能为空。
+
+*/
+
+$card1 = new stdclass();
+$card1->name = '测试创建卡片1';
+$card1->pri = '1';
+$card1->estimate = '1';
+$card1->assignedTo = array('po15', 'user3');
+$card1->desc = '测试创建卡片1的卡片描述';
+
+$card2 = new stdclass();
+$card2->name = '测试创建卡片2';
+$card2->pri = '2';
+$card2->estimate = '2';
+$card2->assignedTo = array('user3');
+$card2->desc = '测试创建卡片2的卡片描述';
+
+$card3 = new stdclass();
+$card3->name = '测试创建预计小于0的卡片';
+$card3->pri = '3';
+$card3->estimate = '-1';
+$card3->assignedTo = array('po15');
+$card3->desc = '测试创建预计小于0的卡片的描述';
+
+$card4 = new stdclass();
+$card4->name = '测试创建结束小于开始日期的卡片';
+$card4->pri = '4';
+$card4->estimate = '4';
+$card4->assignedTo = array('user3');
+$card4->begin = '2022-03-29';
+$card4->end = '2022-03-20';
+$card4->desc = '测试创建结束小于开始日期的卡片的描述';
+
+$card5 = new stdclass();
+$card5->name = '';
+$card5->pri = '1';
+$card5->estimate = '5';
+$card5->assignedTo = array('po15');
+$card5->desc = '测试不填写名称的卡片的卡片描述';
+
+$kanban = new kanbanTest();
+
+r($kanban->createCardTest($card1)) && p('name,pri,estimate,desc') && e('测试创建卡片1,1,1,测试创建卡片1的卡片描述'); // 测试创建卡片1
+r($kanban->createCardTest($card2)) && p('name,pri,estimate,desc') && e('测试创建卡片2,2,2,测试创建卡片2的卡片描述'); // 测试创建卡片2
+r($kanban->createCardTest($card3)) && p('estimate') && e('预计不能为负数!'); // 测试创建预计小于0的卡片
+r($kanban->createCardTest($card4)) && p('end') && e('"截止日期"不能小于"预计开始"!'); // 测试创建结束小于开始日期的卡片
+r($kanban->createCardTest($card5)) && p('name:0') && e('『卡片名称』不能为空。'); // 测试创建没有名字的卡片
diff --git a/module/kanban/test/model/createcolumn.php b/module/kanban/test/model/createcolumn.php
new file mode 100755
index 0000000000..41576a6773
--- /dev/null
+++ b/module/kanban/test/model/createcolumn.php
@@ -0,0 +1,97 @@
+#!/usr/bin/env php
+createColumn();
+cid=1
+pid=1
+
+创建没有在制品限制的看板列 >> 测试创建不限制看板列,-1,#333,0,1
+创建没有在制品限制的看板列 >> 测试创建不限制子看板列,-1,#333,1,1
+创建有在制品限制的看板列 >> 测试创建限制父看板列,111,#333,-1,1
+创建有在制品限制的子看板列 >> 测试创建限制子看板列,11,#333,5263,1
+创建没有名称的看板列 >> 『看板列名称』不能为空。
+创建没有填写在制品限制的看板列 >> 在制品数量必须是正整数。
+创建在制品数量为0的看板列 >> 在制品数量必须是正整数。
+创建在制品数量超出限制的子看板列 >> 父列的在制品数量不能小于子列在制品数量之和
+
+*/
+
+$column1 = new stdclass();
+$column1->name = '测试创建不限制看板列';
+$column1->limit = '-1';
+$column1->noLimit = '-1';
+$column1->color = '#333';
+$column1->group = '1';
+$column1->parent = '0';
+
+$column2 = new stdclass();
+$column2->name = '测试创建不限制子看板列';
+$column2->limit = '-1';
+$column2->noLimit = '-1';
+$column2->color = '#333';
+$column2->group = '1';
+$column2->parent = '1';
+
+$column3 = new stdclass();
+$column3->name = '测试创建限制父看板列';
+$column3->WIPCount = '111';
+$column3->limit = '111';
+$column3->color = '#333';
+$column3->group = '1';
+$column3->parent = '-1';
+
+$column4 = new stdclass();
+$column4->name = '测试创建限制子看板列';
+$column4->WIPCount = '11';
+$column4->limit = '11';
+$column4->color = '#333';
+$column4->group = '1';
+$column4->parent = '5263';
+
+$column5 = new stdclass();
+$column5->name = '';
+$column5->limit = '-1';
+$column5->noLimit = '-1';
+$column5->color = '#333';
+$column5->group = '1';
+$column5->parent = '0';
+
+$column6 = new stdclass();
+$column6->name = '测试创建不填写在制品数量的看板列';
+$column6->WIPCount = '';
+$column6->limit = '';
+$column6->color = '#333';
+$column6->group = '1';
+$column6->parent = '0';
+
+$column7 = new stdclass();
+$column7->name = '测试创建在制品数量为0的看板列';
+$column7->WIPCount = 0;
+$column7->limit = 0;
+$column7->color = '#333';
+$column7->group = '1';
+$column7->parent = '0';
+
+$column8 = new stdclass();
+$column8->name = '测试创建在制品数量超出限制的子看板列';
+$column8->WIPCount = '111';
+$column8->limit = '111';
+$column8->color = '#333';
+$column8->group = '1';
+$column8->parent = '5263';
+
+$kanban = new kanbanTest();
+
+r($kanban->createColumnTest($column1)) && p('name,limit,color,parent,group') && e('测试创建不限制看板列,-1,#333,0,1'); // 创建没有在制品限制的看板列
+r($kanban->createColumnTest($column2)) && p('name,limit,color,parent,group') && e('测试创建不限制子看板列,-1,#333,1,1'); // 创建没有在制品限制的看板列
+r($kanban->createColumnTest($column3)) && p('name,limit,color,parent,group') && e('测试创建限制父看板列,111,#333,-1,1'); // 创建有在制品限制的看板列
+r($kanban->createColumnTest($column4)) && p('name,limit,color,parent,group') && e('测试创建限制子看板列,11,#333,5263,1'); // 创建有在制品限制的子看板列
+r($kanban->createColumnTest($column5)) && p('name:0') && e('『看板列名称』不能为空。'); // 创建没有名称的看板列
+r($kanban->createColumnTest($column6)) && p('limit') && e('在制品数量必须是正整数。'); // 创建没有填写在制品限制的看板列
+r($kanban->createColumnTest($column7)) && p('limit') && e('在制品数量必须是正整数。'); // 创建在制品数量为0的看板列
+r($kanban->createColumnTest($column8)) && p('limit:0') && e('父列的在制品数量不能小于子列在制品数量之和'); // 创建在制品数量超出限制的子看板列
diff --git a/module/kanban/test/model/createdefaultcolumns.php b/module/kanban/test/model/createdefaultcolumns.php
new file mode 100755
index 0000000000..dddbc6f79d
--- /dev/null
+++ b/module/kanban/test/model/createdefaultcolumns.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+createDefaultColumns();
+cid=1
+pid=1
+
+创建region 1 group 1的默认泳道列 >> 8
+创建region 2 group 2的默认泳道列 >> 8
+创建region 3 group 3的默认泳道列 >> 8
+创建region 4 group 4的默认泳道列 >> 8
+创建region 5 group 5的默认泳道列 >> 8
+重复创建region 1 group 1的默认泳道列 >> 12
+
+*/
+
+$kanban = new kanbanTest();
+
+$regionIDList = array('1', '2', '3', '4', '5');
+$groupIDList = array('1', '2', '3', '4', '5');
+
+r($kanban->createDefaultColumnsTest($regionIDList[0], $groupIDList[0])) && p() && e('8'); // 创建region 1 group 1的默认泳道列
+r($kanban->createDefaultColumnsTest($regionIDList[1], $groupIDList[1])) && p() && e('8'); // 创建region 2 group 2的默认泳道列
+r($kanban->createDefaultColumnsTest($regionIDList[2], $groupIDList[2])) && p() && e('8'); // 创建region 3 group 3的默认泳道列
+r($kanban->createDefaultColumnsTest($regionIDList[3], $groupIDList[3])) && p() && e('8'); // 创建region 4 group 4的默认泳道列
+r($kanban->createDefaultColumnsTest($regionIDList[4], $groupIDList[4])) && p() && e('8'); // 创建region 5 group 5的默认泳道列
+r($kanban->createDefaultColumnsTest($regionIDList[0], $groupIDList[0])) && p() && e('12'); // 重复创建region 1 group 1的默认泳道列
diff --git a/module/kanban/test/model/createdefaultlane.php b/module/kanban/test/model/createdefaultlane.php
new file mode 100755
index 0000000000..868d103faf
--- /dev/null
+++ b/module/kanban/test/model/createdefaultlane.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+createDefaultLane();
+cid=1
+pid=1
+
+创建region 1 group 1的默认泳道 >> 默认泳道,1,1,common
+创建region 2 group 2的默认泳道 >> 默认泳道,2,2,common
+创建region 3 group 3的默认泳道 >> 默认泳道,3,3,common
+创建region 4 group 4的默认泳道 >> 默认泳道,4,4,common
+创建region 5 group 5的默认泳道 >> 默认泳道,5,5,common
+
+*/
+
+$kanban = new kanbanTest();
+
+$regionIDList = array('1', '2', '3', '4', '5');
+$groupIDList = array('1', '2', '3', '4', '5');
+
+r($kanban->createDefaultLaneTest($regionIDList[0], $groupIDList[0])) && p('name,group,region,type') && e('默认泳道,1,1,common'); // 创建region 1 group 1的默认泳道
+r($kanban->createDefaultLaneTest($regionIDList[1], $groupIDList[1])) && p('name,group,region,type') && e('默认泳道,2,2,common'); // 创建region 2 group 2的默认泳道
+r($kanban->createDefaultLaneTest($regionIDList[2], $groupIDList[2])) && p('name,group,region,type') && e('默认泳道,3,3,common'); // 创建region 3 group 3的默认泳道
+r($kanban->createDefaultLaneTest($regionIDList[3], $groupIDList[3])) && p('name,group,region,type') && e('默认泳道,4,4,common'); // 创建region 4 group 4的默认泳道
+r($kanban->createDefaultLaneTest($regionIDList[4], $groupIDList[4])) && p('name,group,region,type') && e('默认泳道,5,5,common'); // 创建region 5 group 5的默认泳道
diff --git a/module/kanban/test/model/createdefaultregion.php b/module/kanban/test/model/createdefaultregion.php
new file mode 100755
index 0000000000..11f3eb7c04
--- /dev/null
+++ b/module/kanban/test/model/createdefaultregion.php
@@ -0,0 +1,47 @@
+#!/usr/bin/env php
+createDefaultRegion();
+cid=1
+pid=1
+
+创建看板10001的默认区域 >> 10001,10001,默认区域
+创建看板10002的默认区域 >> 10002,10002,默认区域
+创建看板10003的默认区域 >> 10003,10003,默认区域
+创建看板10004的默认区域 >> 10004,10004,默认区域
+重复创建看板1的默认区域 >> 『区域名称』已经有『默认区域』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+$kanban1 = new stdclass();
+$kanban1->id = 10001;
+$kanban1->space = 10001;
+
+$kanban2 = new stdclass();
+$kanban2->id = 10002;
+$kanban2->space = 10002;
+
+$kanban3 = new stdclass();
+$kanban3->id = 10003;
+$kanban3->space = 10003;
+
+$kanban4 = new stdclass();
+$kanban4->id = 10004;
+$kanban4->space = 10004;
+
+$kanban5 = new stdclass();
+$kanban5->id = 1;
+$kanban5->space = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->createDefaultRegionTest($kanban1)) && p('space,kanban,name') && e('10001,10001,默认区域'); // 创建看板10001的默认区域
+r($kanban->createDefaultRegionTest($kanban2)) && p('space,kanban,name') && e('10002,10002,默认区域'); // 创建看板10002的默认区域
+r($kanban->createDefaultRegionTest($kanban3)) && p('space,kanban,name') && e('10003,10003,默认区域'); // 创建看板10003的默认区域
+r($kanban->createDefaultRegionTest($kanban4)) && p('space,kanban,name') && e('10004,10004,默认区域'); // 创建看板10004的默认区域
+r($kanban->createDefaultRegionTest($kanban5)) && p('name:0') && e('『区域名称』已经有『默认区域』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 重复创建看板1的默认区域
diff --git a/module/kanban/test/model/createexecutioncolumns.php b/module/kanban/test/model/createexecutioncolumns.php
new file mode 100755
index 0000000000..4398d3e081
--- /dev/null
+++ b/module/kanban/test/model/createexecutioncolumns.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+createExecutionColumns();
+cid=1
+pid=1
+
+创建泳道 100001 执行101 需求的看板列 >> 11
+创建泳道 100001 执行101 任务的看板列 >> 7
+创建泳道 100001 执行101 bug 的看板列 >> 9
+创建泳道 100002 执行102 需求的看板列 >> 11
+创建泳道 100002 执行102 任务的看板列 >> 7
+创建泳道 100002 执行102 bug 的看板列 >> 14
+创建泳道 100003 执行103 需求的看板列 >> 11
+创建泳道 100003 执行103 任务的看板列 >> 7
+创建泳道 100003 执行103 bug 的看板列 >> 9
+创建泳道 100004 执行104 需求的看板列 >> 11
+创建泳道 100004 执行104 任务的看板列 >> 7
+创建泳道 100004 执行104 bug 的看板列 >> 9
+创建泳道 100005 执行105 需求的看板列 >> 11
+创建泳道 100005 执行105 任务的看板列 >> 7
+创建泳道 100005 执行105 bug 的看板列 >> 9
+
+*/
+
+$laneIDList = array('100001', '100002', '100003', '10004', '10005');
+$executionIDList = array('101', '102', '103', '104', '105');
+$typeList = array('story', 'task', 'bug');
+
+$kanban = new kanbanTest();
+
+r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[0], $executionIDList[0])) && p() && e('11'); // 创建泳道 100001 执行101 需求的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[1], $executionIDList[0])) && p() && e('7'); // 创建泳道 100001 执行101 任务的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[0], $typeList[2], $executionIDList[0])) && p() && e('9'); // 创建泳道 100001 执行101 bug 的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[0], $executionIDList[1])) && p() && e('11'); // 创建泳道 100002 执行102 需求的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[1], $executionIDList[1])) && p() && e('7'); // 创建泳道 100002 执行102 任务的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[1], $typeList[1], $executionIDList[1])) && p() && e('14'); // 创建泳道 100002 执行102 bug 的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[0], $executionIDList[2])) && p() && e('11'); // 创建泳道 100003 执行103 需求的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[1], $executionIDList[2])) && p() && e('7'); // 创建泳道 100003 执行103 任务的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[2], $typeList[2], $executionIDList[2])) && p() && e('9'); // 创建泳道 100003 执行103 bug 的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[0], $executionIDList[3])) && p() && e('11'); // 创建泳道 100004 执行104 需求的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[1], $executionIDList[3])) && p() && e('7'); // 创建泳道 100004 执行104 任务的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[3], $typeList[2], $executionIDList[3])) && p() && e('9'); // 创建泳道 100004 执行104 bug 的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[0], $executionIDList[4])) && p() && e('11'); // 创建泳道 100005 执行105 需求的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[1], $executionIDList[4])) && p() && e('7'); // 创建泳道 100005 执行105 任务的看板列
+r($kanban->createExecutionColumnsTest($laneIDList[4], $typeList[2], $executionIDList[4])) && p() && e('9'); // 创建泳道 100005 执行105 bug 的看板列
diff --git a/module/kanban/test/model/createexecutionlane.php b/module/kanban/test/model/createexecutionlane.php
new file mode 100755
index 0000000000..f24d4ca46c
--- /dev/null
+++ b/module/kanban/test/model/createexecutionlane.php
@@ -0,0 +1,47 @@
+#!/usr/bin/env php
+createExecutionLane();
+cid=1
+pid=1
+
+创建执行101的泳道 >> 3
+创建执行101 需求的泳道 >> 2
+创建执行101 需求 按类别分组的泳道 >> 3
+创建执行101的泳道 >> 3
+创建执行102 需求 按来源分组的泳道 >> 3
+创建执行102 任务 按优先级分组的泳道 >> 4
+创建执行102 任务 按需求分组的泳道 >> 7
+创建执行103的泳道 >> 3
+创建执行103 bug 按严重程度分组的泳道 >> 4
+创建执行103 bug 按模块分组的泳道 >> 8
+创建执行103 bug 按指派给分组的泳道 >> 10
+创建执行104的泳道 >> 3
+创建执行105的泳道 >> 3
+
+*/
+
+$executionIDList = array('101', '102', '103', '104', '105');
+$typeIDList = array('all', 'story', 'task', 'bug');
+$groupByIDList = array('default', 'pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
+
+$kanban = new kanbanTest();
+
+r($kanban->createExecutionLaneTest($executionIDList[0])) && p() && e('3'); // 创建执行101的泳道
+r($kanban->createExecutionLaneTest($executionIDList[0], $typeIDList[1])) && p() && e('2'); // 创建执行101 需求的泳道
+r($kanban->createExecutionLaneTest($executionIDList[0], $typeIDList[1], $groupByIDList[2])) && p() && e('3'); // 创建执行101 需求 按类别分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[1])) && p() && e('3'); // 创建执行101的泳道
+r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[1], $groupByIDList[4])) && p() && e('3'); // 创建执行102 需求 按来源分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[2], $groupByIDList[1])) && p() && e('4'); // 创建执行102 任务 按优先级分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[1], $typeIDList[2], $groupByIDList[6])) && p() && e('7'); // 创建执行102 任务 按需求分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[2])) && p() && e('3'); // 创建执行103的泳道
+r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[7])) && p() && e('4'); // 创建执行103 bug 按严重程度分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[3])) && p() && e('8'); // 创建执行103 bug 按模块分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[2], $typeIDList[3], $groupByIDList[5])) && p() && e('10'); // 创建执行103 bug 按指派给分组的泳道
+r($kanban->createExecutionLaneTest($executionIDList[3])) && p() && e('3'); // 创建执行104的泳道
+r($kanban->createExecutionLaneTest($executionIDList[4])) && p() && e('3'); // 创建执行105的泳道
diff --git a/module/kanban/test/model/creategroup.php b/module/kanban/test/model/creategroup.php
new file mode 100755
index 0000000000..3bdf8e9dda
--- /dev/null
+++ b/module/kanban/test/model/creategroup.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+createGroup();
+cid=1
+pid=1
+
+测试创建看板1 区域1的看板组 >> ,1,
+测试创建看板2 区域2的看板组 >> ,2,
+测试创建看板3 区域3的看板组 >> ,3,
+测试创建看板4 区域4的看板组 >> ,4,
+测试创建看板5 区域5的看板组 >> ,5,
+
+*/
+
+$kanbanIDList = array('1', '2', '3', '4', '5');
+$regionIDList = array('1', '2', '3', '4', '5');
+
+$kanban = new kanbanTest();
+
+r($kanban->createGroupTest($kanbanIDList[0], $regionIDList[0])) && p('kanaban,region,orde') && e(',1,'); // 测试创建看板1 区域1的看板组
+r($kanban->createGroupTest($kanbanIDList[1], $regionIDList[1])) && p('kanaban,region,orde') && e(',2,'); // 测试创建看板2 区域2的看板组
+r($kanban->createGroupTest($kanbanIDList[2], $regionIDList[2])) && p('kanaban,region,orde') && e(',3,'); // 测试创建看板3 区域3的看板组
+r($kanban->createGroupTest($kanbanIDList[3], $regionIDList[3])) && p('kanaban,region,orde') && e(',4,'); // 测试创建看板4 区域4的看板组
+r($kanban->createGroupTest($kanbanIDList[4], $regionIDList[4])) && p('kanaban,region,orde') && e(',5,'); // 测试创建看板5 区域5的看板组
diff --git a/module/kanban/test/model/createlane.php b/module/kanban/test/model/createlane.php
new file mode 100755
index 0000000000..90004793b6
--- /dev/null
+++ b/module/kanban/test/model/createlane.php
@@ -0,0 +1,52 @@
+#!/usr/bin/env php
+createLane();
+cid=1
+pid=1
+
+测试创建与其他泳道使用相同看板列的泳道 >> 测试创建与其他泳道使用相同看板列的泳道,1,1
+测试创建使用独立看板列的泳道 >> 测试创建使用独立看板列的泳道,1,641
+测试创建不填写名称的泳道 >> 『泳道名称』不能为空。
+测试创建复用泳道1信息的泳道 >> 默认泳道,1,1
+测试创建复用泳道2信息的泳道 >> 默认泳道,2,2
+
+*/
+
+$kanbanID = 1;
+$regionID = 1;
+
+$lane1 = new stdclass();
+$lane1->name = '测试创建与其他泳道使用相同看板列的泳道';
+$lane1->mode = 'sameAsOther';
+$lane1->otherLane = '1';
+$lane1->color = '#7ec5ff';
+
+$lane2 = new stdclass();
+$lane2->name = '测试创建使用独立看板列的泳道';
+$lane2->mode = 'independent';
+$lane2->color = '#229f24';
+
+$lane3 = new stdclass();
+$lane3->name = '';
+$lane3->mode = 'independent';
+$lane3->color = '#229f24';
+
+$lane4 = new stdclass();
+$lane4->id = 1;
+
+$lane5 = new stdclass();
+$lane5->id = 2;
+
+$kanban = new kanbanTest();
+
+r($kanban->createLaneTest($lane1, $kanbanID, $regionID)) && p('name,region,group') && e('测试创建与其他泳道使用相同看板列的泳道,1,1'); //测试创建与其他泳道使用相同看板列的泳道
+r($kanban->createLaneTest($lane2, $kanbanID, $regionID)) && p('name,region,group') && e('测试创建使用独立看板列的泳道,1,641'); //测试创建使用独立看板列的泳道
+r($kanban->createLaneTest($lane3, $kanbanID, $regionID)) && p('name:0') && e('『泳道名称』不能为空。'); //测试创建不填写名称的泳道
+r($kanban->createLaneTest($lane4, $kanbanID, $regionID)) && p('name,region,group') && e('默认泳道,1,1'); //测试创建复用泳道1信息的泳道
+r($kanban->createLaneTest($lane5, $kanbanID, $regionID)) && p('name,region,group') && e('默认泳道,2,2'); //测试创建复用泳道2信息的泳道
diff --git a/module/kanban/test/model/createrdcolumn.php b/module/kanban/test/model/createrdcolumn.php
new file mode 100755
index 0000000000..f5880b644a
--- /dev/null
+++ b/module/kanban/test/model/createrdcolumn.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+createRDColumn();
+cid=1
+pid=1
+
+测试创建执行161 区域101 泳道组101 泳道101 story执行看板的泳道列 >> 22
+测试创建执行161 区域101 泳道组102 泳道102 bug执行看板的泳道列 >> 18
+测试创建执行161 区域101 泳道组103 泳道103 task执行看板的泳道列 >> 14
+测试创建执行162 区域102 泳道组104 泳道104 story执行看板的泳道列 >> 22
+测试创建执行162 区域102 泳道组105 泳道105 bug执行看板的泳道列 >> 18
+测试创建执行162 区域102 泳道组106 泳道106 task执行看板的泳道列 >> 14
+
+*/
+
+$regionIDList = array('101', '102');
+$groupIDList = array('101', '102', '103', '104', '105', '106');
+$laneIDList = array('101', '102', '103', '104', '105', '106');
+$laneTypeList = array('story', 'bug', 'task');
+$executionIDList = array('161', '162');
+
+$kanban = new kanbanTest();
+
+r($kanban->createRDColumnTest($regionIDList[0], $groupIDList[0], $laneIDList[0], $laneTypeList[0], $executionIDList[0])) && p() && e('22'); // 测试创建执行161 区域101 泳道组101 泳道101 story执行看板的泳道列
+r($kanban->createRDColumnTest($regionIDList[0], $groupIDList[1], $laneIDList[1], $laneTypeList[1], $executionIDList[0])) && p() && e('18'); // 测试创建执行161 区域101 泳道组102 泳道102 bug执行看板的泳道列
+r($kanban->createRDColumnTest($regionIDList[0], $groupIDList[2], $laneIDList[2], $laneTypeList[2], $executionIDList[0])) && p() && e('14'); // 测试创建执行161 区域101 泳道组103 泳道103 task执行看板的泳道列
+r($kanban->createRDColumnTest($regionIDList[1], $groupIDList[3], $laneIDList[3], $laneTypeList[0], $executionIDList[1])) && p() && e('22'); // 测试创建执行162 区域102 泳道组104 泳道104 story执行看板的泳道列
+r($kanban->createRDColumnTest($regionIDList[1], $groupIDList[4], $laneIDList[4], $laneTypeList[1], $executionIDList[1])) && p() && e('18'); // 测试创建执行162 区域102 泳道组105 泳道105 bug执行看板的泳道列
+r($kanban->createRDColumnTest($regionIDList[1], $groupIDList[5], $laneIDList[5], $laneTypeList[2], $executionIDList[1])) && p() && e('14'); // 测试创建执行162 区域102 泳道组106 泳道106 task执行看板的泳道列
diff --git a/module/kanban/test/model/createrdkanban.php b/module/kanban/test/model/createrdkanban.php
new file mode 100755
index 0000000000..53d2a45d5b
--- /dev/null
+++ b/module/kanban/test/model/createrdkanban.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+createRDKanban();
+cid=1
+pid=1
+
+测试创建执行10001的执行看板 >> 1,3,0
+测试创建执行10002的执行看板 >> 1,3,0
+测试创建执行10003的执行看板 >> 1,3,0
+测试创建执行10004的执行看板 >> 1,3,0
+测试创建执行10005的执行看板 >> 1,3,0
+
+*/
+
+$execution1 = new stdclass();
+$execution1->id = '100001';
+
+$execution2 = new stdclass();
+$execution2->id = '100002';
+
+$execution3 = new stdclass();
+$execution3->id = '100003';
+
+$execution4 = new stdclass();
+$execution4->id = '100004';
+
+$execution5 = new stdclass();
+$execution5->id = '100005';
+
+$kanban = new kanbanTest();
+
+r($kanban->createRDKanbanTest($execution1)) && p() && e('1,3,0'); // 测试创建执行10001的执行看板
+r($kanban->createRDKanbanTest($execution2)) && p() && e('1,3,0'); // 测试创建执行10002的执行看板
+r($kanban->createRDKanbanTest($execution3)) && p() && e('1,3,0'); // 测试创建执行10003的执行看板
+r($kanban->createRDKanbanTest($execution4)) && p() && e('1,3,0'); // 测试创建执行10004的执行看板
+r($kanban->createRDKanbanTest($execution5)) && p() && e('1,3,0'); // 测试创建执行10005的执行看板
diff --git a/module/kanban/test/model/createrdlane.php b/module/kanban/test/model/createrdlane.php
new file mode 100755
index 0000000000..7a5dfafa65
--- /dev/null
+++ b/module/kanban/test/model/createrdlane.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+createRDLane();
+cid=1
+pid=1
+
+测试创建执行101的执行看板的泳道 >> 6
+测试创建执行102的执行看板的泳道 >> 6
+测试创建执行103的执行看板的泳道 >> 6
+测试创建执行104的执行看板的泳道 >> 6
+测试创建执行105的执行看板的泳道 >> 6
+
+*/
+
+$executionIDList = array('161', '162', '163', '164', '165');
+$regionIDList = array('101', '102', '103', '104', '105');
+
+$kanban = new kanbanTest();
+
+r($kanban->createRDLaneTest($executionIDList[0], $regionIDList[0])) && p() && e('6'); // 测试创建执行101的执行看板的泳道
+r($kanban->createRDLaneTest($executionIDList[1], $regionIDList[1])) && p() && e('6'); // 测试创建执行102的执行看板的泳道
+r($kanban->createRDLaneTest($executionIDList[2], $regionIDList[2])) && p() && e('6'); // 测试创建执行103的执行看板的泳道
+r($kanban->createRDLaneTest($executionIDList[3], $regionIDList[3])) && p() && e('6'); // 测试创建执行104的执行看板的泳道
+r($kanban->createRDLaneTest($executionIDList[4], $regionIDList[4])) && p() && e('6'); // 测试创建执行105的执行看板的泳道
diff --git a/module/kanban/test/model/createrdregion.php b/module/kanban/test/model/createrdregion.php
new file mode 100755
index 0000000000..b80bfb0793
--- /dev/null
+++ b/module/kanban/test/model/createrdregion.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+createRDRegion();
+cid=1
+pid=1
+
+测试创建执行10001的执行看板区域 >> 默认区域,100001
+测试创建执行10002的执行看板区域 >> 默认区域,100002
+测试创建执行10003的执行看板区域 >> 默认区域,100003
+测试创建执行10004的执行看板区域 >> 默认区域,100004
+测试创建执行10005的执行看板区域 >> 默认区域,100005
+
+*/
+
+$execution1 = new stdclass();
+$execution1->id = '100001';
+
+$execution2 = new stdclass();
+$execution2->id = '100002';
+
+$execution3 = new stdclass();
+$execution3->id = '100003';
+
+$execution4 = new stdclass();
+$execution4->id = '100004';
+
+$execution5 = new stdclass();
+$execution5->id = '100005';
+
+$kanban = new kanbanTest();
+
+r($kanban->createRDRegionTest($execution1)) && p('name,kanban') && e('默认区域,100001'); // 测试创建执行10001的执行看板区域
+r($kanban->createRDRegionTest($execution2)) && p('name,kanban') && e('默认区域,100002'); // 测试创建执行10002的执行看板区域
+r($kanban->createRDRegionTest($execution3)) && p('name,kanban') && e('默认区域,100003'); // 测试创建执行10003的执行看板区域
+r($kanban->createRDRegionTest($execution4)) && p('name,kanban') && e('默认区域,100004'); // 测试创建执行10004的执行看板区域
+r($kanban->createRDRegionTest($execution5)) && p('name,kanban') && e('默认区域,100005'); // 测试创建执行10005的执行看板区域
diff --git a/module/kanban/test/model/createregion.php b/module/kanban/test/model/createregion.php
new file mode 100755
index 0000000000..6662395a73
--- /dev/null
+++ b/module/kanban/test/model/createregion.php
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+createRegion();
+cid=1
+pid=1
+
+创建默认区域 >> 默认区域,1,100001
+创建自定义区域1 >> 新增的区域1,1,100001
+创建复制样式区域2 >> 新增的区域2,1,0
+创建自定义区域3 >> 新增的区域3,1,100001
+创建复制样式区域4 >> 新增的区域4,1,0
+创建没有名称的区域 >> 『区域名称』不能为空。
+创建重名自定义区域1 >> 『区域名称』已经有『新增的区域1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+$kanban1 = new stdclass();
+$kanban1->id = '100001';
+$kanban1->space = '1';
+
+$copyRegionID = 1;
+
+$region1 = new stdclass;
+$region1->name = '新增的区域1';
+$region1->space = 1;
+
+$region2 = new stdclass;
+$region2->name = '新增的区域2';
+$region2->space = 1;
+
+$region3 = new stdclass;
+$region3->name = '新增的区域3';
+$region3->space = 1;
+
+$region4 = new stdclass;
+$region4->name = '新增的区域4';
+$region4->space = 1;
+
+$region5 = new stdclass;
+$region5->name = '';
+$region5->space = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->createRegionTest($kanban1)) && p('name,space,kanban') && e('默认区域,1,100001'); // 创建默认区域
+r($kanban->createRegionTest($kanban1, $region1)) && p('name,space,kanban') && e('新增的区域1,1,100001'); // 创建自定义区域1
+r($kanban->createRegionTest($kanban1, $region2, $copyRegionID)) && p('name,space,kanban') && e('新增的区域2,1,0'); // 创建复制样式区域2
+r($kanban->createRegionTest($kanban1, $region3)) && p('name,space,kanban') && e('新增的区域3,1,100001'); // 创建自定义区域3
+r($kanban->createRegionTest($kanban1, $region4, $copyRegionID)) && p('name,space,kanban') && e('新增的区域4,1,0'); // 创建复制样式区域4
+r($kanban->createRegionTest($kanban1, $region5)) && p('name:0') && e('『区域名称』不能为空。'); // 创建没有名称的区域
+r($kanban->createRegionTest($kanban1, $region1)) && p('name:0') && e('『区域名称』已经有『新增的区域1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 创建重名自定义区域1
diff --git a/module/kanban/test/model/createspace.php b/module/kanban/test/model/createspace.php
new file mode 100755
index 0000000000..0cd71bab45
--- /dev/null
+++ b/module/kanban/test/model/createspace.php
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+createSpace();
+cid=1
+pid=1
+
+创建私人空间 >> 测试创建私人空间,private,私人空间的描述,admin,,admin,po15
+创建协作空间 >> 测试创建协作空间,cooperation,协作空间的描述,po16,po15,admin,po16,
+创建公共空间 >> 测试创建公共空间,public,公共空间的描述,user1,user2,user3,admin,user1,
+创建不填写名称的空间 >> 『空间名称』不能为空。
+创建不填写负责人的空间 >> 『负责人』不能为空。
+
+*/
+
+$space1 = new stdclass();
+$space1->type = 'private';
+$space1->name = '测试创建私人空间';
+$space1->owner = '';
+$space1->contactListMenu = '';
+$space1->desc = '私人空间的描述';
+$space1->whitelist = array('po15');
+
+$space2 = new stdclass();
+$space2->type = 'cooperation';
+$space2->name = '测试创建协作空间';
+$space2->owner = 'po16';
+$space2->contactListMenu = '';
+$space2->desc = '协作空间的描述';
+$space2->team = array('po15');
+
+$space3 = new stdclass();
+$space3->type = 'public';
+$space3->name = '测试创建公共空间';
+$space3->owner = 'user1';
+$space3->contactListMenu = '';
+$space3->desc = '公共空间的描述';
+$space3->team = array('user2', 'user3');
+
+$space4 = new stdclass();
+$space4->type = 'public';
+$space4->name = '';
+$space4->owner = 'user1';
+$space4->contactListMenu = '';
+$space4->desc = '不填写名字的公共空间描述';
+$space4->team = array('user2', 'user3');
+
+$space5 = new stdclass();
+$space5->type = 'public';
+$space5->name = '不填写负责人的公共空间';
+$space5->owner = '';
+$space5->contactListMenu = '';
+$space5->desc = '不填写负责人的公共空间描述';
+$space5->team = array('user2', 'user3');
+
+$kanban = new kanbanTest();
+
+r($kanban->createSpaceTest($space1)) && p('name,type,desc,owner,team,whitelist') && e('测试创建私人空间,private,私人空间的描述,admin,,admin,po15'); // 创建私人空间
+r($kanban->createSpaceTest($space2)) && p('name,type,desc,owner,team,whitelist') && e('测试创建协作空间,cooperation,协作空间的描述,po16,po15,admin,po16,'); // 创建协作空间
+r($kanban->createSpaceTest($space3)) && p('name,type,desc,owner,team,whitelist') && e('测试创建公共空间,public,公共空间的描述,user1,user2,user3,admin,user1,'); // 创建公共空间
+r($kanban->createSpaceTest($space4)) && p('name:0') && e('『空间名称』不能为空。'); // 创建不填写名称的空间
+r($kanban->createSpaceTest($space5)) && p('owner:0') && e('『负责人』不能为空。'); // 创建不填写负责人的空间
\ No newline at end of file
diff --git a/module/kanban/test/model/getbyid.php b/module/kanban/test/model/getbyid.php
new file mode 100755
index 0000000000..2f46fd68e4
--- /dev/null
+++ b/module/kanban/test/model/getbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+测试查询看板1的信息 >> 通用看板1,1,po15,,user3,po15,,,user3,po15
+测试查询看板2的信息 >> 通用看板2,1,po15,,user3,po15,,,user3,po15
+测试查询看板3的信息 >> 通用看板3,2,po16,,user4,po16,,,user4,po16
+测试查询看板4的信息 >> 通用看板4,2,po16,,user4,po16,,,user4,po16
+测试查询看板5的信息 >> 通用看板5,3,po17,,user5,po17,,,user5,po17
+测试查询不存在的看板信息 >> 0
+
+*/
+
+$kanbanIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getByIDTest($kanbanIDList[0])) && p('name,space,owner,team,whitelist') && e('通用看板1,1,po15,,user3,po15,,,user3,po15'); // 测试查询看板1的信息
+r($kanban->getByIDTest($kanbanIDList[1])) && p('name,space,owner,team,whitelist') && e('通用看板2,1,po15,,user3,po15,,,user3,po15'); // 测试查询看板2的信息
+r($kanban->getByIDTest($kanbanIDList[2])) && p('name,space,owner,team,whitelist') && e('通用看板3,2,po16,,user4,po16,,,user4,po16'); // 测试查询看板3的信息
+r($kanban->getByIDTest($kanbanIDList[3])) && p('name,space,owner,team,whitelist') && e('通用看板4,2,po16,,user4,po16,,,user4,po16'); // 测试查询看板4的信息
+r($kanban->getByIDTest($kanbanIDList[4])) && p('name,space,owner,team,whitelist') && e('通用看板5,3,po17,,user5,po17,,,user5,po17'); // 测试查询看板5的信息
+r($kanban->getByIDTest($kanbanIDList[5])) && p('name,space,owner,team,whitelist') && e('0'); // 测试查询不存在的看板信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getcanviewobjects.php b/module/kanban/test/model/getcanviewobjects.php
new file mode 100755
index 0000000000..a9c472bc65
--- /dev/null
+++ b/module/kanban/test/model/getcanviewobjects.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+getCanViewObjects();
+cid=1
+pid=1
+
+测试查询admin有权限查看的看板个数 >> 32
+测试查询admin有权限查看的空间个数 >> 19
+测试查询admin有权限查看的未关闭看板个数 >> 100
+测试查询admin有权限查看的私人看板个数 >> 32
+测试查询admin有权限查看的协同看板个数 >> 100
+测试查询admin有权限查看的公共看板个数 >> 100
+测试查询admin有权限查看的参与看板个数 >> 0
+测试查询admin有权限查看的看板个数 >> 32
+测试查询admin有权限查看的看板个数 >> 32
+测试查询po1有权限查看的看板个数 >> 32
+测试查询po2有权限查看的看板个数 >> 32
+测试查询user1有权限查看的看板个数 >> 32
+测试查询user2有权限查看的看板个数 >> 32
+测试查询pm1有权限查看的看板个数 >> 32
+测试查询pm2有权限查看的看板个数 >> 32
+
+*/
+
+$kanban = new kanbanTest();
+
+$userList = array('admin', 'po1', 'po2', 'user1', 'user2', 'pm1', 'pm2');
+$objectType = array('kanban', 'kanbanspace');
+$paramList = array('noclosed', 'private', 'cooperation', 'public', 'involved');
+
+r($kanban->getCanViewObjectsTest($userList[0])) && p() && e('32'); // 测试查询admin有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[1])) && p() && e('19'); // 测试查询admin有权限查看的空间个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[0], $paramList[0])) && p() && e('100'); // 测试查询admin有权限查看的未关闭看板个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[0], $paramList[1])) && p() && e('32'); // 测试查询admin有权限查看的私人看板个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[0], $paramList[2])) && p() && e('100'); // 测试查询admin有权限查看的协同看板个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[0], $paramList[3])) && p() && e('100'); // 测试查询admin有权限查看的公共看板个数
+r($kanban->getCanViewObjectsTest($userList[0], $objectType[0], $paramList[4])) && p() && e('0'); // 测试查询admin有权限查看的参与看板个数
+r($kanban->getCanViewObjectsTest($userList[0])) && p() && e('32'); // 测试查询admin有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[0])) && p() && e('32'); // 测试查询admin有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[1])) && p() && e('32'); // 测试查询po1有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[2])) && p() && e('32'); // 测试查询po2有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[3])) && p() && e('32'); // 测试查询user1有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[4])) && p() && e('32'); // 测试查询user2有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[5])) && p() && e('32'); // 测试查询pm1有权限查看的看板个数
+r($kanban->getCanViewObjectsTest($userList[6])) && p() && e('32'); // 测试查询pm2有权限查看的看板个数
\ No newline at end of file
diff --git a/module/kanban/test/model/getcardbyid.php b/module/kanban/test/model/getcardbyid.php
new file mode 100755
index 0000000000..a682605262
--- /dev/null
+++ b/module/kanban/test/model/getcardbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getCardByID();
+cid=1
+pid=1
+
+测试查询卡片1的信息 >> 卡片1,doing,3,0
+测试查询卡片2的信息 >> 卡片2,doing,3,50
+测试查询卡片3的信息 >> 卡片3,done,3,100
+测试查询卡片4的信息 >> 卡片4,doing,3,0
+测试查询卡片5的信息 >> 卡片5,doing,3,50
+测试查询不存在卡片的信息 >> 0
+
+*/
+
+$cardIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getCardByIDTest($cardIDList[0])) && p('name,status,pri,progress') && e('卡片1,doing,3,0'); // 测试查询卡片1的信息
+r($kanban->getCardByIDTest($cardIDList[1])) && p('name,status,pri,progress') && e('卡片2,doing,3,50'); // 测试查询卡片2的信息
+r($kanban->getCardByIDTest($cardIDList[2])) && p('name,status,pri,progress') && e('卡片3,done,3,100'); // 测试查询卡片3的信息
+r($kanban->getCardByIDTest($cardIDList[3])) && p('name,status,pri,progress') && e('卡片4,doing,3,0'); // 测试查询卡片4的信息
+r($kanban->getCardByIDTest($cardIDList[4])) && p('name,status,pri,progress') && e('卡片5,doing,3,50'); // 测试查询卡片5的信息
+r($kanban->getCardByIDTest($cardIDList[5])) && p() && e('0'); // 测试查询不存在卡片的信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getcardgroupbyexecution.php b/module/kanban/test/model/getcardgroupbyexecution.php
new file mode 100755
index 0000000000..0d7eea3a0f
--- /dev/null
+++ b/module/kanban/test/model/getcardgroupbyexecution.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+getCardGroupByExecution();
+cid=1
+pid=1
+
+测试查询execution161的卡片 >> 5
+测试查询execution161的task卡片 >> 1
+测试查询execution161的bug卡片 >> 3
+测试查询execution161的story卡片 >> 1
+测试查询execution162的卡片 >> 5
+测试查询execution162的task卡片 >> 1
+测试查询execution162的bug卡片 >> 3
+测试查询execution162的story卡片 >> 1
+测试查询execution163的卡片 >> 4
+测试查询execution164的卡片 >> 4
+测试查询execution165的卡片 >> 0
+
+*/
+
+$executionIDList = array('161', '162', '163', '164', '165');
+$browseTypeList = array('task', 'bug', 'story');
+
+$kanban = new kanbanTest();
+r($kanban->getCardGroupByExecutionTest($executionIDList[0])) && p() && e('5'); // 测试查询execution161的卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[0], $browseTypeList[0])) && p() && e('1'); // 测试查询execution161的task卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[0], $browseTypeList[1])) && p() && e('3'); // 测试查询execution161的bug卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[0], $browseTypeList[2])) && p() && e('1'); // 测试查询execution161的story卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[1])) && p() && e('5'); // 测试查询execution162的卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[1], $browseTypeList[0])) && p() && e('1'); // 测试查询execution162的task卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[1], $browseTypeList[1])) && p() && e('3'); // 测试查询execution162的bug卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[1], $browseTypeList[2])) && p() && e('1'); // 测试查询execution162的story卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[2])) && p() && e('4'); // 测试查询execution163的卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[3])) && p() && e('4'); // 测试查询execution164的卡片
+r($kanban->getCardGroupByExecutionTest($executionIDList[4])) && p() && e('0'); // 测试查询execution165的卡片
\ No newline at end of file
diff --git a/module/kanban/test/model/getcardgroupbykanban.php b/module/kanban/test/model/getcardgroupbykanban.php
new file mode 100755
index 0000000000..6918320f08
--- /dev/null
+++ b/module/kanban/test/model/getcardgroupbykanban.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getCardGroupByKanban();
+cid=1
+pid=1
+
+测试查询看板1的卡片数量 >> 1
+测试查询看板2的卡片数量 >> 1
+测试查询看板3的卡片数量 >> 1
+测试查询看板4的卡片数量 >> 1
+测试查询看板5的卡片数量 >> 1
+测试查询不存在看板的卡片数量 >> 0
+
+*/
+
+$kanbanIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[0])) && p() && e('1'); // 测试查询看板1的卡片数量
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[1])) && p() && e('1'); // 测试查询看板2的卡片数量
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[2])) && p() && e('1'); // 测试查询看板3的卡片数量
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[3])) && p() && e('1'); // 测试查询看板4的卡片数量
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[4])) && p() && e('1'); // 测试查询看板5的卡片数量
+r($kanban->getCardGroupByKanbanTest($kanbanIDList[5])) && p() && e('0'); // 测试查询不存在看板的卡片数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getcards2import.php b/module/kanban/test/model/getcards2import.php
new file mode 100755
index 0000000000..83fed034ae
--- /dev/null
+++ b/module/kanban/test/model/getcards2import.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+getCards2Import();
+cid=1
+pid=1
+
+测试获取可以导入的卡片数量 >> 256
+测试获取看板1可以导入的卡片数量 >> 0
+测试获取看板1可以导入的卡片数量 排除看板1 >> 0
+测试获取看板2可以导入的卡片数量 >> 0
+测试获取看板2可以导入的卡片数量 排除看板1 >> 0
+测试获取看板3可以导入的卡片数量 >> 0
+测试获取看板3可以导入的卡片数量 排除看板1 >> 0
+测试获取看板4可以导入的卡片数量 >> 0
+测试获取看板4可以导入的卡片数量 排除看板1 >> 0
+测试获取看板5可以导入的卡片数量 >> 8
+测试获取看板5可以导入的卡片数量 >> 8
+测试获取不存在看板可以导入的卡片数量 排除看板1 >> 0
+测试获取不存在看板可以导入的卡片数量 排除看板1 >> 0
+
+*/
+$kanbanIDList = array('1', '2', '3', '4', '5', '1000001');
+$excludedID = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->getCards2ImportTest()) && p() && e('256'); // 测试获取可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[0])) && p() && e('0'); // 测试获取看板1可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[0], $excludedID)) && p() && e('0'); // 测试获取看板1可以导入的卡片数量 排除看板1
+r($kanban->getCards2ImportTest($kanbanIDList[1])) && p() && e('0'); // 测试获取看板2可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[1], $excludedID)) && p() && e('0'); // 测试获取看板2可以导入的卡片数量 排除看板1
+r($kanban->getCards2ImportTest($kanbanIDList[2])) && p() && e('0'); // 测试获取看板3可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[2], $excludedID)) && p() && e('0'); // 测试获取看板3可以导入的卡片数量 排除看板1
+r($kanban->getCards2ImportTest($kanbanIDList[3])) && p() && e('0'); // 测试获取看板4可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[3], $excludedID)) && p() && e('0'); // 测试获取看板4可以导入的卡片数量 排除看板1
+r($kanban->getCards2ImportTest($kanbanIDList[4])) && p() && e('8'); // 测试获取看板5可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[4])) && p() && e('8'); // 测试获取看板5可以导入的卡片数量
+r($kanban->getCards2ImportTest($kanbanIDList[5], $excludedID)) && p() && e('0'); // 测试获取不存在看板可以导入的卡片数量 排除看板1
+r($kanban->getCards2ImportTest($kanbanIDList[5], $excludedID)) && p() && e('0'); // 测试获取不存在看板可以导入的卡片数量 排除看板1
\ No newline at end of file
diff --git a/module/kanban/test/model/getcardsbyobject.php b/module/kanban/test/model/getcardsbyobject.php
new file mode 100755
index 0000000000..f28d161a76
--- /dev/null
+++ b/module/kanban/test/model/getcardsbyobject.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+getCardsByObject();
+cid=1
+pid=1
+
+测试查询kanban 1的卡片数量 >> 16
+测试查询kanban 2的卡片数量 >> 16
+测试查询kanban 3的卡片数量 >> 16
+测试查询kanban 4的卡片数量 >> 16
+测试查询kanban 5的卡片数量 >> 16
+测试查询不存在kanban的卡片数量 >> 0
+测试查询region 1的卡片数量 >> 16
+测试查询region 2的卡片数量 >> 16
+测试查询region 3的卡片数量 >> 16
+测试查询region 4的卡片数量 >> 16
+测试查询region 5的卡片数量 >> 16
+测试查询不存在region的卡片数量 >> 0
+测试查询status doing的卡片数量 >> 667
+测试查询status doing的卡片数量 >> 333
+
+*/
+
+$objectType = array('kanban', 'region', 'status');
+$kanbanIDList = array('1', '2', '3', '4', '5', '1000001');
+$regionIDList = array('1', '2', '3', '4', '5', '1000001');
+$statusList = array('doing', 'done');
+
+$kanban = new kanbanTest();
+
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[0])) && p() && e('16'); // 测试查询kanban 1的卡片数量
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[1])) && p() && e('16'); // 测试查询kanban 2的卡片数量
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[2])) && p() && e('16'); // 测试查询kanban 3的卡片数量
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[3])) && p() && e('16'); // 测试查询kanban 4的卡片数量
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[4])) && p() && e('16'); // 测试查询kanban 5的卡片数量
+r($kanban->getCardsByObjectTest($objectType[0], $kanbanIDList[5])) && p() && e('0'); // 测试查询不存在kanban的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[0])) && p() && e('16'); // 测试查询region 1的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[1])) && p() && e('16'); // 测试查询region 2的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[2])) && p() && e('16'); // 测试查询region 3的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[3])) && p() && e('16'); // 测试查询region 4的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[4])) && p() && e('16'); // 测试查询region 5的卡片数量
+r($kanban->getCardsByObjectTest($objectType[1], $regionIDList[5])) && p() && e('0'); // 测试查询不存在region的卡片数量
+r($kanban->getCardsByObjectTest($objectType[2], $statusList[0])) && p() && e('667'); // 测试查询status doing的卡片数量
+r($kanban->getCardsByObjectTest($objectType[2], $statusList[1])) && p() && e('333'); // 测试查询status doing的卡片数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getcolumnbyid.php b/module/kanban/test/model/getcolumnbyid.php
new file mode 100755
index 0000000000..b3e5338668
--- /dev/null
+++ b/module/kanban/test/model/getcolumnbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getColumnByID();
+cid=1
+pid=1
+
+测试查询看板列1的信息 >> column1,1,未开始,-1
+测试查询看板列2的信息 >> column2,1,进行中,-1
+测试查询看板列3的信息 >> column3,1,已完成,-1
+测试查询看板列4的信息 >> column4,1,已关闭,-1
+测试查询看板列5的信息 >> column5,2,未开始,-1
+测试查询不存在看板列的信息 >> 0
+
+*/
+
+$columnIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getColumnByIDTest($columnIDList[0])) && p('type,region,name,limit') && e('column1,1,未开始,-1'); // 测试查询看板列1的信息
+r($kanban->getColumnByIDTest($columnIDList[1])) && p('type,region,name,limit') && e('column2,1,进行中,-1'); // 测试查询看板列2的信息
+r($kanban->getColumnByIDTest($columnIDList[2])) && p('type,region,name,limit') && e('column3,1,已完成,-1'); // 测试查询看板列3的信息
+r($kanban->getColumnByIDTest($columnIDList[3])) && p('type,region,name,limit') && e('column4,1,已关闭,-1'); // 测试查询看板列4的信息
+r($kanban->getColumnByIDTest($columnIDList[4])) && p('type,region,name,limit') && e('column5,2,未开始,-1'); // 测试查询看板列5的信息
+r($kanban->getColumnByIDTest($columnIDList[5])) && p('type,region,name,limit') && e('0'); // 测试查询不存在看板列的信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getcolumngroupbyregions.php b/module/kanban/test/model/getcolumngroupbyregions.php
new file mode 100755
index 0000000000..f3c8084e51
--- /dev/null
+++ b/module/kanban/test/model/getcolumngroupbyregions.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getColumnGroupByRegions();
+cid=1
+pid=1
+
+测试获取region 1 2 3 的看板列数量 >> 12
+测试获取region 4,5,6的看板列数量 >> 12
+测试获取region 7,8,9的看板列数量 >> 12
+测试获取region 10,11,12的看板列数量 >> 12
+测试获取region 13,14,15的看板列数量 >> 12
+
+*/
+
+$regions1 = '1,2,3';
+$regions2 = '4,5,6';
+$regions3 = '7,8,9';
+$regions4 = '10,11,12';
+$regions5 = '13,14,15';
+
+$kanban = new kanbanTest();
+
+r($kanban->getColumnGroupByRegionsTest($regions1)) && p() && e('12'); // 测试获取region 1 2 3 的看板列数量
+r($kanban->getColumnGroupByRegionsTest($regions2)) && p() && e('12'); // 测试获取region 4,5,6的看板列数量
+r($kanban->getColumnGroupByRegionsTest($regions3)) && p() && e('12'); // 测试获取region 7,8,9的看板列数量
+r($kanban->getColumnGroupByRegionsTest($regions4)) && p() && e('12'); // 测试获取region 10,11,12的看板列数量
+r($kanban->getColumnGroupByRegionsTest($regions5)) && p() && e('12'); // 测试获取region 13,14,15的看板列数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getcolumnidbylaneid.php b/module/kanban/test/model/getcolumnidbylaneid.php
new file mode 100755
index 0000000000..51b6fb6d54
--- /dev/null
+++ b/module/kanban/test/model/getcolumnidbylaneid.php
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+getColumnIDByLaneID();
+cid=1
+pid=1
+
+测试获取泳道1 column1的看板列 >> 1
+测试获取泳道1 column2的看板列 >> 2
+测试获取泳道1 wait的看板列 >> 0
+测试获取泳道1 test的看板列 >> 0
+测试获取泳道1 backlog的看板列 >> 0
+测试获取泳道2 column2的看板列 >> 0
+测试获取泳道2 wait的看板列 >> 0
+测试获取泳道107 wait的看板列 >> 0
+测试获取泳道107 test的看板列 >> 460
+测试获取泳道107 backlog的看板列 >> 455
+测试获取泳道108 wait的看板列 >> 0
+测试获取泳道108 test的看板列 >> 471
+测试获取泳道108 backlog的看板列 >> 0
+测试获取泳道109 wait的看板列 >> 475
+测试获取泳道109 test的看板列 >> 0
+测试获取泳道109 backlog的看板列 >> 0
+测试获取不存在的泳道 common的看板列 >> 0
+
+*/
+
+$laneIDList = array('1', '2', '107', '108', '109', '10001');
+$columnTypeList = array('column1', 'column2', 'wait', 'test', 'backlog');
+
+$kanban = new kanbanTest();
+
+r($kanban->getColumnIDByLaneIDTest($laneIDList[0], $columnTypeList[0])) && p() && e('1'); // 测试获取泳道1 column1的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[0], $columnTypeList[1])) && p() && e('2'); // 测试获取泳道1 column2的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[0], $columnTypeList[2])) && p() && e('0'); // 测试获取泳道1 wait的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[0], $columnTypeList[3])) && p() && e('0'); // 测试获取泳道1 test的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[0], $columnTypeList[4])) && p() && e('0'); // 测试获取泳道1 backlog的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[1], $columnTypeList[1])) && p() && e('0'); // 测试获取泳道2 column2的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[1], $columnTypeList[2])) && p() && e('0'); // 测试获取泳道2 wait的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[2], $columnTypeList[2])) && p() && e('0'); // 测试获取泳道107 wait的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[2], $columnTypeList[3])) && p() && e('460'); // 测试获取泳道107 test的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[2], $columnTypeList[4])) && p() && e('455'); // 测试获取泳道107 backlog的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[3], $columnTypeList[2])) && p() && e('0'); // 测试获取泳道108 wait的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[3], $columnTypeList[3])) && p() && e('471'); // 测试获取泳道108 test的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[3], $columnTypeList[4])) && p() && e('0'); // 测试获取泳道108 backlog的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[4], $columnTypeList[2])) && p() && e('475'); // 测试获取泳道109 wait的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[4], $columnTypeList[3])) && p() && e('0'); // 测试获取泳道109 test的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[4], $columnTypeList[4])) && p() && e('0'); // 测试获取泳道109 backlog的看板列
+r($kanban->getColumnIDByLaneIDTest($laneIDList[5], $columnTypeList[0])) && p() && e('0'); // 测试获取不存在的泳道 common的看板列
\ No newline at end of file
diff --git a/module/kanban/test/model/getcolumnsbyobject.php b/module/kanban/test/model/getcolumnsbyobject.php
new file mode 100755
index 0000000000..127ecc255a
--- /dev/null
+++ b/module/kanban/test/model/getcolumnsbyobject.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+getColumnsByObject();
+cid=1
+pid=1
+
+测试获取parent 457的看板列数量 >> 2
+测试获取parent 468的看板列数量 >> 2
+测试获取parent 471的看板列数量 >> 2
+测试获取parent 100001的看板列数量 >> 0
+测试获取region 1的看板列数量 >> 0
+测试获取region 2的看板列数量 >> 0
+测试获取region 3的看板列数量 >> 0
+测试获取region 100001的看板列数量 >> 0
+测试获取group 1的看板列数量 >> 7
+测试获取group 2的看板列数量 >> 9
+测试获取group 3的看板列数量 >> 9
+测试获取group 100001的看板列数量 >> 0
+
+*/
+
+$objectTypeList = array('parent', 'region', '`group`');
+$parentIDList = array('457', '468', '471', '100001');
+$regionIDList = array('1', '2', '3', '100001');
+$groupIDList = array('1', '2', '3', '100001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getColumnsByObjectTest($objectTypeList[0], $parentIDList[0])) && p() && e('2'); // 测试获取parent 457的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[0], $parentIDList[1])) && p() && e('2'); // 测试获取parent 468的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[0], $parentIDList[2])) && p() && e('2'); // 测试获取parent 471的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[0], $parentIDList[3])) && p() && e('0'); // 测试获取parent 100001的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[1], $parentIDList[0])) && p() && e('0'); // 测试获取region 1的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[1], $parentIDList[1])) && p() && e('0'); // 测试获取region 2的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[1], $parentIDList[2])) && p() && e('0'); // 测试获取region 3的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[1], $parentIDList[3])) && p() && e('0'); // 测试获取region 100001的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[2], $parentIDList[0])) && p() && e('7'); // 测试获取group 1的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[2], $parentIDList[1])) && p() && e('9'); // 测试获取group 2的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[2], $parentIDList[2])) && p() && e('9'); // 测试获取group 3的看板列数量
+r($kanban->getColumnsByObjectTest($objectTypeList[2], $parentIDList[3])) && p() && e('0'); // 测试获取group 100001的看板列数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getexecutionkanban.php b/module/kanban/test/model/getexecutionkanban.php
new file mode 100755
index 0000000000..460a955cf0
--- /dev/null
+++ b/module/kanban/test/model/getexecutionkanban.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+getExecutionKanban();
+cid=1
+pid=1
+
+测试获取execution101的执行看板信息 >> columns:27, lanes:3, cards:15
+测试获取execution101 story的执行看板信息 >> columns:11, lanes:1, cards:0
+测试获取execution101 task的执行看板信息 >> columns:7, lanes:1, cards:11
+测试获取execution101 bug的执行看板信息 >> columns:9, lanes:1, cards:4
+测试获取execution102的执行看板信息 >> columns:27, lanes:3, cards:10
+测试获取execution102 story pri的执行看板信息 >> columns:11, lanes:3, cards:2
+测试获取execution102 story category的执行看板信息 >> columns:11, lanes:2, cards:2
+测试获取execution103的执行看板信息 >> columns:27, lanes:3, cards:10
+测试获取execution103 task module的执行看板信息 >> columns:7, lanes:5, cards:4
+测试获取execution103 story source的执行看板信息 >> columns:11, lanes:3, cards:2
+测试获取execution103的执行看板信息 >> columns:27, lanes:3, cards:10
+测试获取execution103 bug module的执行看板信息 >> columns:9, lanes:2, cards:4
+测试获取execution103 bug source的执行看板信息 >> columns:9, lanes:5, cards:4
+测试获取execution103的执行看板信息 >> columns:27, lanes:3, cards:10
+测试获取execution103 bug module的执行看板信息 >> columns:9, lanes:5, cards:4
+测试获取execution103 bug severity的执行看板信息 >> columns:9, lanes:4, cards:4
+
+*/
+
+$executionIDList = array('101', '102', '103', '104', '105');
+$browseTypeList = array('story', 'task', 'bug');
+$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
+
+$kanban = new kanbanTest();
+
+r($kanban->getExecutionKanbanTest($executionIDList[0])) && p() && e('columns:27, lanes:3, cards:15'); // 测试获取execution101的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[0], $browseTypeList[0])) && p() && e('columns:11, lanes:1, cards:0'); // 测试获取execution101 story的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[0], $browseTypeList[1])) && p() && e('columns:7, lanes:1, cards:11'); // 测试获取execution101 task的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[0], $browseTypeList[2])) && p() && e('columns:9, lanes:1, cards:4'); // 测试获取execution101 bug的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[1])) && p() && e('columns:27, lanes:3, cards:10'); // 测试获取execution102的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[1], $browseTypeList[0], $groupByList[0])) && p() && e('columns:11, lanes:3, cards:2'); // 测试获取execution102 story pri的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[1], $browseTypeList[0], $groupByList[1])) && p() && e('columns:11, lanes:2, cards:2'); // 测试获取execution102 story category的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[2])) && p() && e('columns:27, lanes:3, cards:10'); // 测试获取execution103的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[2], $browseTypeList[1], $groupByList[2])) && p() && e('columns:7, lanes:5, cards:4'); // 测试获取execution103 task module的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[2], $browseTypeList[0], $groupByList[3])) && p() && e('columns:11, lanes:3, cards:2'); // 测试获取execution103 story source的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[3])) && p() && e('columns:27, lanes:3, cards:10'); // 测试获取execution103的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[3], $browseTypeList[2], $groupByList[4])) && p() && e('columns:9, lanes:2, cards:4'); // 测试获取execution103 bug module的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[3], $browseTypeList[2], $groupByList[5])) && p() && e('columns:9, lanes:5, cards:4'); // 测试获取execution103 bug source的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[4])) && p() && e('columns:27, lanes:3, cards:10'); // 测试获取execution103的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[4], $browseTypeList[2], $groupByList[5])) && p() && e('columns:9, lanes:5, cards:4'); // 测试获取execution103 bug module的执行看板信息
+r($kanban->getExecutionKanbanTest($executionIDList[4], $browseTypeList[2], $groupByList[6])) && p() && e('columns:9, lanes:4, cards:4'); // 测试获取execution103 bug severity的执行看板信息
diff --git a/module/kanban/test/model/getgroupbyspacelist.php b/module/kanban/test/model/getgroupbyspacelist.php
new file mode 100755
index 0000000000..a27676ff56
--- /dev/null
+++ b/module/kanban/test/model/getgroupbyspacelist.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+getGroupBySpaceList();
+cid=1
+pid=1
+
+获取空间1 2 3的看板 >> 6
+获取空间1 2 3 看板1,2,3,4的看板 >> 2
+获取空间4,5,6的看板 >> 6
+获取空间4,5,6 看板7,8,11,12的看板 >> 2
+获取空间7,8,9的看板 >> 6
+获取空间7,8,9 看板15,16,17,18的看板 >> 2
+获取空间10,11,12的看板 >> 6
+获取空间10,11,12 看板19,20,21,22,23,24,25的看板 >> 3
+获取空间13,14,15的看板 >> 6
+获取空间13,14,15 看板26,28,30的看板 >> 3
+
+*/
+
+$spaceIDList = array('1,2,3', '4,5,6', '7,8,9', '10,11,12', '13,14,15');
+$kanbanIDList = array('1,2,3,4', '7,8,11,12', '15,16,17,18', '19,20,21,22,23,24,25', '26,28,30');
+
+$kanban = new kanbanTest();
+
+r($kanban->getGroupBySpaceListTest($spaceIDList[0])) && p() && e('6'); // 获取空间1 2 3的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[0], $kanbanIDList[0])) && p() && e('2'); // 获取空间1 2 3 看板1,2,3,4的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[1])) && p() && e('6'); // 获取空间4,5,6的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[1], $kanbanIDList[1])) && p() && e('2'); // 获取空间4,5,6 看板7,8,11,12的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[2])) && p() && e('6'); // 获取空间7,8,9的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[2], $kanbanIDList[2])) && p() && e('2'); // 获取空间7,8,9 看板15,16,17,18的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[3])) && p() && e('6'); // 获取空间10,11,12的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[3], $kanbanIDList[3])) && p() && e('3'); // 获取空间10,11,12 看板19,20,21,22,23,24,25的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[4])) && p() && e('6'); // 获取空间13,14,15的看板
+r($kanban->getGroupBySpaceListTest($spaceIDList[4], $kanbanIDList[4])) && p() && e('3'); // 获取空间13,14,15 看板26,28,30的看板
\ No newline at end of file
diff --git a/module/kanban/test/model/getgroupgroupbyregions.php b/module/kanban/test/model/getgroupgroupbyregions.php
new file mode 100755
index 0000000000..f3ad3bdb3f
--- /dev/null
+++ b/module/kanban/test/model/getgroupgroupbyregions.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getGroupGroupByRegions();
+cid=1
+pid=1
+
+获取区域1 2 3的泳道组数量 >> 3
+获取区域4,5,6的泳道组数量 >> 3
+获取区域7,8,9的泳道组数量 >> 3
+获取区域10,11,12的泳道组数量 >> 3
+获取区域13,14,15的泳道组数量 >> 3
+
+*/
+
+$regions = array('1,2,3', '4,5,6', '7,8,9', '10,11,12', '13,14,15');
+
+$kanban = new kanbanTest();
+
+r($kanban->getGroupGroupByRegionsTest($regions[0])) && p() && e('3'); //获取区域1 2 3的泳道组数量
+r($kanban->getGroupGroupByRegionsTest($regions[1])) && p() && e('3'); //获取区域4,5,6的泳道组数量
+r($kanban->getGroupGroupByRegionsTest($regions[2])) && p() && e('3'); //获取区域7,8,9的泳道组数量
+r($kanban->getGroupGroupByRegionsTest($regions[3])) && p() && e('3'); //获取区域10,11,12的泳道组数量
+r($kanban->getGroupGroupByRegionsTest($regions[4])) && p() && e('3'); //获取区域13,14,15的泳道组数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getgrouplist.php b/module/kanban/test/model/getgrouplist.php
new file mode 100755
index 0000000000..4b01d2ca5e
--- /dev/null
+++ b/module/kanban/test/model/getgrouplist.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getGroupList();
+cid=1
+pid=1
+
+获取区域1的看板 >> ,1
+获取区域1的看板 >> ,2
+获取区域1的看板 >> ,179,180,181
+获取区域1的看板 >> ,182,183,184
+获取区域1的看板 >> ,185,186,187
+获取区域1的看板 >> 0
+
+*/
+
+$regionIDList = array('1', '2', '107', '108', '109', '10001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getGroupListTest($regionIDList[0])) && p() && e(',1'); // 获取区域1的看板
+r($kanban->getGroupListTest($regionIDList[1])) && p() && e(',2'); // 获取区域1的看板
+r($kanban->getGroupListTest($regionIDList[2])) && p() && e(',179,180,181'); // 获取区域1的看板
+r($kanban->getGroupListTest($regionIDList[3])) && p() && e(',182,183,184'); // 获取区域1的看板
+r($kanban->getGroupListTest($regionIDList[4])) && p() && e(',185,186,187'); // 获取区域1的看板
+r($kanban->getGroupListTest($regionIDList[5])) && p() && e('0'); // 获取区域1的看板
\ No newline at end of file
diff --git a/module/kanban/test/model/getimportedcards.php b/module/kanban/test/model/getimportedcards.php
new file mode 100755
index 0000000000..79cf4e5fa5
--- /dev/null
+++ b/module/kanban/test/model/getimportedcards.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+getImportedCards();
+cid=1
+pid=1
+
+查看看板1的普通卡片和productplan卡片 >> ,1,2,3,4,5,6,7,8,801,802,803,804,805,806,807,808
+查看看板1的普通卡片和release卡片 >> ,1,2,3,4,5,6,7,8
+查看看板2的普通卡片和productplan卡片 >> ,9,10,11,12,13,14,15,16,809,810,811,812,813,814,815,816
+查看看板2的普通卡片和release卡片 >> ,9,10,11,12,13,14,15,16
+查看看板9的普通卡片和release卡片 >> ,65,66,67,68,69,70,71,72,871,872
+查看看板9的普通卡片和execution卡片 >> ,65,66,67,68,69,70,71,72
+查看看板10的普通卡片和release卡片 >> ,73,74,75,76,77,78,79,80,873,874,875,876,877,878,879,880
+查看看板10的普通卡片和execution卡片 >> ,73,74,75,76,77,78,79,80
+查看看板11的普通卡片和execution卡片 >> ,81,82,83,84,85,86,87,88,881,882,883,884,885,886,887,888
+查看看板11的普通卡片和build卡片 >> ,81,82,83,84,85,86,87,88
+查看看板12的普通卡片和execution卡片 >> ,89,90,91,92,93,94,95,96,889,890,891,892,893,894,895,896
+查看看板12的普通卡片和build卡片 >> ,89,90,91,92,93,94,95,96
+查看看板23的普通卡片和build卡片 >> ,177,178,179,180,181,182,183,184,981,982,983,984
+查看看板23的普通卡片和productplan片 >> ,177,178,179,180,181,182,183,184
+查看看板25的普通卡片和build卡片 >> ,193,194,195,196,197,198,199,200,993,994,995,996,997,998,999,1000
+查看看板25的普通卡片和productplan片 >> ,193,194,195,196,197,198,199,200
+ >> id
+查看看板1已归档的普通卡片和productplan卡片 >> ,6,7,8,801,802,803,804,805,806,807,808
+查看区域ID=1中看板1已归档的普通卡片和productplan卡片 >> ,6,7,8,801,802,803,804,805,806,807,808
+查看区域ID=1中看板1已归档的普通卡片和productplan卡片 >> id
+
+*/
+
+$kanbanIDList = array('1', '2', '9', '10', '11', '12', '23', '25');
+$fromType = array('productplan', 'release', 'execution', 'build');
+$archived = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[0])) && p() && e(',1,2,3,4,5,6,7,8,801,802,803,804,805,806,807,808'); // 查看看板1的普通卡片和productplan卡片
+r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[1])) && p() && e(',1,2,3,4,5,6,7,8'); // 查看看板1的普通卡片和release卡片
+r($kanban->getImportedCardsTest($kanbanIDList[1], $fromType[0])) && p() && e(',9,10,11,12,13,14,15,16,809,810,811,812,813,814,815,816'); // 查看看板2的普通卡片和productplan卡片
+r($kanban->getImportedCardsTest($kanbanIDList[1], $fromType[1])) && p() && e(',9,10,11,12,13,14,15,16'); // 查看看板2的普通卡片和release卡片
+r($kanban->getImportedCardstest($kanbanIDList[2], $fromType[1])) && p() && e(',65,66,67,68,69,70,71,72,871,872'); // 查看看板9的普通卡片和release卡片
+r($kanban->getImportedCardstest($kanbanIDList[2], $fromType[2])) && p() && e(',65,66,67,68,69,70,71,72'); // 查看看板9的普通卡片和execution卡片
+r($kanban->getImportedCardstest($kanbanIDList[3], $fromType[1])) && p() && e(',73,74,75,76,77,78,79,80,873,874,875,876,877,878,879,880'); // 查看看板10的普通卡片和release卡片
+r($kanban->getImportedCardstest($kanbanIDList[3], $fromType[2])) && p() && e(',73,74,75,76,77,78,79,80'); // 查看看板10的普通卡片和execution卡片
+r($kanban->getImportedCardstest($kanbanIDList[4], $fromType[2])) && p() && e(',81,82,83,84,85,86,87,88,881,882,883,884,885,886,887,888'); // 查看看板11的普通卡片和execution卡片
+r($kanban->getImportedCardstest($kanbanIDList[4], $fromType[3])) && p() && e(',81,82,83,84,85,86,87,88'); // 查看看板11的普通卡片和build卡片
+r($kanban->getImportedCardstest($kanbanIDList[5], $fromType[2])) && p() && e(',89,90,91,92,93,94,95,96,889,890,891,892,893,894,895,896'); // 查看看板12的普通卡片和execution卡片
+r($kanban->getImportedCardstest($kanbanIDList[5], $fromType[3])) && p() && e(',89,90,91,92,93,94,95,96'); // 查看看板12的普通卡片和build卡片
+r($kanban->getImportedCardstest($kanbanIDList[6], $fromType[3])) && p() && e(',177,178,179,180,181,182,183,184,981,982,983,984'); // 查看看板23的普通卡片和build卡片
+r($kanban->getImportedCardstest($kanbanIDList[6], $fromType[0])) && p() && e(',177,178,179,180,181,182,183,184'); // 查看看板23的普通卡片和productplan片
+r($kanban->getImportedCardstest($kanbanIDList[7], $fromType[3])) && p() && e(',193,194,195,196,197,198,199,200,993,994,995,996,997,998,999,1000'); // 查看看板25的普通卡片和build卡片
+r($kanban->getImportedCardstest($kanbanIDList[7], $fromType[0])) && p() && e(',193,194,195,196,197,198,199,200'); // 查看看板25的普通卡片和productplan片
+global $tester;
+$tester->dao->update(TABLE_KANBANCARD)->set('archived')->eq(1)->where('id')->gt('5')->exec();
+r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[0], $archived)) && p() && e(',6,7,8,801,802,803,804,805,806,807,808'); // 查看看板1已归档的普通卡片和productplan卡片
+r($kanban->getImportedCardsTest($kanbanIDList[0], $fromType[0], $archived, 1)) && p() && e(',6,7,8,801,802,803,804,805,806,807,808'); // 查看区域ID=1中看板1已归档的普通卡片和productplan卡片
+$tester->dao->update(TABLE_KANBANCARD)->set('archived')->eq(0)->where('id')->gt('5')->exec();
\ No newline at end of file
diff --git a/module/kanban/test/model/getkanban4group.php b/module/kanban/test/model/getkanban4group.php
new file mode 100755
index 0000000000..e9436e80f6
--- /dev/null
+++ b/module/kanban/test/model/getkanban4group.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+getKanban4Group();
+cid=1
+pid=1
+
+获取执行101 类型story 分组pri的看板信息 >> lanes:3
+获取执行101 类型story 分组category的看板信息 >> lanes:2
+获取执行101 类型story 分组module的看板信息 >> lanes:3
+获取执行101 类型story 分组source的看板信息 >> lanes:3
+获取执行102 类型task 分组pri的看板信息 >> lanes:4
+获取执行102 类型task 分组module的看板信息 >> lanes:5
+获取执行102 类型task 分组assignedTo的看板信息 >> lanes:1
+获取执行102 类型task 分组story的看板信息 >> lanes:2
+获取执行103 类型bug 分组pri的看板信息 >> lanes:4
+获取执行103 类型bug 分组module的看板信息 >> lanes:4
+获取执行103 类型bug 分组assignedTo的看板信息 >> lanes:3
+获取执行103 类型bug 分组severity的看板信息 >> lanes:4
+获取执行104 类型story 分组pri的看板信息 >> lanes:3
+获取执行105 类型story 分组pri的看板信息 >> lanes:3
+
+*/
+
+$executionIDList = array('101', '102', '103', '104', '105');
+$browseTypeList = array('story', 'task', 'bug');
+$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
+
+$kanban = new kanbanTest();
+
+r($kanban->getKanban4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[0])) && p() && e('lanes:3'); //获取执行101 类型story 分组pri的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[1])) && p() && e('lanes:2'); //获取执行101 类型story 分组category的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[2])) && p() && e('lanes:3'); //获取执行101 类型story 分组module的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[3])) && p() && e('lanes:3'); //获取执行101 类型story 分组source的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[0])) && p() && e('lanes:4'); //获取执行102 类型task 分组pri的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[2])) && p() && e('lanes:5'); //获取执行102 类型task 分组module的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[4])) && p() && e('lanes:1'); //获取执行102 类型task 分组assignedTo的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[5])) && p() && e('lanes:2'); //获取执行102 类型task 分组story的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[0])) && p() && e('lanes:4'); //获取执行103 类型bug 分组pri的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[2])) && p() && e('lanes:4'); //获取执行103 类型bug 分组module的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[4])) && p() && e('lanes:3'); //获取执行103 类型bug 分组assignedTo的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[6])) && p() && e('lanes:4'); //获取执行103 类型bug 分组severity的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[0])) && p() && e('lanes:3'); //获取执行104 类型story 分组pri的看板信息
+r($kanban->getKanban4GroupTest($executionIDList[4], $browseTypeList[0], $groupByList[0])) && p() && e('lanes:3'); //获取执行105 类型story 分组pri的看板信息
diff --git a/module/kanban/test/model/getkanbancardmenu.php b/module/kanban/test/model/getkanbancardmenu.php
new file mode 100755
index 0000000000..920854bee7
--- /dev/null
+++ b/module/kanban/test/model/getkanbancardmenu.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+getKanbanCardMenu();
+cid=1
+pid=1
+
+测试获取执行101 story的操作数量 >> 12
+测试获取执行101 task的操作数量 >> 60
+测试获取执行101 bug的操作数量 >> 23
+测试获取执行102 story的操作数量 >> 12
+测试获取执行102 task的操作数量 >> 26
+测试获取执行102 bug的操作数量 >> 22
+测试获取执行103 story的操作数量 >> 12
+测试获取执行103 task的操作数量 >> 25
+测试获取执行103 bug的操作数量 >> 23
+测试获取执行104 story的操作数量 >> 12
+测试获取执行104 task的操作数量 >> 26
+测试获取执行104 bug的操作数量 >> 22
+测试获取执行105 story的操作数量 >> 12
+测试获取执行105 task的操作数量 >> 25
+测试获取执行105 bug的操作数量 >> 23
+
+*/
+
+$executionIDList = array('101', '102', '103', '104', '105');
+$browseTypeList = array('story', 'task', 'bug');
+
+$kanban = new kanbanTest();
+
+r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[0])) && p() && e('12'); // 测试获取执行101 story的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[1])) && p() && e('60'); // 测试获取执行101 task的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[0], $browseTypeList[2])) && p() && e('23'); // 测试获取执行101 bug的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[0])) && p() && e('12'); // 测试获取执行102 story的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[1])) && p() && e('26'); // 测试获取执行102 task的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[1], $browseTypeList[2])) && p() && e('22'); // 测试获取执行102 bug的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[0])) && p() && e('12'); // 测试获取执行103 story的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[1])) && p() && e('25'); // 测试获取执行103 task的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[2], $browseTypeList[2])) && p() && e('23'); // 测试获取执行103 bug的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[0])) && p() && e('12'); // 测试获取执行104 story的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[1])) && p() && e('26'); // 测试获取执行104 task的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[3], $browseTypeList[2])) && p() && e('22'); // 测试获取执行104 bug的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[0])) && p() && e('12'); // 测试获取执行105 story的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[1])) && p() && e('25'); // 测试获取执行105 task的操作数量
+r($kanban->getKanbanCardMenuTest($executionIDList[4], $browseTypeList[2])) && p() && e('23'); // 测试获取执行105 bug的操作数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getkanbandata.php b/module/kanban/test/model/getkanbandata.php
new file mode 100755
index 0000000000..1e96c123a6
--- /dev/null
+++ b/module/kanban/test/model/getkanbandata.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getKanbanData();
+cid=1
+pid=1
+
+测试获取kanban1的视图 >> columns:4, lanes:1, cards:4
+测试获取kanban2的视图 >> columns:4, lanes:1, cards:4
+测试获取kanban3的视图 >> columns:4, lanes:1, cards:4
+测试获取kanban4的视图 >> columns:4, lanes:1, cards:4
+测试获取kanban5的视图 >> columns:4, lanes:1, cards:4
+测试获取不存在的kanban的视图 >> columns:0, lanes:0, cards:0
+
+*/
+
+$kanbanIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getKanbanDataTest($kanbanIDList[0])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban1的视图
+r($kanban->getKanbanDataTest($kanbanIDList[1])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban2的视图
+r($kanban->getKanbanDataTest($kanbanIDList[2])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban3的视图
+r($kanban->getKanbanDataTest($kanbanIDList[3])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban4的视图
+r($kanban->getKanbanDataTest($kanbanIDList[4])) && p() && e('columns:4, lanes:1, cards:4'); // 测试获取kanban5的视图
+r($kanban->getKanbanDataTest($kanbanIDList[5])) && p() && e('columns:0, lanes:0, cards:0'); // 测试获取不存在的kanban的视图
\ No newline at end of file
diff --git a/module/kanban/test/model/getkanbanidbyregion.php b/module/kanban/test/model/getkanbanidbyregion.php
new file mode 100755
index 0000000000..467377ebb4
--- /dev/null
+++ b/module/kanban/test/model/getkanbanidbyregion.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getKanbanIDByRegion();
+cid=1
+pid=1
+
+测试通过区域1获取看板id >> 1
+测试通过区域2获取看板id >> 2
+测试通过区域3获取看板id >> 3
+测试通过区域4获取看板id >> 4
+测试通过区域5获取看板id >> 5
+测试通过不存在的区域获取看板id >> 0
+
+*/
+$regionIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getKanbanIDByRegionTest($regionIDList[0])) && p() && e('1'); // 测试通过区域1获取看板id
+r($kanban->getKanbanIDByRegionTest($regionIDList[1])) && p() && e('2'); // 测试通过区域2获取看板id
+r($kanban->getKanbanIDByRegionTest($regionIDList[2])) && p() && e('3'); // 测试通过区域3获取看板id
+r($kanban->getKanbanIDByRegionTest($regionIDList[3])) && p() && e('4'); // 测试通过区域4获取看板id
+r($kanban->getKanbanIDByRegionTest($regionIDList[4])) && p() && e('5'); // 测试通过区域5获取看板id
+r($kanban->getKanbanIDByRegionTest($regionIDList[5])) && p() && e('0'); // 测试通过不存在的区域获取看板id
\ No newline at end of file
diff --git a/module/kanban/test/model/getkanbanpairs.php b/module/kanban/test/model/getkanbanpairs.php
new file mode 100755
index 0000000000..e1324a0d8c
--- /dev/null
+++ b/module/kanban/test/model/getkanbanpairs.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getKanbanPairs();
+cid=1
+pid=1
+
+获取用户admin可以看到的看板pairs >> 100
+获取用户po1可以看到的看板pairs >> 32
+获取用户po2可以看到的看板pairs >> 32
+获取用户user1可以看到的看板pairs >> 32
+获取用户user2可以看到的看板pairs >> 32
+获取用户pm1可以看到的看板pairs >> 32
+获取用户pm2可以看到的看板pairs >> 32
+
+*/
+
+$userList = array('admin', 'po1', 'po2', 'user1', 'user2', 'pm1', 'pm2');
+
+$kanban = new kanbanTest();
+
+r($kanban->getKanbanPairsTest($userList[0])) && p() && e('100'); //获取用户admin可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[1])) && p() && e('32'); //获取用户po1可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[2])) && p() && e('32'); //获取用户po2可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[3])) && p() && e('32'); //获取用户user1可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[4])) && p() && e('32'); //获取用户user2可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[5])) && p() && e('32'); //获取用户pm1可以看到的看板pairs
+r($kanban->getKanbanPairsTest($userList[6])) && p() && e('32'); //获取用户pm2可以看到的看板pairs
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanebyid.php b/module/kanban/test/model/getlanebyid.php
new file mode 100755
index 0000000000..291df8316a
--- /dev/null
+++ b/module/kanban/test/model/getlanebyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getLaneById();
+cid=1
+pid=1
+
+测试通过id1获取泳道信息 >> 默认泳道,common,1,1
+测试通过id2获取泳道信息 >> 默认泳道,common,2,2
+测试通过id3获取泳道信息 >> 默认泳道,common,3,3
+测试通过id4获取泳道信息 >> 默认泳道,common,4,4
+测试通过id5获取泳道信息 >> 默认泳道,common,5,5
+测试通过不存在的id获取泳道信息 >> 0
+
+*/
+
+$laneIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getLaneByIdTest($laneIDList[0])) && p('name,type,region,group') && e('默认泳道,common,1,1'); // 测试通过id1获取泳道信息
+r($kanban->getLaneByIdTest($laneIDList[1])) && p('name,type,region,group') && e('默认泳道,common,2,2'); // 测试通过id2获取泳道信息
+r($kanban->getLaneByIdTest($laneIDList[2])) && p('name,type,region,group') && e('默认泳道,common,3,3'); // 测试通过id3获取泳道信息
+r($kanban->getLaneByIdTest($laneIDList[3])) && p('name,type,region,group') && e('默认泳道,common,4,4'); // 测试通过id4获取泳道信息
+r($kanban->getLaneByIdTest($laneIDList[4])) && p('name,type,region,group') && e('默认泳道,common,5,5'); // 测试通过id5获取泳道信息
+r($kanban->getLaneByIdTest($laneIDList[5])) && p('name,type,region,group') && e('0'); // 测试通过不存在的id获取泳道信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanegroupbyregion.php b/module/kanban/test/model/getlanegroupbyregion.php
new file mode 100755
index 0000000000..0dd4ba5073
--- /dev/null
+++ b/module/kanban/test/model/getlanegroupbyregion.php
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+getLaneGroupByRegion();
+cid=1
+pid=1
+
+测试获取区域101的泳道 >> 3
+测试获取区域101的bug泳道 >> 1
+测试获取区域101的task泳道 >> 1
+测试获取区域101的story泳道 >> 1
+测试获取区域102的泳道 >> 3
+测试获取区域102的bug泳道 >> 1
+测试获取区域102的task泳道 >> 1
+测试获取区域102的story泳道 >> 1
+测试获取区域103的泳道 >> 3
+测试获取区域103的bug泳道 >> 1
+测试获取区域103的task泳道 >> 1
+测试获取区域103的story泳道 >> 1
+测试获取区域104的泳道 >> 3
+测试获取区域104的bug泳道 >> 1
+测试获取区域104的task泳道 >> 1
+测试获取区域104的story泳道 >> 1
+测试获取区域105的泳道 >> 3
+测试获取区域105的bug泳道 >> 1
+测试获取区域105的task泳道 >> 1
+测试获取区域105的story泳道 >> 1
+测试获取不存在的区域的泳道 >> 0
+测试获取不存在的区域的bug泳道 >> 0
+测试获取不存在的区域的task泳道 >> 0
+测试获取不存在的区域的story泳道 >> 0
+
+*/
+
+$regionIDList = array('101', '102', '103', '104', '105', '1000001');
+$type = array('bug', 'task', 'story');
+
+$kanban = new kanbanTest();
+r($kanban->getLaneGroupByRegionTest($regionIDList[0])) && p() && e('3'); // 测试获取区域101的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[0])) && p() && e('1'); // 测试获取区域101的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[1])) && p() && e('1'); // 测试获取区域101的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[0], $type[2])) && p() && e('1'); // 测试获取区域101的story泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[1])) && p() && e('3'); // 测试获取区域102的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[0])) && p() && e('1'); // 测试获取区域102的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[1])) && p() && e('1'); // 测试获取区域102的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[1], $type[2])) && p() && e('1'); // 测试获取区域102的story泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[2])) && p() && e('3'); // 测试获取区域103的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[0])) && p() && e('1'); // 测试获取区域103的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[1])) && p() && e('1'); // 测试获取区域103的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[2], $type[2])) && p() && e('1'); // 测试获取区域103的story泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[3])) && p() && e('3'); // 测试获取区域104的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[0])) && p() && e('1'); // 测试获取区域104的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[1])) && p() && e('1'); // 测试获取区域104的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[3], $type[2])) && p() && e('1'); // 测试获取区域104的story泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[4])) && p() && e('3'); // 测试获取区域105的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[0])) && p() && e('1'); // 测试获取区域105的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[1])) && p() && e('1'); // 测试获取区域105的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[4], $type[2])) && p() && e('1'); // 测试获取区域105的story泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道
+r($kanban->getLaneGroupByRegionTest($regionIDList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanegroupbyregions.php b/module/kanban/test/model/getlanegroupbyregions.php
new file mode 100755
index 0000000000..27c014faef
--- /dev/null
+++ b/module/kanban/test/model/getlanegroupbyregions.php
@@ -0,0 +1,67 @@
+#!/usr/bin/env php
+getLaneGroupByRegions();
+cid=1
+pid=1
+
+测试获取区域101,102,103的泳道 >> 9
+测试获取区域101,102,103的bug泳道 >> 3
+测试获取区域101,102,103的task泳道 >> 3
+测试获取区域101,102,103的story泳道 >> 3
+测试获取区域104,105,106的泳道 >> 9
+测试获取区域104,105,106的bug泳道 >> 3
+测试获取区域104,105,106的task泳道 >> 3
+测试获取区域104,105,106的story泳道 >> 3
+测试获取区域107,108,109的泳道 >> 9
+测试获取区域107,108,109的bug泳道 >> 3
+测试获取区域107,108,109的task泳道 >> 3
+测试获取区域107,108,109的story泳道 >> 3
+测试获取区域110,111,112的泳道 >> 9
+测试获取区域110,111,112的bug泳道 >> 3
+测试获取区域110,111,112的task泳道 >> 3
+测试获取区域110,111,112的story泳道 >> 3
+测试获取区域113,114,115的泳道 >> 9
+测试获取区域113,114,115的bug泳道 >> 3
+测试获取区域113,114,115的task泳道 >> 3
+测试获取区域113,114,115的story泳道 >> 3
+测试获取不存在的区域的泳道 >> 0
+测试获取不存在的区域的bug泳道 >> 0
+测试获取不存在的区域的task泳道 >> 0
+测试获取不存在的区域的story泳道 >> 0
+
+*/
+$regionsList = array('101,102,103', '104,105,106', '107,108,109', '110,111,112', '113,114,115', '1000001');
+$type = array('bug', 'task', 'story');
+
+$kanban = new kanbanTest();
+
+r($kanban->getLaneGroupByRegionsTest($regionsList[0])) && p() && e('9'); // 测试获取区域101,102,103的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[0])) && p() && e('3'); // 测试获取区域101,102,103的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[1])) && p() && e('3'); // 测试获取区域101,102,103的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[0], $type[2])) && p() && e('3'); // 测试获取区域101,102,103的story泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[1])) && p() && e('9'); // 测试获取区域104,105,106的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[0])) && p() && e('3'); // 测试获取区域104,105,106的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[1])) && p() && e('3'); // 测试获取区域104,105,106的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[1], $type[2])) && p() && e('3'); // 测试获取区域104,105,106的story泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[2])) && p() && e('9'); // 测试获取区域107,108,109的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[0])) && p() && e('3'); // 测试获取区域107,108,109的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[1])) && p() && e('3'); // 测试获取区域107,108,109的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[2], $type[2])) && p() && e('3'); // 测试获取区域107,108,109的story泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[3])) && p() && e('9'); // 测试获取区域110,111,112的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[0])) && p() && e('3'); // 测试获取区域110,111,112的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[1])) && p() && e('3'); // 测试获取区域110,111,112的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[3], $type[2])) && p() && e('3'); // 测试获取区域110,111,112的story泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[4])) && p() && e('9'); // 测试获取区域113,114,115的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[0])) && p() && e('3'); // 测试获取区域113,114,115的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[1])) && p() && e('3'); // 测试获取区域113,114,115的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[4], $type[2])) && p() && e('3'); // 测试获取区域113,114,115的story泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道
+r($kanban->getLaneGroupByRegionsTest($regionsList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanepairsbygroup.php b/module/kanban/test/model/getlanepairsbygroup.php
new file mode 100755
index 0000000000..37fc1eb64a
--- /dev/null
+++ b/module/kanban/test/model/getlanepairsbygroup.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getLanePairsByGroup();
+cid=1
+pid=1
+
+获取泳道组101的泳道 >> 研发需求
+获取泳道组102的泳道 >> Bug
+获取泳道组103的泳道 >> 任务
+获取泳道组104的泳道 >> 研发需求
+获取泳道组105的泳道 >> Bug
+获取不存在泳道组的泳道 >> 0
+
+*/
+
+$groupIDList = array('101', '102', '103', '104', '105', '1000001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getLanePairsByGroupTest($groupIDList[0])) && p() && e('研发需求'); // 获取泳道组101的泳道
+r($kanban->getLanePairsByGroupTest($groupIDList[1])) && p() && e('Bug'); // 获取泳道组102的泳道
+r($kanban->getLanePairsByGroupTest($groupIDList[2])) && p() && e('任务'); // 获取泳道组103的泳道
+r($kanban->getLanePairsByGroupTest($groupIDList[3])) && p() && e('研发需求'); // 获取泳道组104的泳道
+r($kanban->getLanePairsByGroupTest($groupIDList[4])) && p() && e('Bug'); // 获取泳道组105的泳道
+r($kanban->getLanePairsByGroupTest($groupIDList[5])) && p() && e('0'); // 获取不存在泳道组的泳道
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanepairsbyregion.php b/module/kanban/test/model/getlanepairsbyregion.php
new file mode 100755
index 0000000000..f1d18ec6cb
--- /dev/null
+++ b/module/kanban/test/model/getlanepairsbyregion.php
@@ -0,0 +1,68 @@
+#!/usr/bin/env php
+getLanePairsByRegion();
+cid=1
+pid=1
+
+测试获取区域101的泳道 >> 研发需求,Bug,任务
+测试获取区域101的bug泳道 >> Bug
+测试获取区域101的task泳道 >> 任务
+测试获取区域101的story泳道 >> 研发需求
+测试获取区域102的泳道 >> 研发需求,Bug,任务
+测试获取区域102的bug泳道 >> Bug
+测试获取区域102的task泳道 >> 任务
+测试获取区域102的story泳道 >> 研发需求
+测试获取区域103的泳道 >> 研发需求,Bug,任务
+测试获取区域103的bug泳道 >> Bug
+测试获取区域103的task泳道 >> 任务
+测试获取区域103的story泳道 >> 研发需求
+测试获取区域104的泳道 >> 研发需求,Bug,任务
+测试获取区域104的bug泳道 >> Bug
+测试获取区域104的task泳道 >> 任务
+测试获取区域104的story泳道 >> 研发需求
+测试获取区域105的泳道 >> 研发需求,Bug,任务
+测试获取区域105的bug泳道 >> Bug
+测试获取区域105的task泳道 >> 任务
+测试获取区域105的story泳道 >> 研发需求
+测试获取不存在的区域的泳道 >> 0
+测试获取不存在的区域的bug泳道 >> 0
+测试获取不存在的区域的task泳道 >> 0
+测试获取不存在的区域的story泳道 >> 0
+
+*/
+
+$regionIDList = array('101', '102', '103', '104', '105', '1000001');
+$type = array('bug', 'task', 'story');
+
+$kanban = new kanbanTest();
+
+r($kanban->getLanePairsByRegionTest($regionIDList[0])) && p() && e('研发需求,Bug,任务'); // 测试获取区域101的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[0])) && p() && e('Bug'); // 测试获取区域101的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[1])) && p() && e('任务'); // 测试获取区域101的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[0], $type[2])) && p() && e('研发需求'); // 测试获取区域101的story泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[1])) && p() && e('研发需求,Bug,任务'); // 测试获取区域102的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[0])) && p() && e('Bug'); // 测试获取区域102的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[1])) && p() && e('任务'); // 测试获取区域102的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[1], $type[2])) && p() && e('研发需求'); // 测试获取区域102的story泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[2])) && p() && e('研发需求,Bug,任务'); // 测试获取区域103的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[0])) && p() && e('Bug'); // 测试获取区域103的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[1])) && p() && e('任务'); // 测试获取区域103的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[2], $type[2])) && p() && e('研发需求'); // 测试获取区域103的story泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[3])) && p() && e('研发需求,Bug,任务'); // 测试获取区域104的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[0])) && p() && e('Bug'); // 测试获取区域104的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[1])) && p() && e('任务'); // 测试获取区域104的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[3], $type[2])) && p() && e('研发需求'); // 测试获取区域104的story泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[4])) && p() && e('研发需求,Bug,任务'); // 测试获取区域105的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[0])) && p() && e('Bug'); // 测试获取区域105的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[1])) && p() && e('任务'); // 测试获取区域105的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[4], $type[2])) && p() && e('研发需求'); // 测试获取区域105的story泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[5])) && p() && e('0'); // 测试获取不存在的区域的泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[0])) && p() && e('0'); // 测试获取不存在的区域的bug泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[1])) && p() && e('0'); // 测试获取不存在的区域的task泳道
+r($kanban->getLanePairsByRegionTest($regionIDList[5], $type[2])) && p() && e('0'); // 测试获取不存在的区域的story泳道
\ No newline at end of file
diff --git a/module/kanban/test/model/getlanes4group.php b/module/kanban/test/model/getlanes4group.php
new file mode 100755
index 0000000000..b837cd8d92
--- /dev/null
+++ b/module/kanban/test/model/getlanes4group.php
@@ -0,0 +1,60 @@
+#!/usr/bin/env php
+getLanes4Group();
+cid=1
+pid=1
+
+获取执行101 story pri的泳道 >> ,优先级: 无,2,4
+获取执行101 story category的泳道 >> ,类型: 无,功能
+获取执行101 story module的泳道 >> ,所属模块: 无,产品模块2,产品模块4
+获取执行101 story source的泳道 >> ,来源: 无,用户,市场
+获取执行102 task pri的泳道 >> ,优先级: 无,1,2,4
+获取执行102 task module的泳道 >> ,所属模块: 无,模块4,模块10,模块13,模块16
+获取执行102 task assignedTo的泳道 >> ,指派给: 无
+获取执行102 task story的泳道 >> ,相关研发需求: 无,用户需求5
+获取执行101 bug pri的泳道 >> ,优先级: 无,1,3,4
+获取执行101 bug module的泳道 >> ,所属模块: 无,产品模块11,产品模块12,产品模块13
+获取执行101 bug assignedTo的泳道 >> ,指派给: 无,admin,测试1
+获取执行101 bug severity的泳道 >> ,严重程度: 无,1,3,4
+获取执行101 story pri的泳道 >> ,优先级: 无,2,4
+获取执行101 story category的泳道 >> ,类型: 无,功能
+获取执行101 story module的泳道 >> ,所属模块: 无,产品模块14,产品模块16
+获取执行101 story source的泳道 >> ,来源: 无,用户,其他
+获取执行102 task pri的泳道 >> ,优先级: 无,1,2,3
+获取执行102 task module的泳道 >> ,所属模块: 无,模块13,模块37,模块40,模块43
+获取执行102 task assignedTo的泳道 >> ,指派给: 无
+获取执行102 task story的泳道 >> ,相关研发需求: 无,用户需求17
+
+*/
+$executionIDList = array('101', '102', '103', '104', '105');
+$browseTypeList = array('story', 'task', 'bug');
+$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
+
+$kanban = new kanbanTest();
+
+r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[0])) && p() && e(',优先级: 无,2,4'); // 获取执行101 story pri的泳道
+r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[1])) && p() && e(',类型: 无,功能'); // 获取执行101 story category的泳道
+r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[2])) && p() && e(',所属模块: 无,产品模块2,产品模块4'); // 获取执行101 story module的泳道
+r($kanban->getLanes4GroupTest($executionIDList[0], $browseTypeList[0], $groupByList[3])) && p() && e(',来源: 无,用户,市场'); // 获取执行101 story source的泳道
+r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[0])) && p() && e(',优先级: 无,1,2,4'); // 获取执行102 task pri的泳道
+r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[2])) && p() && e(',所属模块: 无,模块4,模块10,模块13,模块16'); // 获取执行102 task module的泳道
+r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[4])) && p() && e(',指派给: 无'); // 获取执行102 task assignedTo的泳道
+r($kanban->getLanes4GroupTest($executionIDList[1], $browseTypeList[1], $groupByList[5])) && p() && e(',相关研发需求: 无,用户需求5'); // 获取执行102 task story的泳道
+r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[0])) && p() && e(',优先级: 无,1,3,4'); // 获取执行101 bug pri的泳道
+r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[2])) && p() && e(',所属模块: 无,产品模块11,产品模块12,产品模块13'); // 获取执行101 bug module的泳道
+r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[4])) && p() && e(',指派给: 无,admin,测试1'); // 获取执行101 bug assignedTo的泳道
+r($kanban->getLanes4GroupTest($executionIDList[2], $browseTypeList[2], $groupByList[6])) && p() && e(',严重程度: 无,1,3,4'); // 获取执行101 bug severity的泳道
+r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[0])) && p() && e(',优先级: 无,2,4'); // 获取执行101 story pri的泳道
+r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[1])) && p() && e(',类型: 无,功能'); // 获取执行101 story category的泳道
+r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[2])) && p() && e(',所属模块: 无,产品模块14,产品模块16'); // 获取执行101 story module的泳道
+r($kanban->getLanes4GroupTest($executionIDList[3], $browseTypeList[0], $groupByList[3])) && p() && e(',来源: 无,用户,其他'); // 获取执行101 story source的泳道
+r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[0])) && p() && e(',优先级: 无,1,2,3'); // 获取执行102 task pri的泳道
+r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[2])) && p() && e(',所属模块: 无,模块13,模块37,模块40,模块43'); // 获取执行102 task module的泳道
+r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[4])) && p() && e(',指派给: 无'); // 获取执行102 task assignedTo的泳道
+r($kanban->getLanes4GroupTest($executionIDList[4], $browseTypeList[1], $groupByList[5])) && p() && e(',相关研发需求: 无,用户需求17'); // 获取执行102 task story的泳道
diff --git a/module/kanban/test/model/getobjectgroup.php b/module/kanban/test/model/getobjectgroup.php
new file mode 100755
index 0000000000..3653836003
--- /dev/null
+++ b/module/kanban/test/model/getobjectgroup.php
@@ -0,0 +1,60 @@
+#!/usr/bin/env php
+getObjectGroup();
+cid=1
+pid=1
+
+获取执行101 story pri的分组 >> 4,2
+获取执行101 story category的分组 >> feature
+获取执行101 story module的分组 >> 1824,1822
+获取执行101 story source的分组 >> user,market
+获取执行102 task pri的分组 >> 4,2,1
+获取执行102 task module的分组 >> 36,33,30,24
+获取执行102 task assignedTo的分组 >> 0
+获取执行102 task story的分组 >> 8,6,0
+获取执行101 bug pri的分组 >> 4,3,1
+获取执行101 bug module的分组 >> 1833,1832,1831,0
+获取执行101 bug assignedTo的分组 >> test1,admin
+获取执行101 bug severity的分组 >> 4,3,1
+获取执行101 story pri的分组 >> 4,2
+获取执行101 story category的分组 >> feature
+获取执行101 story module的分组 >> 1836,1834
+获取执行101 story source的分组 >> user,other
+获取执行102 task pri的分组 >> 3,2,1
+获取执行102 task module的分组 >> 63,60,57,33
+获取执行102 task assignedTo的分组 >> 0
+获取执行102 task story的分组 >> 20,18,0
+
+*/
+$executionIDList = array('101', '102', '103', '104', '105');
+$browseTypeList = array('story', 'task', 'bug');
+$groupByList = array('pri', 'category', 'module', 'source', 'assignedTo', 'story', 'severity');
+
+$kanban = new kanbanTest();
+
+r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[0])) && p() && e('4,2'); // 获取执行101 story pri的分组
+r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[1])) && p() && e('feature'); // 获取执行101 story category的分组
+r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[2])) && p() && e('1824,1822'); // 获取执行101 story module的分组
+r($kanban->getObjectGroupTest($executionIDList[0], $browseTypeList[0], $groupByList[3])) && p() && e('user,market'); // 获取执行101 story source的分组
+r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[0])) && p() && e('4,2,1'); // 获取执行102 task pri的分组
+r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[2])) && p() && e('36,33,30,24'); // 获取执行102 task module的分组
+r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[4])) && p() && e('0'); // 获取执行102 task assignedTo的分组
+r($kanban->getObjectGroupTest($executionIDList[1], $browseTypeList[1], $groupByList[5])) && p() && e('8,6,0'); // 获取执行102 task story的分组
+r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[0])) && p() && e('4,3,1'); // 获取执行101 bug pri的分组
+r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[2])) && p() && e('1833,1832,1831,0'); // 获取执行101 bug module的分组
+r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[4])) && p() && e('test1,admin'); // 获取执行101 bug assignedTo的分组
+r($kanban->getObjectGroupTest($executionIDList[2], $browseTypeList[2], $groupByList[6])) && p() && e('4,3,1'); // 获取执行101 bug severity的分组
+r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[0])) && p() && e('4,2'); // 获取执行101 story pri的分组
+r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[1])) && p() && e('feature'); // 获取执行101 story category的分组
+r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[2])) && p() && e('1836,1834'); // 获取执行101 story module的分组
+r($kanban->getObjectGroupTest($executionIDList[3], $browseTypeList[0], $groupByList[3])) && p() && e('user,other'); // 获取执行101 story source的分组
+r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[0])) && p() && e('3,2,1'); // 获取执行102 task pri的分组
+r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[2])) && p() && e('63,60,57,33'); // 获取执行102 task module的分组
+r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[4])) && p() && e('0'); // 获取执行102 task assignedTo的分组
+r($kanban->getObjectGroupTest($executionIDList[4], $browseTypeList[1], $groupByList[5])) && p() && e('20,18,0'); // 获取执行102 task story的分组
\ No newline at end of file
diff --git a/module/kanban/test/model/getplankanban.php b/module/kanban/test/model/getplankanban.php
new file mode 100755
index 0000000000..25a5c5376c
--- /dev/null
+++ b/module/kanban/test/model/getplankanban.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getPlanKanban();
+cid=1
+pid=1
+
+测试获取产品1的计划看板 >> lanes:1, cards:3
+测试获取产品2的计划看板 >> lanes:1, cards:3
+测试获取产品3的计划看板 >> lanes:1, cards:3
+测试获取产品4的计划看板 >> lanes:3, cards:2
+测试获取产品4 分支1的计划看板 >> lanes:1, cards:1
+测试获取产品5的计划看板 >> lanes:3, cards:2
+测试获取产品5 分支3的计划看板 >> lanes:1, cards:1
+
+*/
+
+$productIDList = array('1', '2', '3', '41', '42');
+$branchIDList = array('0', '1', '3');
+
+$kanban = new kanbanTest();
+
+r($kanban->getPlanKanbanTest($productIDList[0])) && p() && e('lanes:1, cards:3'); // 测试获取产品1的计划看板
+r($kanban->getPlanKanbanTest($productIDList[1])) && p() && e('lanes:1, cards:3'); // 测试获取产品2的计划看板
+r($kanban->getPlanKanbanTest($productIDList[2])) && p() && e('lanes:1, cards:3'); // 测试获取产品3的计划看板
+r($kanban->getPlanKanbanTest($productIDList[3])) && p() && e('lanes:3, cards:2'); // 测试获取产品4的计划看板
+r($kanban->getPlanKanbanTest($productIDList[3], $branchIDList[1])) && p() && e('lanes:1, cards:1'); // 测试获取产品4 分支1的计划看板
+r($kanban->getPlanKanbanTest($productIDList[4])) && p() && e('lanes:3, cards:2'); // 测试获取产品5的计划看板
+r($kanban->getPlanKanbanTest($productIDList[4], $branchIDList[2])) && p() && e('lanes:1, cards:1'); // 测试获取产品5 分支3的计划看板
\ No newline at end of file
diff --git a/module/kanban/test/model/getrdcolumngroupbyregions.php b/module/kanban/test/model/getrdcolumngroupbyregions.php
new file mode 100755
index 0000000000..7780fb1e69
--- /dev/null
+++ b/module/kanban/test/model/getrdcolumngroupbyregions.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+getRDColumnGroupByRegions();
+cid=1
+pid=1
+
+测试获取region 1 执行看板泳道列组 >> 4
+测试获取region 1 group 1执行看板泳道列组 >> 4
+测试获取region 1 group 2执行看板泳道列组 >> 0
+测试获取region 2 执行看板泳道列组 >> 4
+测试获取region 2 group 2执行看板泳道列组 >> 4
+测试获取region 2 group 1执行看板泳道列组 >> 0
+测试获取region 3 执行看板泳道列组 >> 8
+测试获取region 3 group 3执行看板泳道列组 >> 4
+测试获取region 3 group 1执行看板泳道列组 >> 0
+测试获取region 4 执行看板泳道列组 >> 12
+测试获取region 4 group 5,6执行看板泳道列组 >> 8
+测试获取region 5 执行看板泳道列组 >> 16
+测试获取region 5 group 8,10执行看板泳道列组 >> 8
+
+*/
+
+$regions = array('1', '2', '3,4', '5,6,7', '8,9,10,11');
+$groupIDList = array('1', '2', '3', '5,6', '8,10');
+
+$kanban = new kanbanTest();
+
+r($kanban->getRDColumnGroupByRegionsTest($regions[0])) && p() && e('4'); // 测试获取region 1 执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[0], $groupIDList[0])) && p() && e('4'); // 测试获取region 1 group 1执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[0], $groupIDList[1])) && p() && e('0'); // 测试获取region 1 group 2执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[1])) && p() && e('4'); // 测试获取region 2 执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[1], $groupIDList[1])) && p() && e('4'); // 测试获取region 2 group 2执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[1], $groupIDList[0])) && p() && e('0'); // 测试获取region 2 group 1执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[2])) && p() && e('8'); // 测试获取region 3 执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[2], $groupIDList[2])) && p() && e('4'); // 测试获取region 3 group 3执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[2], $groupIDList[0])) && p() && e('0'); // 测试获取region 3 group 1执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[3])) && p() && e('12'); // 测试获取region 4 执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[3], $groupIDList[3])) && p() && e('8'); // 测试获取region 4 group 5,6执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[4])) && p() && e('16'); // 测试获取region 5 执行看板泳道列组
+r($kanban->getRDColumnGroupByRegionsTest($regions[4], $groupIDList[4])) && p() && e('8'); // 测试获取region 5 group 8,10执行看板泳道列组
\ No newline at end of file
diff --git a/module/kanban/test/model/getrdkanban.php b/module/kanban/test/model/getrdkanban.php
new file mode 100755
index 0000000000..fc0cd8a7d0
--- /dev/null
+++ b/module/kanban/test/model/getrdkanban.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getRDKanban();
+cid=1
+pid=1
+
+获取执行161的执行看板 >> columns:27, lanes:3, cards:5
+获取执行161 all region 101的执行看板 >> columns:27, lanes:3, cards:8
+获取执行161 all region 102的执行看板 >> columns:0, lanes:0, cards:0
+获取执行162的执行看板 >> columns:27, lanes:3, cards:5
+获取执行162 story region 102的执行看板 >> columns:11, lanes:1, cards:2
+获取执行163的执行看板 >> columns:27, lanes:3, cards:4
+获取执行163 task region 103的执行看板 >> columns:7, lanes:1, cards:4
+获取执行164的执行看板 >> columns:27, lanes:3, cards:4
+获取执行164 bug region 104的执行看板 >> columns:9, lanes:1, cards:3
+获取执行165的执行看板 >> columns:27, lanes:3, cards:0
+获取执行165 story region 105的执行看板 >> columns:11, lanes:1, cards:2
+
+*/
+$executionIDList = array('161', '162', '163', '164', '165');
+$browseTypeList = array('all', 'story', 'task', 'bug');
+$regionIDList = array('0', '101', '102', '103', '104', '105');
+$groupBy = 'pri';
+
+$kanban = new kanbanTest();
+
+r($kanban->getRDKanbanTest($executionIDList[0])) && p() && e('columns:27, lanes:3, cards:5'); // 获取执行161的执行看板
+r($kanban->getRDKanbanTest($executionIDList[0], $browseTypeList[0], $regionIDList[1])) && p() && e('columns:27, lanes:3, cards:8'); // 获取执行161 all region 101的执行看板
+r($kanban->getRDKanbanTest($executionIDList[0], $browseTypeList[0], $regionIDList[2])) && p() && e('columns:0, lanes:0, cards:0'); // 获取执行161 all region 102的执行看板
+r($kanban->getRDKanbanTest($executionIDList[1])) && p() && e('columns:27, lanes:3, cards:5'); // 获取执行162的执行看板
+r($kanban->getRDKanbanTest($executionIDList[1], $browseTypeList[1], $regionIDList[2])) && p() && e('columns:11, lanes:1, cards:2'); // 获取执行162 story region 102的执行看板
+r($kanban->getRDKanbanTest($executionIDList[2])) && p() && e('columns:27, lanes:3, cards:4'); // 获取执行163的执行看板
+r($kanban->getRDKanbanTest($executionIDList[2], $browseTypeList[2], $regionIDList[3])) && p() && e('columns:7, lanes:1, cards:4'); // 获取执行163 task region 103的执行看板
+r($kanban->getRDKanbanTest($executionIDList[3])) && p() && e('columns:27, lanes:3, cards:4'); // 获取执行164的执行看板
+r($kanban->getRDKanbanTest($executionIDList[3], $browseTypeList[3], $regionIDList[4])) && p() && e('columns:9, lanes:1, cards:3'); // 获取执行164 bug region 104的执行看板
+r($kanban->getRDKanbanTest($executionIDList[4])) && p() && e('columns:27, lanes:3, cards:0'); // 获取执行165的执行看板
+r($kanban->getRDKanbanTest($executionIDList[4], $browseTypeList[1], $regionIDList[5])) && p() && e('columns:11, lanes:1, cards:2'); // 获取执行165 story region 105的执行看板
\ No newline at end of file
diff --git a/module/kanban/test/model/getregionbyid.php b/module/kanban/test/model/getregionbyid.php
new file mode 100755
index 0000000000..a1da4a9cf9
--- /dev/null
+++ b/module/kanban/test/model/getregionbyid.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getRegionByID();
+cid=1
+pid=1
+
+测试查询看板1信息 >> 默认区域,1,1
+测试查询看板2信息 >> 默认区域,2,1
+测试查询看板3信息 >> 默认区域,3,2
+测试查询看板4信息 >> 默认区域,4,2
+测试查询看板5信息 >> 默认区域,5,3
+测试查询不存在的看板信息 >> 0
+
+*/
+$regionIDList = array('1', '2', '3', '4', '5', '10001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getRegionByIDTest($regionIDList[0])) && p('name,kanban,space') && e('默认区域,1,1'); // 测试查询看板1信息
+r($kanban->getRegionByIDTest($regionIDList[1])) && p('name,kanban,space') && e('默认区域,2,1'); // 测试查询看板2信息
+r($kanban->getRegionByIDTest($regionIDList[2])) && p('name,kanban,space') && e('默认区域,3,2'); // 测试查询看板3信息
+r($kanban->getRegionByIDTest($regionIDList[3])) && p('name,kanban,space') && e('默认区域,4,2'); // 测试查询看板4信息
+r($kanban->getRegionByIDTest($regionIDList[4])) && p('name,kanban,space') && e('默认区域,5,3'); // 测试查询看板5信息
+r($kanban->getRegionByIDTest($regionIDList[5])) && p('name,kanban,space') && e('0'); // 测试查询不存在的看板信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getregionpairs.php b/module/kanban/test/model/getregionpairs.php
new file mode 100755
index 0000000000..d906e46629
--- /dev/null
+++ b/module/kanban/test/model/getregionpairs.php
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+getRegionPairs();
+cid=1
+pid=1
+
+测试查询kanban1的区域信息 >> 默认区域
+测试查询kanban1 reigon1的区域信息 >> 默认区域
+测试查询kanban1 region2的区域信息 >> 0
+测试查询kanban1的区域信息 >> 默认区域
+测试查询kanban1 reigon2的区域信息 >> 默认区域
+测试查询kanban1 region3的区域信息 >> 0
+测试查询kanban1的区域信息 >> 默认区域
+测试查询kanban1 reigon3的区域信息 >> 默认区域
+测试查询kanban1 region4的区域信息 >> 0
+测试查询kanban1的区域信息 >> 默认区域
+测试查询kanban1 reigon4的区域信息 >> 默认区域
+测试查询kanban1 region5的区域信息 >> 0
+测试查询kanban1的区域信息 >> 默认区域
+测试查询kanban1 reigon5的区域信息 >> 默认区域
+测试查询kanban1 region10001的区域信息 >> 0
+测试查询不存在的kanban的区域信息 >> 0
+测试查询执行161的区域信息 >> 默认区域
+测试查询执行162的区域信息 >> 默认区域
+
+*/
+$kanbanIDList = array('1', '2', '3', '4', '5', '10001');
+$regionIDList = array('1', '2', '3', '4', '5', '10001');
+$executionIDList = array('161', '162');
+
+$kanban = new kanbanTest();
+
+r($kanban->getRegionPairsTest($kanbanIDList[0])) && p('1') && e('默认区域'); // 测试查询kanban1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[0], $regionIDList[0])) && p('1') && e('默认区域'); // 测试查询kanban1 reigon1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[0], $regionIDList[1])) && p('1') && e('0'); // 测试查询kanban1 region2的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[1])) && p('2') && e('默认区域'); // 测试查询kanban1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[1], $regionIDList[1])) && p('2') && e('默认区域'); // 测试查询kanban1 reigon2的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[1], $regionIDList[2])) && p('2') && e('0'); // 测试查询kanban1 region3的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[2])) && p('3') && e('默认区域'); // 测试查询kanban1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[2], $regionIDList[2])) && p('3') && e('默认区域'); // 测试查询kanban1 reigon3的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[2], $regionIDList[3])) && p('3') && e('0'); // 测试查询kanban1 region4的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[3])) && p('4') && e('默认区域'); // 测试查询kanban1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[3], $regionIDList[3])) && p('4') && e('默认区域'); // 测试查询kanban1 reigon4的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[3], $regionIDList[4])) && p('4') && e('0'); // 测试查询kanban1 region5的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[4])) && p('5') && e('默认区域'); // 测试查询kanban1的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[4], $regionIDList[4])) && p('5') && e('默认区域'); // 测试查询kanban1 reigon5的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[4], $regionIDList[5])) && p('5') && e('0'); // 测试查询kanban1 region10001的区域信息
+r($kanban->getRegionPairsTest($kanbanIDList[5])) && p() && e('0'); // 测试查询不存在的kanban的区域信息
+r($kanban->getRegionPairsTest($executionIDList[0], 0, 'execution')) && p('101') && e('默认区域'); // 测试查询执行161的区域信息
+r($kanban->getRegionPairsTest($executionIDList[1], 0, 'execution')) && p('102') && e('默认区域'); // 测试查询执行162的区域信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getspacebyid.php b/module/kanban/test/model/getspacebyid.php
new file mode 100755
index 0000000000..5aed318f47
--- /dev/null
+++ b/module/kanban/test/model/getspacebyid.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getSpaceById();
+cid=1
+pid=1
+
+测试查询空间1信息 >> 协作空间1,cooperation,po15,active
+测试查询空间2信息 >> 私有空间2,private,po16,active
+测试查询空间3信息 >> 公共空间3,public,po17,active
+测试查询空间4信息 >> 协作空间4,cooperation,po18,active
+测试查询空间5信息 >> 私有空间5,private,po19,active
+测试查询不存在的空间信息 >> 0
+
+*/
+$spaceIDList = array('1', '2', '3', '4', '5', '10001');
+
+$kanban = new kanbanTest();
+
+r($kanban->getSpaceByIdTest($spaceIDList[0])) && p('name,type,owner,status') && e('协作空间1,cooperation,po15,active'); // 测试查询空间1信息
+r($kanban->getSpaceByIdTest($spaceIDList[1])) && p('name,type,owner,status') && e('私有空间2,private,po16,active'); // 测试查询空间2信息
+r($kanban->getSpaceByIdTest($spaceIDList[2])) && p('name,type,owner,status') && e('公共空间3,public,po17,active'); // 测试查询空间3信息
+r($kanban->getSpaceByIdTest($spaceIDList[3])) && p('name,type,owner,status') && e('协作空间4,cooperation,po18,active'); // 测试查询空间4信息
+r($kanban->getSpaceByIdTest($spaceIDList[4])) && p('name,type,owner,status') && e('私有空间5,private,po19,active'); // 测试查询空间5信息
+r($kanban->getSpaceByIdTest($spaceIDList[5])) && p('name,type,owner,status') && e('0'); // 测试查询不存在的空间信息
\ No newline at end of file
diff --git a/module/kanban/test/model/getspacelist.php b/module/kanban/test/model/getspacelist.php
new file mode 100755
index 0000000000..10f47b8fd4
--- /dev/null
+++ b/module/kanban/test/model/getspacelist.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+getSpaceList();
+cid=1
+pid=1
+
+查询用户可以看到的admin private的空间数量 >> 0
+查询用户可以看到的admin cooperation的空间数量 >> 17
+查询用户可以看到的admin public的空间数量 >> 16
+查询用户可以看到的admin involved的空间数量 >> 0
+查询用户可以看到的po16 private的空间数量 >> 1
+查询用户可以看到的po16 cooperation的空间数量 >> 0
+查询用户可以看到的po16 public的空间数量 >> 16
+查询用户可以看到的po16 involved的空间数量 >> 0
+查询用户可以看到的pm3 private的空间数量 >> 1
+查询用户可以看到的test37 cooperation的空间数量 >> 0
+查询用户可以看到的test37 public的空间数量 >> 16
+查询用户可以看到的test37 involved的空间数量 >> 0
+查询用户可以看到的user25 private的空间数量 >> 1
+查询用户可以看到的user25 cooperation的空间数量 >> 0
+查询用户可以看到的user25 public的空间数量 >> 16
+查询用户可以看到的user25 involved的空间数量 >> 0
+
+*/
+
+$userList = array('admin', 'po16', 'test37', 'user25');
+$browseType = array('private', 'cooperation', 'public', 'involved');
+
+$kanban = new kanbanTest();
+
+r($kanban->getSpaceListTest($userList[0], $browseType[0])) && p() && e('0'); // 查询用户可以看到的admin private的空间数量
+r($kanban->getSpaceListTest($userList[0], $browseType[1])) && p() && e('17'); // 查询用户可以看到的admin cooperation的空间数量
+r($kanban->getSpaceListTest($userList[0], $browseType[2])) && p() && e('16'); // 查询用户可以看到的admin public的空间数量
+r($kanban->getSpaceListTest($userList[0], $browseType[3])) && p() && e('0'); // 查询用户可以看到的admin involved的空间数量
+r($kanban->getSpaceListTest($userList[1], $browseType[0])) && p() && e('1'); // 查询用户可以看到的po16 private的空间数量
+r($kanban->getSpaceListTest($userList[1], $browseType[1])) && p() && e('0'); // 查询用户可以看到的po16 cooperation的空间数量
+r($kanban->getSpaceListTest($userList[1], $browseType[2])) && p() && e('16'); // 查询用户可以看到的po16 public的空间数量
+r($kanban->getSpaceListTest($userList[1], $browseType[3])) && p() && e('0'); // 查询用户可以看到的po16 involved的空间数量
+r($kanban->getSpaceListTest($userList[2], $browseType[0])) && p() && e('1'); // 查询用户可以看到的pm3 private的空间数量
+r($kanban->getSpaceListTest($userList[2], $browseType[1])) && p() && e('0'); // 查询用户可以看到的test37 cooperation的空间数量
+r($kanban->getSpaceListTest($userList[2], $browseType[2])) && p() && e('16'); // 查询用户可以看到的test37 public的空间数量
+r($kanban->getSpaceListTest($userList[2], $browseType[3])) && p() && e('0'); // 查询用户可以看到的test37 involved的空间数量
+r($kanban->getSpaceListTest($userList[3], $browseType[0])) && p() && e('1'); // 查询用户可以看到的user25 private的空间数量
+r($kanban->getSpaceListTest($userList[3], $browseType[1])) && p() && e('0'); // 查询用户可以看到的user25 cooperation的空间数量
+r($kanban->getSpaceListTest($userList[3], $browseType[2])) && p() && e('16'); // 查询用户可以看到的user25 public的空间数量
+r($kanban->getSpaceListTest($userList[3], $browseType[3])) && p() && e('0'); // 查询用户可以看到的user25 involved的空间数量
\ No newline at end of file
diff --git a/module/kanban/test/model/getspacepairs.php b/module/kanban/test/model/getspacepairs.php
new file mode 100755
index 0000000000..c5bddfad88
--- /dev/null
+++ b/module/kanban/test/model/getspacepairs.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+getSpacePairs();
+cid=1
+pid=1
+
+查询用户可以看到的admin private的空间数量 >> 0
+查询用户可以看到的admin cooperation的空间数量 >> 17
+查询用户可以看到的admin public的空间数量 >> 16
+查询用户可以看到的admin involved的空间数量 >> 0
+查询用户可以看到的po16 private的空间数量 >> 1
+查询用户可以看到的po16 cooperation的空间数量 >> 0
+查询用户可以看到的po16 public的空间数量 >> 16
+查询用户可以看到的po16 involved的空间数量 >> 0
+查询用户可以看到的pm3 private的空间数量 >> 1
+查询用户可以看到的test37 cooperation的空间数量 >> 0
+查询用户可以看到的test37 public的空间数量 >> 16
+查询用户可以看到的test37 involved的空间数量 >> 0
+查询用户可以看到的user25 private的空间数量 >> 1
+查询用户可以看到的user25 cooperation的空间数量 >> 0
+查询用户可以看到的user25 public的空间数量 >> 16
+查询用户可以看到的user25 involved的空间数量 >> 0
+
+*/
+$userList = array('admin', 'po16', 'test37', 'user25');
+$browseType = array('private', 'cooperation', 'public', 'involved');
+
+$kanban = new kanbanTest();
+
+r($kanban->getSpacePairsTest($userList[0], $browseType[0])) && p() && e('0'); // 查询用户可以看到的admin private的空间数量
+r($kanban->getSpacePairsTest($userList[0], $browseType[1])) && p() && e('17'); // 查询用户可以看到的admin cooperation的空间数量
+r($kanban->getSpacePairsTest($userList[0], $browseType[2])) && p() && e('16'); // 查询用户可以看到的admin public的空间数量
+r($kanban->getSpacePairsTest($userList[0], $browseType[3])) && p() && e('0'); // 查询用户可以看到的admin involved的空间数量
+r($kanban->getSpacePairsTest($userList[1], $browseType[0])) && p() && e('1'); // 查询用户可以看到的po16 private的空间数量
+r($kanban->getSpacePairsTest($userList[1], $browseType[1])) && p() && e('0'); // 查询用户可以看到的po16 cooperation的空间数量
+r($kanban->getSpacePairsTest($userList[1], $browseType[2])) && p() && e('16'); // 查询用户可以看到的po16 public的空间数量
+r($kanban->getSpacePairsTest($userList[1], $browseType[3])) && p() && e('0'); // 查询用户可以看到的po16 involved的空间数量
+r($kanban->getSpacePairsTest($userList[2], $browseType[0])) && p() && e('1'); // 查询用户可以看到的pm3 private的空间数量
+r($kanban->getSpacePairsTest($userList[2], $browseType[1])) && p() && e('0'); // 查询用户可以看到的test37 cooperation的空间数量
+r($kanban->getSpacePairsTest($userList[2], $browseType[2])) && p() && e('16'); // 查询用户可以看到的test37 public的空间数量
+r($kanban->getSpacePairsTest($userList[2], $browseType[3])) && p() && e('0'); // 查询用户可以看到的test37 involved的空间数量
+r($kanban->getSpacePairsTest($userList[3], $browseType[0])) && p() && e('1'); // 查询用户可以看到的user25 private的空间数量
+r($kanban->getSpacePairsTest($userList[3], $browseType[1])) && p() && e('0'); // 查询用户可以看到的user25 cooperation的空间数量
+r($kanban->getSpacePairsTest($userList[3], $browseType[2])) && p() && e('16'); // 查询用户可以看到的user25 public的空间数量
+r($kanban->getSpacePairsTest($userList[3], $browseType[3])) && p() && e('0'); // 查询用户可以看到的user25 involved的空间数量
\ No newline at end of file
diff --git a/module/kanban/test/model/gettoandcclist.php b/module/kanban/test/model/gettoandcclist.php
new file mode 100755
index 0000000000..8a606386fd
--- /dev/null
+++ b/module/kanban/test/model/gettoandcclist.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getToAndCcList();
+cid=1
+pid=1
+
+获取id=1的卡片发信人员 >> admin;admin
+
+*/
+$kanban = new kanbanTest();
+
+$card = $kanban->getCardByIDTest('1');
+r($kanban->getToAndCcListTest($card)) && p('0;1') && e('admin;admin'); // 获取id=1的卡片发信人员
\ No newline at end of file
diff --git a/module/kanban/test/model/import.php b/module/kanban/test/model/import.php
new file mode 100755
index 0000000000..2a5d673303
--- /dev/null
+++ b/module/kanban/test/model/import.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+import();
+cid=1
+pid=1
+
+开启看板1的导入功能 可选项全部 >> plans,releases,builds,executions,cards
+开启看板1的导入功能 可选项plans cards >> plans,cards
+关闭看板1的导入功能 可选项全部 >> 0
+关闭看板1的导入功能 可选项plans cards >> 0
+开启看板2的导入功能 可选项全部 >> plans,releases,builds,executions,cards
+开启看板2的导入功能 可选项plans cards >> plans,cards
+关闭看板2的导入功能 可选项全部 >> 0
+关闭看板2的导入功能 可选项plans cards >> 0
+开启看板3的导入功能 可选项全部 >> plans,releases,builds,executions,cards
+开启看板3的导入功能 可选项plans cards >> plans,cards
+关闭看板3的导入功能 可选项全部 >> 0
+关闭看板3的导入功能 可选项plans cards >> 0
+开启看板4的导入功能 可选项全部 >> plans,releases,builds,executions,cards
+开启看板4的导入功能 可选项plans cards >> plans,cards
+关闭看板4的导入功能 可选项全部 >> 0
+关闭看板4的导入功能 可选项plans cards >> 0
+开启看板5的导入功能 可选项全部 >> plans,releases,builds,executions,cards
+开启看板5的导入功能 可选项plans cards >> plans,cards
+关闭看板5的导入功能 可选项全部 >> 0
+关闭看板5的导入功能 可选项plans cards >> 0
+
+*/
+
+$kanban = new kanbanTest();
+
+$kanbanIDList = array('1', '2', '3', '4', '5');
+$import = array('on', 'off');
+$importObjectList1 = array('plans', 'releases', 'builds', 'executions', 'cards');
+$importObjectList2 = array('plans', 'cards');
+
+r($kanban->importTest($kanbanIDList[0], $import[0], $importObjectList1)) && p('object') && e('plans,releases,builds,executions,cards '); // 开启看板1的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[0], $import[0], $importObjectList2)) && p('object') && e('plans,cards'); // 开启看板1的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[0], $import[1], $importObjectList1)) && p('object') && e('0'); // 关闭看板1的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[0], $import[1], $importObjectList2)) && p('object') && e('0'); // 关闭看板1的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[1], $import[0], $importObjectList1)) && p('object') && e('plans,releases,builds,executions,cards '); // 开启看板2的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[1], $import[0], $importObjectList2)) && p('object') && e('plans,cards'); // 开启看板2的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[1], $import[1], $importObjectList1)) && p('object') && e('0'); // 关闭看板2的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[1], $import[1], $importObjectList2)) && p('object') && e('0'); // 关闭看板2的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[2], $import[0], $importObjectList1)) && p('object') && e('plans,releases,builds,executions,cards '); // 开启看板3的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[2], $import[0], $importObjectList2)) && p('object') && e('plans,cards'); // 开启看板3的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[2], $import[1], $importObjectList1)) && p('object') && e('0'); // 关闭看板3的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[2], $import[1], $importObjectList2)) && p('object') && e('0'); // 关闭看板3的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[3], $import[0], $importObjectList1)) && p('object') && e('plans,releases,builds,executions,cards '); // 开启看板4的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[3], $import[0], $importObjectList2)) && p('object') && e('plans,cards'); // 开启看板4的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[3], $import[1], $importObjectList1)) && p('object') && e('0'); // 关闭看板4的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[3], $import[1], $importObjectList2)) && p('object') && e('0'); // 关闭看板4的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[4], $import[0], $importObjectList1)) && p('object') && e('plans,releases,builds,executions,cards '); // 开启看板5的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[4], $import[0], $importObjectList2)) && p('object') && e('plans,cards'); // 开启看板5的导入功能 可选项plans cards
+r($kanban->importTest($kanbanIDList[4], $import[1], $importObjectList1)) && p('object') && e('0'); // 关闭看板5的导入功能 可选项全部
+r($kanban->importTest($kanbanIDList[4], $import[1], $importObjectList2)) && p('object') && e('0'); // 关闭看板5的导入功能 可选项plans cards
diff --git a/module/kanban/test/model/importcard.php b/module/kanban/test/model/importcard.php
new file mode 100755
index 0000000000..74d931beed
--- /dev/null
+++ b/module/kanban/test/model/importcard.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+importCard();
+cid=1
+pid=1
+
+测试导入卡片72 73 74到column 1 >> ,72,73,74,1,2,801,
+测试导入卡片75 77 77到column 5 >> ,75,76,77,9,10,809,
+测试导入卡片72 73 74到column 9 >> ,82,83,84,17,18,817,
+测试导入卡片75 77 77到column 13 >> ,85,86,87,25,26,825,
+测试导入卡片72 73 74到column 17 >> ,95,96,97,33,34,833,
+
+*/
+
+$cards1 = array('72', '73', '74');
+$cards2 = array('75', '76', '77');
+$cards3 = array('82', '83', '84');
+$cards4 = array('85', '86', '87');
+$cards5 = array('95', '96', '97');
+
+$targetLaneIDList = array('1', '2', '3', '4', '5');
+$kanbanIDList = array('1', '2', '3', '4', '5');
+$regionIDList = array('1', '2', '3', '4', '5');
+$groupIDList = array('1', '2', '3', '4', '5');
+$columnIDList = array('1', '5', '9', '13', '17');
+
+$kanban = new kanbanTest();
+
+r($kanban->importCardTest($kanbanIDList[0], $regionIDList[0], $groupIDList[0], $columnIDList[0], $cards1, $targetLaneIDList[0])) && p('cards') && e(',72,73,74,1,2,801,'); // 测试导入卡片72 73 74到column 1
+r($kanban->importCardTest($kanbanIDList[1], $regionIDList[1], $groupIDList[1], $columnIDList[1], $cards2, $targetLaneIDList[1])) && p('cards') && e(',75,76,77,9,10,809,'); // 测试导入卡片75 77 77到column 5
+r($kanban->importCardTest($kanbanIDList[2], $regionIDList[2], $groupIDList[2], $columnIDList[2], $cards3, $targetLaneIDList[2])) && p('cards') && e(',82,83,84,17,18,817,');// 测试导入卡片72 73 74到column 9
+r($kanban->importCardTest($kanbanIDList[3], $regionIDList[3], $groupIDList[3], $columnIDList[3], $cards4, $targetLaneIDList[3])) && p('cards') && e(',85,86,87,25,26,825,');// 测试导入卡片75 77 77到column 13
+r($kanban->importCardTest($kanbanIDList[4], $regionIDList[4], $groupIDList[4], $columnIDList[4], $cards5, $targetLaneIDList[4])) && p('cards') && e(',95,96,97,33,34,833,');// 测试导入卡片72 73 74到column 17
diff --git a/module/kanban/test/model/importobject.php b/module/kanban/test/model/importobject.php
new file mode 100755
index 0000000000..06ab3085f5
--- /dev/null
+++ b/module/kanban/test/model/importobject.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+importObject();
+cid=1
+pid=1
+
+测试导入卡片72 73 74到column 1 >> ,1001,1002,1003,1,2,801,
+测试导入卡片75 77 77到column 5 >> ,1004,1005,1006,9,10,809,
+测试导入卡片72 73 74到column 9 >> ,1007,1008,1009,17,18,817,
+测试导入卡片75 77 77到column 13 >> ,1010,1011,1012,25,26,825,
+
+*/
+$productplans = array('72', '73', '74');
+$releases = array('75', '76', '77');
+$executions = array('82', '83', '84');
+$builds = array('85', '86', '87');
+
+$targetLaneIDList = array('1', '2', '3', '4', '5');
+$kanbanIDList = array('1', '2', '3', '4', '5');
+$regionIDList = array('1', '2', '3', '4', '5');
+$groupIDList = array('1', '2', '3', '4', '5');
+$columnIDList = array('1', '5', '9', '13', '17');
+
+$param1 = array('productplans' => $productplans, 'targetLane' => $targetLaneIDList[0]);
+$param2 = array('releases' => $releases, 'targetLane' => $targetLaneIDList[1]);
+$param3 = array('executions' => $executions, 'targetLane' => $targetLaneIDList[2]);
+$param4 = array('builds' => $builds, 'targetLane' => $targetLaneIDList[3]);
+
+$objectType = array('productplan', 'release', 'execution', 'build');
+
+$kanban = new kanbanTest();
+
+r($kanban->importObjectTest($kanbanIDList[0], $regionIDList[0], $groupIDList[0], $columnIDList[0], $objectType[0], $param1)) && p('cards') && e(',1001,1002,1003,1,2,801,'); // 测试导入卡片72 73 74到column 1
+r($kanban->importObjectTest($kanbanIDList[1], $regionIDList[1], $groupIDList[1], $columnIDList[1], $objectType[1], $param2)) && p('cards') && e(',1004,1005,1006,9,10,809,'); // 测试导入卡片75 77 77到column 5
+r($kanban->importObjectTest($kanbanIDList[2], $regionIDList[2], $groupIDList[2], $columnIDList[2], $objectType[2], $param3)) && p('cards') && e(',1007,1008,1009,17,18,817,');// 测试导入卡片72 73 74到column 9
+r($kanban->importObjectTest($kanbanIDList[3], $regionIDList[3], $groupIDList[3], $columnIDList[3], $objectType[3], $param4)) && p('cards') && e(',1010,1011,1012,25,26,825,');// 测试导入卡片75 77 77到column 13
diff --git a/module/kanban/test/model/isclickable.php b/module/kanban/test/model/isclickable.php
new file mode 100755
index 0000000000..ffab569f34
--- /dev/null
+++ b/module/kanban/test/model/isclickable.php
@@ -0,0 +1,70 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+测试lane1 是否可以排序 >> 2
+测试lane1 是否可以删除 >> 2
+测试lane276 是否可以排序 >> 2
+测试lane276 是否可以删除 >> 1
+测试column1 是否可以拆分子列 >> 1
+测试column1 是否可以还原 >> 2
+测试column1 是否可以归档 >> 1
+测试column1 是否可以删除 >> 1
+测试column1 是否可以排序 >> 1
+测试column403 是否可以拆分子列 >> 2
+测试column403 是否可以还原 >> 2
+测试column403 是否可以归档 >> 1
+测试column403 是否可以删除 >> 1
+测试column403 是否可以排序 >> 1
+测试column404 是否可以拆分子列 >> 2
+测试column404 是否可以还原 >> 2
+测试column404 是否可以归档 >> 1
+测试column404 是否可以删除 >> 1
+测试column404 是否可以排序 >> 1
+测试column405 是否可以拆分子列 >> 2
+测试column405 是否可以还原 >> 2
+测试column405 是否可以归档 >> 1
+测试column405 是否可以删除 >> 1
+测试column405 是否可以排序 >> 1
+
+*/
+
+$objectType = array('Lane', 'Column');
+$objectID = array('1', '276', '403', '404', '405');
+
+$actionList = array('sortlane', 'deletelane', 'splitcolumn', 'restorecolumn', 'archivecolumn', 'deletecolumn', 'sortColumn');
+
+$kanban = new kanbanTest();
+
+r($kanban->isClickableTest($objectType[0], $objectID[0], $actionList[0])) && p() && e('2'); // 测试lane1 是否可以排序
+r($kanban->isClickableTest($objectType[0], $objectID[0], $actionList[1])) && p() && e('2'); // 测试lane1 是否可以删除
+r($kanban->isClickableTest($objectType[0], $objectID[1], $actionList[0])) && p() && e('2'); // 测试lane276 是否可以排序
+r($kanban->isClickableTest($objectType[0], $objectID[1], $actionList[1])) && p() && e('1'); // 测试lane276 是否可以删除
+r($kanban->isClickableTest($objectType[1], $objectID[0], $actionList[2])) && p() && e('1'); // 测试column1 是否可以拆分子列
+r($kanban->isClickableTest($objectType[1], $objectID[0], $actionList[3])) && p() && e('2'); // 测试column1 是否可以还原
+r($kanban->isClickableTest($objectType[1], $objectID[0], $actionList[4])) && p() && e('1'); // 测试column1 是否可以归档
+r($kanban->isClickableTest($objectType[1], $objectID[0], $actionList[5])) && p() && e('1'); // 测试column1 是否可以删除
+r($kanban->isClickableTest($objectType[1], $objectID[0], $actionList[6])) && p() && e('1'); // 测试column1 是否可以排序
+r($kanban->isClickableTest($objectType[1], $objectID[2], $actionList[2])) && p() && e('2'); // 测试column403 是否可以拆分子列
+r($kanban->isClickableTest($objectType[1], $objectID[2], $actionList[3])) && p() && e('2'); // 测试column403 是否可以还原
+r($kanban->isClickableTest($objectType[1], $objectID[2], $actionList[4])) && p() && e('1'); // 测试column403 是否可以归档
+r($kanban->isClickableTest($objectType[1], $objectID[2], $actionList[5])) && p() && e('1'); // 测试column403 是否可以删除
+r($kanban->isClickableTest($objectType[1], $objectID[2], $actionList[6])) && p() && e('1'); // 测试column403 是否可以排序
+r($kanban->isClickableTest($objectType[1], $objectID[3], $actionList[2])) && p() && e('2'); // 测试column404 是否可以拆分子列
+r($kanban->isClickableTest($objectType[1], $objectID[3], $actionList[3])) && p() && e('2'); // 测试column404 是否可以还原
+r($kanban->isClickableTest($objectType[1], $objectID[3], $actionList[4])) && p() && e('1'); // 测试column404 是否可以归档
+r($kanban->isClickableTest($objectType[1], $objectID[3], $actionList[5])) && p() && e('1'); // 测试column404 是否可以删除
+r($kanban->isClickableTest($objectType[1], $objectID[3], $actionList[6])) && p() && e('1'); // 测试column404 是否可以排序
+r($kanban->isClickableTest($objectType[1], $objectID[4], $actionList[2])) && p() && e('2'); // 测试column405 是否可以拆分子列
+r($kanban->isClickableTest($objectType[1], $objectID[4], $actionList[3])) && p() && e('2'); // 测试column405 是否可以还原
+r($kanban->isClickableTest($objectType[1], $objectID[4], $actionList[4])) && p() && e('1'); // 测试column405 是否可以归档
+r($kanban->isClickableTest($objectType[1], $objectID[4], $actionList[5])) && p() && e('1'); // 测试column405 是否可以删除
+r($kanban->isClickableTest($objectType[1], $objectID[4], $actionList[6])) && p() && e('1'); // 测试column405 是否可以排序
\ No newline at end of file
diff --git a/module/kanban/test/model/movecard.php b/module/kanban/test/model/movecard.php
new file mode 100755
index 0000000000..43f95f0d47
--- /dev/null
+++ b/module/kanban/test/model/movecard.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+moveCard();
+cid=1
+pid=1
+
+将卡片1从泳道1 列1转移到泳道1 列2 >> ,3,4,803,1,
+将卡片2从泳道1 列1转移到泳道1 列2 >> ,3,4,803,1,2,
+将卡片3从泳道1 列2转移到泳道1 列3 >> ,5,6,805,3,
+将卡片4从泳道1 列2转移到泳道1 列3 >> ,5,6,805,3,4,
+将卡片5从泳道1 列3转移到泳道1 列1 >> ,801,5,
+将卡片6从泳道1 列3转移到泳道1 列1 >> ,801,5,6,
+
+*/
+$cardIDList = array('1', '2', '3', '4', '5', '6');
+$columnIDList = array('1', '2', '3');
+
+$laneID = 1;
+$kanbanID = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->moveCardTest($cardIDList[0], $columnIDList[0], $columnIDList[1], $laneID, $laneID, $kanbanID)) && p('cards') && e(',3,4,803,1,'); // 将卡片1从泳道1 列1转移到泳道1 列2
+r($kanban->moveCardTest($cardIDList[1], $columnIDList[0], $columnIDList[1], $laneID, $laneID, $kanbanID)) && p('cards') && e(',3,4,803,1,2, '); // 将卡片2从泳道1 列1转移到泳道1 列2
+r($kanban->moveCardTest($cardIDList[2], $columnIDList[1], $columnIDList[2], $laneID, $laneID, $kanbanID)) && p('cards') && e(',5,6,805,3,'); // 将卡片3从泳道1 列2转移到泳道1 列3
+r($kanban->moveCardTest($cardIDList[3], $columnIDList[1], $columnIDList[2], $laneID, $laneID, $kanbanID)) && p('cards') && e(',5,6,805,3,4,'); // 将卡片4从泳道1 列2转移到泳道1 列3
+r($kanban->moveCardTest($cardIDList[4], $columnIDList[2], $columnIDList[0], $laneID, $laneID, $kanbanID)) && p('cards') && e(',801,5,'); // 将卡片5从泳道1 列3转移到泳道1 列1
+r($kanban->moveCardTest($cardIDList[5], $columnIDList[2], $columnIDList[0], $laneID, $laneID, $kanbanID)) && p('cards') && e(',801,5,6,'); // 将卡片6从泳道1 列3转移到泳道1 列1
diff --git a/module/kanban/test/model/processcards.php b/module/kanban/test/model/processcards.php
new file mode 100755
index 0000000000..ba4c6afbb6
--- /dev/null
+++ b/module/kanban/test/model/processcards.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+processCards();
+cid=1
+pid=1
+
+计算删除列203后的卡片 >> 204:,407,408,807,405,406,805,
+计算删除列204后的卡片 >> 203:,405,406,805,407,408,807,405,406,805,
+计算删除列207后的卡片 >> 208:,415,416,815,413,414,813,
+计算删除列208后的卡片 >> 207:,413,414,813,415,416,815,413,414,813,
+
+*/
+
+$columnIDList = array('203', '204', '207', '208');
+
+$kanban = new kanbanTest();
+
+r($kanban->processCardsTest($columnIDList[0])) && p() && e('204:,407,408,807,405,406,805,'); // 计算删除列203后的卡片
+r($kanban->processCardsTest($columnIDList[1])) && p() && e('203:,405,406,805,407,408,807,405,406,805,'); // 计算删除列204后的卡片
+r($kanban->processCardsTest($columnIDList[2])) && p() && e('208:,415,416,815,413,414,813,'); // 计算删除列207后的卡片
+r($kanban->processCardsTest($columnIDList[3])) && p() && e('207:,413,414,813,415,416,815,413,414,813,'); // 计算删除列208后的卡片
diff --git a/module/kanban/test/model/refreshcards.php b/module/kanban/test/model/refreshcards.php
new file mode 100755
index 0000000000..50498187eb
--- /dev/null
+++ b/module/kanban/test/model/refreshcards.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+refreshCards();
+cid=1
+pid=1
+
+刷新泳道101的卡片 >> 401; 402; 403; 404:244,; 405; 406; 407; 408; 409; 410; 411:
+刷新泳道102的卡片 >> 412; 413; 414; 415; 416; 417; 418; 419; 420:181,182,183,
+刷新泳道103的卡片 >> 421:781,61,; 422; 423:782,; 424:783,; 425; 426; 427:
+刷新泳道104的卡片 >> 428; 429; 430; 431; 432; 433; 434:246,; 435; 436:248,; 437; 438:
+刷新泳道105的卡片 >> 439; 440; 441; 442; 443; 444; 445; 446; 447:184,185,186,
+
+*/
+
+$laneIDList = array('101', '102', '103', '104', '105');
+
+$kanban = new kanbanTest();
+
+r($kanban->refreshCardsTest($laneIDList[0])) && p() && e('401; 402; 403; 404:244,; 405; 406; 407; 408; 409; 410; 411:'); // 刷新泳道101的卡片
+r($kanban->refreshCardsTest($laneIDList[1])) && p() && e('412; 413; 414; 415; 416; 417; 418; 419; 420:181,182,183,'); // 刷新泳道102的卡片
+r($kanban->refreshCardsTest($laneIDList[2])) && p() && e('421:781,61,; 422; 423:782,; 424:783,; 425; 426; 427:'); // 刷新泳道103的卡片
+r($kanban->refreshCardsTest($laneIDList[3])) && p() && e('428; 429; 430; 431; 432; 433; 434:246,; 435; 436:248,; 437; 438:'); // 刷新泳道104的卡片
+r($kanban->refreshCardsTest($laneIDList[4])) && p() && e('439; 440; 441; 442; 443; 444; 445; 446; 447:184,185,186,'); // 刷新泳道105的卡片
diff --git a/module/kanban/test/model/removekanbancell.php b/module/kanban/test/model/removekanbancell.php
new file mode 100755
index 0000000000..be23048cb3
--- /dev/null
+++ b/module/kanban/test/model/removekanbancell.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+removeKanbanCell();
+cid=1
+pid=1
+
+移除common 看板1的卡片1 >> 1:2,801,; 2:3,4,803,; 3:5,6,805,; 4:7,8,807,
+移除common 看板2的卡片3 4 >> 1:2,801,; 2:803,; 3:5,6,805,; 4:7,8,807,
+移除story 看板161的卡片244 >> 401; 402; 403; 404; 405; 406; 407; 408; 409; 410; 411; 428:246,; 429; 430; 431; 432; 433; 434; 435; 436; 437; 438:
+移除story 看板161的卡片246 >> 401; 402; 403; 404; 405; 406; 407; 408; 409; 410; 411; 428; 429; 430; 431; 432; 433; 434; 435; 436; 437; 438:
+移除bug 看板161的卡片181 >> 412:182,183,; 413; 414; 415; 416; 417; 418; 419; 420; 439:184,185,186,; 440; 441; 442; 443; 444; 445; 446; 447:
+移除bug 看板161的卡片182 >> 412:183,; 413; 414; 415; 416; 417; 418; 419; 420; 439:184,185,186,; 440; 441; 442; 443; 444; 445; 446; 447:
+移除task 看板161的卡片61 >> 421; 422; 423; 424; 425; 426; 427; 448:62,; 449; 450; 451; 452; 453; 454:
+移除task 看板161的卡片62 >> 421; 422; 423; 424; 425; 426; 427; 448; 449; 450; 451; 452; 453; 454:
+
+*/
+
+$typeList = array('common', 'story', 'bug', 'task');
+$cardIDList = array(array('1'), array('3', '4'), '244', '246', '181', '182', '61', '62');
+$kanbanList = array('1' => '1', '3' => '1', '4' => '1', '244' => '161', '246' => '162', '181' => '161', '182' => '161', '61' => '161', '62' => '162');
+
+$kanban = new kanbanTest();
+
+r($kanban->removeKanbanCellTest($typeList[0], $cardIDList[0], $kanbanList)) && p() && e('1:2,801,; 2:3,4,803,; 3:5,6,805,; 4:7,8,807, '); // 移除common 看板1的卡片1
+r($kanban->removeKanbanCellTest($typeList[0], $cardIDList[1], $kanbanList)) && p() && e('1:2,801,; 2:803,; 3:5,6,805,; 4:7,8,807,'); // 移除common 看板2的卡片3 4
+r($kanban->removeKanbanCellTest($typeList[1], $cardIDList[2], $kanbanList)) && p() && e('401; 402; 403; 404; 405; 406; 407; 408; 409; 410; 411; 428:246,; 429; 430; 431; 432; 433; 434; 435; 436; 437; 438:'); // 移除story 看板161的卡片244
+r($kanban->removeKanbanCellTest($typeList[1], $cardIDList[3], $kanbanList)) && p() && e('401; 402; 403; 404; 405; 406; 407; 408; 409; 410; 411; 428; 429; 430; 431; 432; 433; 434; 435; 436; 437; 438:'); // 移除story 看板161的卡片246
+r($kanban->removeKanbanCellTest($typeList[2], $cardIDList[4], $kanbanList)) && p() && e('412:182,183,; 413; 414; 415; 416; 417; 418; 419; 420; 439:184,185,186,; 440; 441; 442; 443; 444; 445; 446; 447:'); // 移除bug 看板161的卡片181
+r($kanban->removeKanbanCellTest($typeList[2], $cardIDList[5], $kanbanList)) && p() && e('412:183,; 413; 414; 415; 416; 417; 418; 419; 420; 439:184,185,186,; 440; 441; 442; 443; 444; 445; 446; 447:'); // 移除bug 看板161的卡片182
+r($kanban->removeKanbanCellTest($typeList[3], $cardIDList[6], $kanbanList)) && p() && e('421; 422; 423; 424; 425; 426; 427; 448:62,; 449; 450; 451; 452; 453; 454:'); // 移除task 看板161的卡片61
+r($kanban->removeKanbanCellTest($typeList[3], $cardIDList[7], $kanbanList)) && p() && e('421; 422; 423; 424; 425; 426; 427; 448; 449; 450; 451; 452; 453; 454:'); // 移除task 看板161的卡片62
diff --git a/module/kanban/test/model/restorecard.php b/module/kanban/test/model/restorecard.php
new file mode 100755
index 0000000000..74ca128e5b
--- /dev/null
+++ b/module/kanban/test/model/restorecard.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+restoreCard();
+cid=1
+pid=1
+
+还原卡片1 >> archived,1,0
+还原卡片1 >> archived,1,0
+还原卡片2 >> archived,1,0
+还原卡片3 >> archived,1,0
+还原卡片4 >> archived,1,0
+
+*/
+$kanbanIDList = array('1', '2', '3', '4', '5');
+
+$kanban = new kanbanTest();
+
+$kanban->archiveCardTest($kanbanIDList[0]);
+$kanban->archiveCardTest($kanbanIDList[1]);
+$kanban->archiveCardTest($kanbanIDList[2]);
+$kanban->archiveCardTest($kanbanIDList[3]);
+$kanban->archiveCardTest($kanbanIDList[4]);
+
+r($kanban->restoreCardTest($kanbanIDList[0])) && p('0:field,old,new') && e('archived,1,0'); // 还原卡片1
+r($kanban->restoreCardTest($kanbanIDList[1])) && p('0:field,old,new') && e('archived,1,0'); // 还原卡片1
+r($kanban->restoreCardTest($kanbanIDList[2])) && p('0:field,old,new') && e('archived,1,0'); // 还原卡片2
+r($kanban->restoreCardTest($kanbanIDList[3])) && p('0:field,old,new') && e('archived,1,0'); // 还原卡片3
+r($kanban->restoreCardTest($kanbanIDList[4])) && p('0:field,old,new') && e('archived,1,0'); // 还原卡片4
\ No newline at end of file
diff --git a/module/kanban/test/model/restorecolumn.php b/module/kanban/test/model/restorecolumn.php
new file mode 100755
index 0000000000..f858a34add
--- /dev/null
+++ b/module/kanban/test/model/restorecolumn.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+restoreColumn();
+cid=1
+pid=1
+
+还原卡片1 >> 未开始,0
+还原卡片1 >> 进行中,0
+还原卡片2 >> 已完成,0
+还原卡片3 >> 已关闭,0
+还原卡片4 >> 未开始,0
+
+*/
+
+$columnIDList = array('1', '2', '3', '4', '5');
+
+$kanban = new kanbanTest();
+
+$kanban->archiveColumnTest($columnIDList[0]);
+$kanban->archiveColumnTest($columnIDList[1]);
+$kanban->archiveColumnTest($columnIDList[2]);
+$kanban->archiveColumnTest($columnIDList[3]);
+$kanban->archiveColumnTest($columnIDList[4]);
+
+r($kanban->restoreColumnTest($columnIDList[0])) && p('name,archived') && e('未开始,0'); // 还原卡片1
+r($kanban->restoreColumnTest($columnIDList[1])) && p('name,archived') && e('进行中,0'); // 还原卡片1
+r($kanban->restoreColumnTest($columnIDList[2])) && p('name,archived') && e('已完成,0'); // 还原卡片2
+r($kanban->restoreColumnTest($columnIDList[3])) && p('name,archived') && e('已关闭,0'); // 还原卡片3
+r($kanban->restoreColumnTest($columnIDList[4])) && p('name,archived') && e('未开始,0'); // 还原卡片4
\ No newline at end of file
diff --git a/module/kanban/test/model/setcolumnwidth.php b/module/kanban/test/model/setcolumnwidth.php
new file mode 100755
index 0000000000..078bbdd8ca
--- /dev/null
+++ b/module/kanban/test/model/setcolumnwidth.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+setColumnWidth();
+cid=1
+pid=1
+
+测试修改看板1的fluidBoard值 >> 通用看板1,1
+测试修改看板2的fluidBoard值 >> 通用看板2,1
+测试修改看板3的fluidBoard值 >> 通用看板3,1
+测试修改看板4的fluidBoard值 >> 迭代1,1
+测试修改看板5的fluidBoard值 >> 迭代2,1
+测试修改不存在的看板的fluidBoard值 >> 0
+
+*/
+
+$fromExecution = 'execution';
+
+$kanbanIDList = array('1', '2', '3', '101', '102', '10001');
+$fluidBoard = 1;
+
+$kanban = new kanbanTest();
+
+r($kanban->setColumnWidthTest($kanbanIDList[0], $fluidBoard)) && p('name,fluidBoard') && e('通用看板1,1'); // 测试修改看板1的fluidBoard值
+r($kanban->setColumnWidthTest($kanbanIDList[1], $fluidBoard)) && p('name,fluidBoard') && e('通用看板2,1'); // 测试修改看板2的fluidBoard值
+r($kanban->setColumnWidthTest($kanbanIDList[2], $fluidBoard)) && p('name,fluidBoard') && e('通用看板3,1'); // 测试修改看板3的fluidBoard值
+r($kanban->setColumnWidthTest($kanbanIDList[3], $fluidBoard, $fromExecution)) && p('name,fluidBoard') && e('迭代1,1'); // 测试修改看板4的fluidBoard值
+r($kanban->setColumnWidthTest($kanbanIDList[4], $fluidBoard, $fromExecution)) && p('name,fluidBoard') && e('迭代2,1'); // 测试修改看板5的fluidBoard值
+r($kanban->setColumnWidthTest($kanbanIDList[5], $fluidBoard)) && p('name,fluidBoard') && e('0'); // 测试修改不存在的看板的fluidBoard值
diff --git a/module/kanban/test/model/setlane.php b/module/kanban/test/model/setlane.php
new file mode 100755
index 0000000000..a73faacd48
--- /dev/null
+++ b/module/kanban/test/model/setlane.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+setLane();
+cid=1
+pid=1
+
+测试设置泳道1 >> 修改泳道1,#333
+测试设置泳道2 >> 修改泳道2,#2b529c
+测试设置泳道3 >> 修改泳道3,#333
+测试设置泳道4 >> 修改泳道4,#2b529c
+测试设置泳道5 >> 修改泳道5,#333
+测试设置不填写名字 >> 『泳道名称』不能为空。
+测试设置填写空格 >> 『泳道名称』不能为空。
+
+*/
+
+$idList = array('1' ,'2', '3', '4', '5');
+$nameList = array('修改泳道1', '修改泳道2', '修改泳道3', '修改泳道4', '修改泳道5', '', ' ');
+$colorList = array('#333', '#2b529c');
+
+$kanban = new kanbanTest();
+
+r($kanban->setLaneTest($idList[0], $nameList[0], $colorList[0])) && p('name,color') && e('修改泳道1,#333'); // 测试设置泳道1
+r($kanban->setLaneTest($idList[1], $nameList[1], $colorList[1])) && p('name,color') && e('修改泳道2,#2b529c'); // 测试设置泳道2
+r($kanban->setLaneTest($idList[2], $nameList[2], $colorList[0])) && p('name,color') && e('修改泳道3,#333'); // 测试设置泳道3
+r($kanban->setLaneTest($idList[3], $nameList[3], $colorList[1])) && p('name,color') && e('修改泳道4,#2b529c'); // 测试设置泳道4
+r($kanban->setLaneTest($idList[4], $nameList[4], $colorList[0])) && p('name,color') && e('修改泳道5,#333'); // 测试设置泳道5
+r($kanban->setLaneTest($idList[4], $nameList[5], $colorList[0])) && p('name:0') && e('『泳道名称』不能为空。'); // 测试设置不填写名字
+r($kanban->setLaneTest($idList[4], $nameList[6], $colorList[0])) && p('name:0') && e('『泳道名称』不能为空。'); // 测试设置填写空格
diff --git a/module/kanban/test/model/setlaneheight.php b/module/kanban/test/model/setlaneheight.php
new file mode 100755
index 0000000000..4fcfecdeb4
--- /dev/null
+++ b/module/kanban/test/model/setlaneheight.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+setLaneHeight();
+cid=1
+pid=1
+
+测试设置看板1的泳道高度 >> 通用看板1,0
+测试设置看板1的泳道高度 >> 迭代1,3
+测试设置看板1的泳道高度 >> 迭代2,4
+测试设置看板1的泳道高度 >> 卡片数量必须是大于2的正整数。
+测试设置看板1的泳道高度 >> 卡片数量必须是大于2的正整数。
+
+*/
+
+$laneIDList = array('1' ,'101', '102', '4', '5');
+$heightTypeList = array('auto', 'custom');
+$displayCardsList = array('', '3', '4', '2', 'a3');
+
+$kanban = new kanbanTest();
+
+r($kanban->setLaneHeightTest($laneIDList[0], $heightTypeList[0], $displayCardsList[0])) && p('name,displayCards') && e('通用看板1,0'); // 测试设置看板1的泳道高度
+r($kanban->setLaneHeightTest($laneIDList[1], $heightTypeList[1], $displayCardsList[1], 'execution')) && p('name,displayCards') && e('迭代1,3'); // 测试设置看板1的泳道高度
+r($kanban->setLaneHeightTest($laneIDList[2], $heightTypeList[1], $displayCardsList[2], 'execution')) && p('name,displayCards') && e('迭代2,4'); // 测试设置看板1的泳道高度
+r($kanban->setLaneHeightTest($laneIDList[3], $heightTypeList[1], $displayCardsList[3])) && p('displayCards') && e('卡片数量必须是大于2的正整数。'); // 测试设置看板1的泳道高度
+r($kanban->setLaneHeightTest($laneIDList[4], $heightTypeList[1], $displayCardsList[4])) && p('displayCards') && e('卡片数量必须是大于2的正整数。'); // 测试设置看板1的泳道高度
diff --git a/module/kanban/test/model/setwip.php b/module/kanban/test/model/setwip.php
new file mode 100755
index 0000000000..922466a434
--- /dev/null
+++ b/module/kanban/test/model/setwip.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+setWIP();
+cid=1
+pid=1
+
+测试设置看板列401的在制品限制 >> Backlog,-1
+测试设置看板列402的在制品限制 >> 准备好,100
+测试设置看板列404的在制品限制 >> 进行中,100
+测试设置看板列405的在制品限制 >> 完成,100
+测试设置看板列403的在制品限制 >> 开发,220
+测试设置看板列406的在制品限制 子列未设置在制品数量 >> 请先设置子列的在制品数量后再操作
+测试设置看板列407的在制品限制 >> 进行中,100
+测试设置看板列408的在制品限制 >> 完成,100
+测试设置看板列406的在制品限制 父列小于子列 >> 父列的在制品数量不能小于子列在制品数量之和
+测试设置看板列406的在制品限制 >> 测试,220
+测试设置看板列408的在制品限制 子列大于父列 >> 子列在制品数量之和不能大于父列的在制品数量
+测试设置看板列401的在制品限制 非正整数 >> 在制品数量必须是正整数。
+
+*/
+
+$columnIDList = array('401', '402', '403', '404', '405', '406', '407', '408');
+$limitList = array('-1', '0', '100', '150', '220');
+$WIPCountList = array('0', '100', '150', '220');
+$noLimit = -1;
+
+$kanban = new kanbanTest();
+
+r($kanban->setWIPTest($columnIDList[0], $limitList[0], $noLimit)) && p('name,limit') && e('Backlog,-1'); // 测试设置看板列401的在制品限制
+r($kanban->setWIPTest($columnIDList[1], $limitList[2], $WIPCountList[1])) && p('name,limit') && e('准备好,100'); // 测试设置看板列402的在制品限制
+r($kanban->setWIPTest($columnIDList[3], $limitList[2], $WIPCountList[1])) && p('name,limit') && e('进行中,100'); // 测试设置看板列404的在制品限制
+r($kanban->setWIPTest($columnIDList[4], $limitList[2], $WIPCountList[1])) && p('name,limit') && e('完成,100'); // 测试设置看板列405的在制品限制
+r($kanban->setWIPTest($columnIDList[2], $limitList[4], $WIPCountList[3])) && p('name,limit') && e('开发,220'); // 测试设置看板列403的在制品限制
+r($kanban->setWIPTest($columnIDList[5], $limitList[4], $WIPCountList[1])) && p('limit') && e('请先设置子列的在制品数量后再操作'); // 测试设置看板列406的在制品限制 子列未设置在制品数量
+r($kanban->setWIPTest($columnIDList[6], $limitList[2], $WIPCountList[1])) && p('name,limit') && e('进行中,100'); // 测试设置看板列407的在制品限制
+r($kanban->setWIPTest($columnIDList[7], $limitList[2], $WIPCountList[1])) && p('name,limit') && e('完成,100'); // 测试设置看板列408的在制品限制
+r($kanban->setWIPTest($columnIDList[5], $limitList[3], $WIPCountList[2])) && p('limit') && e('父列的在制品数量不能小于子列在制品数量之和'); // 测试设置看板列406的在制品限制 父列小于子列
+r($kanban->setWIPTest($columnIDList[5], $limitList[4], $WIPCountList[3])) && p('name,limit') && e('测试,220'); // 测试设置看板列406的在制品限制
+r($kanban->setWIPTest($columnIDList[7], $limitList[4], $WIPCountList[3])) && p('limit') && e('子列在制品数量之和不能大于父列的在制品数量'); // 测试设置看板列408的在制品限制 子列大于父列
+r($kanban->setWIPTest($columnIDList[0], $limitList[1], $WIPCountList[0])) && p('limit') && e('在制品数量必须是正整数。'); // 测试设置看板列401的在制品限制 非正整数
diff --git a/module/kanban/test/model/sortgroup.php b/module/kanban/test/model/sortgroup.php
new file mode 100755
index 0000000000..aea23583d1
--- /dev/null
+++ b/module/kanban/test/model/sortgroup.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+sortGroup();
+cid=1
+pid=1
+
+测试区域101 泳道组101 102 103排序 >> 103,101,102
+测试区域102 泳道组104 105 106排序 >> 105,106,104
+测试区域103 泳道组107 108 109排序 >> 107,109,108
+测试区域104 泳道组110 111 112排序 >> 112,111,110
+测试区域105 泳道组113 114 115排序 >> 114,113,115
+
+*/
+
+$regionIDList = array('101', '102', '103', '104', '105');
+$groupIDList = array(array('103', '101', '102'), array('105', '106', '104'), array('107', '109', '108'), array('112', '111', '110'), array('114', '113', '115'));
+
+$kanban = new kanbanTest();
+
+r($kanban->sortGroupTest($regionIDList[0], $groupIDList[0])) && p() && e('103,101,102'); // 测试区域101 泳道组101 102 103排序
+r($kanban->sortGroupTest($regionIDList[1], $groupIDList[1])) && p() && e('105,106,104'); // 测试区域102 泳道组104 105 106排序
+r($kanban->sortGroupTest($regionIDList[2], $groupIDList[2])) && p() && e('107,109,108'); // 测试区域103 泳道组107 108 109排序
+r($kanban->sortGroupTest($regionIDList[3], $groupIDList[3])) && p() && e('112,111,110'); // 测试区域104 泳道组110 111 112排序
+r($kanban->sortGroupTest($regionIDList[4], $groupIDList[4])) && p() && e('114,113,115'); // 测试区域105 泳道组113 114 115排序
\ No newline at end of file
diff --git a/module/kanban/test/model/splitcolumn.php b/module/kanban/test/model/splitcolumn.php
new file mode 100755
index 0000000000..4b94d21dbd
--- /dev/null
+++ b/module/kanban/test/model/splitcolumn.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+splitColumn();
+cid=1
+pid=1
+
+测试拆分列1 >> 2
+测试拆分列2 >> 2
+测试拆分列3 >> 2
+测试拆分列4 >> 在制品数量必须是正整数。
+测试拆分列4 >> 『看板列名称』不能为空。
+
+*/
+
+$columnIDList = array('1', '2', '3', '4');
+
+$name = array('1' => '拆分的子列1', '2' => '拆分的子列2');
+$color = array('1' => '#333', '2' => '#333');
+$WIPCount = array('1' => '111');
+$noLimit = array('2' => '-1');
+$splits1 = array('name' => $name, 'color' => $color, 'WIPCount' => $WIPCount, 'noLimit' => $noLimit);
+
+$name = array('1' => '拆分的子列3', '2' => '拆分的子列4');
+$WIPCount = array('1' => '111', '2' => '111');
+$splits2 = array('name' => $name, 'color' => $color, 'WIPCount' => $WIPCount);
+
+$name = array('1' => '拆分的子列5', '2' => '拆分的子列6');
+$noLimit = array('1' => '-1', '2' => '-1');
+$splits3 = array('name' => $name, 'color' => $color, 'noLimit' => $noLimit);
+
+$WIPCount = array('1' => 'a', '2' => '0');
+$splits4 = array('name' => $name, 'color' => $color, 'WIPCount' => $WIPCount);
+
+$name = array('1' => '', '2' => '');
+$splits5 = array('name' => $name, 'color' => $color, 'noLimit' => $noLimit);
+
+$kanban = new kanbanTest();
+
+r($kanban->splitColumnTest($columnIDList[0], $splits1)) && p() && e('2'); // 测试拆分列1
+r($kanban->splitColumnTest($columnIDList[1], $splits2)) && p() && e('2'); // 测试拆分列2
+r($kanban->splitColumnTest($columnIDList[2], $splits3)) && p() && e('2'); // 测试拆分列3
+r($kanban->splitColumnTest($columnIDList[3], $splits4)) && p('limit') && e('在制品数量必须是正整数。'); // 测试拆分列4
+r($kanban->splitColumnTest($columnIDList[3], $splits5)) && p('name') && e('『看板列名称』不能为空。'); // 测试拆分列4
diff --git a/module/kanban/test/model/update.php b/module/kanban/test/model/update.php
new file mode 100755
index 0000000000..e69b19ea6c
--- /dev/null
+++ b/module/kanban/test/model/update.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试修改看板名称 >> name,通用看板1,修改名字
+测试修改看板空间 >> space,1,2
+测试修改看板备注 >> desc,看板详情,修改注释
+测试修改看板负责人 >> owner,po16,user4
+测试修改看板团队成员 >> team,,user5,po17,,user5,po17,user3
+测试重复修改看板名称 >> 没有数据更新
+测试修改看板名称为空 >> 『看板名称』不能为空。
+测试修改看板名称为空格 >> 『看板名称』不能为空。
+测试修改看板空间为空 >> 『所属空间』不能为空。
+
+*/
+
+$kanbanIDList = array('1', '2', '3', '4', '5');
+
+$names = array('修改名字', '', ' ');
+$space = array('2', '');
+$desc = '修改注释';
+$owner = 'user4';
+$team = array('user5', 'po17', 'user3');
+
+$kanban = new kanbanTest();
+
+r($kanban->updateTest($kanbanIDList[0], array('name' => $names[0]))) && p('0:field,old,new') && e('name,通用看板1,修改名字'); // 测试修改看板名称
+r($kanban->updateTest($kanbanIDList[1], array('space' => $space[0]))) && p('0:field,old,new') && e('space,1,2'); // 测试修改看板空间
+r($kanban->updateTest($kanbanIDList[2], array('desc' => $desc))) && p('0:field,old,new') && e('desc,看板详情,修改注释'); // 测试修改看板备注
+r($kanban->updateTest($kanbanIDList[3], array('owner' => $owner))) && p('0:field,old,new') && e('owner,po16,user4'); // 测试修改看板负责人
+r($kanban->updateTest($kanbanIDList[4], array('team' => $team))) && p('0:field,old,new') && e('team,,user5,po17,,user5,po17,user3'); // 测试修改看板团队成员
+r($kanban->updateTest($kanbanIDList[0], array('name' => $names[0]))) && p() && e('没有数据更新'); // 测试重复修改看板名称
+r($kanban->updateTest($kanbanIDList[0], array('name' => $names[1]))) && p('name:0') && e('『看板名称』不能为空。'); // 测试修改看板名称为空
+r($kanban->updateTest($kanbanIDList[0], array('name' => $names[2]))) && p('name:0') && e('『看板名称』不能为空。'); // 测试修改看板名称为空格
+r($kanban->updateTest($kanbanIDList[0], array('space' => $space[1]))) && p('space:0') && e('『所属空间』不能为空。'); // 测试修改看板空间为空
diff --git a/module/kanban/test/model/updatecard.php b/module/kanban/test/model/updatecard.php
new file mode 100755
index 0000000000..811f4e9ac9
--- /dev/null
+++ b/module/kanban/test/model/updatecard.php
@@ -0,0 +1,58 @@
+#!/usr/bin/env php
+updateCard();
+cid=1
+pid=1
+
+测试修改卡片1 >> name,卡片1,修改名字;desc,,修改注释;estimate,0,3
+测试修改卡片2 >> begin,2022-03-30;end,2022-04-01;progress,50,0
+测试修改卡片3 >> assignedTo,admin,user5,po17,user3;progress,100,50;status,done,doing
+测试修改卡片4 >> progress,0,100;status,doing,done
+测试修改卡片5 >> pri,3,1
+测试修改卡片开始小于结束日期 >> "截止日期"不能小于"预计开始"!
+测试修改卡片预计小于0 >> 预计不能为负数!
+测试修改卡片进度小于0 >> 请输入正确的进度
+测试修改卡片进度大于100 >> 请输入正确的进度
+
+*/
+
+$cardIDList = array('1', '2', '3', '4', '5');
+
+$name = array('修改名字', '', ' ');
+$desc = '修改注释';
+$assignedTo = array('user5', 'po17', 'user3');
+$begin = '2022-03-30';
+$end = '2022-04-01';
+$pri = '1';
+$estimate = array('3' , '0', '', '-1');
+$progress = array('0', '50', '100', '-1', '101');
+
+$param1 = array('name' => $name[0], 'desc' => $desc, 'estimate' => $estimate[0]);
+$param2 = array('begin' => $begin, 'end' => $end, 'progress' => $progress[0]);
+$param3 = array('assignedTo' => $assignedTo, 'estimate' => $estimate[1], 'progress' => $progress[1]);
+$param4 = array('estimate' => $estimate[2], 'progress' => $progress[2]);
+$param5 = array('pri' => $pri);
+
+$end = '2022-01-01';
+$param6 = array('begin' => $begin, 'end' => $end);
+$param7 = array('estimate' => $estimate[3]);
+$param8 = array('progress' => $progress[3]);
+$param9 = array('progress' => $progress[4]);
+
+$kanban = new kanbanTest();
+
+r($kanban->updateCardTest($cardIDList[0], $param1)) && p('0:field,old,new;1:field,old,new;2:field,old,new') && e('name,卡片1,修改名字;desc,,修改注释;estimate,0,3'); // 测试修改卡片1
+r($kanban->updateCardTest($cardIDList[1], $param2)) && p('0:field,new;1:field,new;2:field,old,new') && e('begin,2022-03-30;end,2022-04-01;progress,50,0'); // 测试修改卡片2
+r($kanban->updateCardTest($cardIDList[2], $param3)) && p('0:field,old,new;1:field,old,new;2:field,old,new') && e('assignedTo,admin,user5,po17,user3;progress,100,50;status,done,doing'); // 测试修改卡片3
+r($kanban->updateCardTest($cardIDList[3], $param4)) && p('0:field,old,new;1:field,old,new') && e('progress,0,100;status,doing,done'); // 测试修改卡片4
+r($kanban->updateCardTest($cardIDList[4], $param5)) && p('0:field,old,new') && e('pri,3,1'); // 测试修改卡片5
+r($kanban->updateCardTest($cardIDList[0], $param6)) && p() && e('"截止日期"不能小于"预计开始"!'); // 测试修改卡片开始小于结束日期
+r($kanban->updateCardTest($cardIDList[0], $param7)) && p() && e('预计不能为负数!'); // 测试修改卡片预计小于0
+r($kanban->updateCardTest($cardIDList[0], $param8)) && p() && e('请输入正确的进度'); // 测试修改卡片进度小于0
+r($kanban->updateCardTest($cardIDList[0], $param9)) && p() && e('请输入正确的进度'); // 测试修改卡片进度大于100
diff --git a/module/kanban/test/model/updatecardcolor.php b/module/kanban/test/model/updatecardcolor.php
new file mode 100755
index 0000000000..ad59bdf30e
--- /dev/null
+++ b/module/kanban/test/model/updatecardcolor.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+updateCardColor();
+cid=1
+pid=1
+
+更新卡片1的颜色 >> 1,卡片1,#b10b0b
+更新卡片2的颜色 >> 2,卡片2,#cfa227
+更新卡片3的颜色 >> 3,卡片3,#2a5f29
+更新卡片4的颜色 >> 4,卡片4,#b10b0b
+更新卡片5的颜色 >> 5,卡片5,#cfa227
+
+*/
+
+$cardIDList = array('1', '2', '3', '4', '5');
+$colorList = array('b10b0b', 'cfa227', '2a5f29');
+
+$kanban = new kanbanTest();
+
+r($kanban->updateCardColorTest($cardIDList[0], $colorList[0])) && p('id,name,color') && e('1,卡片1,#b10b0b'); // 更新卡片1的颜色
+r($kanban->updateCardColorTest($cardIDList[1], $colorList[1])) && p('id,name,color') && e('2,卡片2,#cfa227'); // 更新卡片2的颜色
+r($kanban->updateCardColorTest($cardIDList[2], $colorList[2])) && p('id,name,color') && e('3,卡片3,#2a5f29'); // 更新卡片3的颜色
+r($kanban->updateCardColorTest($cardIDList[3], $colorList[0])) && p('id,name,color') && e('4,卡片4,#b10b0b'); // 更新卡片4的颜色
+r($kanban->updateCardColorTest($cardIDList[4], $colorList[1])) && p('id,name,color') && e('5,卡片5,#cfa227'); // 更新卡片5的颜色
\ No newline at end of file
diff --git a/module/kanban/test/model/updatelane.php b/module/kanban/test/model/updatelane.php
new file mode 100755
index 0000000000..1b29f91e19
--- /dev/null
+++ b/module/kanban/test/model/updatelane.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+updateLane();
+cid=1
+pid=1
+
+测试更新执行101的story泳道 >> 0
+测试更新执行101的bug泳道 >> ,1,3,301,2,
+测试更新执行101的task泳道 >> ,1,901,907,902,908,903,909,904,910,905,906,
+测试更新执行102的story泳道 >> ,6,8,
+测试更新执行102的bug泳道 >> ,5,302,4,6,
+测试更新执行102的task泳道 >> ,2,604,605,606,
+测试更新执行103的story泳道 >> ,10,12,
+测试更新执行103的bug泳道 >> ,7,9,303,8,
+测试更新执行103的task泳道 >> ,607,608,3,609,
+
+*/
+
+$executionID = array('101', '102', '103');
+$laneType = array('story', 'bug', 'task');
+
+$kanban = new kanbanTest();
+
+r($kanban->updateLaneTest($executionID[0], $laneType[0])) && p() && e('0'); // 测试更新执行101的story泳道
+r($kanban->updateLaneTest($executionID[0], $laneType[1])) && p() && e(',1,3,301,2,'); // 测试更新执行101的bug泳道
+r($kanban->updateLaneTest($executionID[0], $laneType[2])) && p() && e(',1,901,907,902,908,903,909,904,910,905,906,'); // 测试更新执行101的task泳道
+r($kanban->updateLaneTest($executionID[1], $laneType[0])) && p() && e(',6,8,'); // 测试更新执行102的story泳道
+r($kanban->updateLaneTest($executionID[1], $laneType[1])) && p() && e(',5,302,4,6,'); // 测试更新执行102的bug泳道
+r($kanban->updateLaneTest($executionID[1], $laneType[2])) && p() && e(',2,604,605,606,'); // 测试更新执行102的task泳道
+r($kanban->updateLaneTest($executionID[2], $laneType[0])) && p() && e(',10,12,'); // 测试更新执行103的story泳道
+r($kanban->updateLaneTest($executionID[2], $laneType[1])) && p() && e(',7,9,303,8,'); // 测试更新执行103的bug泳道
+r($kanban->updateLaneTest($executionID[2], $laneType[2])) && p() && e(',607,608,3,609,'); // 测试更新执行103的task泳道
\ No newline at end of file
diff --git a/module/kanban/test/model/updatelanecolumn.php b/module/kanban/test/model/updatelanecolumn.php
new file mode 100755
index 0000000000..7582a11bfd
--- /dev/null
+++ b/module/kanban/test/model/updatelanecolumn.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+updateLaneColumn();
+cid=1
+pid=1
+
+测试修改列1信息 >> name,测试修改列名1,未开始;color,#2b519c,#333
+测试修改列2信息 >> name,测试修改列名2,进行中;color,#e48610,#333
+测试修改列3信息 >> name,测试修改列名3,已完成;color,#d2313d,#333
+测试修改列4信息 >> 『看板列名称』不能为空。
+测试修改列5信息 >> 『看板列名称』不能为空。
+
+*/
+$columnIDList = array('1', '2', '3', '4', '5');
+$nameList = array('测试修改列名1', '测试修改列名2', '测试修改列名3', '', ' ');
+$colorList = array('#2b519c', '#e48610', '#d2313d', '#2a9f23', '#777');
+
+$kanban = new kanbanTest();
+
+r($kanban->updateLaneColumnTest($columnIDList[0], $nameList[0], $colorList[0])) && p('0:field,new,old;1:field,new,old') && e('name,测试修改列名1,未开始;color,#2b519c,#333'); // 测试修改列1信息
+r($kanban->updateLaneColumnTest($columnIDList[1], $nameList[1], $colorList[1])) && p('0:field,new,old;1:field,new,old') && e('name,测试修改列名2,进行中;color,#e48610,#333'); // 测试修改列2信息
+r($kanban->updateLaneColumnTest($columnIDList[2], $nameList[2], $colorList[2])) && p('0:field,new,old;1:field,new,old') && e('name,测试修改列名3,已完成;color,#d2313d,#333'); // 测试修改列3信息
+r($kanban->updateLaneColumnTest($columnIDList[3], $nameList[3], $colorList[3])) && p('name:0') && e('『看板列名称』不能为空。'); // 测试修改列4信息
+r($kanban->updateLaneColumnTest($columnIDList[4], $nameList[4], $colorList[4])) && p('name:0') && e('『看板列名称』不能为空。'); // 测试修改列5信息
\ No newline at end of file
diff --git a/module/kanban/test/model/updateregion.php b/module/kanban/test/model/updateregion.php
new file mode 100755
index 0000000000..930355c091
--- /dev/null
+++ b/module/kanban/test/model/updateregion.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+updateRegion();
+cid=1
+pid=1
+
+测试修改区域1的信息 >> name,默认区域,测试修改区域名称1
+测试修改区域2的信息 >> name,默认区域,测试修改区域名称2
+测试修改区域3的信息 >> name,默认区域,测试修改区域名称3
+测试修改区域4的信息 >> 『区域名称』不能为空。
+测试修改区域5的信息 >> 『区域名称』不能为空。
+
+*/
+
+$regionIDList = array('1', '2', '3', '4', '5');
+$nameList = array('测试修改区域名称1', '测试修改区域名称2', '测试修改区域名称3', '', ' ');
+
+$kanban = new kanbanTest();
+
+r($kanban->updateRegionTest($regionIDList[0], $nameList[0])) && p('0:field,old,new') && e('name,默认区域,测试修改区域名称1'); // 测试修改区域1的信息
+r($kanban->updateRegionTest($regionIDList[1], $nameList[1])) && p('0:field,old,new') && e('name,默认区域,测试修改区域名称2'); // 测试修改区域2的信息
+r($kanban->updateRegionTest($regionIDList[2], $nameList[2])) && p('0:field,old,new') && e('name,默认区域,测试修改区域名称3'); // 测试修改区域3的信息
+r($kanban->updateRegionTest($regionIDList[3], $nameList[3])) && p('name:0') && e('『区域名称』不能为空。'); // 测试修改区域4的信息
+r($kanban->updateRegionTest($regionIDList[4], $nameList[4])) && p('name:0') && e('『区域名称』不能为空。'); // 测试修改区域5的信息
\ No newline at end of file
diff --git a/module/kanban/test/model/updatespace.php b/module/kanban/test/model/updatespace.php
new file mode 100755
index 0000000000..88a2be71bf
--- /dev/null
+++ b/module/kanban/test/model/updatespace.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+updateSpace();
+cid=1
+pid=1
+
+测试修改空间1 >> name,协作空间1,测试修改名称1;owner,po15,user3
+测试修改空间2 >> name,私有空间2,测试修改名称2;whitelist,,user4,po16,,,user4,po16,user3,
+测试修改空间3 >> name,公共空间3,测试修改名称3;team,,user5,po17,,,user5,po17,user3,
+测试修改空间4 >> name,协作空间4,测试修改名称4;desc,,修改备注
+测试重复修改空间4 >> 没有数据更新
+测试修改空间5 不填写名称 >> 『空间名称』不能为空。
+测试修改空间5 名称为空格 >> 『空间名称』不能为空。
+测试修改空间5 不填写负责人 >> 『负责人』不能为空。
+
+*/
+
+$spaceIDList = array('1', '2', '3', '4', '5');
+$typeList = array('cooperation', 'private', 'public');
+$nameList = array('测试修改名称1', '测试修改名称2', '测试修改名称3', '测试修改名称4', '', ' ');
+$ownerList = array('user3', '');
+$whitelist = array(',user4,po16,user3,');
+$team = array(',user5,po17,user3,');
+$desc = '修改备注';
+
+$param1 = array('name' => $nameList[0], 'owner' => $ownerList[0]);
+$param2 = array('name' => $nameList[1], 'whitelist' => $whitelist);
+$param3 = array('name' => $nameList[2], 'team' => $team);
+$param4 = array('name' => $nameList[3], 'desc' => $desc);
+$param5 = array('name' => $nameList[4]);
+$param6 = array('name' => $nameList[5]);
+$param7 = array('owner' => $ownerList[1]);
+
+$kanban = new kanbanTest();
+
+r($kanban->updateSpaceTest($spaceIDList[0], $typeList[0], $param1)) && p('0:field,old,new;1:field,old,new') && e('name,协作空间1,测试修改名称1;owner,po15,user3'); // 测试修改空间1
+r($kanban->updateSpaceTest($spaceIDList[1], $typeList[1], $param2)) && p('0:field,old,new;1:field,old,new') && e('name,私有空间2,测试修改名称2;whitelist,,user4,po16,,,user4,po16,user3,'); // 测试修改空间2
+r($kanban->updateSpaceTest($spaceIDList[2], $typeList[2], $param3)) && p('0:field,old,new;1:field,old,new') && e('name,公共空间3,测试修改名称3;team,,user5,po17,,,user5,po17,user3,'); // 测试修改空间3
+r($kanban->updateSpaceTest($spaceIDList[3], $typeList[0], $param4)) && p('0:field,old,new;1:field,old,new') && e('name,协作空间4,测试修改名称4;desc,,修改备注'); // 测试修改空间4
+r($kanban->updateSpaceTest($spaceIDList[3], $typeList[0], $param4)) && p() && e('没有数据更新'); // 测试重复修改空间4
+r($kanban->updateSpaceTest($spaceIDList[4], $typeList[1], $param5)) && p('name:0') && e('『空间名称』不能为空。'); // 测试修改空间5 不填写名称
+r($kanban->updateSpaceTest($spaceIDList[4], $typeList[1], $param6)) && p('name:0') && e('『空间名称』不能为空。'); // 测试修改空间5 名称为空格
+r($kanban->updateSpaceTest($spaceIDList[4], $typeList[1], $param7)) && p('owner:0') && e('『负责人』不能为空。'); // 测试修改空间5 不填写负责人
diff --git a/module/mail/test/mail.class.php b/module/mail/test/mail.class.php
new file mode 100644
index 0000000000..8b31b2cd3b
--- /dev/null
+++ b/module/mail/test/mail.class.php
@@ -0,0 +1,299 @@
+dao = $dao;
+ $this->tester = $tester;
+ $this->objectModel = $tester->loadModel('mail');
+ }
+
+ /**
+ * AutoDetect.
+ *
+ * @param int $email
+ * @access public
+ * @return object
+ */
+ public function autoDetectTest($email)
+ {
+ $objects = $this->objectModel->autoDetect($email);
+
+ if(dao::isError()) return dao::getError();
+ if(!$objects->host) return '没有检测到相关信息';
+
+ return $objects;
+ }
+
+ /**
+ * Get config from provider.
+ *
+ * @param int $domain
+ * @param int $username
+ * @access public
+ * @return object
+ */
+ public function getConfigFromProviderTest($domain, $username)
+ {
+ $object = $this->objectModel->getConfigFromProvider($domain, $username);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Get config by MXRR.
+ *
+ * @param int $domain
+ * @param int $username
+ * @access public
+ * @return object
+ */
+ public function getConfigByMXRRTest($domain, $username)
+ {
+ $object = $this->objectModel->getConfigByMXRR($domain, $username);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Get config by detecting SMTP.
+ *
+ * @param int $domain
+ * @param int $username
+ * @param int $port
+ * @access public
+ * @return object
+ */
+ public function getConfigByDetectingSMTPTest($domain, $username, $port)
+ {
+ $object = $this->objectModel->getConfigByDetectingSMTP($domain, $username, $port);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Set MTA.
+ *
+ * @access public
+ * @return object
+ */
+ public function setMTATest()
+ {
+ $object = $this->objectModel->setMTA();
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Set sendmail.
+ *
+ * @access public
+ * @return object
+ */
+ public function setSendMailTest()
+ {
+ $object = $this->objectModel->setSendMail();
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+
+ /**
+ * Send.
+ *
+ * @param int $toList
+ * @param int $subject
+ * @param string $body
+ * @param string $ccList
+ * @param int $includeMe
+ * @param array $emails
+ * @access public
+ * @return object
+ */
+ public function sendTest($toList, $subject, $body = '', $ccList = '', $includeMe = false, $emails = array())
+ {
+ $object = $this->objectModel->send($toList, $subject, $body, $ccList, $includeMe, $emails);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Set CC.
+ *
+ * @param int $ccList
+ * @param int $emails
+ * @access public
+ * @return object
+ */
+ public function setCCTest($ccList, $emails)
+ {
+ $this->objectModel->setCC($ccList, $emails);
+
+ return $this->setMTATest();
+ }
+
+ /**
+ * Set subject.
+ *
+ * @param int $subject
+ * @access public
+ * @return object
+ */
+ public function setSubjectTest($subject)
+ {
+ $this->objectModel->setSubject($subject);
+
+ return $this->setMTATest();
+ }
+
+ /**
+ * Set body.
+ *
+ * @param int $body
+ * @access public
+ * @return object
+ */
+ public function setBodyTest($body)
+ {
+ $this->objectModel->setBody($body);
+
+ return $this->setMTATest();
+ }
+
+ /**
+ * Mail exist.
+ *
+ * @access public
+ * @return object
+ */
+ public function mailExistTest()
+ {
+ $object = $this->objectModel->mailExist();
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Add queue.
+ *
+ * @param int $toList
+ * @param int $subject
+ * @param string $body
+ * @param string $ccList
+ * @param int $includeMe
+ * @access public
+ * @return object
+ */
+ public function addQueueTest($toList, $subject, $body = '', $ccList = '', $includeMe = false)
+ {
+ $this->objectModel->addQueue($toList, $subject, $body, $ccList, $includeMe);
+
+ if($toList and $subject)
+ {
+ $id = $this->dao->lastInsertID();
+ $object = $this->dao->select('*')->from(TABLE_NOTIFY)->where('id')->eq($id)->fetch();
+ }
+
+ if(!$object) return '没有数据提交';
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Get queue.
+ *
+ * @param string $status
+ * @param string $orderBy
+ * @param int $pager
+ * @access public
+ * @return object
+ */
+ public function getQueueTest($status = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getQueue($status = '', $orderBy = 'id_desc', $pager = null);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get queue by id.
+ *
+ * @param int $queueID
+ * @access public
+ * @return object
+ */
+ public function getQueueByIdTest($queueID)
+ {
+ $object = $this->objectModel->getQueueById($queueID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Merge mails.
+ *
+ * @param int $user
+ * @access public
+ * @return object
+ */
+ public function mergeMailsTest($user)
+ {
+ $mails = $this->dao->select('*')->from(TABLE_NOTIFY)
+ ->where('objectType')->eq('mail')
+ ->andWhere('toList')->eq($user)
+ ->fetchAll();
+
+ $object = $this->objectModel->mergeMails($mails);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Get subject.
+ *
+ * @param int $objectType
+ * @param int $object
+ * @param int $title
+ * @param int $actionType
+ * @access public
+ * @return object
+ */
+ public function getSubjectTest($objectType, $object, $title, $actionType)
+ {
+ $object = $this->tester->loadModel($objectType)->getByID($object);
+ $object = $this->objectModel->getSubject($objectType, $object, $title, $actionType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+}
diff --git a/module/mail/test/model/addqueue.php b/module/mail/test/model/addqueue.php
new file mode 100755
index 0000000000..bde1cf179a
--- /dev/null
+++ b/module/mail/test/model/addqueue.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+addQueue();
+cid=1
+pid=1
+
+提交数据为空时 >> 没有数据提交
+获取添加的邮件主题 >> 测试提交队列
+获取收件人列表不包含自己 >> user3
+获取收件人列表包含自己 >> user3,admin
+
+*/
+
+$mail = new mailTest();
+
+$result1 = $mail->addQueueTest('','');
+$result2 = $mail->addQueueTest('user3', '测试提交队列', '测试发信内容');
+$result3 = $mail->addQueueTest('user3,admin', '测试提交队列', '测试发信内容');
+$result4 = $mail->addQueueTest('user3,admin', '测试提交队列', '测试发信内容', '', true);
+
+r($result1) && p() && e('没有数据提交'); //提交数据为空时
+r($result2) && p('subject') && e('测试提交队列'); //获取添加的邮件主题
+r($result3) && p('toList') && e('user3'); //获取收件人列表不包含自己
+r($result4) && p('toList') && e('user3,admin'); //获取收件人列表包含自己
\ No newline at end of file
diff --git a/module/mail/test/model/autodetect.php b/module/mail/test/model/autodetect.php
new file mode 100755
index 0000000000..7f898d3e7f
--- /dev/null
+++ b/module/mail/test/model/autodetect.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+autoDetect();
+cid=1
+pid=1
+
+检测qq邮箱信息 >> smtp.qq.com
+检测163邮箱信息 >> smtp.163.com
+检测搜狐邮箱信息 >> smtp.sohu.com
+检测搜狐vip邮箱信息 >> smtp.vip.sohu.com
+检测不存在的邮箱服务商信息 >> 没有检测到相关信息
+
+*/
+
+$mail = new mailTest();
+
+$data = array('test@qq.com', 'test@163.com', 'test@sohu.com', 'test@vip.sohu.com', 'testm');
+
+r($mail->autoDetectTest($data[0])) && p('host') && e('smtp.qq.com'); //检测qq邮箱信息
+r($mail->autoDetectTest($data[1])) && p('host') && e('smtp.163.com'); //检测163邮箱信息
+r($mail->autoDetectTest($data[2])) && p('host') && e('smtp.sohu.com'); //检测搜狐邮箱信息
+r($mail->autoDetectTest($data[3])) && p('host') && e('smtp.vip.sohu.com'); //检测搜狐vip邮箱信息
+r($mail->autoDetectTest($data[4])) && p() && e('没有检测到相关信息'); //检测不存在的邮箱服务商信息
\ No newline at end of file
diff --git a/module/mail/test/model/getconfigbydetectingsmtp.php b/module/mail/test/model/getconfigbydetectingsmtp.php
new file mode 100755
index 0000000000..9a92ea9a1d
--- /dev/null
+++ b/module/mail/test/model/getconfigbydetectingsmtp.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getConfigByDetectingSMTP();
+cid=1
+pid=1
+
+根据域名获取smtp >> smtp.qq.com
+根据域名获取secure >> ssl
+当端口号不为465时获取secure >> 0
+当域名不存在时 >> 0
+
+*/
+
+$mail = new mailTest();
+
+$result1 = $mail->getConfigByDetectingSMTPTest('qq.com','122@qq.com',465);
+$result2 = $mail->getConfigByDetectingSMTPTest('qq.com','122@qq.com',465);
+$result3 = $mail->getConfigByDetectingSMTPTest('qq.com','122@qq.com',22);
+$result4 = $mail->getConfigByDetectingSMTPTest('testqq.com','122@qq.com',22);
+
+r($result1) && p('host') && e('smtp.qq.com'); //根据域名获取smtp
+r($result2) && p('secure') && e('ssl'); //根据域名获取secure
+r($result3) && p('secure') && e('0'); //当端口号不为465时获取secure
+r($result4) && p() && e('0'); //当域名不存在时
\ No newline at end of file
diff --git a/module/mail/test/model/getconfigbymxrr.php b/module/mail/test/model/getconfigbymxrr.php
new file mode 100755
index 0000000000..7502c7e153
--- /dev/null
+++ b/module/mail/test/model/getconfigbymxrr.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getConfigByMXRR();
+cid=1
+pid=1
+
+获取qq相关信息 >> smtp.qq.com
+获取sohu相关信息 >> smtp.sohu.com
+
+*/
+
+$mail = new mailTest();
+
+$result1 = $mail->getConfigByMXRRTest('qq.com','test');
+$result2 = $mail->getConfigByMXRRTest('sohu.com','test');
+
+r($result1) && p('host') && e('smtp.qq.com'); //获取qq相关信息
+r($result2) && p('host') && e('smtp.sohu.com'); //获取sohu相关信息
\ No newline at end of file
diff --git a/module/mail/test/model/getconfigfromprovider.php b/module/mail/test/model/getconfigfromprovider.php
new file mode 100755
index 0000000000..2f9af18f80
--- /dev/null
+++ b/module/mail/test/model/getconfigfromprovider.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getConfigFromProvider();
+cid=1
+pid=1
+
+获取qq相关信息 >> smtp.qq.com
+获取sohu相关信息 >> smtp.sohu.com
+
+*/
+
+$mail = new mailTest();
+
+$result1 = $mail->getConfigFromProviderTest('qq.com','123');
+$result2 = $mail->getConfigFromProviderTest('sohu.com','123');
+
+r($result1) && p('host') && e('smtp.qq.com'); //获取qq相关信息
+r($result2) && p('host') && e('smtp.sohu.com'); //获取sohu相关信息
\ No newline at end of file
diff --git a/module/mail/test/model/getqueue.php b/module/mail/test/model/getqueue.php
new file mode 100755
index 0000000000..f8efc02808
--- /dev/null
+++ b/module/mail/test/model/getqueue.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getQueue();
+cid=1
+pid=1
+
+按照收件人分组获取邮件列表个数 >> 7
+按照收件人分组获取发送失败的邮件数量 >> 7
+按照收件人分组获取待发送的邮件数量 >> 7
+按照收件人分组获取第一条待发送的邮件内容 >> 测试发信内容
+
+*/
+
+$mail = new mailTest();
+
+$result1 = count($mail->getQueueTest());
+$result2 = count($mail->getQueueTest('fail'));
+$result3 = count($mail->getQueueTest('wait'));
+$result4 = $mail->getQueueTest('wait');
+
+r($result1) && p() && e('7'); //按照收件人分组获取邮件列表个数
+r($result2) && p() && e('7'); //按照收件人分组获取发送失败的邮件数量
+r($result3) && p() && e('7'); //按照收件人分组获取待发送的邮件数量
+r($result4) && p('0:data') && e('测试发信内容'); //按照收件人分组获取第一条待发送的邮件内容
\ No newline at end of file
diff --git a/module/mail/test/model/getqueuebyid.php b/module/mail/test/model/getqueuebyid.php
new file mode 100755
index 0000000000..c23df07273
--- /dev/null
+++ b/module/mail/test/model/getqueuebyid.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getQueueById();
+cid=1
+pid=1
+
+获取id为1的邮件主题 >> 主题1
+获取id为10的收件人 >> top10
+获取id不存在的邮件信息 >> 0
+
+*/
+
+$mail = new mailTest();
+
+$queueID = array(1,10,0);
+
+r($mail->getQueueByIdTest($queueID[0])) && p('subject') && e('主题1'); //获取id为1的邮件主题
+r($mail->getQueueByIdTest($queueID[1])) && p('toList') && e('top10'); //获取id为10的收件人
+r($mail->getQueueByIdTest($queueID[2])) && p() && e('0'); //获取id不存在的邮件信息
\ No newline at end of file
diff --git a/module/mail/test/model/getsubject.php b/module/mail/test/model/getsubject.php
new file mode 100755
index 0000000000..deaf4a288b
--- /dev/null
+++ b/module/mail/test/model/getsubject.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getSubject();
+cid=1
+pid=1
+
+获取关闭测试单时邮件主题 >> admin关闭了测试单 #1:测试单1
+获取创建文档时的邮件主题 >> admin创建了文档 #1:文档标题901
+获取操作需求时的邮件主题 >> STORY #1 test - 正常产品1
+获取操作任务时的邮件主题 >> TASK #1 test - 迭代1
+获取操作BUG时的邮件主题 >> BUG #1 test - 正常产品1
+
+*/
+
+$mail = new mailTest();
+
+$result1 = $mail->getSubjectTest('testtask', 1, '123', 'closed');
+$result2 = $mail->getSubjectTest('doc', 1, 'test', 'created');
+$result3 = $mail->getSubjectTest('story', 1, 'test', 'created');
+$result4 = $mail->getSubjectTest('task', 1, 'test', 'created');
+$result5 = $mail->getSubjectTest('bug', 1, 'test', 'created');
+
+r($result1) && p() && e('admin关闭了测试单 #1:测试单1'); //获取关闭测试单时邮件主题
+r($result2) && p() && e('admin创建了文档 #1:文档标题901'); //获取创建文档时的邮件主题
+r($result3) && p() && e('STORY #1 test - 正常产品1'); //获取操作需求时的邮件主题
+r($result4) && p() && e('TASK #1 test - 迭代1'); //获取操作任务时的邮件主题
+r($result5) && p() && e('BUG #1 test - 正常产品1'); //获取操作BUG时的邮件主题
\ No newline at end of file
diff --git a/module/mail/test/model/mailexist.php b/module/mail/test/model/mailexist.php
new file mode 100755
index 0000000000..9e91acb01f
--- /dev/null
+++ b/module/mail/test/model/mailexist.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+mailExist();
+cid=1
+pid=1
+
+检查系统是否至少存在邮件 >> 10001000@qq.com
+
+*/
+
+$mail = new mailTest();
+
+r($mail->mailExistTest()) && p('email') && e('10001000@qq.com'); //检查系统是否至少存在邮件
\ No newline at end of file
diff --git a/module/mail/test/model/mergemails.php b/module/mail/test/model/mergemails.php
new file mode 100755
index 0000000000..d21cad7c31
--- /dev/null
+++ b/module/mail/test/model/mergemails.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+mergeMails();
+cid=1
+pid=1
+
+获取邮件合并后的id >> 6,1
+获取邮件合并后的主题 >> 主题6|主题1
+
+*/
+
+$mail = new mailTest();
+
+r($mail->mergeMailsTest('admin')) && p('id') && e('6,1'); //获取邮件合并后的id
+r($mail->mergeMailsTest('admin')) && p('subject') && e('主题6|主题1'); //获取邮件合并后的主题
\ No newline at end of file
diff --git a/module/mail/test/model/send.php b/module/mail/test/model/send.php
new file mode 100755
index 0000000000..d414194349
--- /dev/null
+++ b/module/mail/test/model/send.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+send();
+cid=1
+pid=1
+
+ >> 0
+
+*/
+
+$mail = new mailTest();
+
+/* If you don't set SMTP Please input you SMTP setting. */
+$mailConfig = new stdclass();
+$mailConfig->smtp = new stdclass();
+
+$mailConfig->turnon = 1;
+$mailConfig->mta = 'smtp';
+$mailConfig->async = 0;
+$mailConfig->fromAddress = '';
+$mailConfig->fromName = '';
+$mailConfig->domain = '';
+$mailConfig->smtp->host = '';
+$mailConfig->smtp->port = '';
+$mailConfig->smtp->auth = '1';
+$mailConfig->smtp->username = '';
+$mailConfig->smtp->password = '';
+$mailConfig->smtp->secure = '';
+$mailConfig->smtp->debug = 1;
+$mailConfig->smtp->charset = 'utf-8';
+
+global $tester;
+if(!isset($tester->config->mail->turnon)) $tester->loadModel('setting')->setItems('system.mail', $mailConfig);
+
+$result1 = $mail->sendTest('admin','test','test','',true);
+
+r($result1) && p() && e('0');
\ No newline at end of file
diff --git a/module/mail/test/model/sendmail.php b/module/mail/test/model/sendmail.php
new file mode 100755
index 0000000000..2082abd9bd
--- /dev/null
+++ b/module/mail/test/model/sendmail.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+sendmail();
+cid=1
+pid=1
+
+测试为dev4用户发送邮件通知 >> 0
+
+*/
+
+$mail = new mailTest();
+
+r($mail->sendmailTest(48,48)) && p() && e('0'); //测试为dev4用户发送邮件通知
\ No newline at end of file
diff --git a/module/mail/test/model/setbody.php b/module/mail/test/model/setbody.php
new file mode 100755
index 0000000000..be401a758c
--- /dev/null
+++ b/module/mail/test/model/setbody.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+setCC();
+cid=1
+pid=1
+
+测试设置内容 >> test body
+
+*/
+
+$mail = new mailTest();
+
+r($mail->setBodyTest('test body')) && p('Body') && e('test body'); //测试设置内容
\ No newline at end of file
diff --git a/module/mail/test/model/setmta.php b/module/mail/test/model/setmta.php
new file mode 100755
index 0000000000..cd96012b5f
--- /dev/null
+++ b/module/mail/test/model/setmta.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+setCC();
+cid=1
+pid=1
+
+获取MTA主机 >> localhost
+获取MTAdebug设置 >> 0
+
+*/
+
+$mail = new mailTest();
+
+r($mail->setMTATest()) && p('Host') && e('localhost'); //获取MTA主机
+r($mail->setMTATest()) && p('SMTPDebug') && e('0'); //获取MTAdebug设置
\ No newline at end of file
diff --git a/module/mail/test/model/setsubject.php b/module/mail/test/model/setsubject.php
new file mode 100755
index 0000000000..375c40e0f0
--- /dev/null
+++ b/module/mail/test/model/setsubject.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+setCC();
+cid=1
+pid=1
+
+测试设置主题 >> test subject
+
+*/
+
+$mail = new mailTest();
+
+r($mail->setSubjectTest('test subject')) && p('Subject') && e('test subject'); //测试设置主题
\ No newline at end of file
diff --git a/module/message/test/message.class.php b/module/message/test/message.class.php
new file mode 100644
index 0000000000..dae6f3a58f
--- /dev/null
+++ b/module/message/test/message.class.php
@@ -0,0 +1,122 @@
+objectModel = $tester->loadModel('message');
+ }
+
+ public function getMessagesTest($status)
+ {
+ $objects = $this->objectModel->getMessages($status);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get objectTypes.
+ *
+ * @access public
+ * @return void
+ */
+ public function getObjectTypesTest()
+ {
+ $objects = $this->objectModel->getObjectTypes();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get object actions.
+ *
+ * @access public
+ * @return void
+ */
+ public function getObjectActionsTest()
+ {
+ $objects = $this->objectModel->getObjectActions();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Check send.
+ *
+ * @param int $objectType
+ * @param int $objectID
+ * @param int $actionType
+ * @param int $actionID
+ * @param string $actor
+ * @access public
+ * @return void
+ */
+ public function sendTest($objectType, $objectID, $actionType, $actionID, $actor = '')
+ {
+ $objects = $this->objectModel->send($objectType, $objectID, $actionType, $actionID, $actor = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Save notice.
+ *
+ * @param int $objectType
+ * @param int $objectID
+ * @param int $actionType
+ * @param int $actionID
+ * @param string $actor
+ * @access public
+ * @return void
+ */
+ public function saveNoticeTest($objectType, $objectID, $actionType, $actionID, $actor = '')
+ {
+ $objects = $this->objectModel->saveNotice($objectType, $objectID, $actionType, $actionID, $actor = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get toList.
+ *
+ * @param int $objectType
+ * @access public
+ * @return void
+ */
+ public function getToListTest($objectType)
+ {
+ global $tester;
+ $table = $tester->config->objectTables[$objectType];
+ $object = $tester->dao->select('*')->from($table)->where('id')->eq('1')->fetch();
+ $objects = $this->objectModel->getToList($object, $objectType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get notice todos.
+ *
+ * @access public
+ * @return void
+ */
+ public function getNoticeTodosTest()
+ {
+ $objects = $this->objectModel->getNoticeTodos();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/message/test/model/getmessages.php b/module/message/test/model/getmessages.php
new file mode 100755
index 0000000000..8bc3fdcdbc
--- /dev/null
+++ b/module/message/test/model/getmessages.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getMessages();
+cid=1
+pid=1
+
+拿取status为wait的数据信息 >> 1
+拿取status为wait的数据信息 >> 114
+
+*/
+
+$message = new messageTest();
+
+r($message->getMessagesTest('wait')) && p('1:id') && e('1'); //拿取status为wait的数据信息
+r($message->getMessagesTest('wait')) && p('2:action') && e('114'); //拿取status为wait的数据信息
\ No newline at end of file
diff --git a/module/message/test/model/getnoticetodos.php b/module/message/test/model/getnoticetodos.php
new file mode 100755
index 0000000000..f69408e0ee
--- /dev/null
+++ b/module/message/test/model/getnoticetodos.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getNoticeTodos();
+cid=1
+pid=1
+
+查询notice为空的todo的信息 >> 0
+
+*/
+
+$message = new messageTest();
+
+r($message->getNoticeTodosTest()) && p('0') && e('0'); //查询notice为空的todo的信息
\ No newline at end of file
diff --git a/module/message/test/model/getobjectactions.php b/module/message/test/model/getobjectactions.php
new file mode 100755
index 0000000000..3d9de421c0
--- /dev/null
+++ b/module/message/test/model/getobjectactions.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+getObjectActions();
+cid=1
+pid=1
+
+查询objectType为product的action是opened的lab标签 >> 创建
+查询objectType为story的action是frombug的lab标签 >> 转研发需求
+查询objectType为productplan的action是edited的lab标签 >> 编辑
+查询objectType为project的action是delayed的lab标签 >> 延期
+查询objectType为task的action是assigned的lab标签 >> 指派
+查询objectType为bug的action是closed的lab标签 >> 关闭
+查询objectType为case的action是opended的lab标签 >> 创建
+查询objectType为testtask的action是starteded的lab标签 >> 开始
+查询objectType为todo的action是edited的lab标签 >> 编辑
+查询objectType为doc的action是created的lab标签 >> 创建
+查询objectType为mr的action是compilefail的lab标签 >> 构建失败
+
+*/
+
+$message = new messageTest();
+
+r($message->getObjectActionsTest()) && p('product:opened') && e('创建'); //查询objectType为product的action是opened的lab标签
+r($message->getObjectActionsTest()) && p('story:frombug') && e('转研发需求'); //查询objectType为story的action是frombug的lab标签
+r($message->getObjectActionsTest()) && p('productplan:edited') && e('编辑'); //查询objectType为productplan的action是edited的lab标签
+r($message->getObjectActionsTest()) && p('project:delayed') && e('延期'); //查询objectType为project的action是delayed的lab标签
+r($message->getObjectActionsTest()) && p('task:assigned') && e('指派'); //查询objectType为task的action是assigned的lab标签
+r($message->getObjectActionsTest()) && p('bug:closed') && e('关闭'); //查询objectType为bug的action是closed的lab标签
+r($message->getObjectActionsTest()) && p('case:opened') && e('创建'); //查询objectType为case的action是opended的lab标签
+r($message->getObjectActionsTest()) && p('testtask:started') && e('开始'); //查询objectType为testtask的action是starteded的lab标签
+r($message->getObjectActionsTest()) && p('todo:edited') && e('编辑'); //查询objectType为todo的action是edited的lab标签
+r($message->getObjectActionsTest()) && p('doc:created') && e('创建'); //查询objectType为doc的action是created的lab标签
+r($message->getObjectActionsTest()) && p('mr:compilefail') && e('构建失败'); //查询objectType为mr的action是compilefail的lab标签
\ No newline at end of file
diff --git a/module/message/test/model/getobjecttypes.php b/module/message/test/model/getobjecttypes.php
new file mode 100755
index 0000000000..3aa366073c
--- /dev/null
+++ b/module/message/test/model/getobjecttypes.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+getObjectTypes();
+cid=1
+pid=1
+
+查询objectType为product的objectTypes >> 产品
+查询objectType为story的objectTypes >> 研发需求
+查询objectType为productplan的objectTypes >> 计划
+查询objectType为project的objectTypes >> 项目
+查询objectType为task的objectTypes >> 任务
+查询objectType为bug的objectTypes >> Bug
+查询objectType为case的objectTypes >> 用例
+查询objectType为testcase的objectTypes >> 测试单
+查询objectType为todo的objectTypes >> 待办
+查询objectType为doc的objectTypes >> 文档
+查询objectType为mr的objectTypes >> 合并请求
+
+*/
+
+$message = new messageTest();
+
+r($message->getObjectTypesTest()) && p('product') && e('产品'); //查询objectType为product的objectTypes
+r($message->getObjectTypesTest()) && p('story') && e('研发需求'); //查询objectType为story的objectTypes
+r($message->getObjectTypesTest()) && p('productplan') && e('计划'); //查询objectType为productplan的objectTypes
+r($message->getObjectTypesTest()) && p('project') && e('项目'); //查询objectType为project的objectTypes
+r($message->getObjectTypesTest()) && p('task') && e('任务'); //查询objectType为task的objectTypes
+r($message->getObjectTypesTest()) && p('bug') && e('Bug'); //查询objectType为bug的objectTypes
+r($message->getObjectTypesTest()) && p('case') && e('用例'); //查询objectType为case的objectTypes
+r($message->getObjectTypesTest()) && p('testtask') && e('测试单'); //查询objectType为testcase的objectTypes
+r($message->getObjectTypesTest()) && p('todo') && e('待办'); //查询objectType为todo的objectTypes
+r($message->getObjectTypesTest()) && p('doc') && e('文档'); //查询objectType为doc的objectTypes
+r($message->getObjectTypesTest()) && p('mr') && e('合并请求'); //查询objectType为mr的objectTypes
\ No newline at end of file
diff --git a/module/message/test/model/gettolist.php b/module/message/test/model/gettolist.php
new file mode 100755
index 0000000000..99d8c9999c
--- /dev/null
+++ b/module/message/test/model/gettolist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getToList();
+cid=1
+pid=1
+
+通过一条todo数据展示 >> admin
+通过一条testtask数据展示 >> user3
+通过一条meeting数据展示 >> admin,admin,
+通过一条mr数据展示 >> admin,admin
+通过一条release数据展示 >> po1
+通过一条task数据展示 >> po82
+
+*/
+
+$message = new messageTest();
+
+r($message->getToListTest('todo')) && p() && e('admin'); //通过一条todo数据展示$toList
+r($message->getToListTest('testtask')) && p() && e('user3'); //通过一条testtask数据展示$toList
+r($message->getToListTest('meeting')) && p() && e('admin,admin,'); //通过一条meeting数据展示$toList
+r($message->getToListTest('mr')) && p() && e('admin,admin'); //通过一条mr数据展示$toList
+r($message->getToListTest('release')) && p() && e('po1'); //通过一条release数据展示$toList
+r($message->getToListTest('task')) && p() && e('po82'); //通过一条task数据展示$toList
\ No newline at end of file
diff --git a/module/message/test/model/savenotice.php b/module/message/test/model/savenotice.php
new file mode 100755
index 0000000000..1e8f461f74
--- /dev/null
+++ b/module/message/test/model/savenotice.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+saveNotice();
+cid=1
+pid=1
+
+通过拿取todo表的第一条数据并且将actor赋值admin获取返回值 >> 0
+通过拿取task表的第一条数据并且将actor赋值admin获取返回值 >> 0
+通过拿取todo表的第一条数据并且不给actor赋值获取返回值 >> 0
+通过拿取todo表的第一条数据并且给actor赋值user1获取返回值 >> 0
+
+*/
+
+$message = new messageTest();
+
+r($message->saveNoticeTest('todo', '1', 'product', '1', 'admin')) && p() && e('0'); //通过拿取todo表的第一条数据并且将actor赋值admin获取返回值
+r($message->saveNoticeTest('task', '1', 'product', '1', 'admin')) && p() && e('0'); //通过拿取task表的第一条数据并且将actor赋值admin获取返回值
+r($message->saveNoticeTest('todo', '1', 'product', '1', '')) && p() && e('0'); //通过拿取todo表的第一条数据并且不给actor赋值获取返回值
+r($message->saveNoticeTest('todo', '1', 'product', '1', 'user1')) && p() && e('0'); //通过拿取todo表的第一条数据并且给actor赋值user1获取返回值
\ No newline at end of file
diff --git a/module/message/test/model/send.php b/module/message/test/model/send.php
new file mode 100755
index 0000000000..88f6100042
--- /dev/null
+++ b/module/message/test/model/send.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+send();
+cid=1
+pid=1
+
+通过拿取todo表的第一条数据并且将actor赋值admin获取返回值 >> 0
+通过拿取todo表的第0条数据并且将actor赋值admin获取返回值 >> 0
+
+*/
+
+$message = new messageTest();
+
+r($message->sendTest('todo', '1', 'product', '1', 'admin')) && p() && e('0'); //通过拿取todo表的第一条数据并且将actor赋值admin获取返回值
+r($message->sendTest('todo', '0', 'product', '1', 'admin')) && p() && e('0'); //通过拿取todo表的第0条数据并且将actor赋值admin获取返回值
\ No newline at end of file
diff --git a/module/misc/test/misc.class.php b/module/misc/test/misc.class.php
new file mode 100644
index 0000000000..1346917bc0
--- /dev/null
+++ b/module/misc/test/misc.class.php
@@ -0,0 +1,60 @@
+misc = $tester->loadModel('misc');
+ }
+
+ /**
+ * hello
+ *
+ * @access public
+ * @return void
+ */
+ public function hello()
+ {
+ $miscs = $this->misc->hello();
+ return $miscs;
+ }
+
+ /**
+ * getTableAndStatus
+ * 传入参数来获取表状态
+ * @param string $type
+ * @access public
+ * @return void
+ */
+ public function getTableAndStatus($type = 'check')
+ {
+ $miscs = $this->misc->getTableAndStatus($type = 'check');
+ return $miscs;
+ }
+
+ /**
+ * getRemind
+ *
+ * @access public
+ * @return void
+ */
+ public function getRemind()
+ {
+ $miscs = $this->misc->getRemind();
+ return $miscs;
+ }
+
+ /**
+ * checkOneClickPackage
+ *
+ * @access public
+ * @return void
+ */
+ public function checkOneClickPackage()
+ {
+ $miscs = $this->misc->checkOneClickPackage();
+ return $miscs;
+ }
+}
+?>
diff --git a/module/misc/test/model/checkoneclickpackage.php b/module/misc/test/model/checkoneclickpackage.php
new file mode 100755
index 0000000000..82cbeffb28
--- /dev/null
+++ b/module/misc/test/model/checkoneclickpackage.php
@@ -0,0 +1,9 @@
+#!/usr/bin/env php
+checkOneClickPackage()) && p() && e('');
+?>
diff --git a/module/misc/test/model/getremind.php b/module/misc/test/model/getremind.php
new file mode 100755
index 0000000000..726a0dae08
--- /dev/null
+++ b/module/misc/test/model/getremind.php
@@ -0,0 +1,9 @@
+#!/usr/bin/env php
+getRemind()) && p() && e('0'); //调用方法返回值
+?>
diff --git a/module/misc/test/model/gettableandstatus.php b/module/misc/test/model/gettableandstatus.php
new file mode 100755
index 0000000000..9993f9af84
--- /dev/null
+++ b/module/misc/test/model/gettableandstatus.php
@@ -0,0 +1,12 @@
+#!/usr/bin/env php
+getTableAndStatus('check')) && p('zt_account') && e('ok'); //输入表名,查看数据库表状态使用情况等,正常输出ok
+r($misc->getTableAndStatus('check')) && p('zt_zoutput') && e('ok'); //如被占用返回:1 client is using or hasn't closed the table properly(由于动态更新,此处断言两张表正常状态)
+r($misc->getTableAndStatus('repair')) && p('zt_webhook') && e('ok'); //可以传入repair参数,状态与上述一致
+r($misc->getTableAndStatus('aaaaa')) && p('zt_account') && e('ok'); //这里测试传入不同参数||返回值相同
+?>
diff --git a/module/misc/test/model/hello.php b/module/misc/test/model/hello.php
new file mode 100755
index 0000000000..2c7908a3f9
--- /dev/null
+++ b/module/misc/test/model/hello.php
@@ -0,0 +1,9 @@
+#!/usr/bin/env php
+hello()) && p() && e('hello world from hello()
'); //简单打印,maybe test function。
+?>
diff --git a/module/mr/test/model/apicreate.php b/module/mr/test/model/apicreate.php
new file mode 100755
index 0000000000..a632bca31c
--- /dev/null
+++ b/module/mr/test/model/apicreate.php
@@ -0,0 +1,71 @@
+#!/usr/bin/env php
+> fail
+使用正确的RepoUrl,错误的分支数据创建mr请求 >> fail
+使用源分支和目标分支一样的数据创建mr请求 >> success
+使用正确的数据创建mr请求 >> success
+
+*/
+
+global $lang;
+$mrModel = $tester->loadModel('mr');
+
+$_POST = array(
+ 'data' => array()
+);
+
+$_POST['data']['RepoUrl'] = '';
+$result = $mrModel->apiCreate();
+if(!$result) $result = 'fail';
+r($result) && p() && e('fail'); //使用空的RepoUrl数据创建
+
+dao::$errors = array();
+$_POST['data']['RepoUrl'] = 'http://192.168.1.161:51080/root/azalea723test.git';
+$_POST['data']['DiffMsg'] = '';
+$_POST['data']['RepoSrcBranch'] = '';
+$_POST['data']['RepoDistBranch'] = '';
+$_POST['data']['MergeStatus'] = '1';
+$result = $mrModel->apiCreate();
+if(!$result) $result = 'fail';
+r($result) && p() && e('fail'); //使用正确的RepoUrl,错误的分支数据创建mr请求
+
+dao::$errors = array();
+$_POST['data']['RepoSrcBranch'] = 'master';
+$_POST['data']['RepoDistBranch'] = 'master';
+
+/* Get same opened MR and close it.*/
+$gitlabID = 1;
+$projectID = 42;
+$oldMR = $mrModel->apiGetSameOpened($gitlabID, $projectID, 'master', $projectID, 'master');
+if($oldMR) $mrModel->apiCloseMR(1, 42, $oldMR->iid);
+
+$result = $mrModel->apiCreate();
+if(!$result and dao::isError())
+{
+ $errors = dao::getError();
+ if($errors[0] == $lang->mr->errorLang[1]) $result = 'success';
+}
+r($result) && p() && e('success'); //使用源分支和目标分支一样的数据创建mr请求
+
+dao::$errors = array();
+$_POST['data']['RepoSrcBranch'] = 'branch-08';
+$_POST['data']['RepoDistBranch'] = 'master';
+$oldMR = $mrModel->apiGetSameOpened($gitlabID, $projectID, 'branch-08', $projectID, 'master');
+if($oldMR) $mrModel->apiCloseMR(1, 42, $oldMR->iid);
+
+$result = $mrModel->apiCreate();
+if(dao::isError())
+{
+ $errors = dao::getError();
+ $result = preg_match('/[存在另外一个同样的合并请求在源项目分支中,存在重复并且未关闭的合并请求]: ID([0-9]+)/', $errors[0], $matches); //检查错误原因是否是已存在一样的mr请求
+}
+if($result) $result = 'success';
+r($result) && p() && e('success'); //使用正确的数据创建mr请求
\ No newline at end of file
diff --git a/module/mr/test/model/apigetsameopened.php b/module/mr/test/model/apigetsameopened.php
new file mode 100755
index 0000000000..61e659fcb5
--- /dev/null
+++ b/module/mr/test/model/apigetsameopened.php
@@ -0,0 +1,134 @@
+#!/usr/bin/env php
+> success
+使用空的gitlabID >> null
+使用空的sourceProject >> null
+使用空的sourceBranch >> null
+使用空的targetProject >> null
+使用空的targetBranch >> null
+使用错误的gitlabID >> null
+使用错误的sourceProject >> null
+使用错误的sourceBranch >> null
+使用错误的targetProject >> null
+使用错误的targetBranch >> null
+
+*/
+$mrModel = $tester->loadModel('mr');
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$_POST['gitlabID'] = $gitlabID;
+$_POST['title'] = 'test_create';
+$_POST['description'] = 'test_create';
+$_POST['repoID'] = 1;
+$_POST['assignee'] = '';
+$_POST['removeSourceBranch'] = '1';
+$_POST['sourceProject'] = $sourceProject;
+$_POST['sourceBranch'] = $sourceBranch;
+$_POST['targetProject'] = $targetProject;
+$_POST['targetBranch'] = $targetBranch;
+$result = $mrModel->create();
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if(isset($result->iid)) $result = 'success';
+r($result) && p() && e('success'); //使用正确的gitlabID, sourceProject,sourceBranch,targetProject,targetBranch
+
+$gitlabID = '';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用空的gitlabID
+
+$gitlabID = '1';
+$sourceProject = '';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用空的sourceProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = '';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用空的sourceBranch
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用空的targetProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = '';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用空的targetBranch
+
+$gitlabID = 'test';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用错误的gitlabID
+
+$gitlabID = '1';
+$sourceProject = 'test';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用错误的sourceProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用错误的sourceBranch
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = 'test';
+$targetBranch = 'master';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用错误的targetProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'main';
+$result = $mrModel->apiGetSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+if($result === null) $result = 'null';
+r($result) && p() && e('null'); //使用错误的targetBranch
\ No newline at end of file
diff --git a/module/mr/test/model/checksameopened.php b/module/mr/test/model/checksameopened.php
new file mode 100755
index 0000000000..323b2b5cdc
--- /dev/null
+++ b/module/mr/test/model/checksameopened.php
@@ -0,0 +1,112 @@
+#!/usr/bin/env php
+> fail
+使用空的gitlabID >> success
+使用空的sourceProject >> success
+使用空的sourceBranch >> success
+使用空的targetProject >> success
+使用空的targetBranch >> success
+使用错误的gitlabID >> success
+使用错误的sourceProject >> success
+使用错误的sourceBranch >> success
+使用错误的targetProject >> success
+使用错误的targetBranch >> success
+
+*/
+$mrModel = $tester->loadModel('mr');
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('fail'); //使用正确的gitlabID, sourceProject,sourceBranch,targetProject,targetBranch
+
+$gitlabID = '';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用空的gitlabID
+
+$gitlabID = '1';
+$sourceProject = '';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用空的sourceProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = '';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用空的sourceBranch
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用空的targetProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = '';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用空的targetBranch
+
+$gitlabID = 'test';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用错误的gitlabID
+
+$gitlabID = '1';
+$sourceProject = 'test';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用错误的sourceProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch08';
+$targetProject = '42';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用错误的sourceBranch
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = 'test';
+$targetBranch = 'master';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用错误的targetProject
+
+$gitlabID = '1';
+$sourceProject = '42';
+$sourceBranch = 'branch-08';
+$targetProject = '42';
+$targetBranch = 'main';
+$result = $mrModel->checkSameOpened($gitlabID, $sourceProject, $sourceBranch, $targetProject, $targetBranch);
+r($result) && p('result') && e('success'); //使用错误的targetBranch
\ No newline at end of file
diff --git a/module/mr/test/model/convertapierror.php b/module/mr/test/model/convertapierror.php
new file mode 100755
index 0000000000..b91291a8e9
--- /dev/null
+++ b/module/mr/test/model/convertapierror.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+> success
+使用空的message >> success
+
+*/
+$mrModel = $tester->loadModel('mr');
+
+$message = array();
+$message[0] = 'Another open merge request already exists for this source branch: !11';
+$result = $mrModel->convertApiError($message);
+if($result != $message[0]) $result = 'success';
+r($result) && p('') && e('success'); //使用正确的message
+
+$message = '';
+$result = $mrModel->convertApiError($message);
+if(empty($result)) $result = 'success';
+r($result) && p('') && e('success'); //使用空的message
\ No newline at end of file
diff --git a/module/mr/test/model/create.php b/module/mr/test/model/create.php
new file mode 100644
index 0000000000..1e096b0c63
--- /dev/null
+++ b/module/mr/test/model/create.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+> 『GitLab』不能为空。
+使用正确的repoID, gitlabID。POST数据正确 或者错误原因为已存在一样的mr请求 >> success
+使用源分支和目标分支一样的数据mr请求 >> 通过API创建合并请求失败,失败原因:源项目分支与目标项目分支不能相同
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$_POST = array();
+
+$_POST['gitlabID'] = 0;
+$_POST['repoID'] = 0;
+$_POST['sourceProject'] = 42;
+$_POST['sourceBranch'] = 'branch-08';
+$_POST['targetProject'] = 42;
+$_POST['targetBranch'] = 'branch-09';
+$result = $mrModel->create();
+r($result) && p('message[gitlabID]:0') && e('『GitLab』不能为空。'); //使用空的repoID, gitlabID。创建mr。
+
+$_POST['gitlabID'] = 1;
+$_POST['title'] = 'test_create';
+$_POST['description'] = 'test_create';
+$_POST['repoID'] = 1;
+$_POST['assignee'] = '';
+$_POST['removeSourceBranch'] = '1';
+$result = $mrModel->create();
+if($result['result'] == 'success') $result = 'success';
+$result = preg_match('/存在另外一个同样的合并请求在源项目分支中: ID([0-9]+)/', $result['message'], $matches); //检查错误原因是否是已存在一样的mr请求
+if($result) $result = 'success';
+r($result) && p() && e('success'); //使用正确的repoID, gitlabID。POST数据正确 或者错误原因为已存在一样的mr请求
+
+$_POST['targetBranch'] = 'branch-08';
+$result = $mrModel->create();
+r($result) && p('message') && e('通过API创建合并请求失败,失败原因:源项目分支与目标项目分支不能相同'); //使用源分支和目标分支一样的数据mr请求
diff --git a/module/mr/test/model/getallgitlabprojects.php b/module/mr/test/model/getallgitlabprojects.php
new file mode 100755
index 0000000000..8b5dd6d68e
--- /dev/null
+++ b/module/mr/test/model/getallgitlabprojects.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> return empty
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$result = $mrModel->getAllGitlabProjects();
+if(empty($result)) $result = 'return empty';
+r($result) && p() && e('return empty'); //普通用户获取所有gitlab服务器项目列表
+
+su('admin');
+$result = $mrModel->getAllGitlabProjects();
+r(isset(array_shift($result[1])->name)) && p() && e(1); //管理员获取所有gitlab服务器项目列表
\ No newline at end of file
diff --git a/module/mr/test/model/getdiffs.php b/module/mr/test/model/getdiffs.php
new file mode 100755
index 0000000000..afc358862f
--- /dev/null
+++ b/module/mr/test/model/getdiffs.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> return null
+使用正确的MR >> return normal
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$MR = '';
+$result = $mrModel->getDiffs($MR);
+if(empty($result)) $result = 'return null';
+r($result) && p() && e('return null'); //使用空的MR
+
+$MR = $tester->dao->select('*')->from(TABLE_MR)->orderBy('id_desc')->limit(1)->fetch();
+$result = $mrModel->getDiffs($MR);
+if(!empty($result))
+{
+ $first = reset($result);
+ if(isset($first->fileName) and is_array($first->contents)) $result = 'return normal';
+}
+r($result) && p() && e('return normal'); //使用正确的MR
\ No newline at end of file
diff --git a/module/mr/test/model/getlastreviewinfo.php b/module/mr/test/model/getlastreviewinfo.php
new file mode 100755
index 0000000000..c4334abaf9
--- /dev/null
+++ b/module/mr/test/model/getlastreviewinfo.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+> return null
+使用正确的repoID >> return normal
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$repoID = 0;
+$result = $mrModel->getLastReviewInfo($repoID);
+if(empty($result)) $result = 'return null';
+r($result) && p() && e('return null'); //使用空的repoID
+
+$repo = $tester->dao->select('*')->from(TABLE_REPO)->orderBy('id_desc')->limit(1)->fetch();
+$result = $mrModel->getLastReviewInfo($repo->id);
+if(isset($result->bug) and isset($result->task)) $result = 'return normal';
+r($result) && p() && e('return normal'); //使用正确的repoID
\ No newline at end of file
diff --git a/module/mr/test/model/getlist.php b/module/mr/test/model/getlist.php
new file mode 100755
index 0000000000..9309317271
--- /dev/null
+++ b/module/mr/test/model/getlist.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+> return empty
+管理员获取mr列表 >> Test MR
+
+*/
+
+$tester->app->loadClass('pager', $static = true);
+$mrModel = $tester->loadModel('mr');
+
+$mode = 'all';
+$param = 'all';
+$orderBy = 'id_desc';
+$pager = new pager(0, 20, 1);
+
+$projects = $mrModel->getAllGitlabProjects();
+$result = $mrModel->getList($mode, $param, $orderBy, $pager, empty($projects) ? false : $projects);
+if(empty($result)) $result = 'return empty';
+r($result) && p() && e('return empty'); //普通用户获取mr列表
+
+su('admin');
+$projects = $mrModel->getAllGitlabProjects();
+$result = $mrModel->getList($mode, $param, $orderBy, $pager, empty($projects) ? false : $projects);
+r(array_shift($result)) && p('title') && e('Test MR'); //管理员获取mr列表
\ No newline at end of file
diff --git a/module/mr/test/model/getreview.php b/module/mr/test/model/getreview.php
new file mode 100755
index 0000000000..e721c58d9b
--- /dev/null
+++ b/module/mr/test/model/getreview.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+> return null
+使用正确的repoID, MRID >> return normal
+使用正确的repoID, MRID, 错误的revision >> return null
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$repoID = 0;
+$MRID = 0;
+$revision = '';
+
+$result = $mrModel->getReview($repoID, $MRID, $revision);
+if(empty($result)) $result = 'return null';
+r($result) && p() && e('return null'); //使用空的repoID, MRID, revision
+
+$MR = $tester->dao->select('*')->from(TABLE_MR)->orderBy('id_desc')->limit(1)->fetch();
+$repoID = $MR->repoID;
+$MRID = $MR->id;
+$result = $mrModel->getReview($repoID, $MRID, $revision);
+if(!empty($result))
+{
+ $first = reset($result);
+ if(isset($first['bug']) or isset($first['task'])) $result = 'return normal';
+}
+r($result) && p() && e('return normal'); //使用正确的repoID, MRID
+
+$revision = '123qwe';
+$result = $mrModel->getReview($repoID, $MRID, $revision);
+if(empty($result)) $result = 'return null';
+r($result) && p() && e('return null'); //使用正确的repoID, MRID, 错误的revision
\ No newline at end of file
diff --git a/module/mr/test/model/savebug.php b/module/mr/test/model/savebug.php
new file mode 100755
index 0000000000..251c634c1f
--- /dev/null
+++ b/module/mr/test/model/savebug.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+> return false
+使用正确的repoID, MRID。空的title。 >> return false
+使用正确的repoID, MRID。POST数据正确。 >> Test Bug Review
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$_POST = array();
+$_POST['title'] = 'Test Bug Review';
+$_POST['commentText'] = 'Test Bug Review';
+$_POST['module'] = '1';
+$_POST['begin'] = '8';
+$_POST['end'] = '8';
+$_POST['product'] = '1';
+$_POST['assignedTo'] = '';
+
+$repoID = 0;
+$MRID = 0;
+$v1 = 0;
+$v2 = '';
+$result = $mrModel->saveBug($repoID, $MRID, $v1, $v2);
+if($result['result'] == 'fail' and isset($result['message']['mr']) and isset($result['message']['repo'])) $result = 'return false';
+r($result) && p() && e('return false'); //使用空的repoID, MRID
+
+$_POST['title'] = '';
+$MR = $tester->dao->select('*')->from(TABLE_MR)->orderBy('id_desc')->limit(1)->fetch();
+$result = $mrModel->saveBug($MR->repoID, $MR->id, $v1, $v2);
+if($result['result'] == 'fail' and isset($result['message']['title'])) $result = 'return false';
+r($result) && p() && e('return false'); //使用正确的repoID, MRID。空的title。
+
+$_POST['title'] = 'Test Bug Review';
+$result = $mrModel->saveBug($MR->repoID, $MR->id, $v1, $v2);
+r($result) && p('title') && e('Test Bug Review'); //使用正确的repoID, MRID。POST数据正确。
\ No newline at end of file
diff --git a/module/mr/test/model/savetask.php b/module/mr/test/model/savetask.php
new file mode 100755
index 0000000000..7ae2719454
--- /dev/null
+++ b/module/mr/test/model/savetask.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+> return false
+使用正确的repoID, MRID。空的title。 >> return false
+使用正确的repoID, MRID。POST数据正确。 >> Test Task Review
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+
+$_POST = array();
+$_POST['title'] = 'Test Task Review';
+$_POST['commentText'] = 'Test Task Review';
+$_POST['taskModule'] = '1';
+$_POST['taskExecution'] = '1';
+$_POST['begin'] = '8';
+$_POST['end'] = '8';
+$_POST['taskAssignedTo'] = '';
+$_POST['entry'] = '';
+
+$repoID = 0;
+$MRID = 0;
+$v1 = 0;
+$v2 = '';
+$result = $mrModel->saveTask($repoID, $MRID, $v1, $v2);
+if($result['result'] == 'fail' and isset($result['message']['mr']) and isset($result['message']['repo'])) $result = 'return false';
+r($result) && p() && e('return false'); //使用空的repoID, MRID
+
+$_POST['title'] = '';
+$MR = $tester->dao->select('*')->from(TABLE_MR)->orderBy('id_desc')->limit(1)->fetch();
+$result = $mrModel->saveTask($MR->repoID, $MR->id, $v1, $v2);
+if($result['result'] == 'fail' and isset($result['message']['name'])) $result = 'return false';
+r($result) && p() && e('return false'); //使用正确的repoID, MRID。空的title。
+
+$_POST['title'] = 'Test Task Review';
+$result = $mrModel->saveTask($MR->repoID, $MR->id, $v1, $v2);
+r($result) && p('title') && e('Test Task Review'); //使用正确的repoID, MRID。POST数据正确。
\ No newline at end of file
diff --git a/module/mr/test/model/update.php b/module/mr/test/model/update.php
new file mode 100755
index 0000000000..5958fe7264
--- /dev/null
+++ b/module/mr/test/model/update.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+> success
+使用title为空的数据mr请求 >> 『名称』不能为空。
+
+*/
+
+$mrModel = $tester->loadModel('mr');
+$MRID = 1;
+
+$_POST = array();
+$_POST['targetBranch'] = 'master';
+$_POST['title'] = 'Test MR';
+$_POST['description'] = '2022-01-31 23:59:59';
+$_POST['repoID'] = 1;
+$_POST['assignee'] = '';
+$_POST['removeSourceBranch'] = '0';
+$result = $mrModel->update($MRID);
+if($result['result'] == 'success') $result = 'success';
+r($result) && p() && e('success'); //POST数据正确修改MR描述
+
+$_POST['title'] = '';
+$result = $mrModel->update($MRID);
+r($result) && p('message[title]:0') && e('『名称』不能为空。'); //使用title为空的数据mr请求
\ No newline at end of file
diff --git a/module/my/test/model/getactions.php b/module/my/test/model/getactions.php
new file mode 100755
index 0000000000..be05386493
--- /dev/null
+++ b/module/my/test/model/getactions.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getActions();
+cid=1
+pid=1
+
+正常查询action >> 0
+正常查询action统计 >> 0
+
+*/
+
+$my = new myTest();
+
+r($my->getActionsTest()) && p() && e('0'); // 正常查询action
+r(count($my->getActionsTest())) && p() && e('0'); // 正常查询action统计
\ No newline at end of file
diff --git a/module/my/test/model/getassignedbyme.php b/module/my/test/model/getassignedbyme.php
new file mode 100755
index 0000000000..54d46b1d93
--- /dev/null
+++ b/module/my/test/model/getassignedbyme.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getAssignedByMe();
+cid=1
+pid=1
+
+当插入一条action为admin指派了task的动态时,查询结果为1条数据 >> 1
+当插入一条action为admin指派了bug的动态时,查询结果为1条数据 >> 1
+当插入一条action为admin指派了需求的动态时,查询结果为0条数据 >> 0
+
+*/
+
+$my = new myTest();
+$task = array('admin', 0, '', 'id_desc', 0, 'task');
+$bug = array('admin', 0, '', 'id_desc', 0, 'bug');
+$story = array('admin', 0, '', 'id_desc', 0, 'story');
+
+r($my->getAssignedByMeTest($task[0], $task[1], $task[2], $task[3], $task[4], $task[5])) && p() && e('1'); // 当插入一条action为admin指派了task的动态时,查询结果为1条数据
+r($my->getAssignedByMeTest($bug[0], $bug[1], $bug[2], $bug[3], $bug[4], $bug[5])) && p() && e('1'); // 当插入一条action为admin指派了bug的动态时,查询结果为1条数据
+r($my->getAssignedByMeTest($story[0], $story[1], $story[2], $story[3], $story[4], $story[5])) && p() && e('0'); // 当插入一条action为admin指派了需求的动态时,查询结果为0条数据
+
diff --git a/module/my/test/model/getcontribute.php b/module/my/test/model/getcontribute.php
new file mode 100755
index 0000000000..bf142c8c9e
--- /dev/null
+++ b/module/my/test/model/getcontribute.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+getContribute();
+cid=1
+pid=1
+
+myTaskTotal数据获取 >> 0
+myStoryTotal数据获取 >> 0
+myBugTotal数据获取 >> 85
+docCreatedTotal数据获取 >> 900
+ownerProductTotal数据获取 >> 0
+involvedProjectTotal数据获取 >> 1
+
+*/
+
+$my = new myTest();
+
+$myTaskTotal = $my->getContributeTest()->myTaskTotal;
+$myStoryTotal = $my->getContributeTest()->myStoryTotal;
+$myBugTotal = $my->getContributeTest()->myBugTotal;
+$docCreatedTotal = $my->getContributeTest()->docCreatedTotal;
+$ownerProductTotal = $my->getContributeTest()->ownerProductTotal;
+$involvedProjectTotal = $my->getContributeTest()->involvedProjectTotal;
+
+r($myTaskTotal) && p() && e('0'); //myTaskTotal数据获取
+r($myStoryTotal) && p() && e('0'); //myStoryTotal数据获取
+r($myBugTotal) && p() && e('85'); //myBugTotal数据获取
+r($docCreatedTotal) && p() && e('900');//docCreatedTotal数据获取
+r($ownerProductTotal) && p() && e('0'); //ownerProductTotal数据获取
+r($involvedProjectTotal) && p() && e('1'); //involvedProjectTotal数据获取
\ No newline at end of file
diff --git a/module/my/test/model/getdoingprojects.php b/module/my/test/model/getdoingprojects.php
new file mode 100755
index 0000000000..fb16163a3d
--- /dev/null
+++ b/module/my/test/model/getdoingprojects.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getDoingProjects();
+cid=1
+pid=1
+
+获取doingcount数据 >> 5
+获取doing状态的项目 >> 项目86,doing
+获取doing状态的项目统计 >> 5
+
+*/
+
+$my = new myTest();
+
+$doingCount = $my->getDoingProjectsTest()->doingCount;
+$projects = $my->getDoingProjectsTest()->projects;
+
+r($doingCount) && p() && e('5'); //获取doingcount数据
+r($projects) && p('0:name,status') && e('项目86,doing');//获取doing状态的项目
+r(count($projects)) && p() && e('5'); //获取doing状态的项目统计
\ No newline at end of file
diff --git a/module/my/test/model/getoverview.php b/module/my/test/model/getoverview.php
new file mode 100755
index 0000000000..bc4e95795d
--- /dev/null
+++ b/module/my/test/model/getoverview.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getOverview();
+cid=1
+pid=1
+
+projectTotal数据获取 >> 110
+allConsumed数据获取 >> 6750
+thisYearConsumed数据获取 >> 0
+
+*/
+
+$my = new myTest();
+
+$projectTotal = $my->getOverviewTest()->projectTotal;
+$allConsumed = $my->getOverviewTest()->allConsumed;
+$thisYearConsumed = $my->getOverviewTest()->thisYearConsumed;
+
+r($projectTotal) && p() && e('110'); //projectTotal数据获取
+r($allConsumed) && p() && e('6750');//allConsumed数据获取
+r($thisYearConsumed) && p() && e('0'); //thisYearConsumed数据获取
\ No newline at end of file
diff --git a/module/my/test/model/getproducts.php b/module/my/test/model/getproducts.php
new file mode 100755
index 0000000000..df7bf4325a
--- /dev/null
+++ b/module/my/test/model/getproducts.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getProducts();
+cid=1
+pid=1
+
+undone产品allCount查询 >> 80
+undone产品unclosedCount查询 >> 80
+undone产品查询统计 >> 5
+ownbyme产品allCount查询 >> 0
+ownbyme产品unclosedCount查询 >> 0
+ownbyme产品查询 >> 0
+ownbyme产品查询统计 >> 0
+随意输入type产品数量查询 >> 5
+不输入type产品数量查询 >> 5
+
+*/
+
+$typeList = array('undone', 'ownbyme', 'all');
+
+$my = new myTest();
+
+$undoneProducts = $my->getProductsTest($typeList[0]);
+$ownbymeProducts = $my->getProductsTest($typeList[1]);
+$allProducts = $my->getProductsTest($typeList[2]);
+$noType = $my->getProductsTest('');
+
+r($undoneProducts->allCount) && p() && e('80'); //undone产品allCount查询
+r($undoneProducts->unclosedCount) && p() && e('80'); //undone产品unclosedCount查询
+r(count($undoneProducts->products)) && p() && e('5'); //undone产品查询统计
+r($ownbymeProducts->allCount) && p() && e('0'); //ownbyme产品allCount查询
+r($ownbymeProducts->unclosedCount) && p() && e('0'); //ownbyme产品unclosedCount查询
+r($ownbymeProducts->products) && p() && e('0'); //ownbyme产品查询
+r(count($ownbymeProducts->products)) && p() && e('0'); //ownbyme产品查询统计
+r(count($allProducts->products)) && p() && e('5'); //随意输入type产品数量查询
+r(count($noType->products)) && p() && e('5'); //不输入type产品数量查询
\ No newline at end of file
diff --git a/module/my/test/model/getrequirementsbysearch.php b/module/my/test/model/getrequirementsbysearch.php
new file mode 100755
index 0000000000..72eba9f0c9
--- /dev/null
+++ b/module/my/test/model/getrequirementsbysearch.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getRequirementsBySearch();
+cid=1
+pid=1
+
+获取requirement状态的项目 >> 用户需求397,draft
+获取requirement状态的项目 >> 用户需求1,active
+
+*/
+
+$my = new myTest();
+$typeList = array('contribute', 'other');
+$orderBy = array('id_desc', 'id_asc');
+
+$requirement1 = $my->getRequirementsBySearchTest(0, $typeList[0], $orderBy[0]);
+$requirement2 = $my->getRequirementsBySearchTest(0, $typeList[1], $orderBy[1]);
+r($requirement1) && p('397:title,status') && e('用户需求397,draft');//获取requirement状态的项目
+r($requirement2) && p('1:title,status') && e('用户需求1,active'); //获取requirement状态的项目
\ No newline at end of file
diff --git a/module/my/test/model/getstoriesbysearch.php b/module/my/test/model/getstoriesbysearch.php
new file mode 100755
index 0000000000..e2d93b28fb
--- /dev/null
+++ b/module/my/test/model/getstoriesbysearch.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getStoriesBySearch();
+cid=1
+pid=1
+
+获取story状态的项目 >> 软件需求350,draft
+获取story状态的项目 >> 软件需求302,draft
+
+*/
+
+$my = new myTest();
+$typeList = array('contribute', 'other');
+$orderBy = array('id_desc', 'id_asc');
+
+$story1 = $my->getStoriesBySearchTest(0, $typeList[0], $orderBy[0]);
+$story2 = $my->getStoriesBySearchTest(0, $typeList[1], $orderBy[1]);
+
+r($story1) && p('350:title,status') && e('软件需求350,draft');//获取story状态的项目
+r($story2) && p('302:title,status') && e('软件需求302,draft');//获取story状态的项目
\ No newline at end of file
diff --git a/module/my/test/model/gettasksbysearch.php b/module/my/test/model/gettasksbysearch.php
new file mode 100755
index 0000000000..752ea70dce
--- /dev/null
+++ b/module/my/test/model/gettasksbysearch.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getTasksBySearch();
+cid=1
+pid=1
+
+获取task状态的项目 >> 批量任务三,wait
+
+*/
+
+$my = new myTest();
+$account = 'admin';
+$limit = 1;
+
+$task = $my->getTasksBySearchTest($account, $limit);
+
+r($task) && p('913:name,status') && e('批量任务三,wait');//获取task状态的项目
\ No newline at end of file
diff --git a/module/my/test/model/gettestcasesbysearch.php b/module/my/test/model/gettestcasesbysearch.php
new file mode 100755
index 0000000000..059b4d9568
--- /dev/null
+++ b/module/my/test/model/gettestcasesbysearch.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getTestcasesBySearch();
+cid=1
+pid=1
+
+获取testcase状态的项目 >> com.ngtesting.autotest.test.TestLogin账号过期,normal
+获取testcase的统计 >> 20
+获取testcase状态的项目 >> com.ngtesting.autotest.test.TestLogin密码错误,normal
+获取testcase的统计 >> 18
+
+*/
+
+$my = new myTest();
+$type = array('contribute', 'openedbyme');
+$order = 'id_desc';
+
+$cases1 = $my->getTestcasesBySearchTest(0, $type[0], $order);
+$cases2 = $my->getTestcasesBySearchTest(0, $type[1], $order);
+
+r($cases1) && p('560:title,status') && e('com.ngtesting.autotest.test.TestLogin账号过期,normal');//获取testcase状态的项目
+r(count($cases1)) && p() && e('20'); //获取testcase的统计
+r($cases2) && p('439:title,status') && e('com.ngtesting.autotest.test.TestLogin密码错误,normal');//获取testcase状态的项目
+r(count($cases2)) && p() && e('18'); //获取testcase的统计
\ No newline at end of file
diff --git a/module/my/test/my.class.php b/module/my/test/my.class.php
new file mode 100644
index 0000000000..ed7182cd37
--- /dev/null
+++ b/module/my/test/my.class.php
@@ -0,0 +1,213 @@
+objectModel = $tester->loadModel('my');
+ }
+
+ /**
+ * Function getProducts test by my
+ *
+ * @param string $type
+ * @access public
+ * @return object
+ */
+ public function getProductsTest($type)
+ {
+ $objects = $this->objectModel->getProducts($type);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function getDoingProjects test by my
+ *
+ * @access public
+ * @return object
+ */
+ public function getDoingProjectsTest()
+ {
+ $objects = $this->objectModel->getDoingProjects();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function getOverview test by my
+ *
+ * @access public
+ * @return object
+ */
+ public function getOverviewTest()
+ {
+ $objects = $this->objectModel->getOverview();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function getContribute test by my
+ *
+ * @access public
+ * @return object
+ */
+ public function getContributeTest()
+ {
+ $objects = $this->objectModel->getContribute();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function getActions test by my
+ *
+ * @access public
+ * @return array
+ */
+ public function getActionsTest()
+ {
+ $objects = $this->objectModel->getActions();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function getAssignedByMe test by my
+ *
+ * @param string $account
+ * @param int $limit
+ * @param int $pager
+ * @param string $orderBy
+ * @param int $projectID
+ * @param string $objectType
+ * @access public
+ * @return int
+ */
+ public function getAssignedByMeTest($account, $limit, $pager, $orderBy, $projectID, $objectType)
+ {
+ global $tester;
+ $recTotal = 0;
+ $recPerPage = 20;
+ $pageID = 0;
+ $tester->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $objects = $this->objectModel->getAssignedByMe($account, $limit, $pager, $orderBy, $objectType);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Get testcases by search.
+ *
+ * @param int $queryID
+ * @param string $type
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getTestcasesBySearchTest($queryID, $type, $orderBy)
+ {
+ global $tester;
+ $recTotal = 0;
+ $recPerPage = 20;
+ $pageID = 0;
+ $tester->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $objects = $this->objectModel->getTestcasesBySearch($query, $type, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tasks by search.
+ *
+ * @param string $account
+ * @param int $limit
+ * @access public
+ * @return array
+ */
+ public function getTasksBySearchTest($account, $limit = 0)
+ {
+ global $tester;
+ $recTotal = 0;
+ $recPerPage = 20;
+ $pageID = 0;
+ $tester->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $objects = $this->objectModel->getTasksBySearch($account, $limit, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get stories by search.
+ *
+ * @param int $queryID
+ * @param string $type
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getStoriesBySearchTest($queryID, $type, $orderBy)
+ {
+ global $tester;
+ $recTotal = 0;
+ $recPerPage = 1;
+ $pageID = 0;
+ $tester->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $objects = $this->objectModel->getStoriesBySearch($queryID, $type, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get requirements by search.
+ *
+ * @param int $queryID
+ * @param string $type
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getRequirementsBySearchTest($queryID, $type, $orderBy)
+ {
+ global $tester;
+ $recTotal = 0;
+ $recPerPage = 1;
+ $pageID = 0;
+ $tester->app->loadClass('pager', $static = true);
+ $pager = new pager($recTotal, $recPerPage, $pageID);
+
+ $objects = $this->objectModel->getRequirementsBySearch($queryID, $type, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+}
diff --git a/module/personnel/test/model/addwhitelist.php b/module/personnel/test/model/addwhitelist.php
new file mode 100755
index 0000000000..68b220a232
--- /dev/null
+++ b/module/personnel/test/model/addwhitelist.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+addWhitelist();
+cid=1
+pid=1
+
+测试正常添加白名单 >> 0
+测试不传用户名的情况,这里不传用户名会导致删除符合条件的数据 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$user = array();
+$user[0] = array('admin');
+$user[1] = array();
+
+$objectID = array();
+$objectID[0] = 11;
+$objectID[1] = 21;
+
+$objectType = array();
+$objectType[0] = 'project';
+$objectType[1] = 'program';
+$objectType[2] = 'product';
+$objectType[3] = 'sprint';
+
+$result1 = $personnel->addWhitelistTest($objectType[0], $objectID[0], $user[0]);
+$result2 = $personnel->addWhitelistTest($objectType[0], $objectID[0], $user[1]);
+
+r($result1) && p() && e('0'); //测试正常添加白名单
+r($result2) && p() && e('0'); //测试不传用户名的情况,这里不传用户名会导致删除符合条件的数据
\ No newline at end of file
diff --git a/module/personnel/test/model/canviewprogram.php b/module/personnel/test/model/canviewprogram.php
new file mode 100755
index 0000000000..197af2b8c5
--- /dev/null
+++ b/module/personnel/test/model/canviewprogram.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+canViewProgram();
+cid=1
+pid=1
+
+看是否具有访问权限有的情况 >> 1
+看是否具有访问权限no的情况 >> 1
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$propramID = array();
+$programID[0] = 1;
+
+$account = array();
+$account[0] = 'test2';
+
+r($personnel->canViewProgramTest(1, 'test2')) && p() && e('1'); //看是否具有访问权限有的情况
+r($personnel->canViewProgramTest(10000, 'test2')) && p() && e('1'); //看是否具有访问权限no的情况
\ No newline at end of file
diff --git a/module/personnel/test/model/deleteexecutionwhitelist.php b/module/personnel/test/model/deleteexecutionwhitelist.php
new file mode 100755
index 0000000000..c72f9ba991
--- /dev/null
+++ b/module/personnel/test/model/deleteexecutionwhitelist.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+deleteExecutionWhitelist();
+cid=1
+pid=1
+
+调用add方法创建spring类型的白名单,并修改source为sync,然后再通过条件删除 >> 0
+不传参数的情况,删除id为0的匹配数据,为空则跳过 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$executionID = array();
+$executionID[0] = 16;
+$executionID[1] = '';
+
+$account = array();
+$account[0] = 'admin';
+$account[1] = '';
+
+$result1 = $personnel->deleteExecutionWhitelistTest($executionID[0], $account[0]);
+$result2 = $personnel->deleteExecutionWhitelistTest($executionID[1], $account[1]);
+
+r($result1) && p() && e('0'); //调用add方法创建spring类型的白名单,并修改source为sync,然后再通过条件删除
+r($result2) && p() && e('0'); //不传参数的情况,删除id为0的匹配数据,为空则跳过
\ No newline at end of file
diff --git a/module/personnel/test/model/deleteproductwhitelist.php b/module/personnel/test/model/deleteproductwhitelist.php
new file mode 100755
index 0000000000..90b94f8ec9
--- /dev/null
+++ b/module/personnel/test/model/deleteproductwhitelist.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+deleteProductWhitelist();
+cid=1
+pid=1
+
+删除了产品10的白名单,这里有个条件,source必须为sync,同步过来的才能删 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$productID = array();
+$productID[0] = 10;
+$peoductID[1] = 11111;
+
+$account = array();
+$account[0] = 'admin';
+$account[1] = 'test111';
+
+$result1 = $personnel->deleteProductWhitelistTest($productID[0], $account[0]);
+
+r($result1) && p() && e('0'); //删除了产品10的白名单,这里有个条件,source必须为sync,同步过来的才能删
\ No newline at end of file
diff --git a/module/personnel/test/model/deleteprogramwhitelist.php b/module/personnel/test/model/deleteprogramwhitelist.php
new file mode 100755
index 0000000000..24b872b888
--- /dev/null
+++ b/module/personnel/test/model/deleteprogramwhitelist.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+deleteProgramWhitelist();
+cid=1
+pid=1
+
+我这里通过add方法创建了一个id为10的项目集白名单,并修改source为同步,然后删除创建的这条信息 >> 0
+传入空时这里我删除了一个objectID为0的,program白名单信息,如果没这条数据跳过 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$programID = array();
+$programID[0] = 10;
+$programID[1] = '';
+
+$account = array();
+$account[0] = 'dev10';
+$account[1] = '';
+
+$result1 = $personnel->deleteProgramWhitelistTest($programID[0], $account[0]);
+$result2 = $personnel->deleteProgramWhitelistTest($programID[1], $account[1]);
+
+r($result1) && p() && e('0'); //我这里通过add方法创建了一个id为10的项目集白名单,并修改source为同步,然后删除创建的这条信息
+r($result2) && p() && e('0'); //传入空时这里我删除了一个objectID为0的,program白名单信息,如果没这条数据跳过
\ No newline at end of file
diff --git a/module/personnel/test/model/deleteprojectwhitelist.php b/module/personnel/test/model/deleteprojectwhitelist.php
new file mode 100755
index 0000000000..0160d9ec35
--- /dev/null
+++ b/module/personnel/test/model/deleteprojectwhitelist.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+deleteProjectWhitelist();
+cid=1
+pid=1
+
+通过add方法创建一个白名单,这里判断了objectType为sprint的情况,正常传入无法删除 >> 0
+传入空的情况时,删除为objectID为0的数据,如果空,则跳过 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$projectID = array();
+$projectID[0] = 15;
+$projectID[1] = '';
+
+$account = array();
+$account[0] = 'dev15';
+$account[1] = '';
+
+$result1 = $personnel->deleteProjectWhitelistTest($projectID[0], $account[0]);
+$result2 = $personnel->deleteProjectWhitelistTest($projectID[1], $account[1]);
+
+r($result1) && p() && e('0'); //通过add方法创建一个白名单,这里判断了objectType为sprint的情况,正常传入无法删除
+r($result2) && p() && e('0'); //传入空的情况时,删除为objectID为0的数据,如果空,则跳过
\ No newline at end of file
diff --git a/module/personnel/test/model/deletewhitelist.php b/module/personnel/test/model/deletewhitelist.php
new file mode 100755
index 0000000000..1e05c48adf
--- /dev/null
+++ b/module/personnel/test/model/deletewhitelist.php
@@ -0,0 +1,47 @@
+#!/usr/bin/env php
+deleteWhitelist();
+cid=1
+pid=1
+
+创建删除objectID为2的项目白名单 >> 0
+创建删除objectID为2的产品白名单 >> 0
+创建删除objectID为10的项目集白名单 >> 0
+创建删除objectID为11的执行白名单 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$users = array();
+$users[0] = 'dev17';
+
+$objectType = array();
+$objectType[0] = 'project';
+$objectType[1] = 'product';
+$objectType[2] = 'program';
+$objectType[3] = 'sprint';
+
+$objectID = array();
+$objectID[0] = '2';
+$objectID[1] = '10';
+$objectID[2] = '11';
+
+$groupID = array();
+$groupID[0] = '1';
+$groupID[1] = '2';
+
+$result1 = $personnel->deleteWhitelistTest($users, $objectType[0], $objectID[0]);
+$result2 = $personnel->deleteWhitelistTest($users, $objectType[1], $objectID[0]);
+$result3 = $personnel->deleteWhitelistTest($users, $objectType[2], $objectID[1]);
+$result4 = $personnel->deleteWhitelistTest($users, $objectType[3], $objectID[2]);
+
+r($result1) && p() && e('0'); //创建删除objectID为2的项目白名单
+r($result2) && p() && e('0'); //创建删除objectID为2的产品白名单
+r($result3) && p() && e('0'); //创建删除objectID为10的项目集白名单
+r($result4) && p() && e('0'); //创建删除objectID为11的执行白名单
\ No newline at end of file
diff --git a/module/personnel/test/model/getaccessiblepersonnel.php b/module/personnel/test/model/getaccessiblepersonnel.php
new file mode 100755
index 0000000000..1289e08869
--- /dev/null
+++ b/module/personnel/test/model/getaccessiblepersonnel.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+getAccessiblePersonnel();
+cid=1
+pid=1
+
+测试取出结果集中的一个对象里的名字programID=1 >> 测试1
+测试取出匹配的数量 >> 10
+测试取出结果集中的一个对象里的名字programID=2 >> 开发11
+测试取出匹配的数量 >> 10
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$programID = array();
+$programID[0] = 1;
+$programID[1] = 2;
+
+$deptID = array();
+$deptID[0] = 11;
+$deptID[1] = 12;
+
+$browseType = array();
+$browseType[0] = 'all';
+$browseType[1] = 'bysearch';
+
+$queryID = array();
+$browseType[0] = 1;
+
+$getrealname1 = $personnel->getAccessiblePersonnelTest($programID[0], $deptID[0], $browseType[0], $browseType[0])[101];
+$getnumber1 = count($personnel->getAccessiblePersonnelTest($programID[0], $deptID[0], $browseType[0], $browseType[0]));
+
+$getrealname2 = $personnel->getAccessiblePersonnelTest($programID[1], $deptID[1], $browseType[0], $browseType[0])[111];
+$getnumber2 = count($personnel->getAccessiblePersonnelTest($programID[1], $deptID[1], $browseType[0], $browseType[0]));
+
+r($getrealname1) && p('realname') && e('测试1'); //测试取出结果集中的一个对象里的名字programID=1
+r($getnumber1) && p() && e('10'); //测试取出匹配的数量
+r($getrealname2) && p('realname') && e('开发11'); //测试取出结果集中的一个对象里的名字programID=2
+r($getnumber2) && p() && e('10'); //测试取出匹配的数量
\ No newline at end of file
diff --git a/module/personnel/test/model/getbugandstoryinvest.php b/module/personnel/test/model/getbugandstoryinvest.php
new file mode 100755
index 0000000000..bce45e6026
--- /dev/null
+++ b/module/personnel/test/model/getbugandstoryinvest.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getBugAndStoryInvest();
+cid=1
+pid=1
+
+admin在项目集1下创建的bug数量 >> 28
+admin在项目集1下解决的bug数量 >> 0
+admin在项目集1下待处理的bug数量 >> 6
+admin在项目集1下创建的用户需求数量 >> 9
+admin在项目集1下创建的软件需求数量 >> 0
+
+*/
+
+global $tester;
+$personnel = $tester->loadModel('personnel');
+$accountList = array('admin' => 'admin');
+
+r($personnel->getBugAndStoryInvest($accountList, 1)) && p('admin:createdBug') && e('28'); //admin在项目集1下创建的bug数量
+r($personnel->getBugAndStoryInvest($accountList, 1)) && p('admin:resolvedBug') && e('0'); //admin在项目集1下解决的bug数量
+r($personnel->getBugAndStoryInvest($accountList, 1)) && p('admin:pendingBug') && e('6'); //admin在项目集1下待处理的bug数量
+r($personnel->getBugAndStoryInvest($accountList, 1)) && p('admin:UR') && e('9'); //admin在项目集1下创建的用户需求数量
+r($personnel->getBugAndStoryInvest($accountList, 1)) && p('admin:SR') && e('0'); //admin在项目集1下创建的软件需求数量
+
diff --git a/module/personnel/test/model/getcopiedobjects.php b/module/personnel/test/model/getcopiedobjects.php
new file mode 100755
index 0000000000..c8afb9f83f
--- /dev/null
+++ b/module/personnel/test/model/getcopiedobjects.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getCopiedObjects();
+cid=1
+pid=1
+
+查找与项目1同项目集的其他项目数量 >> 8
+查找与项目1同项目集的其他项目并标明项目人数 >> 项目11(2人)
+查找与迭代1同项目的其他迭代及所属项目 >> 7
+查找与迭代1同项目的其他迭代及所属项目并标明项目人数 >> 项目1(2人), 迭代91(1人)
+查找与正常产品2同项目集的其他产品数量 >> 10
+查找出项目集1外的其他所有项目集 >> 9
+
+*/
+
+global $tester;
+$personnel = $tester->loadModel('personnel');
+
+$copyProject1 = $personnel->getCopiedObjects(11, 'project');
+$copyProject2 = $personnel->getCopiedObjects(11, 'project', true);
+$copySprint1 = $personnel->getCopiedObjects(101, 'sprint');
+$copySprint2 = $personnel->getCopiedObjects(101, 'sprint', true);
+$copyProduct = $personnel->getCopiedObjects(2, 'product');
+$copyProgram = $personnel->getCopiedObjects(1, 'program');
+
+r(count($copyProject1)) && p() && e('8'); //查找与项目1同项目集的其他项目数量
+r($copyProject2) && p('21') && e('项目11(2人)'); //查找与项目1同项目集的其他项目并标明项目人数
+r(count($copySprint1)) && p() && e('7'); //查找与迭代1同项目的其他迭代及所属项目
+r($copySprint2) && p('11,191') && e('项目1(2人), 迭代91(1人)'); //查找与迭代1同项目的其他迭代及所属项目并标明项目人数
+r(count($copyProduct)) && p() && e('10'); //查找与正常产品2同项目集的其他产品数量
+r(count($copyProgram)) && p() && e('9'); //查找出项目集1外的其他所有项目集
diff --git a/module/personnel/test/model/getinvest.php b/module/personnel/test/model/getinvest.php
new file mode 100755
index 0000000000..b28fbb8e57
--- /dev/null
+++ b/module/personnel/test/model/getinvest.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getInvest();
+cid=1
+pid=1
+
+项目集1下投入人员admin创建的bug数量 >> 测试,28
+项目集1下投入人员admin待处理的bug数量 >> 测试,6
+项目集1下投入人员po53创建的任务数量 >> 研发,0
+项目集1下投入人员po53完成的任务数量 >> 研发,0
+
+*/
+
+$personnel = new personnelTest('admin');
+$programID = array(1,2);
+
+r($personnel->getInvestTest($programID[0])) && p('qa[admin]:role,createdBug') && e('测试,28'); //项目集1下投入人员admin创建的bug数量
+r($personnel->getInvestTest($programID[0])) && p('qa[admin]:role,pendingBug') && e('测试,6'); //项目集1下投入人员admin待处理的bug数量
+r($personnel->getInvestTest($programID[1])) && p('dev[po53]:role,createdTask') && e('研发,0'); //项目集1下投入人员po53创建的任务数量
+r($personnel->getInvestTest($programID[1])) && p('dev[po53]:role,finishedTask') && e('研发,0'); //项目集1下投入人员po53完成的任务数量
diff --git a/module/personnel/test/model/getinvolvedexecutions.php b/module/personnel/test/model/getinvolvedexecutions.php
new file mode 100755
index 0000000000..027e3b581b
--- /dev/null
+++ b/module/personnel/test/model/getinvolvedexecutions.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getInvolvedExecutions();
+cid=1
+pid=1
+
+涉及到执行的人员计数 >> 8
+取出其中一个 >> 1
+传入不存在的id >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$project = array();
+$project[0] = array(11, 12);
+$project[1] = 12222;
+
+$result1 = count($personnel->getInvolvedExecutionsTest($project[0]));
+$result2 = $personnel->getInvolvedExecutionsTest($project[0]);
+$result3 = $personnel->getInvolvedExecutionsTest($project[1]);
+
+r($result1) && p() && e('8'); //涉及到执行的人员计数
+r($result2) && p('pm72') && e('1'); //取出其中一个
+r($result3) && p() && e('0'); //传入不存在的id
\ No newline at end of file
diff --git a/module/personnel/test/model/getinvolvedprojects.php b/module/personnel/test/model/getinvolvedprojects.php
new file mode 100755
index 0000000000..d484c4d6df
--- /dev/null
+++ b/module/personnel/test/model/getinvolvedprojects.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getInvolvedProjects();
+cid=1
+pid=1
+
+计数project11,12的团队人员个数 >> 4
+取出其中一个角色 >> 1
+传入不存在的ID >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$projectID = array();
+$projectID[0] = array(11, 12);
+$projectID[1] = array(1111);
+
+$result1 = count($personnel->getInvolvedProjectsTest($projectID[0]));
+$result2 = $personnel->getInvolvedProjectsTest($projectID[0]);
+$result3 = count($personnel->getInvolvedProjectsTest($projectID[1]));
+
+r($result1) && p() && e('4'); //计数project11,12的团队人员个数
+r($result2) && p('admin') && e('1'); //取出其中一个角色
+r($result3) && p() && e('0'); //传入不存在的ID
\ No newline at end of file
diff --git a/module/personnel/test/model/getprojecttaskinvest.php b/module/personnel/test/model/getprojecttaskinvest.php
new file mode 100755
index 0000000000..18ab87f946
--- /dev/null
+++ b/module/personnel/test/model/getprojecttaskinvest.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getProjectTaskInvest();
+cid=1
+pid=1
+
+次方法为页面上的项目信息,人员,创建人物 >> 0
+次方法为页面上的项目信息,人员,已完成任务 >> 0
+次方法为页面上的项目信息,人员,待处理 >> 0
+次方法为页面上的项目信息,人员,任务消耗 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$projectID = array();
+$projectID[0] = 11;
+$projectID[1] = 12;
+
+$account = array();
+$account[0] = 'admin';
+$account[1] = 'user3';
+
+$result1 = $personnel->getProjectTaskInvestTest($projectID, $account);
+
+r($result1) && p('0:createdTask') && e('0'); //次方法为页面上的项目信息,人员,创建人物
+r($result1) && p('0:finishedTask') && e('0'); //次方法为页面上的项目信息,人员,已完成任务
+r($result1) && p('0:pendingTask') && e('0'); //次方法为页面上的项目信息,人员,待处理
+r($result1) && p('0:consumedTask') && e('0'); //次方法为页面上的项目信息,人员,任务消耗
\ No newline at end of file
diff --git a/module/personnel/test/model/getuserhours.php b/module/personnel/test/model/getuserhours.php
new file mode 100755
index 0000000000..c582b714f3
--- /dev/null
+++ b/module/personnel/test/model/getuserhours.php
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+id->range('1-10');
+$project->project->range('0,0,2{8}');
+$project->type->range('program,project,sprint{8}');
+$project->status->range('doing{3},wait{7}');
+$project->vision->range('rnd');
+$project->name->range('1-10')->prefix('Object');
+$project->multiple->range('1');
+$project->deleted->range('`0`');
+$project->gen(10);
+
+$task = zdTable('task');
+$task->id->range('1');
+$task->name->range('task1');
+$task->project->range('2');
+$task->type->range('dev');
+$task->left->range('1');
+$task->openedBy->range('admin');
+$task->consumed->range('5');
+$task->deleted->range('`0`');
+$task->gen(1);
+
+$effort = zdTable('effort');
+$effort->id->range('1-2');
+$effort->objectType->range('task');
+$effort->objectID->range('1');
+$effort->account->range('admin');
+$effort->left->range('7,1');
+$effort->consumed->range('2,3');
+$effort->deleted->range('`0`');
+$effort->gen(2);
+
+/**
+
+title=测试 personnelModel->getUserHours();
+cid=1
+pid=1
+
+正常传入的情况 >> 1
+传入不存在的情况 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$result1 = $personnel->getUserHoursTest('2', array('admin'));
+$result2 = $personnel->getUserHoursTest('100', array('admin'));
+
+r($result1['admin']->left) && p() && e('1'); //正常传入的情况
+r($result2) && p() && e('0'); //传入不存在的情况
diff --git a/module/personnel/test/model/getwhitelist.php b/module/personnel/test/model/getwhitelist.php
new file mode 100755
index 0000000000..b431d946fc
--- /dev/null
+++ b/module/personnel/test/model/getwhitelist.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getWhitelist();
+cid=1
+pid=1
+
+获取项目1白名单人员数量 >> 3
+当传入空时,查看匹配项目的人员数量 >> 0
+获取项目集9白名单人员数量 >> 1
+
+*/
+
+global $tester;
+$personnel = $tester->loadModel('personnel');
+
+r(count($personnel->getWhitelist(1, 'project'))) && p() && e('3'); //获取项目1白名单人员数量
+r(count($personnel->getWhitelist('', 'project'))) && p() && e('0'); //当传入空时,查看匹配项目的人员数量
+r(count($personnel->getWhitelist(9, 'program'))) && p() && e('1'); //获取项目集9白名单人员数量
diff --git a/module/personnel/test/model/getwhitelistaccount.php b/module/personnel/test/model/getwhitelistaccount.php
new file mode 100755
index 0000000000..764c69ffde
--- /dev/null
+++ b/module/personnel/test/model/getwhitelistaccount.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+getWhitelistAccount();
+cid=1
+pid=1
+
+这是一个正常测试,统计关联白名单人员数量 >> 3
+取出其中一个数据admin >> admin
+取出另一个数据dev10 >> dev10
+取出objectid2的白名单数量 >> 0
+当objectID不存在时,统计匹配数量 >> 0
+当传入参数为空时,统计匹配人员数量 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$objectID = array();
+$objectID[0] = 1;
+$objectID[1] = 2;
+$objectID[2] = 1111;
+$objectID[3] = '';
+
+$objectType = array();
+$objectType[0] = 'project';
+$objectType[1] = 'program';
+$objectType[2] = 'product';
+$objectType[3] = 'sprint';
+
+$result1 = $personnel->getWhitelistAccountTest($objectID[0], $objectType[1]);
+$result2 = $personnel->getWhitelistAccountTest($objectID[1], $objectType[2]);
+$result3 = $personnel->getWhitelistAccountTest($objectID[2], $objectType[3]);
+$result4 = $personnel->getWhitelistAccountTest($objectID[3], $objectType[0]);
+
+r(count($result1)) && p() && e('3'); //这是一个正常测试,统计关联白名单人员数量
+r($result1) && p('admin') && e('admin'); //取出其中一个数据admin
+r($result1) && p('dev10') && e('dev10'); //取出另一个数据dev10
+r(count($result2)) && p() && e('0'); //取出objectid2的白名单数量
+r(count($result3)) && p() && e('0'); //当objectID不存在时,统计匹配数量
+r(count($result4)) && p() && e('0'); //当传入参数为空时,统计匹配人员数量
diff --git a/module/personnel/test/model/updatewhitelist.php b/module/personnel/test/model/updatewhitelist.php
new file mode 100755
index 0000000000..18e37531d8
--- /dev/null
+++ b/module/personnel/test/model/updatewhitelist.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+updateWhitelist();
+cid=1
+pid=1
+
+传入已有参数时,数据变更类型source为add >> 0
+传入已有参数时,数据变更type为blacklist >> 0
+传入没有的参数时,新建一条source为sync的数据 >> 0
+
+*/
+
+$personnel = new personnelTest('admin');
+
+$user = array();
+$user[0] = array('admin', 'dev10');
+$user[1] = array('test1', 'test2');
+
+$objectType = array();
+$objectType[0] = 'project';
+$objectType[1] = 'program';
+$objectType[2] = 'product';
+$objectType[3] = 'sprint';
+
+$objectID = array();
+$objectID[0] = 1;
+$objectID[1] = 2;
+
+$type = array();
+$type[0] = 'whitelist';
+$type[1] = 'blacklist';
+
+$source = array();
+$source[0] = 'update';
+$source[1] = 'add';
+$source[2] = 'sync';
+
+$updateType = array();
+$updateType[0] = 'increase';
+$updateType[1] = 'replace';
+
+$result1 = $personnel->updateWhitelistTest($user[0], $objectType[0], $objectID[1], $type[0], $source[1], $updateType[0]);
+$result2 = $personnel->updateWhitelistTest($user[0], $objectType[1], $objectID[0], $type[1], $source[0], $updateType[1]);
+$result3 = $personnel->updateWhitelistTest($user[1], $objectType[0], $objectID[0], $type[0], $source[2], $updateType[0]);
+
+r($result1) && p() && e('0'); //传入已有参数时,数据变更类型source为add
+r($result2) && p() && e('0'); //传入已有参数时,数据变更type为blacklist
+r($result3) && p() && e('0'); //传入没有的参数时,新建一条source为sync的数据
\ No newline at end of file
diff --git a/module/personnel/test/personnel.class.php b/module/personnel/test/personnel.class.php
new file mode 100644
index 0000000000..3998ec5307
--- /dev/null
+++ b/module/personnel/test/personnel.class.php
@@ -0,0 +1,337 @@
+objectModel = $tester->loadModel('personnel');
+ $tester->app->loadClass('dao');
+ }
+ /**
+ * Get accessible personnel test
+ *
+ * @param int $programID
+ * @param int $deptID
+ * @param string $browseType
+ * @param int $queryID
+ * @access public
+ * @return array
+ */
+ public function getAccessiblePersonnelTest($programID = 0, $deptID = 0, $browseType = 'all', $queryID = 0)
+ {
+ $objects = $this->objectModel->getAccessiblePersonnel($programID, $deptID, $browseType, $queryID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Check if you have permission to view the program
+ *
+ * @param int mixed $programID
+ * @param string mixed $account
+ * @access public
+ * @return bool
+ */
+ public function canViewProgramTest($programID, $account)
+ {
+ $objects = $this->objectModel->canViewProgram($programID, $account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get invest test
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getInvestTest($programID = 0)
+ {
+ $objects = $this->objectModel->getInvest($programID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getInvolvedProjectsTest($projects)
+ {
+ global $tester;
+ $projectID = $tester->dao->select('id')->from(TABLE_PROJECT)->where('id')->in($projects)->fetchall('id');
+ $objects = $this->objectModel->getInvolvedProjects($projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get involved executions test
+ *
+ * @param array mixed $projectID
+ * @access public
+ * @return array
+ */
+ public function getInvolvedExecutionsTest($projectID)
+ {
+ global $tester;
+ $project = $tester->dao->select('id')->from(TABLE_PROJECT)->where('id')->in($projectID)->fetchall('id');
+ $objects = $this->objectModel->getInvolvedExecutions($project);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get project task invest test
+ *
+ * @param array mixed $projects
+ * @param array mixed $accounts
+ * @access public
+ * @return void
+ */
+ public function getProjectTaskInvestTest($projectID, $accounts)
+ {
+ global $tester;
+ $project = $tester->dao->select('id')->from(TABLE_PROJECT)->where('id')->in($projectID)->fetchall('id');
+ $objects = $this->objectModel->getProjectTaskInvest($project, $accounts);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * GetUserHoursTest
+ *
+ * @param mixed $projectID
+ * @param array $accounts
+ * @access public
+ * @return void
+ */
+ public function getUserHoursTest($projectID, $accounts)
+ {
+ global $tester;
+ $projects = $tester->dao->select('id')->from(TABLE_PROJECT)->where('id')->in($projectID)->fetchall('id');
+ $tasks = $tester->dao->select('id,status,openedBy,finishedBy,assignedTo,project')->from(TABLE_TASK)
+ ->where('project')->in(array_keys($projects))
+ ->andWhere('deleted')->eq('0')
+ ->fetchAll('id');
+
+ /* Initialize personnel related tasks. */
+ $invest = array();
+ foreach($accounts as $account)
+ {
+ $invest[$account]['createdTask'] = 0;
+ $invest[$account]['finishedTask'] = 0;
+ $invest[$account]['pendingTask'] = 0;
+ $invest[$account]['consumedTask'] = 0;
+ $invest[$account]['leftTask'] = 0;
+ }
+
+ $userTasks = array();
+
+ foreach($tasks as $task)
+ {
+ if($task->openedBy && isset($invest[$task->openedBy]))
+ {
+ $invest[$task->openedBy]['createdTask'] += 1;
+ $userTasks[$task->openedBy][$task->id] = $task->id;
+ }
+
+ if($task->finishedBy && isset($invest[$task->finishedBy]))
+ {
+ $invest[$task->finishedBy]['finishedTask'] += 1;
+ $userTasks[$task->finishedBy][$task->id] = $task->id;
+ }
+
+ if($task->assignedTo && $task->status == 'wait' && isset($invest[$task->assignedTo]))
+ {
+ $invest[$task->assignedTo]['pendingTask'] += 1;
+ $userTasks[$task->assignedTo][$task->id] = $task->id;
+ }
+ }
+
+ $objects = $this->objectModel->getUserHours($userTasks);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get whitelist test
+ *
+ * @param int $objectID
+ * @param string $objectType
+ * @param string $orderBy
+ * @param string $pager
+ * @access public
+ * @return array
+ */
+ public function getWhitelistTest($objectID = 0, $objectType = '', $orderBy = 'id_desc', $pager = '')
+ {
+ $objects = $this->objectModel->getWhitelist($objectID, $objectType, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get whitelist account test
+ *
+ * @param int $objectID
+ * @param string $objectType
+ * @access public
+ * @return array
+ */
+ public function getWhitelistAccountTest($objectID = 0, $objectType = '')
+ {
+ $objects = $this->objectModel->getWhitelistAccount($objectID, $objectType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function updateWhitelistTest($users = array(), $objectType = '', $objectID = 0, $type = 'whitelist', $source = 'add', $updateType = 'replace')
+ {
+ $objects = $this->objectModel->updateWhitelist($users, $objectType, $objectID, $type, $source, $updateType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Add whitelist test
+ *
+ * @param string $objectType
+ * @param int $objectID
+ * @param array mixed $user
+ * @access public
+ * @return void
+ */
+ public function addWhitelistTest($objectType = '', $objectID = 0, $user = '')
+ {
+ $users = array('accounts' => $user);
+ foreach($users as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->addWhitelist($objectType, $objectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete product whitelist Test
+ *
+ * @param int mixed $productID
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function deleteProductWhitelistTest($productID, $account = '')
+ {
+ global $tester;
+ $this->addWhitelistTest('product', $productID, array('admin'));
+ $tester->dao->update(TABLE_ACL)->set('source')->eq('sync')->where('objectID')->eq($productID)->andWhere('objectType')->eq('product')->exec();
+
+ $objects = $this->objectModel->deleteProductWhitelist($productID, $account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete program whitelist Test
+ *
+ * @param int $programID
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function deleteProgramWhitelistTest($programID, $account)
+ {
+ global $tester;
+ $this->addWhitelistTest('program', $programID, array($account));
+ $tester->dao->update(TABLE_ACL)->set('source')->eq('sync')->where('objectID')->eq($programID)->andWhere('objectType')->eq('program')->exec();
+ $objects = $this->objectModel->deleteProgramWhitelist($programID, $account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete project whitelist Test
+ *
+ * @param int mixed $objectID
+ * @param string mixed $account
+ * @access public
+ * @return void
+ */
+ public function deleteProjectWhitelistTest($objectID, $account)
+ {
+ global $tester;
+ $this->addWhitelistTest('project', $objectID, array($account));
+ $tester->dao->update(TABLE_ACL)->set('source')->eq('sync')->where('objectID')->eq($objectID)->andWhere('objectType')->eq('project')->exec();
+ $objects = $this->objectModel->deleteProjectWhitelist($objectID, $account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete execution whitelist Test
+ *
+ * @param int mixed $executionID
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function deleteExecutionWhitelistTest($executionID, $account = '')
+ {
+ global $tester;
+ $this->addWhitelistTest('sprint', $executionID, array($account));
+ $tester->dao->update(TABLE_ACL)->set('source')->eq('sync')->where('objectID')->eq($executionID)->andWhere('objectType')->eq('sprint')->exec();
+ $objects = $this->objectModel->deleteExecutionWhitelist($executionID, $account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Delete whitelist Test
+ *
+ * @param array $users
+ * @param string $objectType
+ * @param int $objectID
+ * @param int $groupID
+ * @access public
+ * @return void
+ */
+ public function deleteWhitelistTest($users = array(), $objectType = 'program', $objectID = 0, $groupID = 0)
+ {
+ global $tester;
+ $this->addWhitelistTest($objectType, $objectID, $users);
+ $tester->dao->update(TABLE_ACL)->set('source')->eq('sync')->where('objectID')->eq($objectID)->andWhere('objectType')->eq($objectType)->exec();
+ $objects = $this->objectModel->deleteWhitelist($users, $objectType, $objectID, $groupID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/pipeline/test/model/create.php b/module/pipeline/test/model/create.php
new file mode 100755
index 0000000000..d58f42b1d7
--- /dev/null
+++ b/module/pipeline/test/model/create.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+获取添加的type >> Jenkins
+获取添加的account >> JenkinsAccount
+添加错误的url信息 >> 『服务地址』应当为合法的URL。
+添加名称为空时 >> 『名称』不能为空
+
+*/
+
+$pipeline = new pipelineTest();
+
+$data = new stdClass();
+$data->name = 'Jenkins';
+$data->url = 'http://www.zentaopms.com/';
+$data->account = 'JenkinsAccount';
+$data->token = 'Jenkins';
+$data->password = 'Jenkins';
+
+$result1 = $pipeline->createTest('Jenkins', $data); //获取添加的name
+$result2 = $pipeline->createTest('Jenkins', $data); //获取添加的account
+
+$data->url = 'error url';
+$result3 = $pipeline->createTest('Jenkins', $data); //添加错误的url信息
+
+$data->url = 'http://www.zentaopms.com/';
+$data->name = '';
+$result4 = $pipeline->createTest('Jenkins', $data); //添加名称为空时
+
+r($result1) && p('type') && e('Jenkins'); //获取添加的type
+r($result2) && p('account') && e('JenkinsAccount'); //获取添加的account
+r($result3) && p('url:0') && e('『服务地址』应当为合法的URL。'); //添加错误的url信息
+r($result4) && p('name:0') && e('『名称』不能为空'); //添加名称为空时
+
diff --git a/module/pipeline/test/model/delete.php b/module/pipeline/test/model/delete.php
new file mode 100755
index 0000000000..2abea74b74
--- /dev/null
+++ b/module/pipeline/test/model/delete.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+delete();
+cid=1
+pid=1
+
+测试删除之后deleted值是否为1 >> 1
+
+*/
+
+$pipeline = new pipelineTest();
+
+r($pipeline->deleteTest(1)) && p('deleted') && e('1'); //测试删除之后deleted值是否为1
+
diff --git a/module/pipeline/test/model/getbyid.php b/module/pipeline/test/model/getbyid.php
new file mode 100755
index 0000000000..83ea3ced10
--- /dev/null
+++ b/module/pipeline/test/model/getbyid.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+获取id为1的name字段值 >> gitlab服务器
+
+*/
+
+$IDList = array('1','0');
+
+$pipeline = new pipelineTest();
+
+r($pipeline->getByIDTest($IDList[0])) && p('name') && e('gitlab服务器'); //获取id为1的name字段值
+r($pipeline->getByIDTest($IDList[1])) && p() && e(); //获取id为不存在的数据
\ No newline at end of file
diff --git a/module/pipeline/test/model/getlist.php b/module/pipeline/test/model/getlist.php
new file mode 100755
index 0000000000..e7d8148545
--- /dev/null
+++ b/module/pipeline/test/model/getlist.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+获取第一页第一条数据的name >> gitlab服务器
+统计所有type为gitlab的数量 >> 1
+统计所有type为sonarqube的数据量 >> 1
+
+*/
+
+global $tester;
+$pipeline = new pipelineTest();
+$tester->app->loadClass('pager', $static = true);
+
+$pager = new pager(0, 10, 1);
+
+$gitlabList = $pipeline->getListTest('gitlab', 'id_desc', $pager);
+$sonarqubeList = $pipeline->getListTest('sonarqube ', 'id_desc', $pager);
+
+r($gitlabList) && p('1:name') && e('gitlab服务器'); //获取第一页第一条数据的name
+r(count($gitlabList)) && p() && e('1'); //统计所有type为gitlab的数量
+r(count($sonarqubeList)) && p() && e('1'); //统计所有type为sonarqube的数据量
\ No newline at end of file
diff --git a/module/pipeline/test/model/getpairs.php b/module/pipeline/test/model/getpairs.php
new file mode 100755
index 0000000000..d8145d3ae4
--- /dev/null
+++ b/module/pipeline/test/model/getpairs.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+id为1且type为gitlab的pipeline名称 >> gitlab服务器
+id为2且type为sonarqube的pipeline名称 >> sonarqube服务器
+获取不存在的type >> 没有获取到数据
+
+*/
+
+$pipeline = new pipelineTest();
+
+$data[0] = array('type' => 'gitlab', 'id' => 1);
+$data[1] = array('type' => 'sonarqube', 'id' => 2);
+$data[2] = array('type' => 'testType');
+
+r($pipeline->getPairs($data[0])) && p() && e('gitlab服务器'); //id为1且type为gitlab的pipeline名称
+r($pipeline->getPairs($data[1])) && p() && e('sonarqube服务器'); //id为2且type为sonarqube的pipeline名称
+r($pipeline->getPairs($data[2])) && p() && e('没有获取到数据'); //获取不存在的type
\ No newline at end of file
diff --git a/module/pipeline/test/model/update.php b/module/pipeline/test/model/update.php
new file mode 100755
index 0000000000..98368e167d
--- /dev/null
+++ b/module/pipeline/test/model/update.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+获取修改后的name值 >> 测试修改gitlab服务器名称
+当名称为空时 >> 『名称』不能为空。
+url为空时 >> 『服务地址』不能为空。
+
+*/
+
+$pipeline = new pipelineTest();
+
+$_POST['name'] = '测试修改gitlab服务器名称';
+$_POST['url'] = 'http://www.zentaopms.com/upgrade.php';
+$result1 = $pipeline->updateTest(1);
+
+$_POST['name'] = '';
+$result2 = $pipeline->updateTest(1);
+
+$_POST['name'] = '测试修改gitlab服务器名称';
+$_POST['url'] = '';
+$result3 = $pipeline->updateTest(1);
+
+unset($_POST);
+
+r($result1) && p('name') && e('测试修改gitlab服务器名称'); //获取修改后的name值
+r($result2) && p('name:0') && e('『名称』不能为空。'); //当名称为空时
+r($result3) && p('url:0') && e('『服务地址』不能为空。'); //url为空时
+
diff --git a/module/pipeline/test/pipeline.class.php b/module/pipeline/test/pipeline.class.php
new file mode 100644
index 0000000000..2fd000a20b
--- /dev/null
+++ b/module/pipeline/test/pipeline.class.php
@@ -0,0 +1,126 @@
+objectModel = $tester->loadModel('pipeline');
+ }
+
+ /**
+ * Get a pipeline by id.
+ *
+ * @param int $id
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($id)
+ {
+ $objects = $this->objectModel->getByID($id);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get pipeline list.
+ *
+ * @param string $type jenkins|gitlab
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getListTest($type = 'jenkins', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getList($type, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get pipeline pairs
+ *
+ * @param int $data
+ * @access public
+ * @return array
+ */
+ public function getPairs($data)
+ {
+ $objects = $this->objectModel->getPairs($data['type']);
+
+ if(empty($objects)) return '没有获取到数据';
+ if(isset($data['id'])) return $objects[$data['id']];
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Create a pipeline.
+ *
+ * @param int $type
+ * @param int $param
+ * @access public
+ * @return void
+ */
+ public function createTest($type, $param)
+ {
+ foreach($param as $k => $v) $_POST[$k] = $v;
+ $objects = $this->objectModel->create($type);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getById($objects);
+
+ return $objects;
+ }
+
+ /**
+ * Update a pipeline.
+ *
+ * @param int $id
+ * @access public
+ * @return bool
+ */
+ public function updateTest($id)
+ {
+ $objects = $this->objectModel->update($id);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($id);
+
+ return $objects;
+ }
+
+ /**
+ * Delete one record.
+ *
+ * @param string $id the id to be deleted
+ * @param string $object the action object
+ * @access public
+ * @return int
+ */
+ public function deleteTest($id, $object = 'gitlab')
+ {
+ $objects = $this->objectModel->delete($id, $object = 'gitlab');
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getById($id);
+
+ return $objects;
+ }
+}
diff --git a/module/product/test/model/batchgetstorystage.php b/module/product/test/model/batchgetstorystage.php
new file mode 100755
index 0000000000..f7ef81455f
--- /dev/null
+++ b/module/product/test/model/batchgetstorystage.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+batchGetStoryStage();
+cid=1
+pid=1
+
+测试获取需求1 2 3的阶段 >> wait;planned;projected
+测试获取需求4 5 6的阶段 >> developing;developed;testing
+测试获取需求7 8 9的阶段 >> tested;verified;released
+
+*/
+
+$story1 = new stdclass();
+$story1->id = 1;
+
+$story2 = new stdclass();
+$story2->id = 2;
+
+$story3 = new stdclass();
+$story3->id = 3;
+
+$story4 = new stdclass();
+$story4->id = 4;
+
+$story5 = new stdclass();
+$story5->id = 5;
+
+$story6 = new stdclass();
+$story6->id = 6;
+
+$story7 = new stdclass();
+$story7->id = 7;
+
+$story8 = new stdclass();
+$story8->id = 8;
+
+$story9 = new stdclass();
+$story9->id = 9;
+
+$stories1 = array($story1, $story2, $story3);
+$stories2 = array($story4, $story5, $story6);
+$stories3 = array($story7, $story8, $story9);
+
+$product = new productTest('admin');
+
+r($product->batchGetStoryStageTest($stories1)) && p('1;2;3') && e('wait;planned;projected'); // 测试获取需求1 2 3的阶段
+r($product->batchGetStoryStageTest($stories2)) && p('4;5;6') && e('developing;developed;testing'); // 测试获取需求4 5 6的阶段
+r($product->batchGetStoryStageTest($stories3)) && p('7;8;9') && e('tested;verified;released'); // 测试获取需求7 8 9的阶段
\ No newline at end of file
diff --git a/module/product/test/model/batchupdate.php b/module/product/test/model/batchupdate.php
new file mode 100755
index 0000000000..f2e98c1c55
--- /dev/null
+++ b/module/product/test/model/batchupdate.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+批量修改product名称 >> name,正常产品1,批量修改产品1
+批量修改produc测试负责人 >> QD,test2,test1
+批量修改product状态 >> status,normal,closed
+
+*/
+
+$names = array('1' => '批量修改产品1', '2' => '正常产品2', '3' => '正常产品3');
+$QDs = array('1' => 'test1', '2' => 'test1', '3' => 'test3');
+$status = array('1' => 'normal', '2' => 'normal', '3' => 'closed');
+
+$changeName = array('names' => $names);
+$changeQDs = array('QDs' => $QDs);
+$changeStatus = array('statuses' => $status);
+
+$product = new productTest('admin');
+
+r($product->batchUpdateTest($changeName, '1')) && p('0:field,old,new') && e('name,正常产品1,批量修改产品1'); // 批量修改product名称
+r($product->batchUpdateTest($changeQDs, '2')) && p('0:field,old,new') && e('QD,test2,test1'); // 批量修改produc测试负责人
+r($product->batchUpdateTest($changeStatus, '3')) && p('0:field,old,new') && e('status,normal,closed'); // 批量修改product状态
diff --git a/module/product/test/model/checkpriv.php b/module/product/test/model/checkpriv.php
new file mode 100755
index 0000000000..f0457e9869
--- /dev/null
+++ b/module/product/test/model/checkpriv.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+checkPriv();
+cid=1
+pid=1
+
+测试admin能否看到产品1 >> 1
+测试admin能否看到产品2 >> 1
+测试admin能否看到产品3 >> 1
+测试admin能否看到产品4 >> 1
+测试admin能否看到产品5 >> 1
+测试admin能否看到不存在的产品 >> 1
+测试po1能否看到产品1 >> 1
+测试po1能否看到产品2 >> 1
+测试po1能否看到产品3 >> 1
+测试po1能否看到产品4 >> 1
+测试po1能否看到产品5 >> 1
+测试po1能否看到不存在的产品 >> 2
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$productTest = new productTest('admin');
+r($productTest->checkPrivTest($productIDList[0])) && p() && e('1'); // 测试admin能否看到产品1
+r($productTest->checkPrivTest($productIDList[1])) && p() && e('1'); // 测试admin能否看到产品2
+r($productTest->checkPrivTest($productIDList[2])) && p() && e('1'); // 测试admin能否看到产品3
+r($productTest->checkPrivTest($productIDList[3])) && p() && e('1'); // 测试admin能否看到产品4
+r($productTest->checkPrivTest($productIDList[4])) && p() && e('1'); // 测试admin能否看到产品5
+r($productTest->checkPrivTest($productIDList[5])) && p() && e('1'); // 测试admin能否看到不存在的产品
+
+$productTest = new productTest('po1');
+r($productTest->checkPrivTest($productIDList[0])) && p() && e('1'); // 测试po1能否看到产品1
+r($productTest->checkPrivTest($productIDList[1])) && p() && e('1'); // 测试po1能否看到产品2
+r($productTest->checkPrivTest($productIDList[2])) && p() && e('1'); // 测试po1能否看到产品3
+r($productTest->checkPrivTest($productIDList[3])) && p() && e('1'); // 测试po1能否看到产品4
+r($productTest->checkPrivTest($productIDList[4])) && p() && e('1'); // 测试po1能否看到产品5
+r($productTest->checkPrivTest($productIDList[5])) && p() && e('2'); // 测试po1能否看到不存在的产品
+
diff --git a/module/product/test/model/close.php b/module/product/test/model/close.php
new file mode 100755
index 0000000000..275de37ce1
--- /dev/null
+++ b/module/product/test/model/close.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+测试关闭产品1 >> status,normal,closed
+测试关闭产品2 >> status,normal,closed
+测试关闭产品3 >> status,normal,closed
+测试关闭产品4 >> status,normal,closed
+测试关闭产品5 >> status,normal,closed
+测试关闭不存在产品 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->closeTest($productIDList[0])) && p('0:field,old,new') && e('status,normal,closed'); // 测试关闭产品1
+r($product->closeTest($productIDList[1])) && p('0:field,old,new') && e('status,normal,closed'); // 测试关闭产品2
+r($product->closeTest($productIDList[2])) && p('0:field,old,new') && e('status,normal,closed'); // 测试关闭产品3
+r($product->closeTest($productIDList[3])) && p('0:field,old,new') && e('status,normal,closed'); // 测试关闭产品4
+r($product->closeTest($productIDList[4])) && p('0:field,old,new') && e('status,normal,closed'); // 测试关闭产品5
+r($product->closeTest($productIDList[5])) && p() && e('0'); // 测试关闭不存在产品
diff --git a/module/product/test/model/create.php b/module/product/test/model/create.php
new file mode 100755
index 0000000000..26992f7023
--- /dev/null
+++ b/module/product/test/model/create.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试正常的创建 >> case1
+测试不填产品代号的情况 >> 『产品代号』不能为空。
+测试创建重复的产品 >> 『产品代号』已经有『testcase1』这条记录了。
+测试不填产品名称的情况 >> 『产品名称』不能为空。
+测试传入name和code >> case3,testcase3
+测试传入program、name、code >> 3,case4,testcase4
+测试传入program、name、code、type、status >> 4,branch,closed
+测试不填权限控制的情况 >> 『访问控制』不符合格式,应当为:『/open|private|custom/』。
+
+*/
+
+$product = new productTest('admin');
+
+$t_create = array('name' => 'case1', 'code' => 'testcase1');
+$t_noid = array('name' => 'case2');
+$t_repeat = array('name' => 'case1', 'code' => 'testcase1');
+$t_noname = array('code' => 'testcase1');
+$t_namecode = array('name' => 'case3', 'code' => 'testcase3');
+$t_pronamecode = array('program' => '3', 'name' => 'case4', 'code' => 'testcase4');
+$t_intypestatus = array('program' => '4', 'name' => 'case5', 'code' => 'testcase5', 'type' => 'branch', 'status' => 'closed');
+$t_noacl = array('name' => 'case12', 'code' => 'testcase1', 'acl' => '');
+
+r($product->createObject($t_create)) && p('name') && e('case1'); // 测试正常的创建
+r($product->createObject($t_noid)) && p('code:0') && e('『产品代号』不能为空。'); // 测试不填产品代号的情况
+r($product->createObject($t_repeat)) && p('code:0') && e('『产品代号』已经有『testcase1』这条记录了。'); // 测试创建重复的产品
+r($product->createObject($t_noname)) && p('name:0') && e('『产品名称』不能为空。'); // 测试不填产品名称的情况
+r($product->createObject($t_namecode)) && p('name,code') && e('case3,testcase3'); // 测试传入name和code
+r($product->createObject($t_pronamecode)) && p('program,name,code') && e('3,case4,testcase4'); // 测试传入program、name、code
+r($product->createObject($t_intypestatus)) && p('program,type,status') && e('4,branch,closed'); // 测试传入program、name、code、type、status
+r($product->createObject($t_noacl)) && p('acl:0') && e('『访问控制』不符合格式,应当为:『/open|private|custom/』。'); // 测试不填权限控制的情况
diff --git a/module/product/test/model/getallexecutionpairsbyproduct.php b/module/product/test/model/getallexecutionpairsbyproduct.php
new file mode 100755
index 0000000000..6dbd9d008a
--- /dev/null
+++ b/module/product/test/model/getallexecutionpairsbyproduct.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getAllExecutionPairsByProduct();
+cid=1
+pid=1
+
+测试获取产品1的执行信息 >> 项目1/迭代1,项目11/迭代11,项目1/迭代91,项目11/迭代101,项目1/迭代181,项目11/迭代191,项目1/迭代271,项目11/迭代281,项目1/迭代361,项目11/迭代371,项目1/迭代451,项目11/迭代461,项目1/迭代541,项目11/迭代551
+测试获取产品2的执行信息 >> 项目2/迭代2,项目12/迭代12,项目2/迭代92,项目12/迭代102,项目2/迭代182,项目12/迭代192,项目2/迭代272,项目12/迭代282,项目2/迭代362,项目12/迭代372,项目2/迭代452,项目12/迭代462,项目2/迭代542,项目12/迭代552
+测试获取产品3的执行信息 >> 项目3/迭代3,项目13/迭代13,项目3/迭代93,项目13/迭代103,项目3/迭代183,项目13/迭代193,项目3/迭代273,项目13/迭代283,项目3/迭代363,项目13/迭代373,项目3/迭代453,项目13/迭代463,项目3/迭代543,项目13/迭代553
+测试获取产品4的执行信息 >> 项目4/迭代4,项目14/迭代14,项目4/迭代94,项目14/迭代104,项目4/迭代184,项目14/迭代194,项目4/迭代274,项目14/迭代284,项目4/迭代364,项目14/迭代374,项目4/迭代454,项目14/迭代464,项目4/迭代544,项目14/迭代554
+测试获取产品5的执行信息 >> 项目5/迭代5,项目15/迭代15,项目5/迭代95,项目15/迭代105,项目5/迭代185,项目15/迭代195,项目5/迭代275,项目15/迭代285,项目5/迭代365,项目15/迭代375,项目5/迭代455,项目15/迭代465,项目5/迭代545,项目15/迭代555
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getAllExecutionPairsByProductTest($productIDList[0])) && p('101,111,191,201,281,291,371,381,461,471,551,561,641,651') && e('项目1/迭代1,项目11/迭代11,项目1/迭代91,项目11/迭代101,项目1/迭代181,项目11/迭代191,项目1/迭代271,项目11/迭代281,项目1/迭代361,项目11/迭代371,项目1/迭代451,项目11/迭代461,项目1/迭代541,项目11/迭代551'); // 测试获取产品1的执行信息
+r($product->getAllExecutionPairsByProductTest($productIDList[1])) && p('102,112,192,202,282,292,372,382,462,472,552,562,642,652') && e('项目2/迭代2,项目12/迭代12,项目2/迭代92,项目12/迭代102,项目2/迭代182,项目12/迭代192,项目2/迭代272,项目12/迭代282,项目2/迭代362,项目12/迭代372,项目2/迭代452,项目12/迭代462,项目2/迭代542,项目12/迭代552'); // 测试获取产品2的执行信息
+r($product->getAllExecutionPairsByProductTest($productIDList[2])) && p('103,113,193,203,283,293,373,383,463,473,553,563,643,653') && e('项目3/迭代3,项目13/迭代13,项目3/迭代93,项目13/迭代103,项目3/迭代183,项目13/迭代193,项目3/迭代273,项目13/迭代283,项目3/迭代363,项目13/迭代373,项目3/迭代453,项目13/迭代463,项目3/迭代543,项目13/迭代553'); // 测试获取产品3的执行信息
+r($product->getAllExecutionPairsByProductTest($productIDList[3])) && p('104,114,194,204,284,294,374,384,464,474,554,564,644,654') && e('项目4/迭代4,项目14/迭代14,项目4/迭代94,项目14/迭代104,项目4/迭代184,项目14/迭代194,项目4/迭代274,项目14/迭代284,项目4/迭代364,项目14/迭代374,项目4/迭代454,项目14/迭代464,项目4/迭代544,项目14/迭代554'); // 测试获取产品4的执行信息
+r($product->getAllExecutionPairsByProductTest($productIDList[4])) && p('105,115,195,205,285,295,375,385,465,475,555,565,645,655') && e('项目5/迭代5,项目15/迭代15,项目5/迭代95,项目15/迭代105,项目5/迭代185,项目15/迭代195,项目5/迭代275,项目15/迭代285,项目5/迭代365,项目15/迭代375,项目5/迭代455,项目15/迭代465,项目5/迭代545,项目15/迭代555'); // 测试获取产品5的执行信息
+r($product->getAllExecutionPairsByProductTest($productIDList[5])) && p('0:') && e(''); // 测试获取不存在产品的执行信息
\ No newline at end of file
diff --git a/module/product/test/model/getbyid.php b/module/product/test/model/getbyid.php
new file mode 100755
index 0000000000..232b55713d
--- /dev/null
+++ b/module/product/test/model/getbyid.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+测试获取产品1的信息 >> 正常产品1,code1,normal,po1,test1,dev1
+测试获取产品2的信息 >> 正常产品2,code2,normal,po2,test2,dev2
+测试获取产品3的信息 >> 正常产品3,code3,normal,po3,test3,dev3
+测试获取产品4的信息 >> 正常产品4,code4,normal,po4,test4,dev4
+测试获取产品5的信息 >> 正常产品5,code5,normal,po5,test5,dev5
+测试获取不存在产品的信息 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getByIdTest($productIDList[0])) && p('name,code,type,PO,QD,RD') && e('正常产品1,code1,normal,po1,test1,dev1'); // 测试获取产品1的信息
+r($product->getByIdTest($productIDList[1])) && p('name,code,type,PO,QD,RD') && e('正常产品2,code2,normal,po2,test2,dev2'); // 测试获取产品2的信息
+r($product->getByIdTest($productIDList[2])) && p('name,code,type,PO,QD,RD') && e('正常产品3,code3,normal,po3,test3,dev3'); // 测试获取产品3的信息
+r($product->getByIdTest($productIDList[3])) && p('name,code,type,PO,QD,RD') && e('正常产品4,code4,normal,po4,test4,dev4'); // 测试获取产品4的信息
+r($product->getByIdTest($productIDList[4])) && p('name,code,type,PO,QD,RD') && e('正常产品5,code5,normal,po5,test5,dev5'); // 测试获取产品5的信息
+r($product->getByIdTest($productIDList[5])) && p('name,code,type,PO,QD,RD') && e('0'); // 测试获取不存在产品的信息
\ No newline at end of file
diff --git a/module/product/test/model/getbyidlist.php b/module/product/test/model/getbyidlist.php
new file mode 100755
index 0000000000..0a2c66c78a
--- /dev/null
+++ b/module/product/test/model/getbyidlist.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getByIdList();
+cid=1
+pid=1
+
+测试获取product 1 2 3的信息 >> 正常产品1,po1,test1,dev1;正常产品2,po2,test2,dev2;正常产品3,po3,test3,dev3
+测试获取product 4 5 6的信息 >> 正常产品4,po4,test4,dev4;正常产品5,po5,test5,dev5;正常产品6,po6,test6,dev6
+测试获取product 7 8 9的信息 >> 正常产品7,po7,test7,dev7;正常产品8,po8,test8,dev8;正常产品9,po9,test9,dev9
+
+*/
+
+$product = new productTest('admin');
+
+$productIDList1 = array('1', '2', '3');
+$productIDList2 = array('4', '5', '6');
+$productIDList3 = array('7', '8', '9');
+
+r($product->getByIdListTest($productIDList1)) && p('1:name,PO,QD,RD;2:name,PO,QD,RD;3:name,PO,QD,RD') && e('正常产品1,po1,test1,dev1;正常产品2,po2,test2,dev2;正常产品3,po3,test3,dev3'); // 测试获取product 1 2 3的信息
+r($product->getByIdListTest($productIDList2)) && p('4:name,PO,QD,RD;5:name,PO,QD,RD;6:name,PO,QD,RD') && e('正常产品4,po4,test4,dev4;正常产品5,po5,test5,dev5;正常产品6,po6,test6,dev6'); // 测试获取product 4 5 6的信息
+r($product->getByIdListTest($productIDList3)) && p('7:name,PO,QD,RD;8:name,PO,QD,RD;9:name,PO,QD,RD') && e('正常产品7,po7,test7,dev7;正常产品8,po8,test8,dev8;正常产品9,po9,test9,dev9'); // 测试获取product 7 8 9的信息
\ No newline at end of file
diff --git a/module/product/test/model/getexecutionpairsbyproduct.php b/module/product/test/model/getexecutionpairsbyproduct.php
new file mode 100755
index 0000000000..448fe1536f
--- /dev/null
+++ b/module/product/test/model/getexecutionpairsbyproduct.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+getExecutionPairsByProduct();
+cid=1
+pid=1
+
+测试获取产品1的信息 >> 项目1/迭代1;项目11/迭代11
+测试获取产品1 项目11的信息 >> 迭代1;
+测试获取产品1 项目21的信息 >> ;迭代11
+测试获取产品2的信息 >> 项目2/迭代2;项目12/迭代12
+测试获取产品2 项目12的信息 >> 迭代2;
+测试获取产品2 项目22的信息 >> ;迭代12
+测试获取产品3的信息 >> 项目3/迭代3;项目13/迭代13
+测试获取产品3 项目13的信息 >> 迭代3;
+测试获取产品3 项目23的信息 >> ;迭代13
+测试获取产品4的信息 >> 项目4/迭代4;项目14/迭代14
+测试获取产品4 项目14的信息 >> 迭代4;
+测试获取产品4 项目24的信息 >> ;迭代14
+测试获取产品5的信息 >> 项目5/迭代5;项目15/迭代15
+测试获取产品5 项目15的信息 >> 迭代5;
+测试获取产品5 项目25的信息 >> ;迭代15
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+$projectIDList = array('11', '21', '12', '22', '13', '23', '14', '24', '15', '25');
+
+$product = new productTest('admin');
+
+r($product->getExecutionPairsByProductTest($productIDList[0])) && p('101;111') && e('项目1/迭代1;项目11/迭代11'); // 测试获取产品1的信息
+r($product->getExecutionPairsByProductTest($productIDList[0], $projectIDList[0])) && p('101;111') && e('迭代1;'); // 测试获取产品1 项目11的信息
+r($product->getExecutionPairsByProductTest($productIDList[0], $projectIDList[1])) && p('101;111') && e(';迭代11'); // 测试获取产品1 项目21的信息
+r($product->getExecutionPairsByProductTest($productIDList[1])) && p('102;112') && e('项目2/迭代2;项目12/迭代12'); // 测试获取产品2的信息
+r($product->getExecutionPairsByProductTest($productIDList[1], $projectIDList[2])) && p('102;112') && e('迭代2;'); // 测试获取产品2 项目12的信息
+r($product->getExecutionPairsByProductTest($productIDList[1], $projectIDList[3])) && p('102;112') && e(';迭代12'); // 测试获取产品2 项目22的信息
+r($product->getExecutionPairsByProductTest($productIDList[2])) && p('103;113') && e('项目3/迭代3;项目13/迭代13'); // 测试获取产品3的信息
+r($product->getExecutionPairsByProductTest($productIDList[2], $projectIDList[4])) && p('103;113') && e('迭代3;'); // 测试获取产品3 项目13的信息
+r($product->getExecutionPairsByProductTest($productIDList[2], $projectIDList[5])) && p('103;113') && e(';迭代13'); // 测试获取产品3 项目23的信息
+r($product->getExecutionPairsByProductTest($productIDList[3])) && p('104;114') && e('项目4/迭代4;项目14/迭代14'); // 测试获取产品4的信息
+r($product->getExecutionPairsByProductTest($productIDList[3], $projectIDList[6])) && p('104;114') && e('迭代4;'); // 测试获取产品4 项目14的信息
+r($product->getExecutionPairsByProductTest($productIDList[3], $projectIDList[7])) && p('104;114') && e(';迭代14'); // 测试获取产品4 项目24的信息
+r($product->getExecutionPairsByProducttest($productIDList[4])) && p('105;115') && e('项目5/迭代5;项目15/迭代15'); // 测试获取产品5的信息
+r($product->getExecutionPairsByProducttest($productIDList[4], $projectIDList[8])) && p('105;115') && e('迭代5;'); // 测试获取产品5 项目15的信息
+r($product->getExecutionPairsByProducttest($productIDList[4], $projectIDList[9])) && p('105;115') && e(';迭代15'); // 测试获取产品5 项目25的信息
\ No newline at end of file
diff --git a/module/product/test/model/getlatestproject.php b/module/product/test/model/getlatestproject.php
new file mode 100755
index 0000000000..d0ebb48745
--- /dev/null
+++ b/module/product/test/model/getlatestproject.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getLatestProject();
+cid=1
+pid=1
+
+测试产品25关联的最后一个未关闭的项目,按begin字段排序 >> 405
+测试产品38关联的最后一个未关闭的项目,按begin字段排序 >> 408
+传入不存在的产品 >> 没有数据
+
+*/
+
+$product = new productTest('admin');
+
+$t_project25 = array('id'=>'25');
+$t_project38 = array('id'=>'38');
+$t_project101 = array('id'=>'10001');
+
+r($product->testGetLatestProject($t_project25['id'])) && p('id') && e('405'); // 测试产品25关联的最后一个未关闭的项目,按begin字段排序
+r($product->testGetLatestProject($t_project38['id'])) && p('id') && e('408'); // 测试产品38关联的最后一个未关闭的项目,按begin字段排序
+r($product->testGetLatestProject($t_project101['id'])) && p() && e('没有数据'); // 传入不存在的产品
diff --git a/module/product/test/model/getlinepairs.php b/module/product/test/model/getlinepairs.php
new file mode 100755
index 0000000000..73e3bfa096
--- /dev/null
+++ b/module/product/test/model/getlinepairs.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getLinePairs();
+cid=1
+pid=1
+
+测试获取程序集1的信息 >> 产品线1,产品线11
+测试获取程序集2的信息 >> 产品线2,产品线12
+测试获取程序集3的信息 >> 产品线3,产品线13
+测试获取程序集4的信息 >> 产品线4,产品线14
+测试获取程序集5的信息 >> 产品线5,产品线15
+测试获取不存在程序集的信息 >> 0
+
+*/
+
+$programIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getLinePairsTest($programIDList[0])) && p('1,11') && e('产品线1,产品线11'); // 测试获取程序集1的信息
+r($product->getLinePairsTest($programIDList[1])) && p('2,12') && e('产品线2,产品线12'); // 测试获取程序集2的信息
+r($product->getLinePairsTest($programIDList[2])) && p('3,13') && e('产品线3,产品线13'); // 测试获取程序集3的信息
+r($product->getLinePairsTest($programIDList[3])) && p('4,14') && e('产品线4,产品线14'); // 测试获取程序集4的信息
+r($product->getLinePairsTest($programIDList[4])) && p('5,15') && e('产品线5,产品线15'); // 测试获取程序集5的信息
+r($product->getLinePairsTest($programIDList[5])) && p('1,11') && e('0'); // 测试获取不存在程序集的信息
\ No newline at end of file
diff --git a/module/product/test/model/getlist.php b/module/product/test/model/getlist.php
new file mode 100755
index 0000000000..ac14c07943
--- /dev/null
+++ b/module/product/test/model/getlist.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+返回项目集1下的产品数量 >> 11
+测试传入programID=0的情况 >> 120
+传入不存在的项目集 >> 0
+返回项目集1下的未关闭的产品数量 >> 7
+获取所有的未关闭的产品数量 >> 80
+返回项目集1下的关闭了的产品数量 >> 4
+返回所有的未关闭的产品数量 >> 40
+返回项目集1下的与当前用户有关系的产品数量 >> 0
+返回项目集1下产品线1的产品数量 >> 11
+返回项目集1下产品线2的产品数量 >> 0
+
+*/
+
+$product = new productTest('admin');
+
+$t_numproject = array('0','1', '2', '11');
+
+r($product->getAllProductsCount($t_numproject[1])) && p() && e('11'); // 返回项目集1下的产品数量
+r($product->getAllProductsCount($t_numproject[0])) && p() && e('120'); // 测试传入programID=0的情况
+r($product->getAllProductsCount($t_numproject[3])) && p() && e('0'); // 传入不存在的项目集
+r($product->getNoclosedProductsCount($t_numproject[1])) && p() && e('7'); // 返回项目集1下的未关闭的产品数量
+r($product->getNoclosedProductsCount($t_numproject[0])) && p() && e('80'); // 获取所有的未关闭的产品数量
+r($product->getClosedProductsCount($t_numproject[1])) && p() && e('4'); // 返回项目集1下的关闭了的产品数量
+r($product->getClosedProductsCount($t_numproject[0])) && p() && e('40'); // 返回所有的未关闭的产品数量
+r($product->getInvolvedProductsCount($t_numproject[1])) && p() && e('0'); // 返回项目集1下的与当前用户有关系的产品数量
+r($product->countProductsByLine($t_numproject[1], $t_numproject[1])) && p() && e('11'); // 返回项目集1下产品线1的产品数量
+r($product->countProductsByLine($t_numproject[1], $t_numproject[2])) && p() && e('0'); // 返回项目集1下产品线2的产品数量
\ No newline at end of file
diff --git a/module/product/test/model/getmultibranchpairs.php b/module/product/test/model/getmultibranchpairs.php
new file mode 100755
index 0000000000..93718b1ed5
--- /dev/null
+++ b/module/product/test/model/getmultibranchpairs.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getMultiBranchPairs();
+cid=1
+pid=1
+
+测试获取项目集1的产品id >> ,46,57,68,79,90
+测试获取项目集2的产品id >> ,47,58,69,80,91
+测试获取项目集3的产品id >> ,48,59,70,81,92
+测试获取项目集4的产品id >> ,49,60,71,82,93
+测试获取项目集5的产品id >> ,50,61,72,83,94
+测试获取不存在项目集的产品id >> 0
+
+*/
+
+$programIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getMultiBranchPairsTest($programIDList[0])) && p() && e(',46,57,68,79,90'); // 测试获取项目集1的产品id
+r($product->getMultiBranchPairsTest($programIDList[1])) && p() && e(',47,58,69,80,91'); // 测试获取项目集2的产品id
+r($product->getMultiBranchPairsTest($programIDList[2])) && p() && e(',48,59,70,81,92'); // 测试获取项目集3的产品id
+r($product->getMultiBranchPairsTest($programIDList[3])) && p() && e(',49,60,71,82,93'); // 测试获取项目集4的产品id
+r($product->getMultiBranchPairsTest($programIDList[4])) && p() && e(',50,61,72,83,94'); // 测试获取项目集5的产品id
+r($product->getMultiBranchPairsTest($programIDList[5])) && p() && e('0'); // 测试获取不存在项目集的产品id
\ No newline at end of file
diff --git a/module/product/test/model/getorderedproducts.php b/module/product/test/model/getorderedproducts.php
new file mode 100755
index 0000000000..2383369fa7
--- /dev/null
+++ b/module/product/test/model/getorderedproducts.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getOrderedProducts();
+cid=1
+pid=1
+
+测试获取状态为all的产品数量 >> 120
+测试获取状态为noclosed的产品数量 >> 80
+测试获取状态为closed的产品数量 >> 40
+
+*/
+
+$statusList = array('all', 'noclosed', 'closed');
+
+$product = new productTest('admin');
+
+r($product->getOrderedProductsTest($statusList[0])) && p() && e('120'); // 测试获取状态为all的产品数量
+r($product->getOrderedProductsTest($statusList[1])) && p() && e('80'); // 测试获取状态为noclosed的产品数量
+r($product->getOrderedProductsTest($statusList[2])) && p() && e('40'); // 测试获取状态为closed的产品数量
\ No newline at end of file
diff --git a/module/product/test/model/getpairs.php b/module/product/test/model/getpairs.php
new file mode 100755
index 0000000000..a0fc49e55b
--- /dev/null
+++ b/module/product/test/model/getpairs.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试项目集10下的11号产品 >> 正常产品11
+测试项目集10下的55号产品 >> 多分支产品55
+测试项目集10下的99号产品 >> 多平台产品99
+测试不存在的项目集 >> 没有数据
+返回所有产品的数量 >> 120
+返回项目集10下的所有产品 >> 10
+测试项目集10下的未关闭产品5 >> 正常产品6
+返回项目集10下的未关闭产品的数量 >> 6
+
+*/
+
+$product = new productTest('admin');
+
+$t_peoduct10 = array('programID'=>'10');
+$t_noproduct = array('programID'=>'11');
+$t_alproduct = array('programID'=>'0');
+$t_notclose5 = array('programID'=>'5');
+
+r($product->getProductPairs($t_peoduct10['programID'])) && p('11') && e('正常产品11'); // 测试项目集10下的11号产品
+r($product->getProductPairs($t_peoduct10['programID'])) && p('55') && e('多分支产品55'); // 测试项目集10下的55号产品
+r($product->getProductPairs($t_peoduct10['programID'])) && p('99') && e('多平台产品99'); // 测试项目集10下的99号产品
+r($product->getProductPairs($t_noproduct['programID'])) && p() && e('没有数据'); // 测试不存在的项目集
+r($product->getProductPairsCount($t_alproduct['programID'])) && p() && e('120'); // 返回所有产品的数量
+r($product->getProductPairsCount($t_peoduct10['programID'])) && p() && e('10'); // 返回项目集10下的所有产品
+r($product->getNoclosedPairs($t_notclose5['programID'])) && p('6') && e('正常产品6'); // 测试项目集10下的未关闭产品5
+r($product->getNoclosedPairsCount($t_peoduct10['programID'])) && p() && e('6'); // 返回项目集10下的未关闭产品的数量
\ No newline at end of file
diff --git a/module/product/test/model/getpairsbyprojectmodel.php b/module/product/test/model/getpairsbyprojectmodel.php
new file mode 100755
index 0000000000..ae2de7f925
--- /dev/null
+++ b/module/product/test/model/getpairsbyprojectmodel.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getPairsByProjectModel();
+cid=1
+pid=1
+
+测试获取model为all产品数量 >> 120
+测试获取model为scrum产品数量 >> 70
+测试获取model为waterfall产品数量 >> 40
+测试获取model为kanban产品数量 >> 40
+
+*/
+
+$modelList = array('all', 'scrum', 'waterfall', 'kanban');
+
+$product = new productTest('admin');
+
+r($product->getPairsByProjectModelTest($modelList[0])) && p('name') && e('120'); // 测试获取model为all产品数量
+r($product->getPairsByProjectModelTest($modelList[1])) && p('name') && e('70'); // 测试获取model为scrum产品数量
+r($product->getPairsByProjectModelTest($modelList[2])) && p('name') && e('40'); // 测试获取model为waterfall产品数量
+r($product->getPairsByProjectModelTest($modelList[3])) && p('name') && e('40'); // 测试获取model为kanban产品数量
\ No newline at end of file
diff --git a/module/product/test/model/getproductidbyproject.php b/module/product/test/model/getproductidbyproject.php
new file mode 100755
index 0000000000..4223e872ef
--- /dev/null
+++ b/module/product/test/model/getproductidbyproject.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getProductIDByProject();
+cid=1
+pid=1
+
+测试获取项目11的产品信息 >> 1
+测试获取项目12的产品信息 >> 2
+测试获取项目13的产品信息 >> 3
+测试获取项目14的产品信息 >> 4
+测试获取项目15的产品信息 >> 5
+测试获取不存在的项目的产品信息 >> 0
+
+*/
+
+$projectIDList = array('11', '12', '13', '14', '15', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getProductIDByProjectTest($projectIDList[0])) && p() && e('1'); // 测试获取项目11的产品信息
+r($product->getProductIDByProjectTest($projectIDList[1])) && p() && e('2'); // 测试获取项目12的产品信息
+r($product->getProductIDByProjectTest($projectIDList[2])) && p() && e('3'); // 测试获取项目13的产品信息
+r($product->getProductIDByProjectTest($projectIDList[3])) && p() && e('4'); // 测试获取项目14的产品信息
+r($product->getProductIDByProjectTest($projectIDList[4])) && p() && e('5'); // 测试获取项目15的产品信息
+r($product->getProductIDByProjectTest($projectIDList[5])) && p() && e('0'); // 测试获取不存在的项目的产品信息
\ No newline at end of file
diff --git a/module/product/test/model/getproductpairsbyproject.php b/module/product/test/model/getproductpairsbyproject.php
new file mode 100755
index 0000000000..98be3f128f
--- /dev/null
+++ b/module/product/test/model/getproductpairsbyproject.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getProductPairsByProject();
+cid=1
+pid=1
+
+测试获取项目11 状态为all的产品信息 >> 正常产品1;多平台产品81;多平台产品91
+测试获取项目12 状态为all的产品信息 >> 正常产品2;多平台产品82;多平台产品92
+测试获取项目13 状态为all的产品信息 >> 正常产品3;多平台产品83;多平台产品93
+测试获取项目14 状态为all的产品信息 >> 正常产品4;多平台产品84;多平台产品94
+测试获取项目15 状态为all的产品信息 >> 正常产品5;多平台产品85;多平台产品95
+测试获取不存在的项目状态为all的产品信息 >> 0
+测试获取项目11 状态为unclosed的产品信息 >> 正常产品1;多平台产品81;多平台产品91
+测试获取项目12 状态为unclosed的产品信息 >> 正常产品2;多平台产品82;多平台产品92
+测试获取项目13 状态为unclosed的产品信息 >> 正常产品3;多平台产品83;多平台产品93
+测试获取项目14 状态为unclosed的产品信息 >> 正常产品4;多平台产品84;多平台产品94
+测试获取项目15 状态为unclosed的产品信息 >> 正常产品5;多平台产品85;多平台产品95
+测试获取不存在的项目状态为unclosed的产品信息 >> 0
+
+*/
+
+$projectIDList = array('11', '12', '13', '14', '15', '1000001');
+$statusList = array('all', 'noclosed');
+
+$product = new productTest('admin');
+
+r($product->getProductPairsByProjectTest($projectIDList[0], $statusList[0])) && p('1;81;91') && e('正常产品1;多平台产品81;多平台产品91'); // 测试获取项目11 状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[1], $statusList[0])) && p('2;82;92') && e('正常产品2;多平台产品82;多平台产品92'); // 测试获取项目12 状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[2], $statusList[0])) && p('3;83;93') && e('正常产品3;多平台产品83;多平台产品93'); // 测试获取项目13 状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[3], $statusList[0])) && p('4;84;94') && e('正常产品4;多平台产品84;多平台产品94'); // 测试获取项目14 状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[4], $statusList[0])) && p('5;85;95') && e('正常产品5;多平台产品85;多平台产品95'); // 测试获取项目15 状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[5], $statusList[0])) && p() && e('0'); // 测试获取不存在的项目状态为all的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[0], $statusList[1])) && p('1;81;91') && e('正常产品1;多平台产品81;多平台产品91'); // 测试获取项目11 状态为unclosed的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[1], $statusList[1])) && p('2;82;92') && e('正常产品2;多平台产品82;多平台产品92'); // 测试获取项目12 状态为unclosed的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[2], $statusList[1])) && p('3;83;93') && e('正常产品3;多平台产品83;多平台产品93'); // 测试获取项目13 状态为unclosed的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[3], $statusList[1])) && p('4;84;94') && e('正常产品4;多平台产品84;多平台产品94'); // 测试获取项目14 状态为unclosed的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[4], $statusList[1])) && p('5;85;95') && e('正常产品5;多平台产品85;多平台产品95'); // 测试获取项目15 状态为unclosed的产品信息
+r($product->getProductPairsByProjectTest($projectIDList[5], $statusList[1])) && p() && e('0'); // 测试获取不存在的项目状态为unclosed的产品信息
\ No newline at end of file
diff --git a/module/product/test/model/getproducts.php b/module/product/test/model/getproducts.php
new file mode 100755
index 0000000000..03a4d0b1f0
--- /dev/null
+++ b/module/product/test/model/getproducts.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getProducts();
+cid=1
+pid=1
+
+测试获取项目11 状态为all的产品信息 >> 正常产品1;多平台产品81;多平台产品91
+测试获取项目12 状态为all的产品信息 >> 正常产品2;多平台产品82;多平台产品92
+测试获取项目13 状态为all的产品信息 >> 正常产品3;多平台产品83;多平台产品93
+测试获取项目14 状态为all的产品信息 >> 正常产品4;多平台产品84;多平台产品94
+测试获取项目15 状态为all的产品信息 >> 正常产品5;多平台产品85;多平台产品95
+测试获取不存在的项目状态为all的产品信息 >> 0
+测试获取项目11 状态为unclosed的产品信息 >> 正常产品1;多平台产品81;多平台产品91
+测试获取项目12 状态为unclosed的产品信息 >> 正常产品2;多平台产品82;多平台产品92
+测试获取项目13 状态为unclosed的产品信息 >> 正常产品3;多平台产品83;多平台产品93
+测试获取项目14 状态为unclosed的产品信息 >> 正常产品4;多平台产品84;多平台产品94
+测试获取项目15 状态为unclosed的产品信息 >> 正常产品5;多平台产品85;多平台产品95
+测试获取不存在的项目状态为unclosed的产品信息 >> 0
+
+*/
+
+$projectIDList = array('11', '12', '13', '14', '15', '1000001');
+$statusList = array('all', 'noclosed');
+
+$product = new productTest('admin');
+
+r($product->getProductsTest($projectIDList[0], $statusList[0])) && p('1:name;81:name;91:name') && e('正常产品1;多平台产品81;多平台产品91'); // 测试获取项目11 状态为all的产品信息
+r($product->getProductsTest($projectIDList[1], $statusList[0])) && p('2:name;82:name;92:name') && e('正常产品2;多平台产品82;多平台产品92'); // 测试获取项目12 状态为all的产品信息
+r($product->getProductsTest($projectIDList[2], $statusList[0])) && p('3:name;83:name;93:name') && e('正常产品3;多平台产品83;多平台产品93'); // 测试获取项目13 状态为all的产品信息
+r($product->getProductsTest($projectIDList[3], $statusList[0])) && p('4:name;84:name;94:name') && e('正常产品4;多平台产品84;多平台产品94'); // 测试获取项目14 状态为all的产品信息
+r($product->getProductsTest($projectIDList[4], $statusList[0])) && p('5:name;85:name;95:name') && e('正常产品5;多平台产品85;多平台产品95'); // 测试获取项目15 状态为all的产品信息
+r($product->getProductsTest($projectIDList[5], $statusList[0])) && p() && e('0'); // 测试获取不存在的项目状态为all的产品信息
+r($product->getProductsTest($projectIDList[0], $statusList[1])) && p('1:name;81:name;91:name') && e('正常产品1;多平台产品81;多平台产品91'); // 测试获取项目11 状态为unclosed的产品信息
+r($product->getProductsTest($projectIDList[1], $statusList[1])) && p('2:name;82:name;92:name') && e('正常产品2;多平台产品82;多平台产品92'); // 测试获取项目12 状态为unclosed的产品信息
+r($product->getProductsTest($projectIDList[2], $statusList[1])) && p('3:name;83:name;93:name') && e('正常产品3;多平台产品83;多平台产品93'); // 测试获取项目13 状态为unclosed的产品信息
+r($product->getProductsTest($projectIDList[3], $statusList[1])) && p('4:name;84:name;94:name') && e('正常产品4;多平台产品84;多平台产品94'); // 测试获取项目14 状态为unclosed的产品信息
+r($product->getProductsTest($projectIDList[4], $statusList[1])) && p('5:name;85:name;95:name') && e('正常产品5;多平台产品85;多平台产品95'); // 测试获取项目15 状态为unclosed的产品信息
+r($product->getProductsTest($projectIDList[5], $statusList[1])) && p() && e('0'); // 测试获取不存在的项目状态为unclosed的产品信息
\ No newline at end of file
diff --git a/module/product/test/model/getprojectlistbyproduct.php b/module/product/test/model/getprojectlistbyproduct.php
new file mode 100755
index 0000000000..4909502d10
--- /dev/null
+++ b/module/product/test/model/getprojectlistbyproduct.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getProjectListByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目1
+返回产品1关联的项目21名字 >> 项目11
+传入不存在的产品 >> 没有数据
+
+*/
+
+$product = new productTest('admin');
+
+$t_retion = array('1', '1', '10001');
+
+r($product->getAllProjectsByProduct($t_retion[0])) && p('11:name') && e('项目1'); // 返回产品1关联的项目11名字
+r($product->getAllProjectsByProduct($t_retion[1])) && p('21:name') && e('项目11'); // 返回产品1关联的项目21名字
+r($product->getAllProjectsByProduct($t_retion[2])) && p() && e('没有数据'); // 传入不存在的产品
\ No newline at end of file
diff --git a/module/product/test/model/getprojectpairsbyproduct.php b/module/product/test/model/getprojectpairsbyproduct.php
new file mode 100755
index 0000000000..aa05b38626
--- /dev/null
+++ b/module/product/test/model/getprojectpairsbyproduct.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getProjectPairsByProduct();
+cid=1
+pid=1
+
+返回产品1关联的项目11名字 >> 项目1
+返回产品1关联的项目21名字 >> 项目11
+传入不存在的产品 >> 没有数据
+返回id为15的项目名 >> 项目5
+传入不存在的项目id >> 没有数据
+
+*/
+
+$product = new productTest('admin');
+
+$t_return = array('1', '10001', '15', '7010');
+
+r($product->getProjectPairsByProductID($t_return[0])) && p('11') && e('项目1'); // 返回产品1关联的项目11名字
+r($product->getProjectPairsByProductID($t_return[0])) && p('21') && e('项目11'); // 返回产品1关联的项目21名字
+r($product->getProjectPairsByProductID($t_return[1])) && p() && e('没有数据'); // 传入不存在的产品
+r($product->getAppendProject($t_return[2])) && p('15') && e('项目5'); // 返回id为15的项目名
+r($product->getAppendProject($t_return[3])) && p() && e('没有数据'); // 传入不存在的项目id
\ No newline at end of file
diff --git a/module/product/test/model/getprojectstatsbyproduct.php b/module/product/test/model/getprojectstatsbyproduct.php
new file mode 100755
index 0000000000..2aa0334415
--- /dev/null
+++ b/module/product/test/model/getprojectstatsbyproduct.php
@@ -0,0 +1,57 @@
+#!/usr/bin/env php
+getProjectStatsByProduct();
+cid=1
+pid=1
+
+测试获取产品1的 browseType为all的信息 >> 项目1;项目11
+测试获取产品1的 browseType为unclosed的信息 >> 0
+测试获取产品1的 browseType为unplan的信息 >> 0
+测试获取产品1的 browseType为allstory的信息 >> 0
+测试获取产品2的 browseType为all的信息 >> 项目2;项目12
+测试获取产品2的 browseType为assignedtome的信息 >> 0
+测试获取产品2的 browseType为openedbyme的信息 >> 0
+测试获取产品2的 browseType为reviewedbyme的信息 >> 0
+测试获取产品3的 browseType为all的信息 >> 项目3;项目13
+测试获取产品3的 browseType为reviewbyme的信息 >> 0
+测试获取产品3的 browseType为closedbyme的信息 >> 0
+测试获取产品3的 browseType为draftstory的信息 >> 0
+测试获取产品4的 browseType为all的信息 >> 项目4;项目14
+测试获取产品4的 browseType为activestory的信息 >> 0
+测试获取产品4的 browseType为changedstory的信息 >> 0
+测试获取产品5的 browseType为all的信息 >> 项目5;项目15
+测试获取产品5的 browseType为willclose的信息 >> 0
+测试获取产品5的 browseType为closedstory的信息 >> 0
+测试获取不存在产品的信息 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+$browseType = array('unclosed', 'unplan', 'allstory', 'assignedtome', 'openedbyme', 'reviewedbyme', 'reviewbyme', 'closedbyme', 'draftstory', 'activestory', 'changedstory', 'willclose', 'closedstory');
+
+$product = new productTest('admin');
+
+r($product->getProjectStatsByProductTest($productIDList[0])) && p('11;21') && e('项目1;项目11'); // 测试获取产品1的 browseType为all的信息
+r($product->getProjectStatsByProductTest($productIDList[0], $browseType[0])) && p() && e('0'); // 测试获取产品1的 browseType为unclosed的信息
+r($product->getProjectStatsByProductTest($productIDList[0], $browseType[1])) && p() && e('0'); // 测试获取产品1的 browseType为unplan的信息
+r($product->getProjectStatsByProductTest($productIDList[0], $browseType[2])) && p() && e('0'); // 测试获取产品1的 browseType为allstory的信息
+r($product->getProjectStatsByProductTest($productIDList[1])) && p('12;22') && e('项目2;项目12'); // 测试获取产品2的 browseType为all的信息
+r($product->getProjectStatsByProductTest($productIDList[1], $browseType[3])) && p() && e('0'); // 测试获取产品2的 browseType为assignedtome的信息
+r($product->getProjectStatsByProductTest($productIDList[1], $browseType[4])) && p() && e('0'); // 测试获取产品2的 browseType为openedbyme的信息
+r($product->getProjectStatsByProductTest($productIDList[1], $browseType[5])) && p() && e('0'); // 测试获取产品2的 browseType为reviewedbyme的信息
+r($product->getProjectStatsByProductTest($productIDList[2])) && p('13;23') && e('项目3;项目13'); // 测试获取产品3的 browseType为all的信息
+r($product->getProjectStatsByProductTest($productIDList[2], $browseType[6])) && p() && e('0'); // 测试获取产品3的 browseType为reviewbyme的信息
+r($product->getProjectStatsByProductTest($productIDList[2], $browseType[7])) && p() && e('0'); // 测试获取产品3的 browseType为closedbyme的信息
+r($product->getProjectStatsByProductTest($productIDList[2], $browseType[8])) && p() && e('0'); // 测试获取产品3的 browseType为draftstory的信息
+r($product->getProjectStatsByProductTest($productIDList[3])) && p('14;24') && e('项目4;项目14'); // 测试获取产品4的 browseType为all的信息
+r($product->getProjectStatsByProductTest($productIDList[3], $browseType[9])) && p() && e('0'); // 测试获取产品4的 browseType为activestory的信息
+r($product->getProjectStatsByProductTest($productIDList[3], $browseType[10])) && p() && e('0'); // 测试获取产品4的 browseType为changedstory的信息
+r($product->getProjectStatsByProductTest($productIDList[4])) && p('15;25') && e('项目5;项目15'); // 测试获取产品5的 browseType为all的信息
+r($product->getProjectStatsByProductTest($productIDList[4], $browseType[11])) && p() && e('0'); // 测试获取产品5的 browseType为willclose的信息
+r($product->getProjectStatsByProductTest($productIDList[4], $browseType[12])) && p() && e('0'); // 测试获取产品5的 browseType为closedstory的信息
+r($product->getProjectStatsByProductTest($productIDList[5])) && p() && e('0'); // 测试获取不存在产品的信息
\ No newline at end of file
diff --git a/module/product/test/model/getroadmap.php b/module/product/test/model/getroadmap.php
new file mode 100755
index 0000000000..c94dc12fb9
--- /dev/null
+++ b/module/product/test/model/getroadmap.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getRoadmap();
+cid=1
+pid=1
+
+测试获取产品1的roadmap数量 >> 5
+测试获取产品2的roadmap数量 >> 2
+测试获取产品3的roadmap数量 >> 0
+测试获取产品4的roadmap数量 >> 0
+测试获取产品5的roadmap数量 >> 0
+测试获取不存在产品的roadmap数量 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getRoadmapTest($productIDList[0])) && p('total') && e('5'); // 测试获取产品1的roadmap数量
+r($product->getRoadmapTest($productIDList[1])) && p('total') && e('2'); // 测试获取产品2的roadmap数量
+r($product->getRoadmapTest($productIDList[2])) && p('total') && e('0'); // 测试获取产品3的roadmap数量
+r($product->getRoadmapTest($productIDList[3])) && p('total') && e('0'); // 测试获取产品4的roadmap数量
+r($product->getRoadmapTest($productIDList[4])) && p('total') && e('0'); // 测试获取产品5的roadmap数量
+r($product->getRoadmapTest($productIDList[5])) && p('total') && e('0'); // 测试获取不存在产品的roadmap数量
diff --git a/module/product/test/model/getstatbyid.php b/module/product/test/model/getstatbyid.php
new file mode 100755
index 0000000000..1562710156
--- /dev/null
+++ b/module/product/test/model/getstatbyid.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getStatByID();
+cid=1
+pid=1
+
+测试获取产品1的stat信息 >> 正常产品1,0,5,2,7,2,14,9,1,0
+测试获取产品2的stat信息 >> 正常产品2,0,2,2,7,2,14,4,1,0
+测试获取产品3的stat信息 >> 正常产品3,0,0,2,7,2,14,4,1,0
+测试获取产品4的stat信息 >> 正常产品4,0,0,2,7,2,14,4,1,0
+测试获取产品5的stat信息 >> 正常产品5,0,0,2,7,2,14,4,1,0
+测试获取不存在产品的stat信息 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getStatByIDTest($productIDList[0])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('正常产品1,0,5,2,7,2,14,9,1,0'); // 测试获取产品1的stat信息
+r($product->getStatByIDTest($productIDList[1])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('正常产品2,0,2,2,7,2,14,4,1,0'); // 测试获取产品2的stat信息
+r($product->getStatByIDTest($productIDList[2])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('正常产品3,0,0,2,7,2,14,4,1,0'); // 测试获取产品3的stat信息
+r($product->getStatByIDTest($productIDList[3])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('正常产品4,0,0,2,7,2,14,4,1,0'); // 测试获取产品4的stat信息
+r($product->getStatByIDTest($productIDList[4])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('正常产品5,0,0,2,7,2,14,4,1,0'); // 测试获取产品5的stat信息
+r($product->getStatByIDTest($productIDList[5])) && p('name,plans,releases,builds,cases,projects,executions,bugs,docs,progress') && e('0'); // 测试获取不存在产品的stat信息
diff --git a/module/product/test/model/getstats.php b/module/product/test/model/getstats.php
new file mode 100755
index 0000000000..542ba2df9a
--- /dev/null
+++ b/module/product/test/model/getstats.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getStats();
+cid=1
+pid=1
+
+测试获取产品1的stats信息 >> 正常产品1,0,5,9,9,0,0,0,0,0
+测试获取产品101的stats信息 >> 产品正常产品1,0,0,0,0,0,0,0,0,0
+测试获取产品2的stats信息 >> 正常产品2,0,2,4,4,0,0,0,0,0
+测试获取产品102的stats信息 >> 产品正常产品2,0,0,0,0,0,0,0,0,0
+测试获取产品3的stats信息 >> 正常产品3,0,0,4,4,0,0,0,0,0
+测试获取产品103的stats信息 >> 产品正常产品3,0,0,0,0,0,0,0,0,0
+测试获取产品4的stats信息 >> 正常产品4,0,0,4,4,0,0,0,0,0
+测试获取产品104的stats信息 >> 产品正常产品4,0,0,0,0,0,0,0,0,0
+
+*/
+
+$product = new productTest('admin');
+
+r($product->getStatsTest()) && p('0:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('正常产品1,0,5,9,9,0,0,0,0,0'); // 测试获取产品1的stats信息
+r($product->getStatsTest()) && p('1:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('产品正常产品1,0,0,0,0,0,0,0,0,0'); // 测试获取产品101的stats信息
+r($product->getStatsTest()) && p('2:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('正常产品2,0,2,4,4,0,0,0,0,0'); // 测试获取产品2的stats信息
+r($product->getStatsTest()) && p('3:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('产品正常产品2,0,0,0,0,0,0,0,0,0'); // 测试获取产品102的stats信息
+r($product->getStatsTest()) && p('4:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('正常产品3,0,0,4,4,0,0,0,0,0'); // 测试获取产品3的stats信息
+r($product->getStatsTest()) && p('5:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('产品正常产品3,0,0,0,0,0,0,0,0,0'); // 测试获取产品103的stats信息
+r($product->getStatsTest()) && p('6:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('正常产品4,0,0,4,4,0,0,0,0,0'); // 测试获取产品4的stats信息
+r($product->getStatsTest()) && p('7:name,plans,releases,bugs,unResolved,closedBugs,fixedBugs,thisWeekBugs,assignToNull,progress') && e('产品正常产品4,0,0,0,0,0,0,0,0,0'); // 测试获取产品104的stats信息
diff --git a/module/product/test/model/getstats4kanban.php b/module/product/test/model/getstats4kanban.php
new file mode 100755
index 0000000000..9ac297fc05
--- /dev/null
+++ b/module/product/test/model/getstats4kanban.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+getStats4Kanban();
+cid=1
+pid=1
+
+测试获取产品的看板stats信息 >> 项目集1,项目集2,项目集3
+测试获取产品的看板stats信息 >> 正常产品1;正常产品2;正常产品3
+测试获取产品的看板stats信息 >> 项目3;项目4;项目5
+测试获取产品的看板stats信息 >> 迭代544;迭代546;迭代552
+测试获取产品的看板stats信息 >> 44.44,9;100,10
+测试获取产品的看板stats信息 >> 13
+测试获取产品的看板stats信息 >> 22
+测试获取产品的看板stats信息 >> 72
+测试获取产品的看板stats信息 >> 2
+
+*/
+
+$product = new productTest('admin');
+
+$typeList = array('programList', 'productList', 'planList', 'projectList', 'executionList', 'projectProduct', 'projectLatestExecutions', 'hourList', 'releaseList');
+
+r($product->getStats4KanbanTest($typeList[0])) && p('1,2,3') && e('项目集1,项目集2,项目集3'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[1])) && p('1:name;2:name;3:name') && e('正常产品1;正常产品2;正常产品3'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[3])) && p('13:name;14:name;15:name') && e('项目3;项目4;项目5'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[6])) && p('14:name;16:name;22:name') && e('迭代544;迭代546;迭代552'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[7])) && p('612:progress,totalReal;618:progress,totalReal') && e('44.44,9;100,10'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[2], true)) && p() && e('13'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[4], true)) && p() && e('22'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[5], true)) && p() && e('72'); // 测试获取产品的看板stats信息
+r($product->getStats4KanbanTest($typeList[8], true)) && p() && e('2'); // 测试获取产品的看板stats信息
diff --git a/module/product/test/model/getstories.php b/module/product/test/model/getstories.php
new file mode 100755
index 0000000000..2e6c3c8a7b
--- /dev/null
+++ b/module/product/test/model/getstories.php
@@ -0,0 +1,70 @@
+#!/usr/bin/env php
+getStories();
+cid=1
+pid=1
+
+测试获取产品1 browseType为unclosed的需求数量 >> 2
+测试获取产品2 browseType为unclosed的需求数量 >> 2
+测试获取产品3 browseType为unclosed的需求数量 >> 2
+测试获取产品4 browseType为unclosed的需求数量 >> 2
+测试获取产品5 browseType为unclosed的需求数量 >> 2
+测试获取不存在的 browseType为unclosed的需求数量 >> 0
+测试获取产品1 browseType为unplan的需求数量 >> 0
+测试获取产品1 browseType为allstory的需求数量 >> 2
+测试获取产品1 browseType为assignedtome的需求数量 >> 0
+测试获取产品2 browseType为openedbyme的需求数量 >> 0
+测试获取产品2 browseType为reviewedbyme的需求数量 >> 1
+测试获取产品2 browseType为reviewbyme的需求数量 >> 0
+测试获取产品2 browseType为closedbyme的需求数量 >> 0
+测试获取产品3 browseType为draftstory的需求数量 >> 0
+测试获取产品3 browseType为activestory的需求数量 >> 2
+测试获取产品3 browseType为changedstory的需求数量 >> 0
+测试获取产品3 browseType为willclose的需求数量 >> 1
+测试获取产品4 browseType为closedstory的需求数量 >> 0
+测试获取产品4 browseType为unclosed的需求数量 >> 2
+测试获取产品4 browseType为unplan的需求数量 >> 0
+测试获取产品5 browseType为allstory的需求数量 >> 2
+测试获取产品5 browseType为assignedtome的需求数量 >> 0
+测试获取产品5 browseType为openedbyme的需求数量 >> 0
+测试获取不存在产品 browseType为reviewedbyme的需求数量 >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+$branch = 0;
+$browseType = array('unclosed', 'unplan', 'allstory', 'assignedtome', 'openedbyme', 'reviewedbyme', 'reviewbyme', 'closedbyme', 'draftstory', 'activestory', 'changedstory', 'willclose', 'closedstory');
+$queryID = 0;
+$moduleID = 0;
+
+$product = new productTest('admin');
+
+r($product->getStoriesTest($productIDList[0], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品1 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[1], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品2 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[2], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品3 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[3], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品4 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[4], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品5 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[5], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('0'); // 测试获取不存在的 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[0], $branch, $browseType[1], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品1 browseType为unplan的需求数量
+r($product->getStoriesTest($productIDList[0], $branch, $browseType[2], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品1 browseType为allstory的需求数量
+r($product->getStoriesTest($productIDList[0], $branch, $browseType[3], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品1 browseType为assignedtome的需求数量
+r($product->getStoriesTest($productIDList[1], $branch, $browseType[4], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品2 browseType为openedbyme的需求数量
+r($product->getStoriesTest($productIDList[1], $branch, $browseType[5], $queryID, $moduleID)) && p() && e('1'); // 测试获取产品2 browseType为reviewedbyme的需求数量
+r($product->getStoriesTest($productIDList[1], $branch, $browseType[6], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品2 browseType为reviewbyme的需求数量
+r($product->getStoriesTest($productIDList[1], $branch, $browseType[7], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品2 browseType为closedbyme的需求数量
+r($product->getStoriesTest($productIDList[2], $branch, $browseType[8], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品3 browseType为draftstory的需求数量
+r($product->getStoriesTest($productIDList[2], $branch, $browseType[9], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品3 browseType为activestory的需求数量
+r($product->getStoriesTest($productIDList[2], $branch, $browseType[10], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品3 browseType为changedstory的需求数量
+r($product->getStoriesTest($productIDList[2], $branch, $browseType[11], $queryID, $moduleID)) && p() && e('1'); // 测试获取产品3 browseType为willclose的需求数量
+r($product->getStoriesTest($productIDList[3], $branch, $browseType[12], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品4 browseType为closedstory的需求数量
+r($product->getStoriesTest($productIDList[3], $branch, $browseType[0], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品4 browseType为unclosed的需求数量
+r($product->getStoriesTest($productIDList[3], $branch, $browseType[1], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品4 browseType为unplan的需求数量
+r($product->getStoriesTest($productIDList[4], $branch, $browseType[2], $queryID, $moduleID)) && p() && e('2'); // 测试获取产品5 browseType为allstory的需求数量
+r($product->getStoriesTest($productIDList[4], $branch, $browseType[3], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品5 browseType为assignedtome的需求数量
+r($product->getStoriesTest($productIDList[4], $branch, $browseType[4], $queryID, $moduleID)) && p() && e('0'); // 测试获取产品5 browseType为openedbyme的需求数量
+r($product->getStoriesTest($productIDList[5], $branch, $browseType[5], $queryID, $moduleID)) && p() && e('0'); // 测试获取不存在产品 browseType为reviewedbyme的需求数量
\ No newline at end of file
diff --git a/module/product/test/model/getteammemberpairs.php b/module/product/test/model/getteammemberpairs.php
new file mode 100755
index 0000000000..5b16deebff
--- /dev/null
+++ b/module/product/test/model/getteammemberpairs.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getTeamMemberPairs();
+cid=1
+pid=1
+
+测试获取产品1的信息 >> po1,test1,dev1,0,1,2,3
+测试获取产品2的信息 >> po2,test2,dev2,0,1,2,3
+测试获取产品3的信息 >> po3,test3,dev3,0,1,2,3
+测试获取产品4的信息 >> po4,test4,dev4,0,1,2,3
+测试获取产品5的信息 >> po5,test5,dev5,0,1,2,3
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+
+r($product->getTeamMemberPairsTest($productIDList[0])) && p('po1,test1,dev1,admin,pm92,po2,user12') && e('po1,test1,dev1,0,1,2,3'); // 测试获取产品1的信息
+r($product->getTeamMemberPairsTest($productIDList[1])) && p('po2,test2,dev2,pm93,user3,po3,user13') && e('po2,test2,dev2,0,1,2,3'); // 测试获取产品2的信息
+r($product->getTeamMemberPairsTest($productIDList[2])) && p('po3,test3,dev3,pm94,user4,po4,user14') && e('po3,test3,dev3,0,1,2,3'); // 测试获取产品3的信息
+r($product->getTeamMemberPairsTest($productIDList[3])) && p('po4,test4,dev4,pm95,user5,po5,user15') && e('po4,test4,dev4,0,1,2,3'); // 测试获取产品4的信息
+r($product->getTeamMemberPairsTest($productIDList[4])) && p('po5,test5,dev5,pm96,user6,po6,user16') && e('po5,test5,dev5,0,1,2,3'); // 测试获取产品5的信息
\ No newline at end of file
diff --git a/module/product/test/model/isclickable.php b/module/product/test/model/isclickable.php
new file mode 100755
index 0000000000..867c7388a6
--- /dev/null
+++ b/module/product/test/model/isclickable.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+status为normal,action为close >> true
+status为close,action为close >> false
+status为normal,action为start >> true
+status为close,action为start >> true
+
+*/
+
+$product = new productTest('admin');
+
+$t_status = array('2', '75', 'close', 'start');
+
+r($product->testIsClickable($t_status[0], $t_status[2])) && p() && e('true'); // status为normal,action为close
+r($product->testIsClickable($t_status[1], $t_status[2])) && p() && e('false'); // status为close,action为close
+r($product->testIsClickable($t_status[0], $t_status[3])) && p() && e('true'); // status为normal,action为start
+r($product->testIsClickable($t_status[1], $t_status[3])) && p() && e('true'); // status为close,action为start
\ No newline at end of file
diff --git a/module/product/test/model/manageline.php b/module/product/test/model/manageline.php
new file mode 100755
index 0000000000..cff7f2f1d6
--- /dev/null
+++ b/module/product/test/model/manageline.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+manageLine();
+cid=1
+pid=1
+
+测试修改产品线名称 >> 产品线2
+测试修改所属项目集 >> 1
+测试创建新的产品线 >> 产品线21
+
+*/
+
+$product = new productTest('admin');
+
+$modules = array('id1' => '产品线2', 'id2' => '产品线2', 'id3' => '产品线3');
+$programs = array('id1' => '1', 'id2' => '2', 'id3' => '3');
+$lines1 = array('modules' => $modules, 'programs' => $programs);
+
+$modules = array('id1' => '产品线1', 'id2' => '产品线2', 'id3' => '产品线3');
+$programs = array('id1' => '1', 'id2' => '1', 'id3' => '3');
+$lines2 = array('modules' => $modules, 'programs' => $programs);
+
+$modules = array(0 => '产品线21', 1 => '');
+$programs = array(0 => '1', 1 => '1');
+$lines3 = array('modules' => $modules, 'programs' => $programs);
+
+$modules = array(0 => '');
+$programs = array(0 => '1');
+$lines4 = array('modules' => $modules, 'programs' => $programs);
+
+r($product->manageLineTest($lines1, 2)) && p('name') && e('产品线2'); // 测试修改产品线名称
+r($product->manageLineTest($lines2, 1)) && p('root') && e('1'); // 测试修改所属项目集
+r($product->manageLineTest($lines3)) && p('name') && e('产品线21'); // 测试创建新的产品线
+r($product->manageLineTest($lines4)) && p() && e(''); // 测试创建没有项目集的产品线
diff --git a/module/product/test/model/processroadmap.php b/module/product/test/model/processroadmap.php
new file mode 100755
index 0000000000..209b2d5327
--- /dev/null
+++ b/module/product/test/model/processroadmap.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+processRoadmap();
+cid=1
+pid=1
+
+测试获取产品1下的发布roadmap >> 产品1正常的发布1;产品1正常的发布3;产品1正常的里程碑发布5;项目1停止维护的里程碑发布6
+测试获取产品2下的发布roadmap >> 项目2发布!@#$$%^&*()测试发布的名称到底可以有多长asdlfkjla8
+测试获取产品3下的发布roadmap >> 0
+测试获取产品4下的发布roadmap >> 0
+测试获取产品5下的发布roadmap >> 0
+测试获取不存在产品下的发布roadmap >> 0
+
+*/
+
+$productIDList = array('1', '2', '3', '4', '5', '1000001');
+
+$product = new productTest('admin');
+r($product->processRoadmapTest($productIDList[0])) && p('0:name;1:name;2:name;3:name') && e('产品1正常的发布1;产品1正常的发布3;产品1正常的里程碑发布5;项目1停止维护的里程碑发布6'); // 测试获取产品1下的发布roadmap
+r($product->processRoadmapTest($productIDList[1])) && p('0:name') && e('项目2发布!@#$$%^&*()测试发布的名称到底可以有多长asdlfkjla8'); // 测试获取产品2下的发布roadmap
+r($product->processRoadmapTest($productIDList[2])) && p() && e('0'); // 测试获取产品3下的发布roadmap
+r($product->processRoadmapTest($productIDList[3])) && p() && e('0'); // 测试获取产品4下的发布roadmap
+r($product->processRoadmapTest($productIDList[4])) && p() && e('0'); // 测试获取产品5下的发布roadmap
+r($product->processRoadmapTest($productIDList[5])) && p() && e('0'); // 测试获取不存在产品下的发布roadmap
diff --git a/module/product/test/model/statisticdata.php b/module/product/test/model/statisticdata.php
new file mode 100755
index 0000000000..8a08a4fdf8
--- /dev/null
+++ b/module/product/test/model/statisticdata.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+statisticData();
+cid=1
+pid=1
+
+测试获取统计数据集中产品2的信息 >> 项目集1,2,2,2,2,4,0,0,2
+测试获取统计数据集中产品3的信息 >> 项目集2,2,2,2,2,4,0,0,0
+测试获取统计数据集中产品4的信息 >> 项目集3,2,2,2,2,4,0,0,0
+测试获取统计数据集中产品5的信息 >> 项目集4,2,2,2,2,4,0,0,0
+测试获取统计数据集中产品6的信息 >> 项目集5,2,0,1,1,4,0,0,0
+测试获取统计数据集中产品7的信息 >> 项目集6,2,0,1,1,4,0,0,0
+测试获取统计数据集中产品8的信息 >> 项目集7,2,0,1,1,4,0,0,0
+测试获取统计数据集中产品9的信息 >> 项目集8,2,0,1,1,4,0,0,0
+测试获取统计数据集中产品10的信息 >> 项目集9,2,0,1,1,4,0,3,0
+
+*/
+
+$product = new productTest('admin');
+
+$productStats = $product->getStatsTest();
+
+r($product->statisticDataTest($productStats[2])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集1,2,2,2,2,4,0,0,2'); // 测试获取统计数据集中产品2的信息
+r($product->statisticDataTest($productStats[4])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集2,2,2,2,2,4,0,0,0'); // 测试获取统计数据集中产品3的信息
+r($product->statisticDataTest($productStats[6])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集3,2,2,2,2,4,0,0,0'); // 测试获取统计数据集中产品4的信息
+r($product->statisticDataTest($productStats[8])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集4,2,2,2,2,4,0,0,0'); // 测试获取统计数据集中产品5的信息
+r($product->statisticDataTest($productStats[10])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集5,2,0,1,1,4,0,0,0'); // 测试获取统计数据集中产品6的信息
+r($product->statisticDataTest($productStats[12])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集6,2,0,1,1,4,0,0,0'); // 测试获取统计数据集中产品7的信息
+r($product->statisticDataTest($productStats[14])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集7,2,0,1,1,4,0,0,0'); // 测试获取统计数据集中产品8的信息
+r($product->statisticDataTest($productStats[16])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集8,2,0,1,1,4,0,0,0'); // 测试获取统计数据集中产品9的信息
+r($product->statisticDataTest($productStats[18])) && p('programName,totalRequirements,activeRequirements,totalStories,activeStories,unResolvedBugs,closedBugs,plans,releases') && e('项目集9,2,0,1,1,4,0,3,0'); // 测试获取统计数据集中产品10的信息
diff --git a/module/product/test/model/statisticprogram.php b/module/product/test/model/statisticprogram.php
new file mode 100755
index 0000000000..fb34d2d94b
--- /dev/null
+++ b/module/product/test/model/statisticprogram.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+statisticProgram();
+cid=1
+pid=1
+
+测试获取统计数据集中产品1的stats信息 >> 正常产品1,0,5,9
+测试获取统计数据集中产品12的stats信息 >> 正常产品12,0,0,3
+测试获取统计数据集中产品45的stats信息 >> 多分支产品45,2,0,3
+测试获取统计数据集中产品89的stats信息 >> 多平台产品89,0,0,3
+测试获取统计数据集中产品100的stats信息 >> 多平台产品100,0,0,3
+测试获取统计数据集中产品2的stats信息 >> 正常产品2,0,2,4
+测试获取统计数据集中产品13的stats信息 >> 正常产品13,0,0,3
+测试获取统计数据集中产品46的stats信息 >> 多分支产品46,2,0,3
+测试获取统计数据集中产品90的stats信息 >> 多平台产品90,0,0,3
+测试获取统计数据集中产品3的stats信息 >> 正常产品3,0,0,4
+测试获取统计数据集中产品4的stats信息 >> 正常产品4,0,0,4
+测试获取统计数据集中产品5的stats信息 >> 正常产品5,0,0,4
+测试获取统计数据集中产品6的stats信息 >> 正常产品6,0,0,4
+测试获取统计数据集中产品7的stats信息 >> 正常产品7,0,0,4
+测试获取统计数据集中产品8的stats信息 >> 正常产品8,0,0,4
+测试获取统计数据集中产品9的stats信息 >> 正常产品9,0,0,4
+
+*/
+
+$product = new productTest('admin');
+
+$productStats = $product->getStatsTest();
+
+r($product->statisticProgramTest($productStats, '0')) && p('1:name,plans,releases,bugs') && e('正常产品1,0,5,9'); // 测试获取统计数据集中产品1的stats信息
+r($product->statisticProgramTest($productStats, '0')) && p('12:name,plans,releases,bugs') && e('正常产品12,0,0,3'); // 测试获取统计数据集中产品12的stats信息
+r($product->statisticProgramTest($productStats, '0')) && p('45:name,plans,releases,bugs') && e('多分支产品45,2,0,3'); // 测试获取统计数据集中产品45的stats信息
+r($product->statisticProgramTest($productStats, '0')) && p('89:name,plans,releases,bugs') && e('多平台产品89,0,0,3'); // 测试获取统计数据集中产品89的stats信息
+r($product->statisticProgramTest($productStats, '0')) && p('100:name,plans,releases,bugs') && e('多平台产品100,0,0,3'); // 测试获取统计数据集中产品100的stats信息
+r($product->statisticProgramTest($productStats, '1')) && p('2:name,plans,releases,bugs') && e('正常产品2,0,2,4'); // 测试获取统计数据集中产品2的stats信息
+r($product->statisticProgramTest($productStats, '1')) && p('13:name,plans,releases,bugs') && e('正常产品13,0,0,3'); // 测试获取统计数据集中产品13的stats信息
+r($product->statisticProgramTest($productStats, '1')) && p('46:name,plans,releases,bugs') && e('多分支产品46,2,0,3'); // 测试获取统计数据集中产品46的stats信息
+r($product->statisticProgramTest($productStats, '1')) && p('90:name,plans,releases,bugs') && e('多平台产品90,0,0,3'); // 测试获取统计数据集中产品90的stats信息
+r($product->statisticProgramTest($productStats, '2')) && p('3:name,plans,releases,bugs') && e('正常产品3,0,0,4'); // 测试获取统计数据集中产品3的stats信息
+r($product->statisticProgramTest($productStats, '3')) && p('4:name,plans,releases,bugs') && e('正常产品4,0,0,4'); // 测试获取统计数据集中产品4的stats信息
+r($product->statisticProgramTest($productStats, '4')) && p('5:name,plans,releases,bugs') && e('正常产品5,0,0,4'); // 测试获取统计数据集中产品5的stats信息
+r($product->statisticProgramTest($productStats, '5')) && p('6:name,plans,releases,bugs') && e('正常产品6,0,0,4'); // 测试获取统计数据集中产品6的stats信息
+r($product->statisticProgramTest($productStats, '6')) && p('7:name,plans,releases,bugs') && e('正常产品7,0,0,4'); // 测试获取统计数据集中产品7的stats信息
+r($product->statisticProgramTest($productStats, '7')) && p('8:name,plans,releases,bugs') && e('正常产品8,0,0,4'); // 测试获取统计数据集中产品8的stats信息
+r($product->statisticProgramTest($productStats, '8')) && p('9:name,plans,releases,bugs') && e('正常产品9,0,0,4'); // 测试获取统计数据集中产品9的stats信息
diff --git a/module/product/test/model/update.php b/module/product/test/model/update.php
new file mode 100755
index 0000000000..2f47f24144
--- /dev/null
+++ b/module/product/test/model/update.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新产品名称 >> name,正常产品2,john
+测试更新产品代号 >> code,code2,newcode1
+测试更新产品名称和代号 >> name,john,jack;code,newcode1,newcode2
+测试不更改产品名称 >> 没有数据更新
+测试不更改产品代号 >> 没有数据更新
+测试同一项目集下产品名称不能重复 >> 『产品名称』已经有『jack』这条记录了。
+测试同一项目集下产品代号不能重复 >> 『产品代号』已经有『newcode2』这条记录了。
+
+*/
+
+$product = new productTest('admin');
+
+$t_upname = array('name' => 'john');
+$t_upid = array('code' => 'newcode1');
+$t_idname = array('name' => 'jack', 'code' => 'newcode2');
+$t_unname = array('name' => 'jack');
+$t_unid = array('code' => 'newcode2');
+$t_repeaproduct = array('name' => 'jack');
+$t_repeatid = array('code' => 'newcode2');
+
+r($product->updateObject('product', 2, $t_upname)) && p('0:field,old,new') && e('name,正常产品2,john'); // 测试更新产品名称
+r($product->updateObject('product', 2, $t_upid)) && p('0:field,old,new') && e('code,code2,newcode1'); // 测试更新产品代号
+r($product->updateObject('product', 2, $t_idname)) && p('0:field,old,new;1:field,old,new') && e('name,john,jack;code,newcode1,newcode2'); // 测试更新产品名称和代号
+r($product->updateObject('product', 2, $t_unname)) && p() && e('没有数据更新'); // 测试不更改产品名称
+r($product->updateObject('product', 2, $t_unid)) && p() && e('没有数据更新'); // 测试不更改产品代号
+r($product->updateObject('product', 13, $t_repeaproduct)) && p('name:0') && e('『产品名称』已经有『jack』这条记录了。'); // 测试同一项目集下产品名称不能重复
+r($product->updateObject('product', 13, $t_repeatid)) && p('code:0') && e('『产品代号』已经有『newcode2』这条记录了。'); // 测试同一项目集下产品代号不能重复
diff --git a/module/product/test/model/updateprojects.php b/module/product/test/model/updateprojects.php
new file mode 100755
index 0000000000..0370244c98
--- /dev/null
+++ b/module/product/test/model/updateprojects.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+updateProjects();
+cid=1
+pid=1
+
+测试更新产品101的项目信息 >> 731,1,,1,731,
+测试更新产品102的项目信息 >> 0
+测试更新产品103的项目信息 >> 0
+测试更新产品111的项目信息 >> 733,1,,1,733,;734,1,,1,734,;735,1,,1,735,;736,1,,1,736,;737,1,,1,737,
+测试更新产品112的项目信息 >> 738,1,,1,738,;739,1,,1,739,;740,1,,1,740,;741,1,,1,741,;742,1,,1,742,
+
+*/
+$productIDList = array('101', '102', '103', '111', '112');
+
+$product = new productTest('admin');
+
+r($product->updateProjectsTest($productIDList[0])) && p('0:id,parent,path') && e('731,1,,1,731,'); // 测试更新产品101的项目信息
+r($product->updateProjectsTest($productIDList[1])) && p('0:id,parent,path') && e('0'); // 测试更新产品102的项目信息
+r($product->updateProjectsTest($productIDList[2])) && p('0:id,parent,path') && e('0'); // 测试更新产品103的项目信息
+r($product->updateProjectsTest($productIDList[3])) && p('0:id,parent,path;1:id,parent,path;2:id,parent,path;3:id,parent,path;4:id,parent,path') && e('733,1,,1,733,;734,1,,1,734,;735,1,,1,735,;736,1,,1,736,;737,1,,1,737,'); // 测试更新产品111的项目信息
+r($product->updateProjectsTest($productIDList[4])) && p('0:id,parent,path;1:id,parent,path;2:id,parent,path;3:id,parent,path;4:id,parent,path') && e('738,1,,1,738,;739,1,,1,739,;740,1,,1,740,;741,1,,1,741,;742,1,,1,742,'); // 测试更新产品112的项目信息
diff --git a/module/product/test/product.class.php b/module/product/test/product.class.php
new file mode 100644
index 0000000000..277b07545b
--- /dev/null
+++ b/module/product/test/product.class.php
@@ -0,0 +1,1099 @@
+objectModel = $tester->loadModel('product');
+ $tester->app->loadClass('dao');
+ }
+
+ /**
+ * Test create a product.
+ *
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createObject($param = array())
+ {
+ global $createFields;
+ $whitelist = array();
+ $createFields = array('program' => 1, 'line' => 0, 'lineName' => '', 'newLine' => 0, 'name' => '', 'code' => '', 'PO' => 'admin', 'QD' => '', 'RD' => '',
+ 'reviewer' => '', 'type' => 'normal', 'status' => 'normal', 'desc' => '', 'acl' => 'open', 'uid' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getByID($objectID);
+ return $object;
+ }
+ }
+
+ /**
+ * Test get the latest project of the product.
+ *
+ * @param mixed $productID
+ * @access public
+ * @return object
+ */
+ public function testGetLatestProject($productID)
+ {
+ $project = $this->objectModel->getLatestProject($productID);
+ if($project == false) return '没有数据';
+ return $project;
+ }
+
+ /**
+ * Test get all products.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getAllProducts($programID)
+ {
+ return $this->objectModel->getList($programID);
+ }
+
+ /**
+ * Test get all products count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getAllProductsCount($programID)
+ {
+ return count($this->getAllProducts($programID));
+ }
+
+ /**
+ * Test get noclosed products.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getNoclosedProducts($programID)
+ {
+ return $this->objectModel->getList($programID, 'noclosed');
+ }
+
+ /**
+ * Test get noclosed products count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getNoclosedProductsCount($programID)
+ {
+ return count($this->getNoclosedProducts($programID));
+ }
+
+ /**
+ * Test get closed products.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getClosedProducts($programID)
+ {
+ return $this->objectModel->getList($programID, 'closed');
+ }
+
+ /**
+ * Test get closed products count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getClosedProductsCount($programID)
+ {
+ return count($this->getClosedProducts($programID));
+ }
+
+ /**
+ * Test get involved products.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getInvolvedProducts($programID)
+ {
+ return $this->objectModel->getList($programID, 'involved');
+ }
+
+ /**
+ * Test get involved products count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getInvolvedProductsCount($programID)
+ {
+ return count($this->getInvolvedProducts($programID));
+ }
+
+ /**
+ * Test get products by line.
+ *
+ * @param int $programID
+ * @param int $line
+ * @access public
+ * @return array
+ */
+ public function getProductsByLine($programID, $line = 0)
+ {
+ return $this->objectModel->getList($programID, 'all', 0, $line);
+ }
+
+ /**
+ * Test get products count by line.
+ *
+ * @param int $programID
+ * @param int $line
+ * @access public
+ * @return int
+ */
+ public function countProductsByLine($programID, $line = 0)
+ {
+ return count($this->getProductsByLine($programID, $line));
+ }
+
+ /**
+ * Test get product list.
+ *
+ * @param int $programID
+ * @param string $status
+ * @param int $line
+ * @access public
+ * @return array
+ */
+ public function getProductList($programID, $status = 'all', $line = 0)
+ {
+ return $this->objectModel->getList($programID, $status, 0, $line);
+ }
+
+ /**
+ * Test get product count.
+ *
+ * @param int $programID
+ * @param string $status
+ * @param int $line
+ * @access public
+ * @return int
+ */
+ public function getProductCount($programID, $status = 'all', $line = 0)
+ {
+ return count($this->getProductList($programID, $status, $line));
+ }
+
+ /**
+ * Test get product pairs.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getProductPairs($programID)
+ {
+ $pairs = $this->objectModel->getPairs('', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+
+ /**
+ * Test get product pairs count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getProductPairsCount($programID)
+ {
+ $pairsCount = count($this->getProductPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ /**
+ * Test get all product pairs.
+ *
+ * @param int $programID
+ * @access public
+ * @return void
+ */
+ public function getAllPairs($programID)
+ {
+ $pairs = $this->objectModel->getPairs('all', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+
+ /**
+ * Test get all product count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getAllPairsCount($programID)
+ {
+ $pairsCount = count($this->getAllPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ /**
+ * Test get noclosed product pairs.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getNoclosedPairs($programID)
+ {
+ $pairs = $this->objectModel->getPairs('noclosed', $programID);
+ if($pairs == array()) return '没有数据';
+ return $pairs;
+ }
+ /**
+ * Test get noclosed pairs count.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getNoclosedPairsCount($programID)
+ {
+ $pairsCount = count($this->getNoclosedPairs($programID));
+ if($pairsCount == '没有数据') return '0';
+ return $pairsCount;
+ }
+
+ /**
+ * Test get product pairs by order.
+ *
+ * @param int $programID
+ * @param string $orderBy
+ * @param string $mode
+ * @access public
+ * @return array
+ */
+ public function getProductPairsByOrder($programID, $orderBy = 'id_desc', $mode = '')
+ {
+ $this->objectModel->orderBy = $orderBy;
+ $pairs = $this->objectModel->getPairs($mode, $programID);
+ return checkOrder($pairs, $orderBy);
+ }
+
+ /**
+ * Test get all projects by product.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getAllProjectsByProduct($productID)
+ {
+ $projects = $this->objectModel->getProjectListByProduct($productID, 'all');
+ if($projects == array()) return '没有数据';
+ return $projects;
+ }
+
+ /**
+ * Test get projects by status.
+ *
+ * @param int $productID
+ * @param string $status
+ * @access public
+ * @return array
+ */
+ public function getProjectsByStatus($productID, $status)
+ {
+ $projects = $this->objectModel->getProjectListByProduct($productID, $browseType);
+ if($projects == array()) return '没有数据';
+ return $projects;
+ }
+
+ /**
+ * Test get project pairs by product id.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getProjectPairsByProductID($productID)
+ {
+ $projects = $this->objectModel->getProjectPairsByProduct($productID, 0, 0);
+ if($projects == array()) return '没有数据';
+ return $projects;
+ }
+
+ /**
+ * Test get append project.
+ *
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getAppendProject($projectID)
+ {
+ $project = $this->objectModel->getProjectPairsByProduct(10086, 0, $projectID);
+ if($project == array()) return '没有数据';
+ return $project;
+ }
+
+ /**
+ * Test judge an action is clickable or not.
+ *
+ * @param int $productID
+ * @param string $status
+ * @access public
+ * @return string
+ */
+ public function testIsClickable($productID, $status)
+ {
+ $product = $this->objectModel->getById($productID);
+ $isClick = $this->objectModel->isClickable($product, $status);
+ return $isClick == false ? 'false' : 'true';
+ }
+
+ /**
+ * Test update a product.
+ *
+ * @param string $module
+ * @param int $objectID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateObject($module, $objectID, $param = array())
+ {
+ global $tester;
+ $objectModel = $tester->loadModel($module);
+
+ $object = $objectModel->getById($objectID);
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $objectModel->update($objectID);
+ if($change == array()) $change = '没有数据更新';
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $change;
+ }
+ }
+
+ /**
+ * Test check privilege.
+ *
+ * @param int $productID
+ * @access public
+ * @return int
+ */
+ public function checkPrivTest($productID)
+ {
+ $object = $this->objectModel->checkPriv($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object ? 1 : 2;
+ }
+ }
+
+ /**
+ * Test get product by id.
+ *
+ * @param int $productID
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($productID)
+ {
+ $object = $this->objectModel->getById($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get product by id list.
+ *
+ * @param array $productIDList
+ * @access public
+ * @return array
+ */
+ public function getByIdListTest($productIDList)
+ {
+ $objects = $this->objectModel->getByIdList($productIDList);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get product pairs by project.
+ *
+ * @param int $productID
+ * @param string $status
+ * @access public
+ * @return array
+ */
+ public function getProductPairsByProjectTest($projectID, $status = 'all')
+ {
+ $objects = $this->objectModel->getProductPairsByProject($projectID, $status);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get product pairs by project model.
+ *
+ * @param string $model
+ * @access public
+ * @return int
+ */
+ public function getPairsByProjectModelTest($model)
+ {
+ $objects = $this->objectModel->getPairsByProjectModel($model);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return count($objects);
+ }
+ }
+
+ /**
+ * Test get products by project.
+ *
+ * @param int $projectID
+ * @param string $status
+ * @access public
+ * @return array
+ */
+ public function getProductsTest($projectID, $status)
+ {
+ $objects = $this->objectModel->getProducts($projectID, $status);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get product id by project.
+ *
+ * @param int $projectID
+ * @access public
+ * @return int
+ */
+ public function getProductIDByProjectTest($projectID)
+ {
+ $object = $this->objectModel->getProductIDByProject($projectID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get ordered products.
+ *
+ * @param string $status
+ * @access public
+ * @return int
+ */
+ public function getOrderedProductsTest($status)
+ {
+ $objects = $this->objectModel->getOrderedProducts($status);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return count($objects);
+ }
+ }
+
+ /**
+ * Test get Multi-branch product pairs.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getMultiBranchPairsTest($programID)
+ {
+ $objects = $this->objectModel->getMultiBranchPairs($programID);
+
+ $title = '';
+ foreach($objects as $object) $title .= ',' . $object;
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $title;
+ }
+ }
+
+ /**
+ * Test batch update products.
+ *
+ * @param array $param
+ * @param int $productID
+ * @access public
+ * @return void
+ */
+ public function batchUpdateTest($param, $productID)
+ {
+ $batchUpdateFields['productIDList'] = array('1' => '1', '2' => '2', '3' => '3');
+ $batchUpdateFields['programs'] = array('1' => '', '2' => '1', '3' => '2');
+ $batchUpdateFields['names'] = array('1' => '正常产品1', '2' => '正常产品2', '3' => '正常产品3');
+ $batchUpdateFields['lines'] = array('1' => '0', '2' => '1', '3' => '2');
+ $batchUpdateFields['POs'] = array('1' => 'po1', '2' => 'po2', '3' => 'po3');
+ $batchUpdateFields['QDs'] = array('1' => 'test1', '2' => 'test2', '3' => 'test3');
+ $batchUpdateFields['RDs'] = array('1' => 'dev1', '2' => 'dev2', '3' => 'dev3');
+ $batchUpdateFields['types'] = array('1' => 'normal', '2' => 'normal', '3' => 'normal');
+ $batchUpdateFields['statuses'] = array('1' => 'normal', '2' => 'normal', '3' => 'normal');
+ $batchUpdateFields['descs'] = array('1' => '<div> <p><h1>一、禅道项目管理软件是做什么的?</h1> 禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理 </p> <p>我是数字符号23@#$%#^$ </p> <p>我是英文dashcuscbrewg </p> </div>', '2' => '<div> <p><h1>一、禅道项目管理软件是做什么的?</h1> 禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理 </p> <p>我是数字符号23@#$%#^$ </p> <p>我是英文dashcuscbrewg </p> </div>', '3' => 'i<div> <p><h1>一、禅道项目管理软件是做什么的?</h1> 禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理 </p> <p>我是数字符号23@#$%#^$ </p> <p>我是英文dashcuscbrewg </p> </div>');
+ $batchUpdateFields['acls'] = array('1' => 'open', '2' => 'open', '3' => 'open');
+
+ foreach($batchUpdateFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $changes = $this->objectModel->batchUpdate();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $changes[$productID];
+ }
+ }
+
+ /**
+ * Test close a product.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function closeTest($productID)
+ {
+ $changes = $this->objectModel->close($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $changes;
+ }
+ }
+
+ /**
+ * Test manage line.
+ *
+ * @param array $param
+ * @access public
+ * @return void
+ */
+ public function manageLineTest($param, $moduleID = 0)
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->manageLine();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ global $tester;
+
+ $moduleID = $moduleID ? $moduleID : $tester->dao->select('id')->from(TABLE_MODULE)->orderby('id desc')->fetch()->id;
+ $object = $tester->dao->select('*')->from(TABLE_MODULE)->where('id')->eq($moduleID)->fetch();
+
+ return $object;
+ }
+ }
+
+ /**
+ * Test get stories.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param string $browseType
+ * @param int $queryID
+ * @param int $moduleID
+ * @access public
+ * @return array
+ */
+ public function getStoriesTest($productID, $branch, $browseType, $queryID, $moduleID)
+ {
+ $objects = $this->objectModel->getStories($productID, $branch, $browseType, $queryID, $moduleID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return count($objects);
+ }
+ }
+
+ /**
+ * Test batch get story stage.
+ *
+ * @param array $stories
+ * @access public
+ * @return array
+ */
+ public function batchGetStoryStageTest($stories)
+ {
+ $objects = $this->objectModel->batchGetStoryStage($stories);
+
+ foreach($objects as $id => $object) $stages[$id] = $object[0]->stage;
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $stages;
+ }
+ }
+
+ /**
+ * Test get project stats by product.
+ *
+ * @param int $productID
+ * @param string $browseType
+ * @access public
+ * @return array
+ */
+ public function getProjectStatsByProductTest($productID, $browseType = 'all')
+ {
+ $objects = $this->objectModel->getProjectStatsByProduct($productID, $browseType);
+
+ foreach($objects as $object) $projects[$object->id] = $object->name;
+
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return isset($projects) ? $projects : array();
+ }
+ }
+
+ /**
+ * Test get executions by product and project.
+ *
+ * @param int $productID
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getExecutionPairsByProductTest($productID, $projectID = 0)
+ {
+ $objects = $this->objectModel->getExecutionPairsByProduct($productID, 0, 'id_asc', $projectID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get all executions by product.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getAllExecutionPairsByProductTest($productID)
+ {
+ $objects = $this->objectModel->getAllExecutionPairsByProduct($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get roadmap of a proejct.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getRoadmapTest($productID)
+ {
+ $objects = $this->objectModel->getRoadmap($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test process roadmap.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function processRoadmapTest($productID)
+ {
+ global $tester;
+ $releases = $tester->loadModel('release')->getList($productID, '0');
+
+ $roadmapGroups = array('2022' => array($releases));
+
+ $objects = $this->objectModel->processRoadmap($roadmapGroups);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get team members of a product from projects.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getTeamMemberPairsTest($productID)
+ {
+ $product = $this->objectModel->getByID($productID);
+ $objects = $this->objectModel->getTeamMemberPairs($product);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get product stat by id.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getStatByIDTest($productID)
+ {
+ $objects = $this->objectModel->getStatByID($productID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get product stats.
+ *
+ * @access public
+ * @return array
+ */
+ public function getStatsTest()
+ {
+ $objects = $this->objectModel->getStats();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test stats for product kanban.
+ *
+ * @param string $type
+ * @param bool $getCount
+ * @access public
+ * @return array
+ */
+ public function getStats4KanbanTest($type, $getCount = false)
+ {
+ $objects = $this->objectModel->getStats4Kanban();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $getCount ? count($objects[$type]) : $objects[$type];
+ }
+ }
+
+ /**
+ * Test get product line pairs.
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getLinePairsTest($programID)
+ {
+ $objects = $this->objectModel->getLinePairs($programID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test statistics program data.
+ *
+ * @param object $productStats
+ * @param int $index
+ * @access public
+ * @return array
+ */
+ public function statisticProgramTest($productStats, $index)
+ {
+ $objects = $this->objectModel->statisticProgram($productStats);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objects[$index][$index]['products'];
+ }
+ }
+
+ /**
+ * Test statistics product data.
+ *
+ * @param object $product
+ * @access public
+ * @return array
+ */
+ public function statisticDataTest($product)
+ {
+ if($product->line)
+ {
+ /* Line name. */
+ $productStructure[$product->program][$product->line]['lineName'] = $product->lineName;
+ $data = $this->objectModel->statisticData('line', $productStructure, $product);
+ }
+
+ if($product->program)
+ {
+ /* Init vars. */
+ /* Program name. */
+ $productStructure[$product->program]['programName'] = $product->programName;
+ $data = $this->objectModel->statisticData('program', $productStructure, $product);
+ }
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $data;
+ }
+ }
+
+ /**
+ * Test change the projects set of the program.
+ *
+ * @param int $productID
+ * @access public
+ * @return object
+ */
+ public function updateProjectsTest($productID)
+ {
+ $singleLinkProjects = array();
+ $multipleLinkProjects = array();
+
+ global $tester;
+ /* Get the projects linked with this product. */
+ $projectPairs = $tester->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($productID)
+ ->andWhere('t2.type')->eq('project')
+ ->andWhere('t2.deleted')->eq('0')
+ ->fetchPairs();
+
+ $projects = ',';
+ if(!empty($projectPairs))
+ {
+ foreach($projectPairs as $projectID => $projectName)
+ {
+ $projects .= $projectID . ',';
+ $products = $tester->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs();
+ if(count($products) == 1)
+ {
+ $singleLinkProjects[$projectID] = $projectName;
+ }
+
+ if(count($products) > 1)
+ {
+ $multipleLinkProjects[$projectID] = $projectName;
+ }
+ }
+ }
+
+ $_POST['changeProjects'] = $projects;
+
+ $product = $this->objectModel->getById($productID);
+ $_POST['program'] = $product->program == 1 ? 2 : 1;
+
+ $this->objectModel->updateProjects($productID, $singleLinkProjects, $multipleLinkProjects);
+
+ $object = $tester->dao->select('t2.id,t2.parent,t2.path')->from(TABLE_PROJECTPRODUCT)->alias('t1')
+ ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
+ ->where('t1.product')->eq($productID)
+ ->andWhere('t2.type')->eq('project')
+ ->andWhere('t2.deleted')->eq('0')
+ ->fetchAll();
+
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+}
diff --git a/module/productplan/test/model/batchchangestatus.php b/module/productplan/test/model/batchchangestatus.php
new file mode 100755
index 0000000000..f09abbbf7f
--- /dev/null
+++ b/module/productplan/test/model/batchchangestatus.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+batchChangeStatus();
+cid=1
+pid=1
+
+将planiID=4,5的计划状态修改为doing,打印4旧状态 >> wait
+将planiID=4, 5的计划状态修改为doing,打印4新状态 >> doing
+将planiID=4, 5的计划状态修改为doing,打印5旧状态 >> wait
+将planiID=4, 5的计划状态修改为doing,打印5新状态 >> doing
+将planiID=4, 5的计划状态修改回wait, 打印4的当前状态 >> doing
+将planiID=4, 5的计划状态修改回wait, 打印4的修改后的状态 >> wait
+将planiID=4, 5的计划状态修改回wait, 打印5的当前状态 >> doing
+将planiID=4, 5的计划状态修改回wait, 打印5的修改后的状态 >> wait
+
+*/
+$plan = new productPlan('admin');
+
+$postID = array('planIDList' => array(4, 5));
+
+$status = $plan->batchChangeStatus('doing', $postID);
+$status4 = $status[4];
+$status5 = $status[5];
+
+$status = $plan->batchChangeStatus('wait', $postID);
+$status6 = $status[4];
+$status7 = $status[5];
+
+r($status4) && p('0:old') && e('wait'); //将planiID=4,5的计划状态修改为doing,打印4旧状态
+r($status4) && p('0:new') && e('doing'); //将planiID=4, 5的计划状态修改为doing,打印4新状态
+r($status5) && p('0:old') && e('wait'); //将planiID=4, 5的计划状态修改为doing,打印5旧状态
+r($status5) && p('0:new') && e('doing'); //将planiID=4, 5的计划状态修改为doing,打印5新状态
+r($status6) && p('0:old') && e('doing'); //将planiID=4, 5的计划状态修改回wait, 打印4的当前状态
+r($status6) && p('0:new') && e('wait'); //将planiID=4, 5的计划状态修改回wait, 打印4的修改后的状态
+r($status7) && p('0:old') && e('doing'); //将planiID=4, 5的计划状态修改回wait, 打印5的当前状态
+r($status6) && p('0:new') && e('wait'); //将planiID=4, 5的计划状态修改回wait, 打印5的修改后的状态
+?>
diff --git a/module/productplan/test/model/batchupdate.php b/module/productplan/test/model/batchupdate.php
new file mode 100755
index 0000000000..4a65e73559
--- /dev/null
+++ b/module/productplan/test/model/batchupdate.php
@@ -0,0 +1,100 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=1修改后的名字new >> list-1
+当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=2修改后的名字new >> list-2
+当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=3修改后的名字new >> list-3
+当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=4修改后的名字new >> list-4
+当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=5修改后的名字new >> list-5
+当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=6修改后的名字new >> list-6
+
+*/
+$plan = new productPlan('admin');
+
+$product = array();
+$product[0] = 1;
+$product[1] = 2;
+
+$id = array();
+$title = array();
+$begin = array();
+$end = array();
+
+$id1 = $id;
+$id1[1] = 1;
+$id1[2] = 2;
+$id1[3] = 3;
+
+$title1 = $title;
+$title1[1] = 'list-1';
+$title1[2] = 'list-2';
+$title1[3] = 'list-3';
+
+$begin1 = $begin;
+$begin1[1] = '2021-05-10';
+$begin1[2] = '2021-04-12';
+$begin1[3] = '2021-04-01';
+
+$end1 = $end;
+$end1[1] = '2022-11-30';
+$end1[2] = '2022-10-25';
+$end1[3] = '2022-10-23';
+
+$id2 = $id;
+$id2[4] = 4;
+$id2[5] = 5;
+$id2[6] = 6;
+
+$title2 = $title;
+$title2[6] = 'list-6';
+$title2[5] = 'list-5';
+$title2[4] = 'list-4';
+
+$begin2 = $begin;
+$begin2[6] = '2021-05-10';
+$begin2[5] = '2021-06-12';
+$begin2[4] = '2021-06-01';
+
+$end2 = $end;
+$end2[6] = '2022-11-30';
+$end2[5] = '2022-11-28';
+$end2[4] = '2022-11-23';
+
+$branch1 = array();
+$branch1['id'] = $id1;
+$branch1['title'] = $title1;
+$branch1['begin'] = $begin1;
+$branch1['end'] = $end1;
+
+$branch2 = array();
+$branch2['id'] = $id2;
+$branch2['title'] = $title2;
+$branch2['begin'] = $begin2;
+$branch2['end'] = $end2;
+
+$batchUpdate = $plan->batchUpdate($product[0], $branch1);
+
+$batchUpdate1 = $batchUpdate[1];
+$batchUpdate2 = $batchUpdate[2];
+$batchUpdate3 = $batchUpdate[3];
+
+$newBatchUpdate = $plan->batchUpdate($product[1], $branch2);
+$batchUpdate4 = $newBatchUpdate[4];
+$batchUpdate5 = $newBatchUpdate[5];
+$batchUpdate6 = $newBatchUpdate[6];
+
+r($batchUpdate1) && p('0:new') && e('list-1'); //当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=1修改后的名字new
+r($batchUpdate2) && p('0:new') && e('list-2'); //当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=2修改后的名字new
+r($batchUpdate3) && p('0:new') && e('list-3'); //当product=1时,传入正常参数批量修改id=1,2,3的计划,打印id=3修改后的名字new
+r($batchUpdate4) && p('0:new') && e('list-4'); //当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=4修改后的名字new
+r($batchUpdate5) && p('0:new') && e('list-5'); //当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=5修改后的名字new
+r($batchUpdate6) && p('0:new') && e('list-6'); //当product=2时,传入正常参数批量修改id=4,5,6的计划,打印id=6修改后的名字new
+?>
diff --git a/module/productplan/test/model/changeparentfield.php b/module/productplan/test/model/changeparentfield.php
new file mode 100755
index 0000000000..be040cda76
--- /dev/null
+++ b/module/productplan/test/model/changeparentfield.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+changeParentField();
+cid=1
+pid=1
+
+传入ID为1的情况,返回true >> 1
+传入ID为5的情况,返回true,如不存在函数会报错 >> 1
+
+*/
+
+$plan = new productPlan('admin');
+
+$planID = array();
+$planID[0] = 1;
+$planID[1] = 5;
+
+r($plan->changeParentField($planID[0])) && p() && e('1'); //传入ID为1的情况,返回true
+r($plan->changeParentField($planID[1])) && p() && e('1'); //传入ID为5的情况,返回true,如不存在函数会报错
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/create.php b/module/productplan/test/model/create.php
new file mode 100755
index 0000000000..d7df3c41e9
--- /dev/null
+++ b/module/productplan/test/model/create.php
@@ -0,0 +1,61 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试正常创建 >> 110
+测试不传入名称的情况 >> 『名称』不能为空。
+测试不传开始时间的情况 >> 111
+测试不传结束时间的情况 >> 112
+测试不传开始时间及结束时间的情况 >> 113
+测试不传UID的情况 >> 114
+测试不传关联产品的情况 >> 『产品』应当是数字。
+测试不传父级计划的情况 >> 『父计划』应当是数字。
+
+*/
+$plan = new productPlan('admin');
+
+$posts = array();
+$posts['title'] = '测试创建1';
+$posts['begin'] = '2021-10-25';
+$posts['end'] = '2021-10-29';
+$posts['uid'] = '623927843dd9b';
+$posts['product'] = '2';
+$posts['parent'] = '0';
+
+$noTitle = $posts;
+$noTitle['title'] = '';
+
+$noBegin = $posts;
+$noBegin['begin'] = '';
+
+$noEnd = $posts;
+$noEnd['end'] = '';
+
+$noBeginEnd = $noBegin;
+$noBeginEnd['end'] = '';
+
+$noUid = $posts;
+$noUid['uid'] = '';
+
+$noProduct = $posts;
+$noProduct['product'] = '';
+
+$noParent = $posts;
+$noParent['parent'] = '';
+
+r($plan->create($posts)) && p() && e('110'); //测试正常创建
+r($plan->create($noTitle)) && p('title:0') && e('『名称』不能为空。'); //测试不传入名称的情况
+r($plan->create($noBegin)) && p() && e('111'); //测试不传开始时间的情况
+r($plan->create($noEnd)) && p() && e('112'); //测试不传结束时间的情况
+r($plan->create($noBeginEnd)) && p() && e('113'); //测试不传开始时间及结束时间的情况
+r($plan->create($noUid)) && p() && e('114'); //测试不传UID的情况
+r($plan->create($noProduct)) && p('product:0') && e('『产品』应当是数字。'); //测试不传关联产品的情况
+r($plan->create($noParent)) && p('parent:0') && e('『父计划』应当是数字。'); //测试不传父级计划的情况
+?>
diff --git a/module/productplan/test/model/getbranchplanpairs.php b/module/productplan/test/model/getbranchplanpairs.php
new file mode 100755
index 0000000000..77825c9aeb
--- /dev/null
+++ b/module/productplan/test/model/getbranchplanpairs.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getBranchPlanPairs();
+cid=1
+pid=1
+
+传入存在的数据,返回相应信息 >> 1.0 [2021-11-18~2022-09-30]
+传入不存在的分支 >> 0
+传入不存在的产品id >> 0
+
+*/
+$plan = new productPlan('admin');
+
+$product = array();
+$product[0] = 41;
+$product[1] = 1;
+$product[2] = 111;
+
+$branch = array();
+$branch[0] = 1;
+$branch[1] = 111;
+$branch[2] = 1;
+
+r($plan->getBranchPlanPairs($product[0], $branch[0])) && p('1:31') && e('1.0 [2021-11-18~2022-09-30]'); //传入存在的数据,返回相应信息
+r($plan->getBranchPlanPairs($product[1], $branch[1])) && p('1:31') && e('0'); //传入不存在的分支
+r($plan->getBranchPlanPairs($product[2], $branch[2])) && p('1:31') && e('0'); //传入不存在的产品id
+?>
diff --git a/module/productplan/test/model/getbyidlist.php b/module/productplan/test/model/getbyidlist.php
new file mode 100755
index 0000000000..be7035ec20
--- /dev/null
+++ b/module/productplan/test/model/getbyidlist.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> 3
+传入一个数组,取值id为1的数据 >> 1
+传入一个数值,正常取值 >> 1
+传入一个不存在的值返回布尔值 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$IDlist = array();
+$IDlist[0] = 1;
+$IDlist[1] = 1000;
+$IDlist[2] = 3;
+
+r($plan->getByIDList($IDlist)) && p('3:id') && e('3'); //传入一个数组,取值id为3的数据
+r($plan->getByIDList($IDlist)) && p('1:id') && e('1'); //传入一个数组,取值id为1的数据
+r($plan->getByIDList($IDlist[0])) && p('1:id') && e('1'); //传入一个数值,正常取值
+r($plan->getByIDList($IDlist[1])) && p() && e('0'); //传入一个不存在的值返回布尔值
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/getbyidplan.php b/module/productplan/test/model/getbyidplan.php
new file mode 100755
index 0000000000..3f733b461b
--- /dev/null
+++ b/module/productplan/test/model/getbyidplan.php
@@ -0,0 +1,16 @@
+#!/usr/bin/env php
+getByIDPlan($planID[0])) && p('status') && e('wait'); //如果存在,返回数组类型数据
+r($plan->getByIDPlan($planID[0])) && p('begin') && e('2021-06-13'); //取出开始时间
+r($plan->getByIDPlan($planID[0])) && p('end') && e('2021-10-14'); //取出结束时间
+r($plan->getByIDPlan($planID[1])) && p() && e('0'); //如不存在,返回布尔值
+?>
diff --git a/module/productplan/test/model/getchildren.php b/module/productplan/test/model/getchildren.php
new file mode 100755
index 0000000000..2e1f08a708
--- /dev/null
+++ b/module/productplan/test/model/getchildren.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getChildren();
+cid=1
+pid=1
+
+这里统计了取出所有的数量 >> 61
+这里统计不存在的情况 >> 1
+
+*/
+$plan = new productPlan('admin');
+
+$planid = array();
+$planid[0] = 0;
+$planid[1] = 1;
+
+r($plan->getChildren(0)) && p() && e('61'); //这里统计了取出所有的数量
+r($plan->getChildren(1)) && p() && e('1'); //这里统计不存在的情况
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/getforproducts.php b/module/productplan/test/model/getforproducts.php
new file mode 100755
index 0000000000..d231acd1a0
--- /dev/null
+++ b/module/productplan/test/model/getforproducts.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getForProducts();
+cid=1
+pid=1
+
+测试传入一个数组,取出产品名称count >> 1.0
+测试传入一个不存在的product数组,应为空 >> 6
+
+*/
+
+$plan = new productPlan('admin');
+
+$products = array();
+$products[0] = array(1, 2);
+$products[1] = array(1000,1001);
+
+$noProduct = count($plan->getForProducts(array(1000,1001))) -1;
+
+r($plan->getForProducts($products[0])) && p('1') && e('1.0'); //测试传入一个数组,取出产品名称count
+r($noProduct) && p() && e('6'); //测试传入一个不存在的product数组,应为空
+?>
diff --git a/module/productplan/test/model/getgroupbyproduct.php b/module/productplan/test/model/getgroupbyproduct.php
new file mode 100755
index 0000000000..e833b01754
--- /dev/null
+++ b/module/productplan/test/model/getgroupbyproduct.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getGroupByProduct();
+cid=1
+pid=1
+
+传入正常product 1,2; >> 2
+传入部分不存在product; >> 1
+传入不存在product >> 0
+传入正常product 1,2;未过期param >> 0
+传入部分不存在product;未过期param >> 0
+传入不存在product; 未过期param >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$products = array();
+$products[0] = array(1, 2);
+$products[1] = array(2, 10000);
+$products[2] = array(9999, 10000);
+$param = array();
+$param[0] = 'skipParent';
+$param[1] = 'unexpired';
+
+r($plan->getGroupByProduct($products[0], $param[0])) && p() && e('2'); //传入正常product 1,2;
+r($plan->getGroupByProduct($products[1], $param[0])) && p() && e('1'); //传入部分不存在product;
+r($plan->getGroupByProduct($products[2], $param[0])) && p() && e('0'); //传入不存在product
+r($plan->getGroupByProduct($products[0], $param[1])) && p() && e('0'); //传入正常product 1,2;未过期param
+r($plan->getGroupByProduct($products[1], $param[1])) && p() && e('0'); //传入部分不存在product;未过期param
+r($plan->getGroupByProduct($products[2], $param[1])) && p() && e('0'); //传入不存在product; 未过期param
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/getlast.php b/module/productplan/test/model/getlast.php
new file mode 100755
index 0000000000..6bdb28ada8
--- /dev/null
+++ b/module/productplan/test/model/getlast.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getLast();
+cid=1
+pid=1
+
+获取id为1的最后一个产品 >> 3
+获取id为2的最后一个产品 >> 6
+获取不存在的id返回布尔值 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$getLast = array();
+$getLast[0] = 1;
+$getLast[1] = 2;
+$getLast[2] = 200;
+
+r($plan->getLast($getLast[0])) && p('id') && e('3'); //获取id为1的最后一个产品
+r($plan->getLast($getLast[1])) && p('id') && e('6'); //获取id为2的最后一个产品
+r($plan->getLast($getLast[2])) && p('id') && e('0'); //获取不存在的id返回布尔值
+?>
diff --git a/module/productplan/test/model/getlist.php b/module/productplan/test/model/getlist.php
new file mode 100755
index 0000000000..7ae8ba3dd9
--- /dev/null
+++ b/module/productplan/test/model/getlist.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+> 0
+获取product=1的所有的计划 >> 1;1;wait
+获取product=1的所有的非父计划 >> 2;1;wait
+获取product=1的所有未完成的计划 >> 3;1;wait
+获取product=1的所有未开始的计划 >> 3;1;wait
+获取product=1的所有进行中的计划 >> 101;1;doing
+获取product=2的所有已完成的计划 >> 103;2;done
+获取product=1的所有已关闭的计划 >> 102;1;closed
+
+*/
+
+$productplan = new Productplan('admin');
+
+$dataList = array();
+$dataList[0] = $productplan->getList();
+$dataList[1] = $productplan->getList(1, 0, 'all', null, 'begin_desc');
+$dataList[2] = $productplan->getList(1, 0, 'all', null, 'begin_desc', 'kipparent');
+$dataList[3] = $productplan->getList(1, 0, 'undone', null, 'begin_desc');
+$dataList[4] = $productplan->getList(1, 0, 'wait', null, 'begin_desc');
+$dataList[5] = $productplan->getList(1, 0, 'doing', null, 'begin_desc');
+$dataList[6] = $productplan->getList(2, 0, 'done', null, 'begin_desc');
+$dataList[7] = $productplan->getList(1, 0, 'closed', null, 'begin_desc');
+
+r($dataList[0]) && p() && e('0'); // 获取空数据
+r($dataList[1]) && p('1:id;1:product;1:status') && e('1;1;wait'); // 获取product=1的所有的计划
+r($dataList[2]) && p('2:id;2:product;2:status') && e('2;1;wait'); // 获取product=1的所有的非父计划
+r($dataList[3]) && p('3:id;3:product;3:status') && e('3;1;wait'); // 获取product=1的所有未完成的计划
+r($dataList[4]) && p('3:id;3:product;3:status') && e('3;1;wait'); // 获取product=1的所有未开始的计划
+r($dataList[5]) && p('101:id;101:product;101:status') && e('101;1;doing'); // 获取product=1的所有进行中的计划
+r($dataList[6]) && p('103:id;103:product;103:status') && e('103;2;done'); // 获取product=2的所有已完成的计划
+r($dataList[7]) && p('102:id;102:product;102:status') && e('102;1;closed'); // 获取product=1的所有已关闭的计划
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/getpairs.php b/module/productplan/test/model/getpairs.php
new file mode 100755
index 0000000000..94d57dfbf4
--- /dev/null
+++ b/module/productplan/test/model/getpairs.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+id为41的产品分支32 >> 分支2 / 1.1 [2021-11-25 ~ 2022-10-07]
+id为41的产品分支31 >> 分支1 / 1.0 [2021-11-18 ~ 2022-09-30]
+id为42的产品分支34 >> 分支4 / 1.0 [2021-12-09 ~ 2022-10-21]
+
+*/
+
+$plan = new productPlan('admin');
+
+$product = array();
+$product[0] = 41;
+$product[1] = 42;
+$branch = 1;
+$expired = 'unexpired';
+
+r($plan->getPairs($product[0], $branch, $expired)) && p('32') && e('分支2 / 1.1 [2021-11-25 ~ 2022-10-07]'); //id为41的产品分支32
+r($plan->getPairs($product[0], $branch, $expired)) && p('31') && e('分支1 / 1.0 [2021-11-18 ~ 2022-09-30]'); //id为41的产品分支31
+r($plan->getPairs($product[1], $branch, $expired)) && p('34') && e('分支4 / 1.0 [2021-12-09 ~ 2022-10-21]'); //id为42的产品分支34
+?>
diff --git a/module/productplan/test/model/getpairsforstory.php b/module/productplan/test/model/getpairsforstory.php
new file mode 100755
index 0000000000..a74f8df0d8
--- /dev/null
+++ b/module/productplan/test/model/getpairsforstory.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getPairsForStory();
+cid=1
+pid=1
+
+测试传入已有数据product=10,branch=0情况,正常返回 >> 3
+测试传入product=41, branch=1的数据 >> 1
+测试传入一个数组 >> 4
+测试传入不存在的product >> 0
+测试传入不同param情况 >> 3
+测试传入不同param情况 >> 3
+
+*/
+
+$plan = new productPlan('admin');
+
+$product = array(10, 41, 42, 1000);
+$branch = array(0, 1);
+$param = array('skipParent', 'withMainPlan', 'unexpired');
+
+r($plan->getPairsForStory($product[0], $branch[0], $param[1])) && p('') && e('3'); //测试传入已有数据product=10,branch=0情况,正常返回
+r($plan->getPairsForStory($product[1], $branch[1], $param[1])) && p('') && e('1'); //测试传入product=41, branch=1的数据
+r($plan->getPairsForStory($product, $branch[1], $param[1])) && p('') && e('4'); //测试传入一个数组
+r($plan->getPairsForStory($product[3], $branch[1], $param[1])) && p('') && e('0'); //测试传入不存在的product
+r($plan->getPairsForStory($product[0], $branch[0], $param[0])) && p('') && e('3'); //测试传入不同param情况
+r($plan->getPairsForStory($product[0], $branch[0], $param[2])) && p('') && e('3'); //测试传入不同param情况
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/getplansbystories.php b/module/productplan/test/model/getplansbystories.php
new file mode 100755
index 0000000000..cccc05290a
--- /dev/null
+++ b/module/productplan/test/model/getplansbystories.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getPlansByStories();
+cid=1
+pid=1
+
+查询存在的id >> 3
+查询部分存在的id >> 1
+查询不存在的id >> 0
+
+*/
+$plan = new productPlan('admin');
+
+$storyIdList = array();
+$storyIdList[0] = array(5, 6, 7);
+$storyIdList[1] = array(5, 1000);
+$storyIdList[2] = array(1000, 1001);
+
+r($plan->getPlansByStories($storyIdList[0])) && p() && e('3'); //查询存在的id
+r($plan->getPlansByStories($storyIdList[1])) && p() && e('1'); //查询部分存在的id
+r($plan->getPlansByStories($storyIdList[2])) && p() && e('0'); //查询不存在的id
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/gettopplanpairs.php b/module/productplan/test/model/gettopplanpairs.php
new file mode 100755
index 0000000000..3e6d3d5def
--- /dev/null
+++ b/module/productplan/test/model/gettopplanpairs.php
@@ -0,0 +1,16 @@
+#!/usr/bin/env php
+ 1, 'branch' => '', 'exclude' => '');
+$param[1] = array('productID' => 41, 'branch' => 1, 'exclude' => '');
+$param[2] = array('productID' => 41, 'branch' => 2, 'exclude' => '');
+
+r($plan->getTopPlanPairsTest($param[0])) && p('1,2') && e('1.0,1.1'); //测试获取正常产品的顶级计划
+r($plan->getTopPlanPairsTest($param[1])) && p('31') && e('1.0'); //测试获取分支1计划的正常产品的顶级计划
+r($plan->getTopPlanPairsTest($param[2])) && p('32') && e('1.1'); //测试获取分支2计划的正常产品的顶级计划
+?>
diff --git a/module/productplan/test/model/isclickable.php b/module/productplan/test/model/isclickable.php
new file mode 100755
index 0000000000..1517bdb693
--- /dev/null
+++ b/module/productplan/test/model/isclickable.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+id=100,无子集计划,可以点击的id=100 >> 1
+id=1,有子集计划,不能点击 >> 0
+id=102,无子集计划,计划关闭,不可点击 >> 0
+id=105,无子集计划,等待状态,不可点击 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$planID = array();
+$planID[0] = 100;
+$planID[1] = 101;
+$planID[2] = 1;
+$planID[3] = 102;
+$planID[4] = 105;
+
+$action = array();
+$action[0] = 'start';
+$action[1] = 'finish';
+$action[2] = 'close';
+$action[3] = 'activate';
+
+r($plan->isClickable($planID[0], $action[0])) && p() && e('1'); //id=100,无子集计划,可以点击的id=100
+r($plan->isClickable($planID[2], $action[1])) && p() && e('0'); //id=1,有子集计划,不能点击
+r($plan->isClickable($planID[3], $action[2])) && p() && e('0'); //id=102,无子集计划,计划关闭,不可点击
+r($plan->isClickable($planID[4], $action[3])) && p() && e('0'); //id=105,无子集计划,等待状态,不可点击
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/linkbug.php b/module/productplan/test/model/linkbug.php
new file mode 100755
index 0000000000..4f1f088be4
--- /dev/null
+++ b/module/productplan/test/model/linkbug.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+linkBug()
+cid=1
+pid=1
+
+id为100的计划关联id为3的bug >> 0
+id为100的计划关联id为1和2的bug >> 0
+传入不存在的id >> 0
+解除bugid为1的关联关系 >> 0
+解除bugid为2的关联关系 >> 0
+解除不存在的id >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$planID = array();
+$planID[0] = 100;
+
+$bugID = array();
+$bugID[0] = array('bugs' => array(3));
+$bugID[1] = array('bugs' => array(1, 2));
+$bugID[2] = array('bugs' => array(10000));
+
+$unbugID = array();
+$unbugID[0] = 1;
+$unbugID[1] = 2;
+$unbugID[2] = 10000;
+
+r($plan->linkBug($planID[0], $bugID[0])) && p() && e('0'); //id为100的计划关联id为3的bug
+r($plan->linkBug($planID[0], $bugID[1])) && p() && e('0'); //id为100的计划关联id为1和2的bug
+r($plan->linkBug($planID[0], $bugID[2])) && p() && e('0'); //传入不存在的id
+r($plan->unlinkBug($planID[0], $unbugID[0])) && p() && e('0'); //解除bugid为1的关联关系
+r($plan->unlinkBug($planID[0], $unbugID[1])) && p() && e('0'); //解除bugid为2的关联关系
+r($plan->unlinkBug($planID[0], $unbugID[2])) && p() && e('0'); //解除不存在的id
+?>
diff --git a/module/productplan/test/model/linkproject.php b/module/productplan/test/model/linkproject.php
new file mode 100755
index 0000000000..993857dfa8
--- /dev/null
+++ b/module/productplan/test/model/linkproject.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+linkProject();
+cid=1
+pid=1
+
+项目ID=3关联计划ID为11,12的产品计划 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+r($plan->linkProject(13, array(11 ,12))) && p() && e('0'); //项目ID=3关联计划ID为11,12的产品计划
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/linkstory.php b/module/productplan/test/model/linkstory.php
new file mode 100755
index 0000000000..21fdaed66c
--- /dev/null
+++ b/module/productplan/test/model/linkstory.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+linkStory();
+cid=1
+pid=1
+
+关联计划id为100的需求4 >> 0
+关联计划id为101的需求8 >> 0
+传入不存在id的情况 >> 0
+解除id为100关联需求4 >> 0
+解除id为101关联需求8 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$planID = array();
+$planID[0] = 100;
+$planID[1] = 101;
+$planID[2] = 10000;
+
+$storyID = array();
+$storyID[0] = array('stories' => array(4));
+$storyID[1] = array('stories' => array(8));
+$storyID[2] = array('stories' => array(1111));
+
+$unstoryID = array();
+$unstoryID[0] = 4;
+$unstoryID[1] = 8;
+$unstoryID[2] = 1111;
+
+#方法没有return返回结果,页面上看关联成功了,成功失败均返回空
+r($plan->linkStory($planID[0], $storyID[0])) && p() && e('0'); //关联计划id为100的需求4
+r($plan->linkStory($planID[1], $storyID[1])) && p() && e('0'); //关联计划id为101的需求8
+r($plan->linkStory($planID[2], $storyID[2])) && p() && e('0'); //传入不存在id的情况
+
+#这里将另一个同类方法unlinkStory放在这里调用
+r($plan->unlinkStory($unstoryID[0], $planID[0])) && p() && e('0'); //解除id为100关联需求4
+r($plan->unlinkStory($unstoryID[1], $planID[1])) && p() && e('0'); //解除id为101关联需求8
+?>
diff --git a/module/productplan/test/model/reorderchildren.php b/module/productplan/test/model/reorderchildren.php
new file mode 100755
index 0000000000..c6150cdc2d
--- /dev/null
+++ b/module/productplan/test/model/reorderchildren.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+reorder4Children();
+cid=1
+pid=1
+
+传入三个子计划id100,102,101,排序第一个 >> 100
+第二个 >> 101
+第三个,会输出正序排列的数组100,101,102 >> 102
+传入不存在的id时 >> 0
+
+*/
+
+$plan = new productPlan('admin');
+
+$planID = array();
+$planID[0] = array(100, 102, 101);
+$planID[1] = array(1000, 10000);
+
+r($plan->reorder4Children($planID[0])) && p('100:id') && e('100'); //传入三个子计划id100,102,101,排序第一个
+r($plan->reorder4Children($planID[0])) && p('101:id') && e('101'); //第二个
+r($plan->reorder4Children($planID[0])) && p('102:id') && e('102'); //第三个,会输出正序排列的数组100,101,102
+r($plan->reorder4Children($planID[1])) && p() && e('0'); //传入不存在的id时
+?>
\ No newline at end of file
diff --git a/module/productplan/test/model/unlinkstory.php b/module/productplan/test/model/unlinkstory.php
new file mode 100755
index 0000000000..870daa8d0b
--- /dev/null
+++ b/module/productplan/test/model/unlinkstory.php
@@ -0,0 +1,8 @@
+#!/usr/bin/env php
+
diff --git a/module/productplan/test/model/update.php b/module/productplan/test/model/update.php
new file mode 100755
index 0000000000..ab99e6cddf
--- /dev/null
+++ b/module/productplan/test/model/update.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+修改planId=5的数据,打印出旧的名称 >> 1.1
+二次修改旧的数据,由于数据发生变化,理应失败 >> 0
+测试传入结束时间小于开始时间的情况 >> 父计划[测试修改]的完成日期:2021-10-10,不能小于子计划的完成日期: 2022-04-01
+
+*/
+$plan = new productPlan('admin');
+
+$planId = array();
+$planId[0] = 5;
+$planId[1] = 6;
+
+$posts = array();
+$posts['title'] = '测试修改';
+$posts['status'] = 'doing';
+$posts['begin'] = '2021-03-22';
+$posts['end'] = '2022-10-31';
+$posts['uid'] = '';
+$posts['product'] = '2';
+
+$late = $posts;
+$late['end'] = '2021-10-10';
+
+r($plan->update($planId[0], $posts)) && p('0:old') && e('1.1'); //修改planId=5的数据,打印出旧的名称
+r($plan->update($planId[0], $posts)) && p('0:old') && e('0'); //二次修改旧的数据,由于数据发生变化,理应失败
+r($plan->update($planId[0], $late)) && p('end') && e('父计划[测试修改]的完成日期:2021-10-10,不能小于子计划的完成日期: 2022-04-01'); //测试传入结束时间小于开始时间的情况
+?>
diff --git a/module/productplan/test/model/updateparentstatus.php b/module/productplan/test/model/updateparentstatus.php
new file mode 100755
index 0000000000..6fd102047e
--- /dev/null
+++ b/module/productplan/test/model/updateparentstatus.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+updateParentStatus();
+cid=1
+pid=1
+
+将id为1的计划改为wait状态 >> 0
+将id为2的计划改为doing状态 >> 1
+将id为3的计划改为closed状态 >> 1
+将id为4的计划改为done状态 >> 1
+
+*/
+$plan = new productPlan('admin');
+
+$parentId = array();
+$parentid[0] = 1;
+$parentid[1] = 2;
+$parentid[2] = 3;
+$parentid[3] = 4;
+
+#此方法将父级plan状态改为与子plan相同的状态
+r($plan->updateParentStatus($parentid[0])) && p() && e('0'); //将id为1的计划改为wait状态
+r($plan->updateParentStatus($parentid[1])) && p() && e('1'); //将id为2的计划改为doing状态
+r($plan->updateParentStatus($parentid[2])) && p() && e('1'); //将id为3的计划改为closed状态
+r($plan->updateParentStatus($parentid[3])) && p() && e('1'); //将id为4的计划改为done状态
+?>
diff --git a/module/productplan/test/model/updatestatus.php b/module/productplan/test/model/updatestatus.php
new file mode 100755
index 0000000000..f90c8d584f
--- /dev/null
+++ b/module/productplan/test/model/updatestatus.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+updateStatus();
+cid=1
+pid=1
+
+修改id=5的状态为doing >> 1
+修改状态为done >> 1
+修改状态为closed >> 1
+
+*/
+$plan = new productPlan('admin');
+
+$planId = array();
+$planId[0] = 5;
+$planId[1] = 'doing';
+$planId[2] = 'done';
+$planId[3] = 'closed';
+$planId[4] = 'started';
+$planId[5] = 'finished';
+$planId[6] = 'closed';
+$planId[7] = 'activated';
+
+r($plan->updateStatus($planId[0], $planId[1], $planId[4])) && p() && e('1'); //修改id=5的状态为doing
+r($plan->updateStatus($planId[0], $planId[2], $planId[5])) && p() && e('1'); //修改状态为done
+r($plan->updateStatus($planId[0], $planId[3], $planId[6])) && p() && e('1'); //修改状态为closed
+?>
diff --git a/module/productplan/test/productplan.class.php b/module/productplan/test/productplan.class.php
new file mode 100644
index 0000000000..fc790c2d99
--- /dev/null
+++ b/module/productplan/test/productplan.class.php
@@ -0,0 +1,461 @@
+productplan = $tester->loadModel('productplan');
+ }
+
+ /**
+ * Get by ID plan
+ *
+ * @param int mixed $planID
+ * @param bool mixed $setImgSize
+ * @access public
+ * @return array
+ */
+ public function getByIDPlan($planID, $setImgSize = false)
+ {
+ $productplans = $this->productplan->getByID($planID, $setImgSize = false);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get by ID list
+ *
+ * @param array(int) mixed $planIDList
+ * @access public
+ * @return array
+ */
+ public function getByIDList($planIDList)
+ {
+ $productplans = $this->productplan->getByIDList($planIDList);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get last
+ *
+ * @param int mixed $productID
+ * @param int $branch
+ * @param int $parent
+ * @access public
+ * @return array
+ */
+ public function getLast($productID, $branch = 0, $parent = 0)
+ {
+ $productplans = $this->productplan->getLast($productID, $parent);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get list
+ *
+ * @param int $product
+ * @param int $branch
+ * @param string $browseType
+ * @param mixed $pager
+ * @param string $orderBy
+ * @param string $param
+ * @access public
+ * @return array
+ */
+ public function getList($product = 0, $branch = 0, $browseType = 'undone', $pager = null, $orderBy = 'begin_desc', $param = '')
+ {
+ $productplans = $this->productplan->getList($product, $branch, $browseType, $pager, $orderBy, $param);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get pairs
+ *
+ * @param int $product
+ * @param string $branch
+ * @param string $expired
+ * @param bool mixed $skipParent
+ * @access public
+ * @return array
+ */
+ public function getPairs($product, $branch = '', $expired = '', $skipParent = false)
+ {
+ $productplans = $this->productplan->getPairs($product, $branch = '', $expired = '', $skipParent = false);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get pairs for story
+ *
+ * @param mrray|int mixed $product
+ * @param int mixed $branch
+ * @param string mixed $param
+ * @access public
+ * @return count
+ */
+ public function getPairsForStory($product, $branch, $param)
+ {
+ $productplans = $this->productplan->getPairsForStory($product, $branch, $param);
+ if(dao::isError()) return dao::getError();
+ return count($productplans) - 1;
+ }
+
+ /**
+ * Get for products
+ *
+ * @param array(int) mixed $products
+ * @access public
+ * @return count
+ */
+ public function getForProducts($products)
+ {
+ $productplans = $this->productplan->getForProducts($products);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get group by product
+ *
+ * @param array(int) mixed $products
+ * @param string mixed $param
+ * @param string $field
+ * @param string $orderBy
+ * @access public
+ * @return count
+ */
+ public function getGroupByProduct($products, $param, $field = 'name', $orderBy = 'id_desc')
+ {
+ $productplans = $this->productplan->getGroupByProduct($products, $param, $field, $orderBy);
+ if(dao::isError()) return dao::getError();
+ return count($productplans);
+ }
+
+ /**
+ * Get children
+ *
+ * @param int mixed $planID
+ * @access public
+ * @return count
+ */
+ public function getChildren($planID)
+ {
+ $productplans = $this->productplan->getChildren($planID);
+ if(dao::isError()) return dao::getError();
+ return count($productplans);
+ }
+
+ /**
+ * Get plans by stories
+ *
+ * @param array(int) mixed $storyIdList
+ * @access public
+ * @return count
+ */
+ public function getPlansByStories($storyIdList)
+ {
+ $productplans = $this->productplan->getPlansByStories($storyIdList);
+ if(dao::isError()) return dao::getError();
+ return count($productplans);
+ }
+
+ /**
+ * Get branch plan pairs
+ *
+ * @param int mixed $productID
+ * @param int mixed $branches
+ * @access public
+ * @return array
+ */
+ public function getBranchPlanPairs($productID, $branches)
+ {
+ $productplans = $this->productplan->getBranchPlanPairs($productID, $branches);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Get top plan pairs
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param int $exclude
+ * @access public
+ * @return array
+ */
+ public function getTopPlanPairsTest($param)
+ {
+ $productID = $param['productID'];
+ $branch = $param['branch'];
+ $exclude = $param['exclude'];
+
+ $planPairs = $this->productplan->getTopPlanPairs($productID, $branch, $exclude);
+
+ if(dao::isError()) return dao::getError();
+
+ return $planPairs;
+ }
+
+ /**
+ * Create
+ *
+ * @param array mixed $param
+ * @access public
+ * @return array
+ */
+ public function create($param)
+ {
+ //初始化传的参数,这里可以设置默认值
+ $createPlan = array('title' => '', 'begin' => '', 'end' => '', 'delta' => '', 'desc' => '', 'uid' => '', 'product' => '', 'parent' => '');
+ //设置foreach循环,将初始化参数传给全局变量$_POST中,通过此方式将传的参数提供给源码create方法
+ foreach($createPlan as $field => $defaultvalue) $_POST[$field] = $defaultvalue;
+ //二次遍历数组将此方法的形参传入$_POST中,这行可以替换掉初始化参数,做到以传入参数为最终结果的目的。同时不传参数的话取默认值
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ //这行代码的作用是调用源码中的方法(参数通过$_POST直接取,具体原理可以不知道)
+ $productPlans = $this->productplan->create();
+ //将方法返回内容返回
+ if(dao::isError()) return dao::getError();
+ return $productPlans;
+ }
+
+ /**
+ * Update
+ *
+ * @param int mixed $planID
+ * @param array mixed $values
+ * @access public
+ * @return array
+ */
+ public function update($planID, $values)
+ {
+ $updatePlan = array('title' => '', 'status' => '', 'begin' => '', 'end' => '', 'desc' => '', 'uid' => '', 'product' => '');
+
+ foreach($updatePlan as $field => $defaultvalue) $_POST[$field] = $defaultvalue;
+ foreach($values as $key =>$value) $_POST[$key] = $value;
+
+ $productplans = $this->productplan->update($planID);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Update status
+ *
+ * @param int mixed $planID
+ * @param string $status
+ * @param string $action
+ * @access public
+ * @return array
+ */
+ public function updateStatus($planID, $status = '', $action = '')
+ {
+ $productplans = $this->productplan->updateStatus($planID, $status, $action);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Update parent status
+ *
+ * @param int mixed $parentId
+ * @access public
+ * @return bool
+ */
+ public function updateParentStatus($parentId)
+ {
+ $productplans = $this->productplan->updateParentStatus($parentId);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Batch update
+ *
+ * @param int mixed $productId
+ * @access public
+ * @return array(array)
+ */
+ public function batchUpdate($productId, $bratch)
+ {
+ $batch = array('id' => array(), 'title' => array(), 'begin' => array(), 'end' => array());
+
+ foreach($batch as $field => $defaultvalue) $_POST[$field] = $defaultvalue;
+ foreach($bratch as $key => $value) $_POST[$key] = $value;
+
+ $productplans = $this->productplan->batchUpdate($productId);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Batch change status
+ *
+ * @param string mixed $status
+ * @access public
+ * @return array
+ */
+ public function batchChangeStatus($status, $planIDList = array('planIDList' => array(4, 5)))
+ {
+ $planID = $planIDList;
+
+ foreach($planID as $field => $defaultvalue) $_POST[$field] = $defaultvalue;
+
+ $productplans = $this->productplan->batchChangeStatus($status);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Change parent field
+ *
+ * @param int mixed $planID
+ * @access public
+ * @return true
+ */
+ public function changeParentField($planID)
+ {
+ $productplans = $this->productplan->changeParentField($planID);
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Link story
+ *
+ * @param int mixed $planID
+ * @param array(stories => array())mixed $storyID
+ * @access public
+ * @return void
+ */
+ public function linkStory($planID, $storyID)
+ {
+
+ foreach($storyID as $key => $value) $_POST[$key] = $value;
+
+ $productplans = $this->productplan->linkStory($planID);
+
+ if(dao::isError()) return dao::getError();
+ return $productplans;
+ }
+
+ /**
+ * Unlink story
+ *
+ * @param int mixed $storyID
+ * @param int mixed $planID
+ * @access public
+ * @return void
+ */
+ public function unlinkStory($storyID, $planID)
+ {
+ $productPlans = $this->productplan->unlinkStory($storyID, $planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productPlans;
+ }
+
+ /**
+ * Link bug
+ *
+ * @param int mixed $planID
+ * @param array mixed $bugID
+ * @access public
+ * @return void
+ */
+ public function linkBug($planID, $bugID)
+ {
+
+ foreach($bugID as $key => $value) $_POST[$key] = $value;
+
+ $productPlans = $this->productplan->linkBug($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productPlans;
+ }
+
+ /**
+ * Unlink bug
+ *
+ * @param int mixed $bugID
+ * @access public
+ * @return void
+ */
+ public function unlinkBug($bugID)
+ {
+ $productplans = $this->productplan->unlinkBug($bugID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productplans;
+ }
+
+ /**
+ * Link project
+ *
+ * @param $projectID mixed $projectID
+ * @param $newPlans mixed $newPlans
+ * @access public
+ * @return void
+ */
+ public function linkProject($projectID, $newPlans)
+ {
+ $productplans = $this->productplan->linkProject($projectID, $newPlans);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productplans;
+ }
+
+ /**
+ * Reorder 4 children
+ *
+ * @param array mixed $plans
+ * @access public
+ * @return array
+ */
+ public function reorder4Children($plans)
+ {
+ $plan = $this->productplan->dao->select('*')->from(TABLE_PRODUCTPLAN)
+ ->where('id')->in($plans)
+ ->andWhere('deleted')->eq(0)
+ ->fetchAll('id');
+
+ $productplans = $this->productplan->reorder4Children($plan);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productplans;
+ }
+
+ /**
+ * Is clickable
+ *
+ * @param int mixed $planID
+ * @param string mixed $action
+ * @access public
+ * @return void
+ */
+ public function isClickable($planID, $action)
+ {
+ $plan = $this->productplan->dao->select('*')->from(TABLE_PRODUCTPLAN)
+ ->where('id')->eq($planID)
+ ->andWhere('deleted')->eq(0)
+ ->fetchAll('id');
+
+ $plans = $plan[$planID];
+ $productplans = $this->productplan->isClickable($plans, $action);
+
+ if(dao::isError()) return dao::getError();
+
+ return $productplans;
+ }
+
+}
+?>
diff --git a/module/program/test/model/accessdenied.php b/module/program/test/model/accessdenied.php
new file mode 100644
index 0000000000..38bf14dd1e
--- /dev/null
+++ b/module/program/test/model/accessdenied.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+> html
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+ob_start();
+$tester->program->accessDenied();
+$result = ob_get_clean();
+
+r(substr($result, 1, 4)) && p() && e('html'); // 权限不足跳转
diff --git a/module/program/test/model/buildoperatemenu.php b/module/program/test/model/buildoperatemenu.php
new file mode 100644
index 0000000000..46d55bccb5
--- /dev/null
+++ b/module/program/test/model/buildoperatemenu.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+su('admin');
+/**
+
+title=测试 programModel::buildOperateMenu();
+cid=1
+pid=1
+
+项目集不存在 >> 0
+项目集存在 >> div
+
+*/
+
+$programTester = new programTest();
+$menus1 = $programTester->buildOperateMenuTest(0);
+$menus2 = $programTester->buildOperateMenuTest(1);
+
+r($menus1) && p() && e('0'); // 项目集不存在
+r(substr($menus2, 1, 3)) && p() && e('div'); // 项目集存在
diff --git a/module/program/test/model/computeprogress.php b/module/program/test/model/computeprogress.php
new file mode 100755
index 0000000000..c8332362f3
--- /dev/null
+++ b/module/program/test/model/computeprogress.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+> 13
+传入任务数组,返回计算后的总预计 >> 15
+传入任务数组,返回计算后的总剩余 >> 7
+传入任务数组,返回计算后的总工时 >> 20
+传入任务数组,返回计算后的进度 >> 65
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+$task1 = new stdclass();
+$task1->consumed = 2;
+$task1->left = 2;
+$task1->estimate = 2;
+$task1->status = 'active';
+
+$task2 = new stdclass();
+$task2->consumed = 4;
+$task2->left = 5;
+$task2->estimate = 6;
+$task2->status = 'active';
+
+$task3 = new stdclass();
+$task3->consumed = 7;
+$task3->left = 7;
+$task3->estimate = 7;
+$task3->status = 'closed';
+
+$tasks[] = $task1;
+$tasks[] = $task2;
+$tasks[] = $task3;
+
+$projectTasks[1] = $tasks;
+
+$hours = $tester->program->computeProgress($projectTasks);
+
+r($hours) && p('1:totalConsumed') && e('13'); // 传入任务数组,返回计算后的总消耗
+r($hours) && p('1:totalEstimate') && e('15'); // 传入任务数组,返回计算后的总预计
+r($hours) && p('1:totalLeft') && e('7'); // 传入任务数组,返回计算后的总剩余
+r($hours) && p('1:totalReal') && e('20'); // 传入任务数组,返回计算后的总工时
+r($hours) && p('1:progress') && e('65'); // 传入任务数组,返回计算后的进度
\ No newline at end of file
diff --git a/module/program/test/model/create.php b/module/program/test/model/create.php
new file mode 100755
index 0000000000..929b0a1854
--- /dev/null
+++ b/module/program/test/model/create.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+id->range('1');
+$program->name->range('父项目集1');
+$program->type->range('program');
+$program->path->range('1')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(1);
+
+/**
+
+title=测试 programModel::create();
+cid=1
+pid=1
+
+创建新项目集 >> 测试新增项目集一
+项目集名称为空时 >> 『项目集名称』不能为空。
+项目集的开始时间为空 >> 『计划开始』不能为空。
+项目集的完成时间为空 >> 『计划完成』不能为空。
+『计划完成』应当大于『2022-01-12』。 >> 『计划完成』应当大于『2022-01-12』。
+
+*/
+
+$programTester = new programTest();
+
+$data = array(
+ 'parent' => 0,
+ 'name' => '测试新增项目集一',
+ 'budget' => '',
+ 'budgetUnit' => 'CNY',
+ 'begin' => '2022-01-12',
+ 'end' => '2022-02-12',
+ 'desc' => '测试项目集描述',
+ 'acl' => 'private',
+ 'whitelist' => ''
+);
+
+$normalProgram = $data;
+
+$emptyNameProgram = $data;
+$emptyNameProgram['name'] = '';
+
+$emptyBeginProgram = $data;
+$emptyBeginProgram['begin'] = '';
+
+$emptyEndProgram = $data;
+$emptyEndProgram['end'] = '';
+
+$beginGtEndProgram = $data;
+$beginGtEndProgram['end'] = '2022-01-10';
+
+r($programTester->createTest($normalProgram)) && p('name') && e('测试新增项目集一'); // 创建新项目集
+r($programTester->createTest($emptyNameProgram)) && p('message[name]:0') && e('『项目集名称』不能为空。'); // 项目集名称为空时
+r($programTester->createTest($emptyBeginProgram)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 项目集的开始时间为空
+r($programTester->createTest($emptyEndProgram)) && p('message[end]:0') && e('『计划完成』不能为空。'); // 项目集的完成时间为空
+r($programTester->createTest($beginGtEndProgram)) && p('message[end]:0') && e('『计划完成』应当大于『2022-01-12』。'); // 『计划完成』应当大于『2022-01-12』。
diff --git a/module/program/test/model/createdefaultprogram.php b/module/program/test/model/createdefaultprogram.php
new file mode 100644
index 0000000000..b5ed218694
--- /dev/null
+++ b/module/program/test/model/createdefaultprogram.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+> 1
+
+*/
+
+$programTester = new programTest();
+
+$result = $programTester->createDefaultProgramTest();
+
+r($result) && p('') && e('1'); // 创建默认项目集
diff --git a/module/program/test/model/createstakeholder.php b/module/program/test/model/createstakeholder.php
new file mode 100755
index 0000000000..6c8985513f
--- /dev/null
+++ b/module/program/test/model/createstakeholder.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+id->range('1');
+$program->name->range('父项目集1');
+$program->type->range('program');
+$program->path->range('1')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(1);
+
+/**
+
+title=测试 programModel::createStakeholder();
+cid=1
+pid=1
+
+创建id=1的项目集的干系人并查看数量。 >> 2
+创建id=1的项目集的干系人dev1,dev2并查看Account。 >> dev1;dev2
+
+*/
+
+$programTester = new programTest();
+
+$accounts = array('dev1', 'dev2');
+$result = $programTester->createStakeholderTest(1, $accounts);
+
+r(count($result)) && p('') && e('2'); // 创建id=1的项目集的干系人并查看数量。
+r($result) && p('0:account;1:account') && e('dev1;dev2'); // 创建id=1的项目集的干系人dev1,dev2并查看Account。
diff --git a/module/program/test/model/getbudgetleft.php b/module/program/test/model/getbudgetleft.php
new file mode 100755
index 0000000000..192951d89d
--- /dev/null
+++ b/module/program/test/model/getbudgetleft.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+/**
+
+title=测试 programModel::getBudgetLeft();
+cid=1
+pid=1
+
+查看项目集1的所有父项目集的预算剩余 >> 900000
+查看项目集2的所有父项目集的预算剩余 >> 899900
+
+*/
+
+$programTester = new programTest();
+$result1 = $programTester->getBudgetLeftTest(1);
+$result2 = $programTester->getBudgetLeftTest(2);
+
+r($result1) && p() && e('900000'); // 查看项目集1的所有父项目集的预算剩余
+r($result2) && p() && e('899900'); // 查看项目集2的所有父项目集的预算剩余
diff --git a/module/program/test/model/getbyid.php b/module/program/test/model/getbyid.php
new file mode 100755
index 0000000000..b8a1dd4e34
--- /dev/null
+++ b/module/program/test/model/getbyid.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+id->range('1-10');
+$program->type->range('program');
+$program->name->setFields(array(
+ array('field' => 'name1', 'range' => '项目集'),
+ array('field' => 'name2', 'range' => '1-10')
+));
+$program->gen(5);
+
+/**
+
+title=测试 programModel::getById();
+cid=1
+pid=1
+
+通过id字段获取id=1的项目集并验证它的name。 >> 项目集1
+通过id字段获取id=1000的项目集,返回空 >> 0
+通过id字段获取id=0的项目集,返回空 >> 0
+
+*/
+
+$programTester = new programTest();
+
+$program1 = $programTester->getByIDTest(1);
+$program2 = $programTester->getByIDTest(1000);
+$program3 = $programTester->getByIDTest(0);
+
+r($program1) && p('name') && e('项目集1'); // 通过id字段获取id=1的项目集并验证它的name。
+r($program2) && p() && e('0'); // 通过id字段获取id=1000的项目集,返回空
+r($program3) && p() && e('0'); // 通过id字段获取id=0的项目集,返回空
diff --git a/module/program/test/model/getchildren.php b/module/program/test/model/getchildren.php
new file mode 100755
index 0000000000..d7f59dc1e7
--- /dev/null
+++ b/module/program/test/model/getchildren.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+id->range('1-3');
+$program->name->range('父项目集1,子项目集1,子项目集2');
+$program->parent->range('0,1,1');
+$program->grade->range('1,2,2');
+$program->type->range('program');
+$program->path->range('`,1,`,`,1,2,`,`,1,3,`');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(3);
+
+/**
+
+title=测试 programModel:: getChildren();
+cid=1
+pid=1
+
+通过id查找id=1的子项目集个数 >> 2
+
+*/
+
+$programTester = new programTest();
+
+r($programTester->getChildrenTest(1)) && p() && e('2'); // 通过id查找id=1的子项目集个数
diff --git a/module/program/test/model/getinvolvedprograms.php b/module/program/test/model/getinvolvedprograms.php
new file mode 100755
index 0000000000..b2731b89e2
--- /dev/null
+++ b/module/program/test/model/getinvolvedprograms.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+id->range('1-3');
+$program->name->range('1-3')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-3')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(3);
+
+/**
+
+title=测试 programModel::getInvolvedPrograms();
+cid=1
+pid=1
+
+获取admin参与的项目集数量 >> 2
+获取test1参与的项目集数量 >> 1
+获取admin参与的项目集ID >> 1
+获取test1参与的项目集ID >> 2
+
+*/
+
+$programTester = new programTest();
+$adminPrograms = $programTester->getInvolvedProgramsTest('admin');
+$test1Programs = $programTester->getInvolvedProgramsTest('test1');
+
+r(count($adminPrograms)) && p() && e('2'); // 获取admin参与的项目集数量
+r(count($test1Programs)) && p() && e('1'); // 获取test1参与的项目集数量
+r($adminPrograms) && p('1') && e('1'); // 获取admin参与的项目集ID
+r($test1Programs) && p('2') && e('2'); // 获取test1参与的项目集ID
diff --git a/module/program/test/model/getkanbangroup.php b/module/program/test/model/getkanbangroup.php
new file mode 100755
index 0000000000..4844827db7
--- /dev/null
+++ b/module/program/test/model/getkanbangroup.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+id->range('1-3');
+$program->name->range('1-3')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-3')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->status->range('wait');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(3);
+
+/**
+
+title=测试 programModel::getKanbanGroup();
+cid=1
+pid=1
+
+查看当前用户负责的项目集看板数量 >> 2
+查看当前用户其他的项目集看板数量 >> 1
+查看当前用户其他的项目集看板详情 >> 项目集2
+
+*/
+
+$programTester = new programTest();
+
+$kanbanGroup = $programTester->getKanbanGroupTest();
+
+r(count($kanbanGroup['my'])) && p('') && e('2'); //查看当前用户负责的项目集看板数量
+r(count($kanbanGroup['others'])) && p('') && e('1'); //查看当前用户其他的项目集看板数量
+r($kanbanGroup['others']) && p('0:name') && e('项目集2'); //查看当前用户其他的项目集看板详情
diff --git a/module/program/test/model/getlink.php b/module/program/test/model/getlink.php
new file mode 100644
index 0000000000..54ca2f718d
--- /dev/null
+++ b/module/program/test/model/getlink.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+> project
+非项目集页面跳转项目集列表 >> all
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+$link1 = $tester->program->getLink('program', 'project', 1);
+$result = '';
+if(strpos($link1, 'project')) $result = 'project';
+r($result) && p() && e('project'); // 项目集页面跳转项目集项目列表
+
+$link2 = $tester->program->getLink('program', 'project', 1, '', 'product');
+if(strpos($link2, 'all')) $result = 'all';
+r($result) && p() && e('all'); // 非项目集页面跳转项目集列表
diff --git a/module/program/test/model/getlist.php b/module/program/test/model/getlist.php
new file mode 100755
index 0000000000..0ac9544592
--- /dev/null
+++ b/module/program/test/model/getlist.php
@@ -0,0 +1,60 @@
+#!/usr/bin/env php
+id->range('1-20');
+$program->name->range('1-20')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-20')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->status->range('wait,doing,suspended,closed');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(20);
+
+/**
+
+title=测试 programModel::getList();
+cid=1
+pid=1
+
+查看所有项目和项目集的个数 >> 20
+查看分页后项目集和项目的个数 >> 10
+查看所有'closed'的项目和项目集的个数 >> 5
+查看所有'suspended'的项目和项目集的个数 >> 5
+按照项目和项目集名称倒序获取第一个ID >> 9
+按照ID正序获取项目和项目集列表第一个ID >> 1
+获取顶级项目集个数 >> 20
+获取分页后顶级项目集个数 >> 10
+获取所有项目集个数 >> 20
+
+*/
+
+global $tester;
+$programTester = new programTest();
+$tester->app->loadClass('pager', $static = true);
+$pager = new pager(0, 10, 1);
+
+$allPorgrams = $programTester->getListTest('all');
+$pagerPrograms = $programTester->getListTest('all', 'id_asc', $pager);
+$closedPrograms = $programTester->getListTest('closed');
+$suspendedPrograms = $programTester->getListTest('closed');
+$namedescPrograms = $programTester->getListTest('all', 'name_desc');
+$idascPrograms = $programTester->getListTest('all', 'id_asc');
+$topPrograms = $programTester->getListTest('all', 'id_asc', null, 'top');
+$topPagePrograms = $programTester->getListTest('all', 'id_asc', $pager, 'top');
+$childPrograms = $programTester->getListTest('all', 'id_asc', null, 'child', $topPrograms);
+
+r(count($allPorgrams)) && p() && e('20'); // 查看所有项目和项目集的个数
+r(count($pagerPrograms)) && p() && e('10'); // 查看分页后项目集和项目的个数
+r(count($closedPrograms)) && p() && e('5'); // 查看所有'closed'的项目和项目集的个数
+r(count($suspendedPrograms)) && p() && e('5'); // 查看所有'suspended'的项目和项目集的个数
+r(key($namedescPrograms)) && p() && e('9'); // 按照项目和项目集名称倒序获取第一个ID
+r(key($idascPrograms)) && p() && e('1'); // 按照ID正序获取项目和项目集列表第一个ID
+r(count($topPrograms)) && p() && e('20'); // 获取顶级项目集个数
+r(count($topPagePrograms)) && p() && e('10'); // 获取分页后顶级项目集个数
+r(count($childPrograms)) && p() && e('20'); // 获取所有项目集个数
diff --git a/module/program/test/model/getlistbysearch.php b/module/program/test/model/getlistbysearch.php
new file mode 100644
index 0000000000..d445dc5b92
--- /dev/null
+++ b/module/program/test/model/getlistbysearch.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$program = zdTable('project');
+$program->id->range('1-20');
+$program->name->range('1-20')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-20')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->status->range('wait,doing,suspended,closed');
+$program->openedBy->range('admin,user1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(20);
+
+$query = zdTable('userquery');
+$query->id->range('1');
+$query->account->range('admin');
+$query->module->range('program');
+$query->title->range('搜索条件1');
+$query->form->range('`a:41:{s:9:"fieldname";s:0:"";s:11:"fieldstatus";s:0:"";s:9:"fielddesc";s:0:"";s:7:"fieldPM";s:0:"";s:15:"fieldopenedDate";s:0:"";s:10:"fieldbegin";s:0:"";s:8:"fieldend";s:0:"";s:13:"fieldopenedBy";s:0:"";s:19:"fieldlastEditedDate";s:0:"";s:14:"fieldrealBegan";s:0:"";s:12:"fieldrealEnd";s:0:"";s:15:"fieldclosedDate";s:0:"";s:6:"andOr1";s:3:"AND";s:6:"field1";s:4:"name";s:9:"operator1";s:7:"include";s:6:"value1";s:9:"项目集";s:6:"andOr2";s:3:"and";s:6:"field2";s:6:"status";s:9:"operator2";s:1:"=";s:6:"value2";s:0:"";s:6:"andOr3";s:3:"and";s:6:"field3";s:4:"desc";s:9:"operator3";s:7:"include";s:6:"value3";s:0:"";s:10:"groupAndOr";s:3:"and";s:6:"andOr4";s:3:"AND";s:6:"field4";s:6:"status";s:9:"operator4";s:1:"=";s:6:"value4";s:4:"wait";s:6:"andOr5";s:3:"and";s:6:"field5";s:10:"openedDate";s:9:"operator5";s:1:"=";s:6:"value5";s:0:"";s:6:"andOr6";s:3:"and";s:6:"field6";s:5:"begin";s:9:"operator6";s:1:"=";s:6:"value6";s:0:"";s:6:"module";s:7:"program";s:9:"actionURL";s:56:"/program-browse-bySearch-order_asc-0-10-1-myQueryID.html";s:10:"groupItems";s:1:"3";s:8:"formType";s:4:"lite";}`');
+$query->sql->range("`(( 1 AND `name` LIKE '%项目集%' ) AND ( 1 AND `status` = 'wait' ))`");
+$query->gen(1);
+
+/**
+
+title=测试 programModel::getListBySearch();
+cid=1
+pid=1
+
+按照id倒序查看,所有名称包含项目集并且未开始的第一个项目集 >> 项目集17
+按照id正序查看,所有名称包含项目集并且进行中的第一个项目集 >> 项目集1
+按照id正序查看,符合搜索条件id=1,的第一个项目集 >> 项目集1
+
+*/
+
+global $tester;
+$programTester = new programTest();
+
+$sql1 = "(( 1 AND `name` LIKE '%项目集%' ) AND ( 1 AND `status` = 'wait' ))";
+$sql2 = "(( 1 AND `name` LIKE '%项目集%' ) AND ( 1 AND `status` = 'doing' ))";
+
+r($programTester->getListBySearchTest('id_desc', 0, $sql)) && p('17:name') && e('项目集17'); // 按照id倒序查看,所有名称包含项目集并且未开始的第一个项目集
+r($programTester->getListBySearchTest('id_asc', 0, $sql)) && p('1:name') && e('项目集1'); // 按照id正序查看,所有名称包含项目集并且进行中的第一个项目集
+r($programTester->getListBySearchTest('id_asc', 1)) && p('1:name') && e('项目集1'); // 按照id正序查看,符合搜索条件id=1,的第一个项目集
diff --git a/module/program/test/model/getpairs.php b/module/program/test/model/getpairs.php
new file mode 100755
index 0000000000..ee079fdbd8
--- /dev/null
+++ b/module/program/test/model/getpairs.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+id->range('1-20');
+$program->name->range('1-20')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-20')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->status->range('wait,doing,suspended,closed');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->deleted->range('0{15},1{5}');
+$program->gen(20);
+
+/**
+
+title=测试 programModel::getPairs();
+cid=1
+pid=1
+
+获取项目集个数 >> 15
+获取所有项目集个数 >> 15
+获取按照id正序的第一个项目集名称 >> 项目集1
+
+*/
+
+$programTester = new programTest();
+
+$programs1 = $programTester->getPairsTest();
+$programs2 = $programTester->getPairsTest('true');
+$programs3 = $programTester->getPairsTest('false', 'id_asc');
+
+r(count($programs1)) && p() && e('15'); // 获取项目集个数
+r(count($programs2)) && p() && e('15'); // 获取所有项目集个数
+r(current($programs3)) && p('1') && e('项目集1'); // 获取按照id正序的第一个项目集名称
diff --git a/module/program/test/model/getpairsbylist.php b/module/program/test/model/getpairsbylist.php
new file mode 100755
index 0000000000..3b9bd0f68a
--- /dev/null
+++ b/module/program/test/model/getpairsbylist.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+id->range('1-10');
+$program->name->range('1-10')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-10')->prefix(',')->postfix(',');
+$program->grade->range('1');
+$program->status->range('wait,doing,suspended,closed');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(10);
+
+/**
+
+title=测试 programModel::getPairsByList();
+cid=1
+pid=1
+
+通过字符串'1'获取项目集名称 >> 项目集1
+通过字符串'1,2,3'获取项目集名称 >> 项目集1,项目集2,项目集3
+通过数组array(1)获取项目集名称 >> 项目集1
+通过数组array(1,2,3)获取项目集名称 >> 项目集1,项目集2,项目集3
+通过id为空获取项目集名称 >> 0
+通过id=0获取项目集名称 >> 0
+通过id=11获取项目集名称 >> 0
+
+*/
+
+$programTester = new programTest();
+$programIdList = array('1', '1,2,3', array(1), array(1,2,3), '', '0', '11');
+
+r($programTester->getPairsByListTest($programIdList[0])) && p('1') && e('项目集1'); // 通过字符串'1'获取项目集名称
+r($programTester->getPairsByListTest($programIdList[1])) && p('1,2,3') && e('项目集1,项目集2,项目集3'); // 通过字符串'1,2,3'获取项目集名称
+r($programTester->getPairsByListTest($programIdList[2])) && p('1') && e('项目集1'); // 通过数组array(1)获取项目集名称
+r($programTester->getPairsByListTest($programIdList[3])) && p('1,2,3') && e('项目集1,项目集2,项目集3'); // 通过数组array(1,2,3)获取项目集名称
+r($programTester->getPairsByListTest($programIdList[4])) && p('') && e('0'); // 通过id为空获取项目集名称
+r($programTester->getPairsByListTest($programIdList[5])) && p('') && e('0'); // 通过id=0获取项目集名称
+r($programTester->getPairsByListTest($programIdList[6])) && p('') && e('0'); // 通过id=11获取项目集名称
diff --git a/module/program/test/model/getparentpairs.php b/module/program/test/model/getparentpairs.php
new file mode 100755
index 0000000000..384d12efa3
--- /dev/null
+++ b/module/program/test/model/getparentpairs.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+id->range('1-10');
+$program->name->setFields(array(
+ array('field' => 'name1', 'range' => '项目集{5},项目{5}'),
+ array('field' => 'name2', 'range' => '1-5'),
+));
+$program->type->range('program{5},project{5}');
+$program->path->range('1-5,`1,6`,`2,7`,`3,8`,`4,9`,`5,10`')->prefix(',')->postfix(',');
+$program->grade->range('1{5},2{5}');
+$program->parent->range('0{5},1-5');
+$program->status->range('wait,doing,suspended,closed');
+$program->model->range('[]{5},scrum{2},waterfall{2},kanban');
+$program->openedBy->range('admin,test1');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->deleted->range('0{15},1{5}');
+$program->gen(10);
+
+/**
+
+title=测试 programModel::getParentPairs();
+cid=1
+pid=1
+
+获取所有父项目集的数量 >> 5
+获取瀑布类型父项目集的数量 >> 1
+获取ID为1的父项目集的名称 >> /项目集1
+获取父项目集的名称显示根目录 >> 0
+获取ID为1的父项目集的名称不显示根目录 >> 项目集1
+
+*/
+
+$programTester = new programTest();
+
+$program1 = $programTester->getParentPairsTest();
+$program2 = $programTester->getParentPairsTest('waterfall');
+$program3 = $programTester->getParentPairsTest('', 'noclosed', false);
+
+r(count($program1)) && p() && e('5'); // 获取所有父项目集的数量
+r(count($program2)) && p() && e('1'); // 获取瀑布类型父项目集的数量
+r($program1) && p('1') && e('/项目集1'); // 获取ID为1的父项目集的名称
+r(key($program1)) && p('0') && e('0'); // 获取父项目集的名称显示根目录
+r(array_shift($program3)) && p() && e('项目集1'); // 获取ID为1的父项目集的名称不显示根目录
diff --git a/module/program/test/model/getparentpm.php b/module/program/test/model/getparentpm.php
new file mode 100755
index 0000000000..59a238d5b8
--- /dev/null
+++ b/module/program/test/model/getparentpm.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+id->range('1-10');
+$program->name->range('1-10')->prefix('项目集');
+$program->type->range('program');
+$program->path->range('1-5,`1,6`,`2,7`,`3,8`,`4,9`,`5,10`')->prefix(',')->postfix(',');
+$program->grade->range('1{5},2{5}');
+$program->parent->range('0{5},1-5');
+$program->status->range('wait,doing,suspended,closed');
+$program->openedBy->range('admin,test1');
+$program->pm->range('admin,test1');
+$program->acl->range('private');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->deleted->range('0{15},1{5}');
+$program->gen(10);
+
+/**
+
+title=测试 programModel::getParentPM();
+cid=1
+pid=1
+
+获取父项目集的负责人数量 >> 2
+获取父项目集的负责人account >> admin
+获取父项目集的负责人account >> test1
+
+*/
+
+$programTester = new programTest();
+
+$programIdList = array(5, 6, 7);
+$parentPM = $programTester->getParentPMTest($programIdList);
+
+r(count($parentPM)) && p() && e('2'); // 获取父项目集的负责人数量
+r($parentPM) && p('6:admin') && e('admin'); // 获取父项目集的负责人account
+r($parentPM) && p('7:test1') && e('test1'); // 获取父项目集的负责人account
diff --git a/module/program/test/model/getproductpairs.php b/module/program/test/model/getproductpairs.php
new file mode 100755
index 0000000000..6aef759a7e
--- /dev/null
+++ b/module/program/test/model/getproductpairs.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+id->range('1');
+$program->name->range('项目集1');
+$program->type->range('program');
+$program->grade->range('1');
+$program->path->range('1')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(1);
+
+/* Create product data. */
+$product = zdTable('product');
+$product->id->range('1-10');
+$product->name->range('1-10')->prefix('产品');
+$product->program->range('1');
+$product->type->range('normal');
+$product->status->range('normal,closed');
+$product->vision->range('rnd');
+$product->gen(10);
+
+/**
+
+title=测试 programModel::getProductPairs();
+cid=1
+pid=1
+
+获取项目集1下的所有产品数量 >> 10
+根据项目集ID获取关联产品名字 >> 产品2
+获取项目集1下的未关闭的产品数量 >> 5
+根据项目或项目集ID获取关联产品详情 >> 产品3
+
+*/
+
+$programTester = new programTest();
+
+$products1 = $programTester->getProductPairsTest(1, 'assign', 'all');
+$products2 = $programTester->getProductPairsTest(1, 'assign', 'noclosed');
+
+r(count($products1)) && p() && e('10'); // 获取项目集1下的所有产品数量
+r($products1) && p('2') && e('产品2'); // 根据项目集ID获取关联产品名字
+r(count($products2)) && p() && e('5'); // 获取项目集1下的未关闭的产品数量
+r($products2) && p('3') && e('产品3'); // 根据项目或项目集ID获取关联产品详情
diff --git a/module/program/test/model/getprogresslist.php b/module/program/test/model/getprogresslist.php
new file mode 100755
index 0000000000..dda2fe451f
--- /dev/null
+++ b/module/program/test/model/getprogresslist.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+id->range('1-8');
+$program->name->setFields(array(
+ array('field' => 'name1', 'range' => '项目集{2},项目{3},迭代{3}'),
+ array('field' => 'name2', 'range' => '1-8')
+));
+$program->type->range('program{2},project{3},sprint{3}');
+$program->status->range('doing');
+$program->parent->range('0,0,1,1,2,3,4,5');
+$program->grade->range('1{2},2{3},1{3}');
+$program->project->range('0{5},3-5');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`,`3,6`,`4,7`,`5,8`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20230212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(8);
+
+$task = zdTable('task');
+$task->name->prefix('任务')->range('1-3');
+$task->project->range('3-5');
+$task->execution->range('6-8');
+$task->estimate->range('6-8');
+$task->consumed->range('1,3,2');
+$task->left->range('5,4,6');
+$task->status->range('doing');
+$task->assignedTo->range('admin');
+$task->gen(3);
+
+/**
+
+title=测试 programModee::getProgressList();
+cid=1
+pid=1
+
+获取项目和项目集的个数 >> 5
+获取id=2的项目的进度 >> 25
+获取id=4的项目集的进度 >> 43
+
+*/
+
+$programTester = new programTest();
+$progressList = $programTester->getProgressListTest();
+
+r(count($progressList)) && p() && e('5'); // 获取项目和项目集的个数
+r($progressList) && p('2') && e('25'); // 获取id=2的项目的进度
+r($progressList) && p('4') && e('43'); // 获取id=4的项目集的进度
diff --git a/module/program/test/model/getprojectlist.php b/module/program/test/model/getprojectlist.php
new file mode 100755
index 0000000000..e15ec69566
--- /dev/null
+++ b/module/program/test/model/getprojectlist.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2,项目1,项目2,项目3');
+$program->type->range('program{2},project{3}');
+$program->status->range('doing{3},closed,doing');
+$program->parent->range('0,0,1,1,2');
+$program->grade->range('1{2},2{3}');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+$team = zdTable('team');
+$team->id->range('1-5');
+$team->root->range('3-5');
+$team->type->range('project');
+$team->account->range('admin');
+$team->account->setFields(array(
+ array('field' => 'account1', 'range' => 'admin,user{4}'),
+ array('field' => 'account2', 'range' => '[],1-4'),
+));
+$team->gen(5);
+
+zdTable('user')->gen(5);
+
+su('admin');
+
+/**
+
+title=测试 programModel::getProjectList();
+cid=1
+pid=1
+
+获取所有项目列表数量 >> 3
+获取未完成项目列表数量 >> 2
+带项目集名称的项目列表数量 >> 2
+获取我参与的项目列表数量 >> 1
+不带项目集名称的项目名称 >> 项目2
+带项目集名称的项目名称 >> 项目集2/项目3
+我参与的项目的名称 >> 项目集1/项目1
+
+*/
+
+$programTester = new programTest();
+
+$allProjects = $programTester->getProjectListTest(0);
+$undoneProjects = $programTester->getProjectListTest(0, 'undone');
+$withProgramProjects = $programTester->getProjectListTest(0, 'undone', 0, 'id_desc', null, 1);
+$involvedProjects = $programTester->getProjectListTest(0, 'undone', 0, 'id_desc', null, 1, true);
+
+r(count($allProjects)) && p() && e('3'); // 获取所有项目列表数量
+r(count($undoneProjects)) && p() && e('2'); // 获取未完成项目列表数量
+r(count($withProgramProjects)) && p() && e('2'); // 带项目集名称的项目列表数量
+r(count($involvedProjects)) && p() && e('1'); // 获取我参与的项目列表数量
+r($allProjects) && p('4:name') && e('项目2'); // 不带项目集名称的项目名称
+r($withProgramProjects) && p('5:name') && e('项目集2/项目3'); // 带项目集名称的项目名称
+r($involvedProjects) && p('3:name') && e('项目集1/项目1'); // 我参与的项目的名称
diff --git a/module/program/test/model/getprojectstats.php b/module/program/test/model/getprojectstats.php
new file mode 100755
index 0000000000..2fd7037495
--- /dev/null
+++ b/module/program/test/model/getprojectstats.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2,项目1,项目2,项目3');
+$program->type->range('program{2},project{3}');
+$program->status->range('doing{3},closed,doing');
+$program->parent->range('0,0,1,1,2');
+$program->grade->range('1{2},2{3}');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+/**
+
+title=测试 programModel::getProjectStats();
+cid=1
+pid=1
+
+查看当前项目集下所有未完成的项目的个数 >> 1
+查看当前项目集下所有未完成的项目的个数 >> 1
+查看当前项目集下所有未完成的项目按照id倒序排的第一个项目集信息 >> 3,项目1
+查看当前项目集下所有未完成的项目按照id正序排的第一个项目集信息 >> 5,项目3
+
+*/
+
+$programTester = new programTest();
+
+$stats1 = $programTester->getProjectStatsTest(1);
+$stats2 = $programTester->getProjectStatsTest(2, 'undone', 0, 'id_asc', null);
+
+r(count($stats1)) && p() && e('1'); // 查看当前项目集下所有未完成的项目的个数
+r(count($stats2)) && p() && e('1'); // 查看当前项目集下所有未完成的项目的个数
+r(current($stats1)) && p('id,name') && e('3,项目1'); // 查看当前项目集下所有未完成的项目按照id倒序排的第一个项目集信息
+r(current($stats2)) && p('id,name') && e('5,项目3'); // 查看当前项目集下所有未完成的项目按照id正序排的第一个项目集信息
diff --git a/module/program/test/model/getstakeholders.php b/module/program/test/model/getstakeholders.php
new file mode 100755
index 0000000000..7044189cdb
--- /dev/null
+++ b/module/program/test/model/getstakeholders.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+zdTable('user')->gen(5);
+
+$stakeholder = zdTable('stakeholder');
+$stakeholder->objectID->range('1,2');
+$stakeholder->objectType->range('program');
+$stakeholder->type->range('inside');
+$stakeholder->user->range('admin,user1,user2');
+$stakeholder->gen(3);
+
+su('admin');
+/**
+
+title=测试 programModel::getStakeholders();
+cid=1
+pid=1
+
+获取干系人数量 >> 2
+获取干系人数量 >> 1
+id倒序排,获取第一个干系人真实姓名 >> 用户2
+id正序排,获取第一个干系人真实姓名 >> 用户1
+
+*/
+
+$programTester = new programTest();
+$stakeholders1 = $programTester->getStakeholdersTest(1, 'id_desc');
+$stakeholders2 = $programTester->getStakeholdersTest(2, 'id_asc');
+
+r(count($stakeholders1)) && p() && e('2'); // 获取干系人数量
+r(count($stakeholders2)) && p() && e('1'); // 获取干系人数量
+r($stakeholders1) && p('0:realname') && e('用户2'); // id倒序排,获取第一个干系人真实姓名
+r($stakeholders2) && p('0:realname') && e('用户1'); // id正序排,获取第一个干系人真实姓名
diff --git a/module/program/test/model/getstakeholdersbyprograms.php b/module/program/test/model/getstakeholdersbyprograms.php
new file mode 100755
index 0000000000..5839306cf3
--- /dev/null
+++ b/module/program/test/model/getstakeholdersbyprograms.php
@@ -0,0 +1,48 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+zdTable('user')->gen(5);
+
+$stakeholder = zdTable('stakeholder');
+$stakeholder->objectID->range('1,2');
+$stakeholder->objectType->range('program');
+$stakeholder->type->range('inside');
+$stakeholder->user->range('admin,user1,user2');
+$stakeholder->gen(3);
+
+su('admin');
+
+/**
+
+title=测试 programModel::getStakeholdersByPrograms();
+cid=1
+pid=1
+
+获取项目集1的干系人名单 >> admin
+获取项目集2的干系人名单 >> user1
+获取项目集1和项目集2的干系人名单 >> admin
+获取项目集1的干系人个数 >> 2
+获取项目集1、2的干系人个数 >> 3
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+
+r($tester->program->getStakeholdersByPrograms('1')) && p('0:account') && e('admin'); // 获取项目集1的干系人名单
+r($tester->program->getStakeholdersByPrograms('2')) && p('0:account') && e('user1'); // 获取项目集2的干系人名单
+r($tester->program->getStakeholdersByPrograms('1,2')) && p('0:account') && e('admin'); // 获取项目集1和项目集2的干系人名单
+r(count($tester->program->getStakeholdersByPrograms('1'))) && p('') && e('2'); // 获取项目集1的干系人个数
+r(count($tester->program->getStakeholdersByPrograms('1,2'))) && p('') && e('3'); // 获取项目集1、2的干系人个数
diff --git a/module/program/test/model/getswitcher.php b/module/program/test/model/getswitcher.php
new file mode 100644
index 0000000000..4fbbdfba8e
--- /dev/null
+++ b/module/program/test/model/getswitcher.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+su('admin');
+/**
+
+title=测试 programModel::saveState();
+cid=1
+pid=1
+
+查看传入空项目集返回的下拉菜单 >> 所有项目集
+查看传入id=1的项目集返回的下拉菜单 >> 父项目集1
+
+*/
+
+$programTester = new programTest();
+$switcher1 = $programTester->getSwitcherTest(0);
+$switcher2 = $programTester->getSwitcherTest(1);
+
+r(strip_tags($switcher1)) && p() && e('所有项目集'); // 查看传入空项目集返回的下拉菜单
+r(strip_tags($switcher2)) && p() && e('父项目集1'); // 查看传入id=1的项目集返回的下拉菜单
diff --git a/module/program/test/model/getteammemberpairs.php b/module/program/test/model/getteammemberpairs.php
new file mode 100755
index 0000000000..6a3a07f2ab
--- /dev/null
+++ b/module/program/test/model/getteammemberpairs.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2,项目1,项目2,项目3');
+$program->type->range('program{2},project{3}');
+$program->status->range('wait');
+$program->parent->range('0,0,1,1,2');
+$program->grade->range('1{2},2{3}');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+$team = zdTable('team');
+$team->id->range('1-5');
+$team->root->range('3-5');
+$team->type->range('project');
+$team->account->range('admin');
+$team->account->setFields(array(
+ array('field' => 'account1', 'range' => 'admin,user{4}'),
+ array('field' => 'account2', 'range' => '[],1-4'),
+));
+$team->gen(5);
+
+zdTable('user')->gen(5);
+
+su('admin');
+
+/**
+
+title=测试 programModel::getTeamMemberPairs();
+cid=1
+pid=1
+
+获取项目集1下所有团队成员数量 >> 5
+获取项目集2下所有团队成员数量 >> 2
+获取项目集1下所有团队成员真实姓名 >> A:admin
+获取项目集2下所有团队成员真实姓名 >> U:用户2
+
+*/
+
+$programTester = new programTest();
+$teams1 = $programTester->getTeamMemberPairsTest(1);
+$teams2 = $programTester->getTeamMemberPairsTest(2);
+
+r(count($teams1)) && p() && e('5'); // 获取项目集1下所有团队成员数量
+r(count($teams2)) && p() && e('2'); // 获取项目集2下所有团队成员数量
+r($teams1) && p('admin') && e('A:admin'); // 获取项目集1下所有团队成员真实姓名
+r($teams2) && p('user2') && e('U:用户2'); // 获取项目集2下所有团队成员真实姓名
diff --git a/module/program/test/model/gettopbyid.php b/module/program/test/model/gettopbyid.php
new file mode 100755
index 0000000000..6bda73ed34
--- /dev/null
+++ b/module/program/test/model/gettopbyid.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+> 1
+获取项目集1000最上级的项目集id >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+$top1 = $tester->program->getTopByID(1);
+$top1000 = $tester->program->getTopByID(1000);
+
+r($top1) && p() && e('1'); //获取项目集1最上级的项目集id
+r($top1000) && p() && e('0'); //获取项目集1000最上级的项目集id
\ No newline at end of file
diff --git a/module/program/test/model/gettopbypath.php b/module/program/test/model/gettopbypath.php
new file mode 100644
index 0000000000..f88d998c09
--- /dev/null
+++ b/module/program/test/model/gettopbypath.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+> 1
+获取子项目集的顶级父项目集 >> 2
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+
+r($tester->program->getTopByPath(',1,')) && p() && e('1'); // 获取顶级项目集的顶级id
+r($tester->program->getTopByPath(',2,3,')) && p() && e('2'); // 获取子项目集的顶级父项目集
diff --git a/module/program/test/model/gettoppairs.php b/module/program/test/model/gettoppairs.php
new file mode 100755
index 0000000000..83f4f1ac9f
--- /dev/null
+++ b/module/program/test/model/gettoppairs.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2');
+$program->type->range('program');
+$program->grade->range('1,1,0{3}');
+$program->status->range('wait,closed,wait{3}');
+$program->parent->range('0,0,1,1,2');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+/**
+
+title=测试 programModel::getTopPairs();
+cid=1
+pid=1
+
+获取系统中所有顶级项目集数量 >> 2
+获取系统中所有未关闭的顶级项目集数量 >> 1
+获取系统中所有顶级项目集数量 >> 2
+
+*/
+
+$programTester = new programTest();
+
+r(count($programTester->getTopPairsTest())) && p() && e('2'); // 获取系统中所有顶级项目集数量
+r(count($programTester->getTopPairsTest('', 'noclosed'))) && p() && e('1'); // 获取系统中所有未关闭的顶级项目集数量
+r(count($programTester->getTopPairsTest('', '', true))) && p() && e('2'); // 获取系统中所有顶级项目集数量
diff --git a/module/program/test/model/gettoppath.php b/module/program/test/model/gettoppath.php
new file mode 100755
index 0000000000..dfdc44f601
--- /dev/null
+++ b/module/program/test/model/gettoppath.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 2
+传入一个path,返回最顶级path >> 100
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+$path1 = ',2,3,4,';
+$path2 = '100,101';
+
+r($tester->program->getTopByPath($path1)) && p() && e('2'); // 传入一个path,返回最顶级path
+r($tester->program->getTopByPath($path2)) && p() && e('100'); // 传入一个path,返回最顶级path
\ No newline at end of file
diff --git a/module/program/test/model/gettreemenu.php b/module/program/test/model/gettreemenu.php
new file mode 100755
index 0000000000..03a9ee3f09
--- /dev/null
+++ b/module/program/test/model/gettreemenu.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2');
+$program->type->range('program');
+$program->status->range('wait');
+$program->parent->range('0,0,1,1,2');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+/**
+
+title=测试 programModel::getTreeMenu();
+cid=1
+pid=1
+
+查看返回的字符个数 >> 项目集1项目集2
+
+*/
+$programTester = new programTest();
+$programs1 = $programTester->getTreeMenuTest(1);
+$programs1 = preg_replace('/\s*/', '', strip_tags($programs1));
+
+r($programs1) && p() && e('项目集1项目集2'); // 查看返回的字符个数
diff --git a/module/program/test/model/hasunfinished.php b/module/program/test/model/hasunfinished.php
new file mode 100755
index 0000000000..01beb457ef
--- /dev/null
+++ b/module/program/test/model/hasunfinished.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2');
+$program->type->range('program');
+$program->status->range('wait');
+$program->parent->range('0,0,1,1,2');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+/**
+
+title=测试 programModel::hasUnfinished();
+cid=1
+pid=1
+
+获取项目集1下未完成的项目和项目集数量 >> 2
+获取项目集2下未完成的项目和项目集数量 >> 1
+
+*/
+
+$programTester = new programTest();
+
+r($programTester->hasUnfinishedTest(1)) && p() && e('2'); // 获取项目集1下未完成的项目和项目集数量
+r($programTester->hasUnfinishedTest(2)) && p() && e('1'); // 获取项目集2下未完成的项目和项目集数量
diff --git a/module/program/test/model/isclickable.php b/module/program/test/model/isclickable.php
new file mode 100755
index 0000000000..d9dc001e77
--- /dev/null
+++ b/module/program/test/model/isclickable.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('项目集1,项目集2');
+$program->type->range('program');
+$program->status->range('wait');
+$program->parent->range('0');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+/**
+
+title=测试 programModel::createStakeholder();
+cid=1
+pid=1
+
+传入项目集1,动作为closed,判断是否可点击 >> 1
+传入项目集1,动作为activate,判断是否可点击 >> 0
+传入项目集1,动作为suspend,判断是否可点击 >> 1
+传入项目集2,动作为closed,判断是否可点击 >> 1
+传入项目集2,动作为activate,判断是否可点击 >> 0
+传入项目集2,动作为activate,判断是否可点击 >> 1
+
+*/
+
+$programTester = new programTest();
+
+$program1 = $programTester->getByIDTest(1);
+$program2 = $programTester->getByIDTest(2);
+
+r($programTester->isClickableTest($program1, 'close')) && p('') && e('1'); // 传入项目集1,动作为closed,判断是否可点击
+r($programTester->isClickableTest($program1, 'activate')) && p('') && e('0'); // 传入项目集1,动作为activate,判断是否可点击
+r($programTester->isClickableTest($program1, 'suspend')) && p('') && e('1'); // 传入项目集1,动作为suspend,判断是否可点击
+r($programTester->isClickableTest($program2, 'close')) && p('') && e('1'); // 传入项目集2,动作为closed,判断是否可点击
+r($programTester->isClickableTest($program2, 'activate')) && p('') && e('0'); // 传入项目集2,动作为activate,判断是否可点击
+r($programTester->isClickableTest($program2, 'suspend')) && p('') && e('1'); // 传入项目集2,动作为activate,判断是否可点击
diff --git a/module/program/test/model/processnode.php b/module/program/test/model/processnode.php
new file mode 100755
index 0000000000..d4c2ddb643
--- /dev/null
+++ b/module/program/test/model/processnode.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+id->range('1-5');
+$program->name->range('项目集1,项目集2,项目1,项目2,项目3');
+$program->type->range('program{2},project{3}');
+$program->status->range('doing{3},closed,doing');
+$program->parent->range('0,0,1,1,2');
+$program->grade->range('1{2},2{3}');
+$program->path->range('1,2,`1,3`,`1,4`,`2,5`')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(5);
+
+/**
+
+title=测试 programModel::processNode();
+cid=1
+pid=1
+
+更新项目集层级和路径 >> 1
+
+*/
+
+global $tester;
+$tester->loadModel('program');
+
+r($tester->program->processNode(1, 2, 1, 1)) && p() && e('1'); // 更新项目集层级和路径
diff --git a/module/program/test/model/savestate.php b/module/program/test/model/savestate.php
new file mode 100644
index 0000000000..24f671e9f0
--- /dev/null
+++ b/module/program/test/model/savestate.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('父项目集1,父项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+su('admin');
+/**
+
+title=测试 programModel::saveState();
+cid=1
+pid=1
+
+项目集存在且正常访问 >> html
+项目集不存在 >> 0
+项目集存在,但不在可以查看的项目集列表 >> 1
+项目集存在,且在可以查看的项目集列表 >> 2
+项目集不存在,且有可以查看的项目集列表 >> 2
+
+*/
+
+$programTester = new programTest();
+ob_start();
+$programTester->saveStateTest(1);
+$program1 = ob_get_clean();
+$program2 = $programTester->saveStateTest(0);
+$program3 = $programTester->saveStateTest(1, array(1 => ''));
+$program4 = $programTester->saveStateTest(3, array(2 => ''));
+$program5 = $programTester->saveStateTest(0, array(2 => ''));
+
+r(substr($program1, 1, 4)) && p() && e('html'); // 项目集存在且正常访问
+r($program2) && p() && e('0'); // 项目集不存在
+r($program3) && p() && e('1'); // 项目集存在,但不在可以查看的项目集列表
+r($program4) && p() && e('2'); // 项目集存在,且在可以查看的项目集列表
+r($program5) && p() && e('2'); // 项目集不存在,且有可以查看的项目集列表
diff --git a/module/program/test/model/setmenu.php b/module/program/test/model/setmenu.php
new file mode 100644
index 0000000000..f744077704
--- /dev/null
+++ b/module/program/test/model/setmenu.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+id->range('1,2');
+$program->name->range('项目集1,项目集2');
+$program->type->range('program');
+$program->budget->range('900000,899900');
+$program->path->range('1,2')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+su('admin');
+
+/**
+
+title=测试 programModel::setMenu();
+cid=1
+pid=1
+
+项目集存在的情况 >> 项目集1
+项目集不存在的情况 >> 0
+
+*/
+
+$programTester = new programTest();
+
+r($programTester->setMenuTest(1)) && p() && e('项目集1'); // 项目集存在的情况
+r($programTester->setMenuTest(3)) && p() && e('0'); // 项目集不存在的情况
diff --git a/module/program/test/model/settreepath.php b/module/program/test/model/settreepath.php
new file mode 100755
index 0000000000..2fae0fc957
--- /dev/null
+++ b/module/program/test/model/settreepath.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+id->range('1,10');
+$program->name->range('项目集1');
+$program->type->range('program');
+$program->parent->range('[],[1]');
+$program->path->range('1,10')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(2);
+
+/**
+
+title=测试 programModel::setTreePath();
+cid=1
+pid=1
+
+设置之前的项目集的path >> ,10,
+设置之后的项目集的path >> ,1,10,
+
+*/
+
+$programTester = new programTest();
+
+$before = $programTester->getByIDTest(10);
+$after = $programTester->setTreePathTest(10);
+
+r($before) && p('path') && e(',10,'); // 设置之前的项目集的path
+r($after) && p('path') && e(',1,10,'); // 设置之后的项目集的path
diff --git a/module/program/test/model/update.php b/module/program/test/model/update.php
new file mode 100755
index 0000000000..d116b4bf95
--- /dev/null
+++ b/module/program/test/model/update.php
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+id->range('1');
+$program->name->range('项目集1');
+$program->type->range('program');
+$program->path->range('1')->prefix(',')->postfix(',');
+$program->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$program->gen(1);
+
+/**
+
+title=测试 programModel::update();
+cid=1
+pid=1
+
+正常更新项目集的情况 >> 测试更新项目集
+更新项目集名称为空时 >> 『项目集名称』不能为空。
+当计划开始为空时更新项目集信息 >> 『计划开始』不能为空。
+当计划完成为空时更新项目集信息 >> 『计划完成』不能为空。
+更新未开始的项目集实际开始时间 >> doing
+
+*/
+
+$programTester = new programTest();
+
+$data = array(
+ 'parent' => '0',
+ 'name' => '测试更新项目集',
+ 'begin' => '2020-10-10',
+ 'end' => '2023-09-03',
+ 'acl' => 'private',
+ 'budget' => '100',
+ 'status' => 'wait',
+ 'budgetUnit' => 'CNY',
+ 'syncPRJUnit' => true,
+ 'exchangeRate' => '',
+ 'whitelist' => array('dev10', 'dev12')
+);
+
+$normalProgram = $data;
+
+$emptyTitleProgram = $data;
+$emptyTitleProgram['name'] = '';
+
+$emptyBeginProgram = $data;
+$emptyBeginProgram['begin'] = '';
+
+$emptyEndProgram = $data;
+$emptyEndProgram['end'] = '';
+
+$realBeganProgram = $data;
+$realBeganProgram['realBegan'] = '2020-11-10';
+
+r($programTester->updateTest(1, $normalProgram)) && p('name') && e('测试更新项目集'); // 正常更新项目集的情况
+r($programTester->updateTest(1, $emptyTitleProgram)) && p('message[name]:0') && e('『项目集名称』不能为空。'); // 更新项目集名称为空时
+r($programTester->updateTest(1, $emptyBeginProgram)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 当计划开始为空时更新项目集信息
+r($programTester->updateTest(1, $emptyEndProgram)) && p('message[end]:0') && e('『计划完成』不能为空。'); // 当计划完成为空时更新项目集信息
+r($programTester->updateTest(1, $realBeganProgram)) && p('status') && e('doing'); // 更新未开始的项目集实际开始时间
diff --git a/module/program/test/program.class.php b/module/program/test/program.class.php
new file mode 100644
index 0000000000..2871829ce6
--- /dev/null
+++ b/module/program/test/program.class.php
@@ -0,0 +1,451 @@
+program = $tester->loadModel('program');
+ }
+
+ /**
+ * Get switcher.
+ *
+ * @param int $programID
+ * @access public
+ * @return string
+ */
+ public function getSwitcherTest($programID = 0)
+ {
+ return $this->program->getSwitcher($programID);
+ }
+
+ /**
+ * Get list by search.
+ *
+ * @param string $orderBy
+ * @param int $queryID
+ * @param string $sql
+ * @access public
+ * @return array
+ */
+ public function getListBySearchTest($orderBy = 'id_asc', $queryID = 0, $sql = '')
+ {
+ if(!empty($sql)) $_SESSION['programQuery'] = $sql;
+
+ return $this->program->getListBySearch($orderBy, $queryID);
+ }
+
+ /**
+ * Get pairs.
+ *
+ * @param bool $isQueryAll
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getPairsTest($isQueryAll = false, $orderBy = 'id_desc')
+ {
+ return $this->program->getPairs($isQueryAll, $orderBy);
+ }
+
+ /**
+ * Get pairs by id list.
+ *
+ * @param string $programIDList
+ * @access public
+ * @return array
+ */
+ public function getPairsByListTest($programIDList = '')
+ {
+ return $this->program->getPairsByList($programIDList);
+ }
+
+ /**
+ * Get parent pairs.
+ *
+ * @param string $model
+ * @param string $mode
+ * @param bool $showRoot
+ * @access public
+ * @return array
+ */
+ public function getParentPairsTest($model = '', $mode = 'noclosed', $showRoot = true)
+ {
+ return $this->program->getParentPairs($model, $mode, $showRoot);
+ }
+
+ /**
+ * Get the product associated with the program.
+ *
+ * @param int $programID
+ * @param string $mode
+ * @param string $status
+ * @param string|array $append
+ * @param int|string $shadow
+ * @param bool $withProgram
+ * @access public
+ * @return array
+ */
+ public function getProductPairsTest($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0, $withProgram = false)
+ {
+ return $this->program->getProductPairs($programID, $mode, $status, $append, $shadow, $withProgram);
+ }
+
+ /**
+ * Test create program.
+ *
+ * @param array $data
+ * @access public
+ * @return object
+ */
+ public function createTest($data)
+ {
+ $_POST = $data;
+
+ $programID = $this->program->create();
+
+ if(dao::isError()) return array('message' => dao::getError());
+
+ $program = $this->program->getByID($programID);
+
+ return $program;
+ }
+
+ /**
+ * Get parent PM.
+ *
+ * @param array $programIdList
+ * @access public
+ * @return array
+ */
+ public function getParentPMTest($programIdList)
+ {
+ return $this->program->getParentPM($programIdList);
+ }
+
+ /**
+ * Create stakeholder.
+ *
+ * @param int $programID
+ * @param array $accounts
+ * @access public
+ * @return void
+ */
+ public function createStakeholderTest($programID, $accounts = array())
+ {
+ $_POST['accounts'] = $accounts;
+ $stakeHolder = $this->program->createStakeholder($programID);
+
+ return $this->program->getStakeholdersByPrograms($programID);
+ }
+
+ /**
+ * Create default program.
+ *
+ * @access public
+ * @return void
+ */
+ public function createDefaultProgramTest()
+ {
+ $programID = $this->program->createDefaultProgram();
+
+ return $programID > 0;
+ }
+
+ /**
+ * Test get list.
+ *
+ * @param mixed $status
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $type top|child
+ * @param mixed $idList
+ * @access public
+ * @return void
+ */
+ public function getListTest($status = 'all', $orderBy = 'id_asc', $pager = NULL, $type = '', $idList = '')
+ {
+ $this->program->cookie->showClosed = 'ture';
+ $programs = $this->program->getList($status, $orderBy, $pager, $type, $idList);
+
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $programs;
+ }
+
+
+ /**
+ * Test update program.
+ *
+ * @param mixed $proguamID
+ * @param mixed $data
+ * @access public
+ * @return void
+ */
+ public function updateTest($programID, $data)
+ {
+ $_POST = $data;
+ $this->program->update($programID);
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $this->program->getByID($programID);
+ }
+
+ /**
+ * Get program by id.
+ *
+ * @param int $proguamID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($programID)
+ {
+ $program = $this->program->getByID($programID);
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $program;
+ }
+
+ /**
+ * Get budget left.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getBudgetLeftTest($programID)
+ {
+ $program = $this->program->getByID($programID);
+ $budget = $this->program->getBudgetLeft($program);
+
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $budget;
+ }
+
+ /**
+ * Set tree path.
+ *
+ * @param int $programID
+ * @access public
+ * @return void
+ */
+ public function setTreePathTest($programID)
+ {
+ $this->program->setTreePath($programID);
+ $program = $this->program->getByID($programID);
+
+ return $program;
+ }
+
+ /**
+ * Get children.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function getChildrenTest($programID)
+ {
+ return $this->program->getChildren($programID);
+ }
+
+ /**
+ * Check clickable.
+ *
+ * @param int $programID
+ * @param string $status
+ * @access public
+ * @return int
+ */
+ public function isClickableTest($programID, $status)
+ {
+ return $this->program->isClickable($programID, $status);
+ }
+
+ /**
+ * Has unfinished.
+ *
+ * @param int $programID
+ * @access public
+ * @return int
+ */
+ public function hasUnfinishedTest($programID)
+ {
+ $program = $this->program->getByID($programID);
+ return $this->program->hasUnfinished($program);
+ }
+
+ /*
+ * get involved programs.
+ *
+ * @param string $account
+ * @access public
+ * @return array
+ */
+ public function getInvolvedProgramsTest($account)
+ {
+ return $this->program->getInvolvedPrograms($account);
+ }
+
+ /*
+ * Get Tree menu.
+ *
+ * @param string $programID
+ * @access public
+ * @return array
+ */
+ public function getTreeMenuTest($programID)
+ {
+ return $this->program->getTreeMenu($programID);
+ }
+
+ /**
+ * Get top pairs.
+ *
+ * @param string $model
+ * @param string $mode
+ * @param bool $isQueryAll
+ * @access public
+ * @return array
+ */
+ public function getTopPairsTest($model = '', $mode = '', $isQueryAll = false)
+ {
+ return $this->program->getTopPairs($model, $mode, $isQueryAll);
+ }
+
+ /**
+ * Get kanban group.
+ *
+ * @access public
+ * @return array
+ */
+ public function getKanbanGroupTest()
+ {
+ return $this->program->getKanbanGroup();
+ }
+
+ /**
+ * Get team member pairs .
+ *
+ * @param int $programID
+ * @access public
+ * @return array
+ */
+ public function getTeamMemberPairsTest($programID)
+ {
+ return $this->program->getTeamMemberPairs($programID);
+ }
+
+ /**
+ * Get project stats.
+ *
+ * @param int $programID
+ * @param string $browseType
+ * @param int $queryID
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getProjectStatsTest($programID = 0, $browseType = 'undone', $queryID = 0, $orderBy = 'id_desc', $pager = null)
+ {
+ return $this->program->getProjectStats($programID, $browseType, $queryID, $orderBy, $pager);
+ }
+
+ /**
+ * Get project list.
+ *
+ * @param int $programID
+ * @param string $browseType
+ * @param int $queryID
+ * @param string $orderBy
+ * @param int $pager
+ * @param int $programTitle
+ * @param int $involved
+ * @access public
+ * @return array
+ */
+ public function getProjectListTest($programID = 0, $browseType = 'all', $queryID = 0, $orderBy = 'id_desc', $pager = null, $programTitle = 0, $involved = 0)
+ {
+ return $this->program->getProjectList($programID, $browseType, $queryID, $orderBy, $pager, $programTitle, $involved);
+ }
+
+ /**
+ * Get progress list.
+ *
+ * @access public
+ * @return array
+ */
+ public function getProgressListTest()
+ {
+ return $this->program->getProgressList();
+ }
+
+ /**
+ * Get stakeholders.
+ *
+ * @param int $programID
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getStakeholdersTest($programID, $orderBy = 'id_desc')
+ {
+ return $this->program->getStakeholders($programID, $orderBy);
+ }
+
+ /**
+ * Test save state.
+ *
+ * @param int $programID
+ * @param array $programs
+ * @access public
+ * @return array
+ */
+ public function saveStateTest($programID = 0, $programs = array())
+ {
+ return $this->program->saveState($programID, $programs);
+ }
+
+ /**
+ * Test build operate menu.
+ *
+ * @param int $programID
+ * @access public
+ * @return string
+ */
+ public function buildOperateMenuTest($programID = 0)
+ {
+ $program = $this->program->getByID($programID);
+ if(empty($program)) return '0';
+
+ return $this->program->buildOperateMenu($program);
+ }
+
+ /**
+ * Test set menu.
+ *
+ * @param int $programID
+ * @access public
+ * @return string
+ */
+ public function setMenuTest($programID = 0)
+ {
+ $program = $this->program->getByID($programID);
+ if(empty($program)) return '0';
+
+ $this->program->setMenu($programID);
+
+ global $lang;
+ return strip_tags($lang->switcherMenu);
+ }
+}
diff --git a/module/programplan/test/model/checkcodeunique.php b/module/programplan/test/model/checkcodeunique.php
new file mode 100644
index 0000000000..b47bb51d08
--- /dev/null
+++ b/module/programplan/test/model/checkcodeunique.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+id->range('10-15');
+$programplan->code->range('1-5')->prefix('code');
+$programplan->deleted->range('0-1');
+$programplan->gen(5);
+
+/**
+
+title=测试 programplanModel->checkCodeUnique();
+cid=1
+pid=1
+
+检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code1 >> code1
+检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code3 >> code3
+检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code5 >> code5
+检查'code1', 'code2', 'code3', 'code4', 'code5' 在除了id为'10', '11', '12', '13', '14'外的未删除数据编号是否唯一 >> 1
+检查'code6', 'code7' 在未删除的数据内编号是否唯一 >> 1
+检查'code2', 'code4' 在未删除的数据内编号是否唯一 >> 1
+
+*/
+
+$codes = array();
+$codes[] = array('code1', 'code2', 'code3', 'code4', 'code5');
+$codes[] = array('code6', 'code7');
+$codes[] = array('code2', 'code4');
+$exclude = array('10', '11', '12', '13', '14');
+
+$programplan = new programplanTest();
+
+r($programplan->checkCodeUniqueTest($codes[0])) && p('code1') && e('code1'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code1
+r($programplan->checkCodeUniqueTest($codes[0])) && p('code3') && e('code3'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code3
+r($programplan->checkCodeUniqueTest($codes[0])) && p('code5') && e('code5'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在未删除的数据内编号是否唯一 code5
+r($programplan->checkCodeUniqueTest($codes[0], $exclude)) && p() && e('1'); // 检查'code1', 'code2', 'code3', 'code4', 'code5' 在除了id为'10', '11', '12', '13', '14'外的未删除数据编号是否唯一
+r($programplan->checkCodeUniqueTest($codes[1])) && p() && e('1'); // 检查'code6', 'code7' 在未删除的数据内编号是否唯一
+r($programplan->checkCodeUniqueTest($codes[2])) && p() && e('1'); // 检查'code2', 'code4' 在未删除的数据内编号是否唯一
diff --git a/module/programplan/test/model/checkleafstage.php b/module/programplan/test/model/checkleafstage.php
new file mode 100755
index 0000000000..95cbd14024
--- /dev/null
+++ b/module/programplan/test/model/checkleafstage.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$execution = zdTable('project');
+$execution->id->range('1-5');
+$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
+$execution->type->range('project,stage{4}');
+$execution->project->range('0,1{4}');
+$execution->parent->range('0,1,2,3,1');
+$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
+$execution->status->range('doing,doing,doing,closed,suspended');
+$execution->openedBy->range('admin,user1');
+$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+/**
+
+title=测试programplanModel->checkLeafStage();
+cid=1
+pid=1
+
+测试id为2判断是否为叶子节点 >> 0
+测试id为5判断是否为叶子节点 >> 1
+
+*/
+
+$plan = new programplanTest();
+
+r($plan->checkLeafStageTest(2)) && p('') && e(0); // 测试id为2判断是否为叶子节点
+r($plan->checkLeafStageTest(5)) && p('') && e(1); // 测试id为5判断是否为叶子节点
diff --git a/module/programplan/test/model/checknameunique.php b/module/programplan/test/model/checknameunique.php
new file mode 100644
index 0000000000..556cf49e82
--- /dev/null
+++ b/module/programplan/test/model/checknameunique.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+id->range('10-15');
+$programplan->name->range('1-5')->prefix('name');
+$programplan->deleted->range('0-1');
+$programplan->gen(5);
+
+/**
+
+title=测试 programplanModel->checkNameUnique();
+cid=1
+pid=1
+
+检查'name1', 'name2', 'name1', 'name3', 'name5' 数组的值是否唯一 >> 0
+检查'name6', 'name7' 数组的值是否唯一 >> 1
+检查'name2', 'name2' 数组的值是否唯一 >> 0
+
+*/
+
+$names = array();
+$names[] = array('name1', 'name2', 'name1', 'name3', 'name5');
+$names[] = array('name6', 'name7');
+$names[] = array('name2', 'name2');
+
+$programplan = new programplanTest();
+
+r($programplan->checkNameUniqueTest($names[0])) && p() && e('0'); // 检查'name1', 'name2', 'name1', 'name3', 'name5' 数组的值是否唯一
+r($programplan->checkNameUniqueTest($names[1])) && p() && e('1'); // 检查'name6', 'name7' 数组的值是否唯一
+r($programplan->checkNameUniqueTest($names[2])) && p() && e('0'); // 检查'name2', 'name2' 数组的值是否唯一
diff --git a/module/programplan/test/model/checktopstage.php b/module/programplan/test/model/checktopstage.php
new file mode 100755
index 0000000000..6716884261
--- /dev/null
+++ b/module/programplan/test/model/checktopstage.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$execution = zdTable('project');
+$execution->id->range('1-5');
+$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
+$execution->type->range('project,stage{4}');
+$execution->project->range('0,1{4}');
+$execution->parent->range('0,1,2,3,1');
+$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
+$execution->status->range('doing,doing,doing,closed,suspended');
+$execution->openedBy->range('admin,user1');
+$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+/**
+
+title=测试programplanModel->checkTopStage();
+cid=1
+pid=1
+
+测试id为2判断是否为顶级阶段 >> 1
+测试id为4判断是否为顶级阶段 >> 0
+测试id为5判断是否为顶级阶段 >> 1
+
+*/
+
+$plan = new programplanTest();
+
+r($plan->checkTopStageTest(2)) && p('') && e(1); // 测试id为2判断是否为顶级阶段
+r($plan->checkTopStageTest(4)) && p('') && e(0); // 测试id为4判断是否为顶级阶段
+r($plan->checkTopStageTest(5)) && p('') && e(1); // 测试id为5判断是否为顶级阶段
diff --git a/module/programplan/test/model/create.php b/module/programplan/test/model/create.php
new file mode 100755
index 0000000000..ae97c31087
--- /dev/null
+++ b/module/programplan/test/model/create.php
@@ -0,0 +1,55 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试创建用例 工作量占比非数字 >> "工作量比例"必须为数字
+测试创建用例 计划开始为空 >> 『计划开始』日期不能为空
+测试创建用例 计划开始非日期 >> 『计划开始』应当为合法的日期
+测试创建用例 计划完成为空 >> 『计划完成』日期不能为空
+测试创建用例 计划完成非日期 >> 『计划完成』应当为合法的日期
+测试创建用例 计划完成小于计划开始 >> "计划完成时间"必须大于"计划开始时间"
+测试创建用例 计划开始小于项目开始日期 >> 阶段的开始时间不能小于所属项目的开始时间
+测试创建用例 计划完成大于项目计划完成 >> 阶段的结束时间不能大于所属项目的结束时间
+测试创建用例 工作量占比之和大于100 >> 工作量占比累计不应当超过100%
+测试正常更新阶段信息 获取阶段数量 >> 7
+测试正常创建一条阶段信息 获取阶段数量 >> 8
+
+*/
+
+$percentNumber = array('percents' => array('a', '0', '0', '0', '0', '0', '0', '', '', '', '', ''));
+$emptyBegin = array('begin' => array('', '2022-03-13', '2022-03-16', '2022-03-16', '2022-03-19', '2022-03-19', '2022-03-22', '', '', '', '', ''));
+$checkBegin = array('begin' => array('a', '2022-03-13', '2022-03-16', '2022-03-16', '2022-03-19', '2022-03-19', '2022-03-22', '', '', '', '', ''));
+$emptyEnd = array('end' => array('', '2022-04-30', '2022-05-18', '2022-05-18', '2022-04-30', '2022-05-18', '2022-05-18', '', '', '', '', ''));
+$checkEnd = array('end' => array('a', '2022-04-30', '2022-05-18', '2022-05-18', '2022-04-30', '2022-05-18', '2022-05-18', '', '', '', '', ''));
+$planFinishSmall = array('end' => array('2022-03-12', '2022-04-30', '2022-05-18', '2022-05-18', '2022-04-30', '2022-05-18', '2022-05-18', '', '', '', '', ''));
+$errorBegin = array('begin' => array('2022-01-01', '2022-03-13', '2022-03-16', '2022-03-16', '2022-03-19', '2022-03-19', '2022-03-22', '', '', '', '', ''));
+$errorEnd = array('end' => array('2100-06-18', '2022-04-30', '2022-05-18', '2022-05-18', '2022-04-30', '2022-05-18', '2022-05-18', '', '', '', '', ''));
+$percentOver = array('percents' => array('50', '51', '0', '0', '0', '0', '0', '', '', '', '', ''));
+
+$names = array('阶段31', '阶段121', '阶段211', '阶段301', '阶段391', '阶段481', '阶段571', '新增的阶段', '', '', '', '');
+$percents = array('0', '0', '0', '0', '0', '0', '0', '0', '', '', '', '');
+$begin = array();
+$end = array();
+$create = array('names' => $names, 'percents' => $percents, 'begin' => $begin, 'end' => $end);
+
+$programplan = new programplanTest();
+
+r($programplan->createTest($percentNumber)) && p() && e('"工作量比例"必须为数字'); // 测试创建用例 工作量占比非数字
+r($programplan->createTest($emptyBegin)) && p() && e('『计划开始』日期不能为空'); // 测试创建用例 计划开始为空
+r($programplan->createTest($checkBegin)) && p() && e('『计划开始』应当为合法的日期'); // 测试创建用例 计划开始非日期
+r($programplan->createTest($emptyEnd)) && p() && e('『计划完成』日期不能为空'); // 测试创建用例 计划完成为空
+r($programplan->createTest($checkEnd)) && p() && e('『计划完成』应当为合法的日期'); // 测试创建用例 计划完成非日期
+r($programplan->createTest($planFinishSmall)) && p() && e('"计划完成时间"必须大于"计划开始时间"'); // 测试创建用例 计划完成小于计划开始
+r($programplan->createTest($errorBegin)) && p() && e("阶段的开始时间不能小于所属项目的开始时间"); // 测试创建用例 计划开始小于项目开始日期
+r($programplan->createTest($errorEnd)) && p() && e("阶段的结束时间不能大于所属项目的结束时间"); // 测试创建用例 计划完成大于项目计划完成
+r($programplan->createTest($percentOver)) && p() && e('工作量占比累计不应当超过100%'); // 测试创建用例 工作量占比之和大于100
+r($programplan->createTest()) && p() && e('7'); // 测试正常更新阶段信息 获取阶段数量
+r($programplan->createTest($create)) && p() && e('8'); // 测试正常创建一条阶段信息 获取阶段数量
diff --git a/module/programplan/test/model/getbyid.php b/module/programplan/test/model/getbyid.php
new file mode 100755
index 0000000000..636bacc210
--- /dev/null
+++ b/module/programplan/test/model/getbyid.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+获取阶段131 >> 阶段31,project31
+获取阶段132 >> 阶段32,project32
+获取阶段133 >> 阶段33,project33
+获取阶段134 >> 阶段34,project34
+获取阶段135 >> 阶段35,project35
+
+*/
+
+$planIDList = array('131', '132', '133', '134', '135');
+
+$programplan = new programplanTest();
+
+r($programplan->getByIDTest($planIDList[0])) && p('name,code') && e('阶段31,project31'); // 获取阶段131
+r($programplan->getByIDTest($planIDList[1])) && p('name,code') && e('阶段32,project32'); // 获取阶段132
+r($programplan->getByIDTest($planIDList[2])) && p('name,code') && e('阶段33,project33'); // 获取阶段133
+r($programplan->getByIDTest($planIDList[3])) && p('name,code') && e('阶段34,project34'); // 获取阶段134
+r($programplan->getByIDTest($planIDList[4])) && p('name,code') && e('阶段35,project35'); // 获取阶段135
\ No newline at end of file
diff --git a/module/programplan/test/model/getbylist.php b/module/programplan/test/model/getbylist.php
new file mode 100755
index 0000000000..8ea17c52ce
--- /dev/null
+++ b/module/programplan/test/model/getbylist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+测试获取项目11 12的信息 >> 项目1;项目2
+测试获取项目13 14的信息 >> 项目3;项目4
+测试获取项目15 16 17的信息 >> 项目5;项目6;项目7
+测试获取项目18 19 20的信息 >> 项目8;项目9;项目10
+测试获取项目21 22 23 24的信息 >> 项目11;项目12;项目13;项目14
+
+*/
+
+$planIDList = array(array(11, 12), array(13, 14), array(15, 16, 17), array(18, 19, 20), array(21, 22, 23, 24));
+
+$programplan = new programplanTest();
+
+r($programplan->getByListTest($planIDList[0])) && p('11:name;12:name') && e('项目1;项目2'); // 测试获取项目11 12的信息
+r($programplan->getByListTest($planIDList[1])) && p('13:name;14:name') && e('项目3;项目4'); // 测试获取项目13 14的信息
+r($programplan->getByListTest($planIDList[2])) && p('15:name;16:name;17:name') && e('项目5;项目6;项目7'); // 测试获取项目15 16 17的信息
+r($programplan->getByListTest($planIDList[3])) && p('18:name;19:name;20:name') && e('项目8;项目9;项目10'); // 测试获取项目18 19 20的信息
+r($programplan->getByListTest($planIDList[4])) && p('21:name;22:name;23:name;24:name') && e('项目11;项目12;项目13;项目14'); // 测试获取项目21 22 23 24的信息
\ No newline at end of file
diff --git a/module/programplan/test/model/getduration.php b/module/programplan/test/model/getduration.php
new file mode 100755
index 0000000000..01c509f461
--- /dev/null
+++ b/module/programplan/test/model/getduration.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getDuration();
+cid=1
+pid=1
+
+测试获取2022-04-01 ~ 2022-05-01持续时间 >> 21
+测试获取2022-04-02 ~ 2022-05-06持续时间 >> 25
+测试获取2022-04-03 ~ 2022-05-11持续时间 >> 28
+测试获取2022-04-04 ~ 2022-05-16持续时间 >> 31
+测试获取2022-04-05 ~ 2022-05-21持续时间 >> 34
+
+*/
+
+$beginList = array('2022-04-01', '2022-04-02', '2022-04-03', '2022-04-04', '2022-04-05');
+$endList = array('2022-05-01', '2022-05-06', '2022-05-11', '2022-05-16', '2022-05-21');
+
+$programplan = new programplanTest();
+
+r($programplan->getDurationTest($beginList[0], $endList[0])) && p() && e('21'); // 测试获取2022-04-01 ~ 2022-05-01持续时间
+r($programplan->getDurationTest($beginList[1], $endList[1])) && p() && e('25'); // 测试获取2022-04-02 ~ 2022-05-06持续时间
+r($programplan->getDurationTest($beginList[2], $endList[2])) && p() && e('28'); // 测试获取2022-04-03 ~ 2022-05-11持续时间
+r($programplan->getDurationTest($beginList[3], $endList[3])) && p() && e('31'); // 测试获取2022-04-04 ~ 2022-05-16持续时间
+r($programplan->getDurationTest($beginList[4], $endList[4])) && p() && e('34'); // 测试获取2022-04-05 ~ 2022-05-21持续时间
\ No newline at end of file
diff --git a/module/programplan/test/model/getmilestonebyproduct.php b/module/programplan/test/model/getmilestonebyproduct.php
new file mode 100755
index 0000000000..65a3060d2b
--- /dev/null
+++ b/module/programplan/test/model/getmilestonebyproduct.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getMilestoneByProduct();
+cid=1
+pid=1
+
+测试获取产品21 项目41的里程碑 >> 阶段121,阶段301,阶段481,阶段31,阶段211,阶段391,阶段571
+测试获取产品32 项目52的里程碑 >> 0
+测试获取产品23 项目43的里程碑 >> 阶段123,阶段303,阶段483,阶段33,阶段213,阶段393,阶段573
+测试获取产品34 项目54的里程碑 >> 0
+测试获取产品25 项目45的里程碑 >> 阶段125,阶段305,阶段485,阶段35,阶段215,阶段395,阶段575
+
+*/
+$projectIDList = array(41, 52, 43, 54, 45);
+$productIDList = array(21, 32, 23, 34, 25);
+
+$programplan = new programplanTest();
+
+r($programplan->getMilestoneByProductTest($productIDList[0], $projectIDList[0])) && p() && e('阶段121,阶段301,阶段481,阶段31,阶段211,阶段391,阶段571'); // 测试获取产品21 项目41的里程碑
+r($programplan->getMilestoneByProductTest($productIDList[1], $projectIDList[1])) && p() && e('0'); // 测试获取产品32 项目52的里程碑
+r($programplan->getMilestoneByProductTest($productIDList[2], $projectIDList[2])) && p() && e('阶段123,阶段303,阶段483,阶段33,阶段213,阶段393,阶段573'); // 测试获取产品23 项目43的里程碑
+r($programplan->getMilestoneByProductTest($productIDList[3], $projectIDList[3])) && p() && e('0'); // 测试获取产品34 项目54的里程碑
+r($programplan->getMilestoneByProductTest($productIDList[4], $projectIDList[4])) && p() && e('阶段125,阶段305,阶段485,阶段35,阶段215,阶段395,阶段575'); // 测试获取产品25 项目45的里程碑
\ No newline at end of file
diff --git a/module/programplan/test/model/getmilestones.php b/module/programplan/test/model/getmilestones.php
new file mode 100755
index 0000000000..687a9425b1
--- /dev/null
+++ b/module/programplan/test/model/getmilestones.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getMilestones();
+cid=1
+pid=1
+
+测试获取项目41的里程碑 >> 阶段571,阶段481,阶段391,阶段301,阶段211
+测试获取项目52的里程碑 >> 0
+测试获取项目43的里程碑 >> 阶段573,阶段483,阶段393,阶段303,阶段213,阶段123,阶段33
+测试获取项目54的里程碑 >> 0
+测试获取项目45的里程碑 >> 阶段575,阶段485,阶段395,阶段305,阶段215,阶段125,阶段35
+
+*/
+$projectIDList = array(41, 52, 43, 54, 45);
+
+$programplan = new programplanTest();
+
+r($programplan->getMilestonesTest($projectIDList[0])) && p() && e('阶段571,阶段481,阶段391,阶段301,阶段211'); // 测试获取项目41的里程碑
+r($programplan->getMilestonesTest($projectIDList[1])) && p() && e('0'); // 测试获取项目52的里程碑
+r($programplan->getMilestonesTest($projectIDList[2])) && p() && e('阶段573,阶段483,阶段393,阶段303,阶段213,阶段123,阶段33'); // 测试获取项目43的里程碑
+r($programplan->getMilestonesTest($projectIDList[3])) && p() && e('0'); // 测试获取项目54的里程碑
+r($programplan->getMilestonesTest($projectIDList[4])) && p() && e('阶段575,阶段485,阶段395,阶段305,阶段215,阶段125,阶段35'); // 测试获取项目45的里程碑
\ No newline at end of file
diff --git a/module/programplan/test/model/getpairs.php b/module/programplan/test/model/getpairs.php
new file mode 100755
index 0000000000..ecc96c7c3c
--- /dev/null
+++ b/module/programplan/test/model/getpairs.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试获取执行41 产品21的计划键值对 >> ,阶段31,阶段31/子阶段1,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571
+测试获取执行42 产品22的计划键值对 >> ,阶段32,阶段32/子阶段2,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572
+测试获取执行43 产品23的计划键值对 >> ,阶段33,阶段33/子阶段3,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573
+测试获取执行44 产品24的计划键值对 >> ,阶段34,阶段34/子阶段4,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574
+测试获取执行45 产品25的计划键值对 >> ,阶段35,阶段35/子阶段5,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575
+
+*/
+$executionIDList = array(41, 42, 43, 44, 45);
+$productIDList = array(21, 22, 23, 24, 25);
+
+$programplan = new programplanTest();
+
+r($programplan->getPairsTest($executionIDList[0], $productIDList[0])) && p() && e(',阶段31,阶段31/子阶段1,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571'); // 测试获取执行41 产品21的计划键值对
+r($programplan->getPairsTest($executionIDList[1], $productIDList[1])) && p() && e(',阶段32,阶段32/子阶段2,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572'); // 测试获取执行42 产品22的计划键值对
+r($programplan->getPairsTest($executionIDList[2], $productIDList[2])) && p() && e(',阶段33,阶段33/子阶段3,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573'); // 测试获取执行43 产品23的计划键值对
+r($programplan->getPairsTest($executionIDList[3], $productIDList[3])) && p() && e(',阶段34,阶段34/子阶段4,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574'); // 测试获取执行44 产品24的计划键值对
+r($programplan->getPairsTest($executionIDList[4], $productIDList[4])) && p() && e(',阶段35,阶段35/子阶段5,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575'); // 测试获取执行45 产品25的计划键值对
\ No newline at end of file
diff --git a/module/programplan/test/model/getparentchildrentypes.php b/module/programplan/test/model/getparentchildrentypes.php
new file mode 100755
index 0000000000..165d7cdfc0
--- /dev/null
+++ b/module/programplan/test/model/getparentchildrentypes.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+id->range('10-20');
+$programplan->parent->range('1-3');
+$programplan->type->range('stage{3},sprint{2},kanban{2},stage{1},sprint{2}');
+$programplan->deleted->range('0-1');
+$programplan->gen(10);
+
+/**
+
+title=测试 programplanModel->getParentChildrenTypes();
+cid=1
+pid=1
+
+查找父ID为 1 未删除的阶段类型 stage >> stage
+查找父ID为 1 未删除的阶段类型 kanban >> kanban
+查找父ID为 1 未删除的阶段类型数量 >> 2
+查找父ID为 2 未删除的阶段类型 sprint >> sprint
+查找父ID为 2 未删除的阶段类型数量 >> 1
+查找父ID为 3 未删除的阶段类型 stage >> stage
+查找父ID为 3 未删除的阶段类型 sprint >> sprint
+查找父ID为 3 未删除的阶段类型数量 >> 2
+查找父ID为 1 未删除的阶段类型 stage >> 0
+查找父ID为 1 未删除的阶段类型 sprint >> 0
+查找父ID为 1 未删除的阶段类型 kanban >> 0
+查找父ID为 1 未删除的阶段类型数量 >> 0
+
+*/
+
+$parentIDList = array(1, 2, 3, 4);
+
+$programplan = new programplanTest();
+
+r($programplan->getParentChildrenTypesTest($parentIDList[0])) && p('stage') && e('stage'); // 查找父ID为 1 未删除的阶段类型 stage
+r($programplan->getParentChildrenTypesTest($parentIDList[0])) && p('kanban') && e('kanban'); // 查找父ID为 1 未删除的阶段类型 kanban
+r(count($programplan->getParentChildrenTypesTest($parentIDList[0]))) && p() && e('2'); // 查找父ID为 1 未删除的阶段类型数量
+r($programplan->getParentChildrenTypesTest($parentIDList[1])) && p('sprint') && e('sprint'); // 查找父ID为 2 未删除的阶段类型 sprint
+r(count($programplan->getParentChildrenTypesTest($parentIDList[1]))) && p() && e('1'); // 查找父ID为 2 未删除的阶段类型数量
+r($programplan->getParentChildrenTypesTest($parentIDList[2])) && p('stage') && e('stage'); // 查找父ID为 3 未删除的阶段类型 stage
+r($programplan->getParentChildrenTypesTest($parentIDList[2])) && p('sprint') && e('sprint'); // 查找父ID为 3 未删除的阶段类型 sprint
+r(count($programplan->getParentChildrenTypesTest($parentIDList[2]))) && p() && e('2'); // 查找父ID为 3 未删除的阶段类型数量
+r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('stage') && e('0'); // 查找父ID为 1 未删除的阶段类型 stage
+r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('sprint') && e('0'); // 查找父ID为 1 未删除的阶段类型 sprint
+r($programplan->getParentChildrenTypesTest($parentIDList[3])) && p('kanban') && e('0'); // 查找父ID为 1 未删除的阶段类型 kanban
+r(count($programplan->getParentChildrenTypesTest($parentIDList[3]))) && p() && e('0'); // 查找父ID为 1 未删除的阶段类型数量
diff --git a/module/programplan/test/model/getparentstagelist.php b/module/programplan/test/model/getparentstagelist.php
new file mode 100755
index 0000000000..9eddd4eabd
--- /dev/null
+++ b/module/programplan/test/model/getparentstagelist.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getParentStageList();
+cid=1
+pid=1
+
+测试查询项目41 计划701 产品21的父阶段信息 >> 无,阶段31
+测试查询项目42 计划702 产品22的父阶段信息 >> 无,阶段32
+测试查询项目43 计划703 产品23的父阶段信息 >> 无,阶段33
+测试查询项目44 计划704 产品24的父阶段信息 >> 无,阶段34
+测试查询项目45 计划705 产品25的父阶段信息 >> 无,阶段35
+
+*/
+$projectIDList = array(41, 42, 43, 44, 45);
+$planIDList = array(701, 702, 703, 704, 705);
+$productIDList = array(21, 22, 23, 24, 25);
+
+$programplan = new programplanTest();
+
+r($programplan->getParentStageListTest($projectIDList[0], $planIDList[0], $productIDList[0])) && p() && e('无,阶段31'); // 测试查询项目41 计划701 产品21的父阶段信息
+r($programplan->getParentStageListTest($projectIDList[1], $planIDList[1], $productIDList[1])) && p() && e('无,阶段32'); // 测试查询项目42 计划702 产品22的父阶段信息
+r($programplan->getParentStageListTest($projectIDList[2], $planIDList[2], $productIDList[2])) && p() && e('无,阶段33'); // 测试查询项目43 计划703 产品23的父阶段信息
+r($programplan->getParentStageListTest($projectIDList[3], $planIDList[3], $productIDList[3])) && p() && e('无,阶段34'); // 测试查询项目44 计划704 产品24的父阶段信息
+r($programplan->getParentStageListTest($projectIDList[4], $planIDList[4], $productIDList[4])) && p() && e('无,阶段35'); // 测试查询项目45 计划705 产品25的父阶段信息
\ No newline at end of file
diff --git a/module/programplan/test/model/getplans.php b/module/programplan/test/model/getplans.php
new file mode 100755
index 0000000000..5ef84df410
--- /dev/null
+++ b/module/programplan/test/model/getplans.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPlans();
+cid=1
+pid=1
+
+测试获取执行41 产品21的计划键值对 >> ,阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571
+测试获取执行42 产品22的计划键值对 >> ,阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572
+测试获取执行43 产品23的计划键值对 >> ,阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573
+测试获取执行44 产品24的计划键值对 >> ,阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574
+测试获取执行45 产品25的计划键值对 >> ,阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575
+
+*/
+$executionIDList = array(41, 42, 43, 44, 45);
+$productIDList = array(21, 22, 23, 24, 25);
+
+$programplan = new programplanTest();
+
+r($programplan->getPlansTest($executionIDList[0], $productIDList[0])) && p() && e(',阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571'); // 测试获取执行41 产品21的计划键值对
+r($programplan->getPlansTest($executionIDList[1], $productIDList[1])) && p() && e(',阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572'); // 测试获取执行42 产品22的计划键值对
+r($programplan->getPlansTest($executionIDList[2], $productIDList[2])) && p() && e(',阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573'); // 测试获取执行43 产品23的计划键值对
+r($programplan->getPlansTest($executionIDList[3], $productIDList[3])) && p() && e(',阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574'); // 测试获取执行44 产品24的计划键值对
+r($programplan->getPlansTest($executionIDList[4], $productIDList[4])) && p() && e(',阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575'); // 测试获取执行45 产品25的计划键值对
\ No newline at end of file
diff --git a/module/programplan/test/model/getselfandchildrenlist.php b/module/programplan/test/model/getselfandchildrenlist.php
new file mode 100755
index 0000000000..110050916f
--- /dev/null
+++ b/module/programplan/test/model/getselfandchildrenlist.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$execution = zdTable('project');
+$execution->id->range('1-5');
+$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
+$execution->type->range('project,stage{4}');
+$execution->project->range('0,1{4}');
+$execution->parent->range('0,1,2,3,1');
+$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
+$execution->status->range('doing,doing,doing,closed,suspended');
+$execution->openedBy->range('admin,user1');
+$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+/**
+
+title=测试programplanModel->getSelfAndChildrenList();
+cid=1
+pid=1
+
+测试id为2时获取自己的状态 >> doing
+测试id为2时获取自己某一个后代的状态 >> 2
+
+*/
+
+$plan = new programplanTest();
+$topPlan = $plan->getSelfAndChildrenListTest(2);
+$topPlanCount = count($topPlan[2]);
+
+r($topPlan[2][2]) && p('status') && e('doing'); // 测试id为2时获取自己的状态
+r($topPlanCount - 1) && p('') && e(2); // 测试id为2时获取自己后代的个数
diff --git a/module/programplan/test/model/getsiblings.php b/module/programplan/test/model/getsiblings.php
new file mode 100755
index 0000000000..94e7892135
--- /dev/null
+++ b/module/programplan/test/model/getsiblings.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$execution = zdTable('project');
+$execution->id->range('1-5');
+$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
+$execution->type->range('project,stage{4}');
+$execution->project->range('0,1{4}');
+$execution->parent->range('0,1,2,3,1');
+$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
+$execution->status->range('doing,doing,doing,closed,suspended');
+$execution->openedBy->range('admin,user1');
+$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+/**
+
+title=测试programplanModel->getSiblings();
+cid=1
+pid=1
+
+测试id为2时获取兄弟阶段的的名称 >> 阶段b
+测试id为2时获取自己兄弟阶段的个数 >> 1
+测试id为4时获取自己兄弟阶段的个数 >> 0
+
+*/
+
+$plan = new programplanTest();
+$topPlan = $plan->getSiblingsTest(2);
+$topPlanCount = count($topPlan[2]);
+
+$leafPlan = $plan->getSiblingsTest(4);
+$leafPlanCount = count($leafPlan[4]);
+
+r($topPlan[2][5]) && p('name') && e('阶段b'); // 测试id为2时获取兄弟阶段的的名称
+r($topPlanCount - 1) && p('') && e(1); // 测试id为2时获取自己兄弟阶段的个数
+r($leafPlanCount - 1) && p('') && e(0); // 测试id为4时获取自己兄弟阶段的个数
diff --git a/module/programplan/test/model/getstage.php b/module/programplan/test/model/getstage.php
new file mode 100755
index 0000000000..562d65dfb9
--- /dev/null
+++ b/module/programplan/test/model/getstage.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getStage();
+cid=1
+pid=1
+
+测试获取执行41 产品21 browse all的计划键值对 >> ,阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571,子阶段1
+测试获取执行41 产品21 browse parent的计划键值对 >> ,阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571
+测试获取执行41 产品21 browse all id desc的计划键值对 >> ,子阶段1,阶段571,阶段481,阶段391,阶段301,阶段211,阶段121,阶段31
+测试获取执行42 产品22 browse all的计划键值对 >> ,阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572,子阶段2
+测试获取执行42 产品22 browse parent的计划键值对 >> ,阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572
+测试获取执行43 产品23 browse all的计划键值对 >> ,阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573,子阶段3
+测试获取执行43 产品23 browse parent的计划键值对 >> ,阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573
+测试获取执行44 产品24 browse all的计划键值对 >> ,阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574,子阶段4
+测试获取执行44 产品24 browse parent的计划键值对 >> ,阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574
+测试获取执行45 产品25 browse all的计划键值对 >> ,阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575,子阶段5
+测试获取执行45 产品25 browse parent的计划键值对 >> ,阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575
+
+*/
+$executionIDList = array(41, 42, 43, 44, 45);
+$productIDList = array(21, 22, 23, 24, 25);
+$browseTypeList = array('all', 'parent');
+$order = 'id_desc';
+
+$programplan = new programplanTest();
+
+r($programplan->getStageTest($executionIDList[0], $productIDList[0], $browseTypeList[0])) && p() && e(',阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571,子阶段1'); // 测试获取执行41 产品21 browse all的计划键值对
+r($programplan->getStageTest($executionIDList[0], $productIDList[0], $browseTypeList[1])) && p() && e(',阶段31,阶段121,阶段211,阶段301,阶段391,阶段481,阶段571'); // 测试获取执行41 产品21 browse parent的计划键值对
+r($programplan->getStageTest($executionIDList[0], $productIDList[0], $browseTypeList[0], $order)) && p() && e(',子阶段1,阶段571,阶段481,阶段391,阶段301,阶段211,阶段121,阶段31'); // 测试获取执行41 产品21 browse all id desc的计划键值对
+r($programplan->getStageTest($executionIDList[1], $productIDList[1], $browseTypeList[0])) && p() && e(',阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572,子阶段2'); // 测试获取执行42 产品22 browse all的计划键值对
+r($programplan->getStageTest($executionIDList[1], $productIDList[1], $browseTypeList[1])) && p() && e(',阶段32,阶段122,阶段212,阶段302,阶段392,阶段482,阶段572'); // 测试获取执行42 产品22 browse parent的计划键值对
+r($programplan->getStageTest($executionIDList[2], $productIDList[2], $browseTypeList[0])) && p() && e(',阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573,子阶段3'); // 测试获取执行43 产品23 browse all的计划键值对
+r($programplan->getStageTest($executionIDList[2], $productIDList[2], $browseTypeList[1])) && p() && e(',阶段33,阶段123,阶段213,阶段303,阶段393,阶段483,阶段573'); // 测试获取执行43 产品23 browse parent的计划键值对
+r($programplan->getStageTest($executionIDList[3], $productIDList[3], $browseTypeList[0])) && p() && e(',阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574,子阶段4'); // 测试获取执行44 产品24 browse all的计划键值对
+r($programplan->getStageTest($executionIDList[3], $productIDList[3], $browseTypeList[1])) && p() && e(',阶段34,阶段124,阶段214,阶段304,阶段394,阶段484,阶段574'); // 测试获取执行44 产品24 browse parent的计划键值对
+r($programplan->getStageTest($executionIDList[4], $productIDList[4], $browseTypeList[0])) && p() && e(',阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575,子阶段5'); // 测试获取执行45 产品25 browse all的计划键值对
+r($programplan->getStageTest($executionIDList[4], $productIDList[4], $browseTypeList[1])) && p() && e(',阶段35,阶段125,阶段215,阶段305,阶段395,阶段485,阶段575'); // 测试获取执行45 产品25 browse parent的计划键值对
\ No newline at end of file
diff --git a/module/programplan/test/model/gettotalpercent.php b/module/programplan/test/model/gettotalpercent.php
new file mode 100755
index 0000000000..e9e8adea7c
--- /dev/null
+++ b/module/programplan/test/model/gettotalpercent.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getTotalPercent();
+cid=1
+pid=1
+
+测试获取阶段131的总进度 >> 60
+测试获取阶段131是父阶段的总进度 >> 0
+测试获取阶段132的总进度 >> 60
+测试获取阶段133的总进度 >> 60
+测试获取阶段134的总进度 >> 60
+测试获取阶段135的总进度 >> 60
+
+*/
+
+$stageIDList = array(131, 132, 133, 134, 135);
+
+$programplan = new programplanTest();
+
+r($programplan->getTotalPercentTest($stageIDList[0])) && p() && e('60'); // 测试获取阶段131的总进度
+r($programplan->getTotalPercentTest($stageIDList[0], true)) && p() && e('0'); // 测试获取阶段131是父阶段的总进度
+r($programplan->getTotalPercentTest($stageIDList[1])) && p() && e('60'); // 测试获取阶段132的总进度
+r($programplan->getTotalPercentTest($stageIDList[2])) && p() && e('60'); // 测试获取阶段133的总进度
+r($programplan->getTotalPercentTest($stageIDList[3])) && p() && e('60'); // 测试获取阶段134的总进度
+r($programplan->getTotalPercentTest($stageIDList[4])) && p() && e('60'); // 测试获取阶段135的总进度
\ No newline at end of file
diff --git a/module/programplan/test/model/iscreatetask.php b/module/programplan/test/model/iscreatetask.php
new file mode 100755
index 0000000000..8f73bb258a
--- /dev/null
+++ b/module/programplan/test/model/iscreatetask.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+isCreateTask();
+cid=1
+pid=1
+
+测试阶段131下有没有任务 >> 1
+测试阶段132下有没有任务 >> 1
+测试阶段133下有没有任务 >> 1
+测试阶段134下有没有任务 >> 1
+测试阶段135下有没有任务 >> 1
+
+*/
+$stageIDList = array(131, 132, 133, 134, 135);
+
+$programplan = new programplanTest();
+
+r($programplan->isCreateTaskTest($stageIDList[0])) && p() && e('1'); // 测试阶段131下有没有任务
+r($programplan->isCreateTaskTest($stageIDList[1])) && p() && e('1'); // 测试阶段132下有没有任务
+r($programplan->isCreateTaskTest($stageIDList[2])) && p() && e('1'); // 测试阶段133下有没有任务
+r($programplan->isCreateTaskTest($stageIDList[3])) && p() && e('1'); // 测试阶段134下有没有任务
+r($programplan->isCreateTaskTest($stageIDList[4])) && p() && e('1'); // 测试阶段135下有没有任务
\ No newline at end of file
diff --git a/module/programplan/test/model/processplan.php b/module/programplan/test/model/processplan.php
new file mode 100755
index 0000000000..ec009bc591
--- /dev/null
+++ b/module/programplan/test/model/processplan.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+processPlan();
+cid=1
+pid=1
+
+测试计算计划131 >> 131,阶段31,已关闭的正常产品21
+测试计算计划132 >> 132,阶段32,已关闭的正常产品22
+测试计算计划133 >> 133,阶段33,已关闭的正常产品23
+测试计算计划134 >> 134,阶段34,已关闭的正常产品24
+测试计算计划135 >> 135,阶段35,已关闭的正常产品25
+
+*/
+$planIDList = array(131, 132, 133, 134, 135);
+
+$programplan = new programplanTest();
+
+r($programplan->processPlanTest($planIDList[0])) && p('id,name,productName') && e('131,阶段31,已关闭的正常产品21'); // 测试计算计划131
+r($programplan->processPlanTest($planIDList[1])) && p('id,name,productName') && e('132,阶段32,已关闭的正常产品22'); // 测试计算计划132
+r($programplan->processPlanTest($planIDList[2])) && p('id,name,productName') && e('133,阶段33,已关闭的正常产品23'); // 测试计算计划133
+r($programplan->processPlanTest($planIDList[3])) && p('id,name,productName') && e('134,阶段34,已关闭的正常产品24'); // 测试计算计划134
+r($programplan->processPlanTest($planIDList[4])) && p('id,name,productName') && e('135,阶段35,已关闭的正常产品25'); // 测试计算计划135
\ No newline at end of file
diff --git a/module/programplan/test/model/processplans.php b/module/programplan/test/model/processplans.php
new file mode 100755
index 0000000000..5f53462e38
--- /dev/null
+++ b/module/programplan/test/model/processplans.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+processPlans();
+cid=1
+pid=1
+
+测试获取计划 11 12的信息 >> 项目1,正常产品1;项目2,正常产品2
+测试获取计划 13 14的信息 >> 项目3,正常产品3;项目4,正常产品4
+测试获取计划 15 16 17的信息 >> 项目5,正常产品5;项目6,正常产品6;项目7,正常产品7
+测试获取计划 18 19 20的信息 >> 项目8,正常产品8;项目9,正常产品9;项目10,正常产品10
+测试获取计划 21 22 23 24的信息 >> 项目11,正常产品1;项目12,正常产品2;项目13,正常产品3;项目14,正常产品4
+
+*/
+$planIDList = array(array(11, 12), array(13, 14), array(15, 16, 17), array(18, 19, 20), array(21, 22, 23, 24));
+
+$programplan = new programplanTest();
+
+r($programplan->processPlansTest($planIDList[0])) && p('11:name,productName;12:name,productName') && e('项目1,正常产品1;项目2,正常产品2'); // 测试获取计划 11 12的信息
+r($programplan->processPlansTest($planIDList[1])) && p('13:name,productName;14:name,productName') && e('项目3,正常产品3;项目4,正常产品4'); // 测试获取计划 13 14的信息
+r($programplan->processPlansTest($planIDList[2])) && p('15:name,productName;16:name,productName;17:name,productName') && e('项目5,正常产品5;项目6,正常产品6;项目7,正常产品7'); // 测试获取计划 15 16 17的信息
+r($programplan->processPlansTest($planIDList[3])) && p('18:name,productName;19:name,productName;20:name,productName') && e('项目8,正常产品8;项目9,正常产品9;项目10,正常产品10'); // 测试获取计划 18 19 20的信息
+r($programplan->processPlansTest($planIDList[4])) && p('21:name,productName;22:name,productName;23:name,productName;24:name,productName') && e('项目11,正常产品1;项目12,正常产品2;项目13,正常产品3;项目14,正常产品4'); // 测试获取计划 21 22 23 24的信息
\ No newline at end of file
diff --git a/module/programplan/test/model/settreepath.php b/module/programplan/test/model/settreepath.php
new file mode 100755
index 0000000000..f2e03e43b7
--- /dev/null
+++ b/module/programplan/test/model/settreepath.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+setTreePath();
+cid=1
+pid=1
+
+测试更新计划131的路径 >> 阶段31;,41,131,
+测试更新计划132的路径 >> 阶段32;,42,132,
+测试更新计划133的路径 >> 阶段33;,43,133,
+测试更新计划134的路径 >> 阶段34;,44,134,
+测试更新计划135的路径 >> 阶段35;,45,135,
+
+*/
+$planIDList = array(131, 132, 133, 134, 135);
+
+$programplan = new programplanTest();
+
+r($programplan->setTreePathTest($planIDList[0])) && p('name;path') && e('阶段31;,41,131,'); // 测试更新计划131的路径
+r($programplan->setTreePathTest($planIDList[1])) && p('name;path') && e('阶段32;,42,132,'); // 测试更新计划132的路径
+r($programplan->setTreePathTest($planIDList[2])) && p('name;path') && e('阶段33;,43,133,'); // 测试更新计划133的路径
+r($programplan->setTreePathTest($planIDList[3])) && p('name;path') && e('阶段34;,44,134,'); // 测试更新计划134的路径
+r($programplan->setTreePathTest($planIDList[4])) && p('name;path') && e('阶段35;,45,135,'); // 测试更新计划135的路径
\ No newline at end of file
diff --git a/module/programplan/test/model/update.php b/module/programplan/test/model/update.php
new file mode 100755
index 0000000000..fe50b81b2b
--- /dev/null
+++ b/module/programplan/test/model/update.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试修改plan的 percent 值 工作占比和超过100 >> 工作量占比累计不应当超过100%
+测试修改plan的 end 值 计划完成小于计划开始 >> 『end』应当不小于。
+测试修改plan的 name 值 名称为空 >> 『name』不能为空。
+测试修改plan的 name 值 >> name,修改后的阶段
+测试修改plan的 percent 值 >> percent,15
+测试修改plan的 begin 值 >> begin,2022-04-01
+测试修改plan的 end 值 >> end,2022-04-30
+
+*/
+$planID = 131;
+$projectID = 41;
+
+$beginNotempty = array('begin' => '');
+$endNotempty = array('end' => '');
+$percentOver = array('percent' => 90);
+$endLeBegin = array('end' => '2022-01-01');
+$nameNotempty = array('name' => '');
+$changeName = array('name' => '修改后的阶段');
+$changePercent = array('percent' => '15');
+$changeBegin = array('begin' => '2022-04-01');
+$changeEnd = array('end' => '2022-04-30');
+
+$programplan = new programplanTest();
+
+//r($programplan->updateTest($planID, $projectID, $beginNotempty, 'begin')) && p() && e(''); // 测试修改plan的 begin 值 计划开始为空
+//r($programplan->updateTest($planID, $projectID, $endNotempty, 'end')) && p() && e(''); // 测试修改plan的 end 值 计划完成为空
+r($programplan->updateTest($planID, $projectID, $percentOver, 'percent')) && p() && e('工作量占比累计不应当超过100%'); // 测试修改plan的 percent 值 工作占比和超过100
+r($programplan->updateTest($planID, $projectID, $endLeBegin, 'end')) && p() && e('『end』应当不小于。'); // 测试修改plan的 end 值 计划完成小于计划开始
+r($programplan->updateTest($planID, $projectID, $nameNotempty, 'name')) && p() && e('『name』不能为空。'); // 测试修改plan的 name 值 名称为空
+r($programplan->updateTest($planID, $projectID, $changeName)) && p('0:field,new') && e('name,修改后的阶段'); // 测试修改plan的 name 值
+r($programplan->updateTest($planID, $projectID, $changePercent)) && p('0:field,new') && e('percent,15'); // 测试修改plan的 percent 值
+r($programplan->updateTest($planID, $projectID, $changeBegin)) && p('0:field,new') && e('begin,2022-04-01'); // 测试修改plan的 begin 值
+r($programplan->updateTest($planID, $projectID, $changeEnd)) && p('0:field,new') && e('end,2022-04-30'); // 测试修改plan的 end 值
diff --git a/module/programplan/test/model/updatesubstageattr.php b/module/programplan/test/model/updatesubstageattr.php
new file mode 100755
index 0000000000..32d38a3265
--- /dev/null
+++ b/module/programplan/test/model/updatesubstageattr.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+gen(5);
+su('admin');
+
+$execution = zdTable('project');
+$execution->id->range('1-5');
+$execution->name->range('瀑布项目1,阶段a,阶段a子1,阶段a子1子1,阶段b');
+$execution->type->range('project,stage{4}');
+$execution->project->range('0,1{4}');
+$execution->parent->range('0,1,2,3,1');
+$execution->path->range("`,1,`,`,1,2,`,`,1,2,3,`,`,1,2,3,4,`,`,1,5,`");
+$execution->status->range('doing,doing,doing,closed,suspended');
+$execution->attribute->range(" ,mix,request,request,review");
+$execution->openedBy->range('admin,user1');
+$execution->begin->range('20220112 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->realBegan->range('20220212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+/**
+
+title=测试programplanModel->updateSubStageAttr();
+cid=1
+pid=1
+
+测试更改id为3的阶段为综合 >> request
+测试更改id为2的阶段为设计 >> design
+
+*/
+
+$plan = new programplanTest();
+
+r($plan->updateSubStageAttrTest(3, 'mix', 4)) && p('') && e('request'); // 测试更改id为3的阶段为综合
+r($plan->updateSubStageAttrTest(2, 'design', 3)) && p('') && e('design'); // 测试更改id为2的阶段为设计
diff --git a/module/programplan/test/programplan.class.php b/module/programplan/test/programplan.class.php
new file mode 100644
index 0000000000..0ba204b175
--- /dev/null
+++ b/module/programplan/test/programplan.class.php
@@ -0,0 +1,474 @@
+objectModel = $tester->loadModel('programplan');
+ $tester->dao->delete()->from(TABLE_PROJECTSPEC)->exec();
+ }
+
+ /**
+ * Test get plan by id.
+ *
+ * @param int $planID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($planID)
+ {
+ $object = $this->objectModel->getByID($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get plans list.
+ *
+ * @param int $executionID
+ * @param int $productID
+ * @param string $browseType
+ * @param string $orderBy
+ * @access public
+ * @return string
+ */
+ public function getStageTest($executionID = 0, $productID = 0, $browseType = 'all', $orderBy = 'id_asc')
+ {
+ $objects = $this->objectModel->getStage($executionID, $productID, $browseType, $orderBy);
+
+ if(dao::isError()) return dao::getError();
+
+ $title = '';
+ foreach($objects as $object) $title .= ',' . $object->name;
+ return $title;
+ }
+
+ /**
+ * Test get plans by idList.
+ *
+ * @param array $idList
+ * @access public
+ * @return array
+ */
+ public function getByListTest($idList = array())
+ {
+ $objects = $this->objectModel->getByList($idList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get plans.
+ *
+ * @param int $executionID
+ * @param int $productID
+ * @param string $orderBy
+ * @access public
+ * @return string
+ */
+ public function getPlansTest($executionID = 0, $productID = 0, $orderBy = 'id_asc')
+ {
+ $objects = $this->objectModel->getPlans($executionID, $productID, $orderBy);
+
+ if(dao::isError()) return dao::getError();
+
+ $title = '';
+ foreach($objects as $object) $title .= ',' . $object->name;
+ return $title;
+ }
+
+ /**
+ * Test get pairs.
+ *
+ * @param int $executionID
+ * @param int $productID
+ * @param string $type
+ * @access public
+ * @return string
+ */
+ public function getPairsTest($executionID, $productID = 0, $type = 'all')
+ {
+ $objects = $this->objectModel->getPairs($executionID, $productID, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get total percent.
+ *
+ * @param int $stageID
+ * @param bool $parent
+ * @access public
+ * @return int
+ */
+ public function getTotalPercentTest($stageID, $parent = false)
+ {
+ $stage = $this->objectModel->getByID($stageID);
+
+ $int = $this->objectModel->getTotalPercent($stage, $parent);
+
+ if(dao::isError()) return dao::getError();
+
+ return $int;
+ }
+
+ /**
+ * Test process plans.
+ *
+ * @param array $planIDList
+ * @access public
+ * @return array
+ */
+ public function processPlansTest($planIDList)
+ {
+ $plans = $this->objectModel->getByList($planIDList);
+
+ $objects = $this->objectModel->processPlans($plans);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test process plan.
+ *
+ * @param int $planID
+ * @access public
+ * @return object
+ */
+ public function processPlanTest($planID)
+ {
+ $plan = $this->objectModel->getByID($planID);
+
+ $object = $this->objectModel->processPlan($plan);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get duration.
+ *
+ * @param date $begin
+ * @param date $end
+ * @access public
+ * @return int
+ */
+ public function getDurationTest($begin, $end)
+ {
+ $count = $this->objectModel->getDuration($begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return $count;
+ }
+
+ /**
+ * Test create a plan.
+ *
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function createTest($param = array())
+ {
+ $_POST['planIDList'] = array('131', '221', '311', '401', '491', '581', '671');
+
+ global $tester;
+ $plans = $tester->dao->select('*')->from(TABLE_PROJECT)->where('id')->in($_POST['planIDList'])->fetchAll();
+
+
+ $_POST['names'] = array('阶段31', '阶段121', '阶段211', '阶段301', '阶段391', '阶段481', '阶段571', '', '', '', '', '');
+ $_POST['PM'] = array('', '', '', '', '', '', '', '', '', '', '', '');
+ $_POST['percents'] = array('0', '0', '0', '0', '0', '0', '0', '', '', '', '', '');
+ $_POST['attributes'] = array('request', 'request', 'request', 'request', 'request', 'request', 'request', 'request', 'request', 'request', 'request', 'request');
+ $_POST['acl'] = array('private', 'open', 'open', 'private', 'private', 'open', 'open', 'open', 'open', 'open', 'open', 'open');
+ $_POST['milestone'] = array('0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0');
+ $_POST['begin'] = (isset($param['begin']) and isset($param['end'])) ? array($plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, '', '', '', '') : array($plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, $plans[0]->begin, '', '', '', '', '');
+ $_POST['end'] = (isset($param['begin']) and isset($param['end'])) ? array($plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, '', '', '', '') : array($plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, $plans[0]->end, '', '', '', '', '');
+ $_POST['realBegan'] = array('', '', '', '', '', '', '', '', '', '', '', '');
+ $_POST['realEnd'] = array('', '', '', '', '', '', '', '', '', '', '', '');
+
+ foreach($param as $field => $value)
+ {
+ if(count($param) == 1 or ($field != 'begin' and $field != 'end')) $_POST[$field] = $value;
+ }
+
+ $objects = $this->objectModel->create(41, 0, 0);
+
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ $error = dao::getError()['message'][0];
+ $error = strpos($error, '所属项目的') > 0 ? preg_replace('/\d{4}-\d{2}-\d{2}/', '', $error) : $error;
+ return $error;
+ }
+
+ $objects = $tester->dao->select('*')->from(TABLE_PROJECT)->where('parent')->eq($plans[0]->parent)->andWhere('type')->eq('stage')->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test set stage tree path.
+ *
+ * @param int $planID
+ * @access public
+ * @return object
+ */
+ public function setTreePathTest($planID)
+ {
+ $this->objectModel->setTreePath($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($planID);
+ return $object;
+ }
+
+ /**
+ * updateTest
+ *
+ * @param int $planID
+ * @param int $projectID
+ * @param array $param
+ * @param string $index
+ * @access public
+ * @return array
+ */
+ public function updateTest($planID, $projectID, $param = array(), $index = '')
+ {
+ $plan = $this->objectModel->getByID($planID);
+
+ $_POST['parent'] = $plan->parent;
+ $_POST['name'] = $plan->name;
+ $_POST['percent'] = $plan->percent;
+ $_POST['attribute'] = $plan->attribute;
+ $_POST['milestone'] = $plan->milestone;
+ $_POST['acl'] = $plan->acl;
+ $_POST['begin'] = $plan->begin;
+ $_POST['end'] = $plan->end;
+ $_POST['realBegan'] = $plan->realBegan;
+ $_POST['realEnd'] = $plan->realEnd;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->update($planID, $projectID);
+
+ unset($_POST);
+
+ if(dao::isError()) return $index == 'end' ? preg_replace('/『\d{4}-\d{2}-\d{2}』/', '', dao::getError()[$index][0]) : dao::getError()[$index][0];
+
+ return $objects;
+ }
+
+ /**
+ * Test is create task.
+ *
+ * @param int $planID
+ * @access public
+ * @return int
+ */
+ public function isCreateTaskTest($planID)
+ {
+ $object = $this->objectModel->isCreateTask($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object ? 2 : 1;
+ }
+
+ /**
+ * Test get the stage set to milestone.
+ *
+ * @param int $projectID
+ * @access public
+ * @return string
+ */
+ public function getMilestonesTest($projectID = 0)
+ {
+ $objects = $this->objectModel->getMilestones($projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get milestone by product.
+ *
+ * @param int $productID
+ * @param int $projectID
+ * @access public
+ * @return string
+ */
+ public function getMilestoneByProductTest($productID, $projectID)
+ {
+ $objects = $this->objectModel->getMilestoneByProduct($productID, $projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get parent stage list.
+ *
+ * @param int $executionID
+ * @param int $planID
+ * @param int $productID
+ * @access public
+ * @return string
+ */
+ public function getParentStageListTest($executionID, $planID, $productID)
+ {
+ $objects = $this->objectModel->getParentStageList($executionID, $planID, $productID);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get parent stage's children types.
+ *
+ * @param int $parentID
+ * @access public
+ * @return string
+ */
+ public function getParentChildrenTypesTest($parentID)
+ {
+ $objects = $this->objectModel->getParentChildrenTypes($parentID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check code unique.
+ *
+ * @param array $codes
+ * @param array $planIDList
+ * @access public
+ * @return string
+ */
+ public function checkCodeUniqueTest($codes, $planIDList = array())
+ {
+ $objects = $this->objectModel->checkCodeUnique($codes, $planIDList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check name unique.
+ *
+ * @param array $names
+ * @access public
+ * @return string
+ */
+ public function checkNameUniqueTest($names)
+ {
+ $objects = $this->objectModel->checkNameUnique($names);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check if the stage is a leaf stage.
+ *
+ * @param int $planID
+ * @access public
+ * @return string
+ */
+ public function checkLeafStageTest($planID)
+ {
+ $objects = $this->objectModel->checkLeafStage($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check whether it is the top stage.
+ *
+ * @param int $planID
+ * @access public
+ * @return string
+ */
+ public function checkTopStageTest($planID)
+ {
+ $objects = $this->objectModel->checkTopStage($planID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test update sub-stage attribute.
+ *
+ * @param int $planID
+ * @param string $attribute
+ * @param int $subStageID
+ * @access public
+ * @return string
+ */
+ public function updateSubStageAttrTest($planID, $attribute, $subStageID)
+ {
+ global $tester;
+
+ $objects = $this->objectModel->updateSubStageAttr($planID, $attribute);
+
+ if(dao::isError()) return dao::getError();
+
+ $attribute = $tester->dao->select('attribute')->from(TABLE_EXECUTION)->where('id')->eq($subStageID)->fetch('attribute');
+
+ return $attribute;
+ }
+
+ /**
+ * Test get plan and its children.
+ *
+ * @param string|int|array $executionIdList
+ * @access public
+ * @return string
+ */
+ public function getSelfAndChildrenListTest($executionIdList)
+ {
+ $objects = $this->objectModel->getSelfAndChildrenList($executionIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get plan's siblings.
+ *
+ * @param string|int|array $executionIdList
+ * @access public
+ * @return string
+ */
+ public function getSiblingsTest($executionIdList)
+ {
+ $objects = $this->objectModel->getSiblings($executionIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/project/test/model/activate.php b/module/project/test/model/activate.php
new file mode 100755
index 0000000000..437fa349f5
--- /dev/null
+++ b/module/project/test/model/activate.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+activate();
+cid=1
+pid=1
+
+激活id为66状态是closed的项目 >> status,closed,doing
+激活id为73状态是suspended的项目 >> status,suspended,doing
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$changes1 = $tester->project->activate(66);
+$changes2 = $tester->project->activate(73);
+
+r($changes1) && p('1:field,old,new') && e('status,closed,doing'); // 激活id为66状态是closed的项目
+r($changes2) && p('1:field,old,new') && e('status,suspended,doing'); // 激活id为73状态是suspended的项目
diff --git a/module/project/test/model/batchupdate.php b/module/project/test/model/batchupdate.php
new file mode 100755
index 0000000000..42bf8dd946
--- /dev/null
+++ b/module/project/test/model/batchupdate.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+查看被编辑了的项目数量 >> 3
+查看被编辑了的项目11详情 >> 批量修改项目11,1,admin,2022-02-08,open
+查看被编辑了的项目12详情 >> 批量修改项目12,2,,2022-03-05,private
+
+*/
+
+$project = new Project();
+$projectIdList = array(11, 12, 13);
+
+$data['names'] = array(11 => '批量修改项目11', 12 => '批量修改项目12', 13 => '批量修改项目13');
+$data['parents'] = array(11 => 1, 12 => 2, 13 => 3);
+$data['projectIdList'] = $projectIdList;
+$data['PMs'] = array(11 => 'admin', 12 => '', 13 => '');
+$data['begins'] = array(11 => '2022-02-08', 12 => '2022-03-05', 13 => '2022-02-19');
+$data['ends'] = array(11 => '2022-04-13', 12 => '2022-04-13', 13 => '2022-04-13');
+$data['dayses'] = array(11 => 10, 12 => 10, 13 => 14);
+$data['acls'] = array(11 => 'open', 12 => 'private', 13 => 'program');
+
+$projects = $project->batchUpdate($data);
+
+r(count($projects)) && p() && e('3'); // 查看被编辑了的项目数量
+r($projects) && p('11:name,parent,PM,begin,acl') && e('批量修改项目11,1,admin,2022-02-08,open'); // 查看被编辑了的项目11详情
+r($projects) && p('12:name,parent,PM,begin,acl') && e('批量修改项目12,2,,2022-03-05,private'); // 查看被编辑了的项目12详情
diff --git a/module/project/test/model/buildmenuquery.php b/module/project/test/model/buildmenuquery.php
new file mode 100755
index 0000000000..a4bfe4e0f1
--- /dev/null
+++ b/module/project/test/model/buildmenuquery.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+buildMenuQuery();
+cid=1
+pid=1
+
+获取构建的查询项目的sql的字符串长度 >> 231
+获取构建的查询项目的sql的字符串长度 >> 233
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r(strlen($tester->project->buildMenuQuery(11))) && p() && e('231'); // 获取构建的查询项目的sql的字符串长度
+r(strlen($tester->project->buildMenuQuery(100))) && p() && e('233'); // 获取构建的查询项目的sql的字符串长度
\ No newline at end of file
diff --git a/module/project/test/model/checkcanchangemodel.php b/module/project/test/model/checkcanchangemodel.php
new file mode 100755
index 0000000000..508a88c88e
--- /dev/null
+++ b/module/project/test/model/checkcanchangemodel.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+checkCanChangeModel();
+cid=1
+pid=1
+
+查看ID为11的敏捷项目是否可切换项目管理模型 >> 0
+查看ID为41的瀑布项目是否可切换项目管理模型 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->checkCanChangeModel(11, 'scrum')) && p() && e('0'); // 查看ID为11的敏捷项目是否可切换项目管理模型
+r($tester->project->checkCanChangeModel(41, 'waterfall')) && p() && e('0'); // 查看ID为41的瀑布项目是否可切换项目管理模型
\ No newline at end of file
diff --git a/module/project/test/model/close.php b/module/project/test/model/close.php
new file mode 100755
index 0000000000..c3ab1d5f8e
--- /dev/null
+++ b/module/project/test/model/close.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+关闭id为20状态不是closed的项目 >> status,wait,closed
+关闭id为26状态是closed的项目 >> closedBy,,admin
+关闭id为41状态是suspended的项目 >> status,suspended,closed
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$_POST['realEnd'] = '2022-03-11';
+
+$changes1 = $tester->project->close(12);
+$changes2 = $tester->project->close(26);
+$changes3 = $tester->project->close(41);
+
+r($changes1) && p('1:field,old,new') && e('status,wait,closed'); // 关闭id为20状态不是closed的项目
+r($changes2) && p('1:field,old,new') && e('closedBy,,admin'); // 关闭id为26状态是closed的项目
+r($changes3) && p('1:field,old,new') && e('status,suspended,closed'); // 关闭id为41状态是suspended的项目
diff --git a/module/project/test/model/computerprogress.php b/module/project/test/model/computerprogress.php
new file mode 100755
index 0000000000..d4b962330c
--- /dev/null
+++ b/module/project/test/model/computerprogress.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+computerProgress();
+cid=1
+pid=1
+
+查看项目11下的所有执行的数量 >> 7
+查看计算后的执行工时汇总信息 >> 10,3,10,23.08,13
+查看计算后的执行工时汇总信息 >> 1,3,1,75,4
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$tester->loadModel('execution');
+
+$executions = $tester->execution->getList(11);
+$executions = $tester->project->computerProgress($executions);
+
+r(count($executions)) && p('') && e('7'); // 查看项目11下的所有执行的数量
+r($executions) && p('551:totalEstimate,totalConsumed,totalLeft,progress,totalReal') && e('10,3,10,23.08,13'); // 查看计算后的执行工时汇总信息
+r($executions) && p('641:totalEstimate,totalConsumed,totalLeft,progress,totalReal') && e('1,3,1,75,4'); // 查看计算后的执行工时汇总信息
\ No newline at end of file
diff --git a/module/project/test/model/create.php b/module/project/test/model/create.php
new file mode 100755
index 0000000000..35e2735dc3
--- /dev/null
+++ b/module/project/test/model/create.php
@@ -0,0 +1,58 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+创建新项目 >> 测试新增项目一
+项目名称为空时 >> 『项目名称』不能为空。
+项目的完成时间为空 >> 『计划完成』不能为空。
+项目的计划完成时间大于计划开始时间 >> 『计划完成』应当大于『2022-02-07』。
+项目的开始时间为空 >> 『计划开始』不能为空。
+
+*/
+
+global $tester;
+$tester->app->loadConfig('execution');
+$project = new Project();
+
+$data = array(
+ 'parent' => 1,
+ 'name' => '测试新增项目一',
+ 'budget' => '',
+ 'budgetUnit' => 'CNY',
+ 'begin' => '2022-02-07',
+ 'end' => '2022-03-01',
+ 'desc' => '测试项目描述',
+ 'acl' => 'private',
+ 'whitelist' => '',
+ 'PM' => '',
+ 'products' => array(1)
+);
+
+$normalProject = $data;
+
+$emptyNameProject = $data;
+$emptyNameProject['name'] = '';
+
+$emptyBeginProject = $data;
+$emptyBeginProject['begin'] = '';
+
+$emptyEndProject = $data;
+$emptyEndProject['end'] = '';
+
+$beginGtEndProject = $data;
+$beginGtEndProject['end'] = '2022-01-10';
+
+r($project->create($normalProject)) && p('name') && e('测试新增项目一'); // 创建新项目
+r($project->create($emptyNameProject)) && p('message[name]:0') && e('『项目名称』不能为空。'); // 项目名称为空时
+r($project->create($emptyEndProject)) && p('message[end]:0') && e('『计划完成』不能为空。'); // 项目的完成时间为空
+r($project->create($beginGtEndProject)) && p('message[end]:0') && e('『计划完成』应当大于『2022-02-07』。'); // 项目的计划完成时间大于计划开始时间
+r($project->create($emptyBeginProject)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 项目的开始时间为空
+
diff --git a/module/project/test/model/getbranchesbyproject.php b/module/project/test/model/getbranchesbyproject.php
new file mode 100755
index 0000000000..11a9ed433e
--- /dev/null
+++ b/module/project/test/model/getbranchesbyproject.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getBranchesByProject();
+cid=1
+pid=1
+
+获取id为11的项目的关联产品的分支数组数量,按产品分组 >> 3
+获取id为11的项目的关联产品的分支数组,获取第一个数组的键 >> 1
+获取id为12的项目的关联产品的分支数组数量,按产品分组 >> 3
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projectIdList = array(11, 12, 13);
+
+r(count($tester->project->getBranchesByProject(11))) && p('') && e('3'); // 获取id为11的项目的关联产品的分支数组数量,按产品分组
+r(key($tester->project->getBranchesByProject(11))) && p('') && e('1'); // 获取id为11的项目的关联产品的分支数组,获取第一个数组的键
+r(count($tester->project->getBranchesByProject(12))) && p('') && e('3'); // 获取id为12的项目的关联产品的分支数组数量,按产品分组
\ No newline at end of file
diff --git a/module/project/test/model/getbranchgroupbyproject.php b/module/project/test/model/getbranchgroupbyproject.php
new file mode 100755
index 0000000000..4c40cf05d7
--- /dev/null
+++ b/module/project/test/model/getbranchgroupbyproject.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getBranchGroupByProject();
+cid=1
+pid=1
+
+获取id为11的项目的关联产品的分支数组数量,按产品分组 >> 1
+获取id为11的项目的关联产品的分支数组,获取第一个数组的键 >> 2
+获取id为12的项目的关联产品的分支数组数量,按产品分组 >> 1
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$productIdList = array(1, 2, 3);
+
+r(count($tester->project->getBranchGroupByProject(11, $productIdList))) && p('') && e('1'); // 获取id为11的项目的关联产品的分支数组数量,按产品分组
+r(key($tester->project->getBranchGroupByProject(12, $productIdList))) && p('') && e('2'); // 获取id为11的项目的关联产品的分支数组,获取第一个数组的键
+r(count($tester->project->getBranchGroupByProject(13, $productIdList))) && p('') && e('1'); // 获取id为12的项目的关联产品的分支数组数量,按产品分组
\ No newline at end of file
diff --git a/module/project/test/model/getbrotherprojects.php b/module/project/test/model/getbrotherprojects.php
new file mode 100755
index 0000000000..79347d3c0d
--- /dev/null
+++ b/module/project/test/model/getbrotherprojects.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getBrotherProjects();
+cid=1
+pid=1
+
+获取项目id为11同一个项目集下的所有项目个数 >> 9
+获取id为731的顶级项目兄弟项目个数 >> 1
+
+*/
+
+global $tester;
+$tester->app->loadConfig('execution');
+$project = new Project();
+
+$projectInst = $project->project->getById(11);
+$programProjects = $project->getBrotherProjectsTest($projectInst);
+$projectInst = $project->project->getById(731);
+$depProjects = $project->getBrotherProjectsTest($projectInst);
+
+r(count($programProjects)) && p() && e('9'); // 获取项目id为11同一个项目集下的所有项目个数
+r(count($depProjects)) && p() && e('1'); // 获取id为731的顶级项目兄弟项目个数
\ No newline at end of file
diff --git a/module/project/test/model/getbudgetunitlist.php b/module/project/test/model/getbudgetunitlist.php
new file mode 100755
index 0000000000..436c4b7e1b
--- /dev/null
+++ b/module/project/test/model/getbudgetunitlist.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+> 人民币,美元
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->getBudgetUnitList()) && p('CNY,USD') && e('人民币,美元'); //获取系统中的货币单位
\ No newline at end of file
diff --git a/module/project/test/model/getbyid.php b/module/project/test/model/getbyid.php
new file mode 100755
index 0000000000..50e5983ad0
--- /dev/null
+++ b/module/project/test/model/getbyid.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+> project1,project
+获取不存在的项目 >> 0
+获取ID等于1的项目集 >> program1,program
+获取不存在的项目集 >> 0
+获取ID等于101的冲刺 >> project1,sprint
+获取不存在的冲刺 >> 0
+获取ID等于131的阶段 >> project31,stage
+获取不存在的阶段 >> 0
+获取ID等于161的阶段 >> project61,kanban
+获取不存在的看板 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->getByID(11, 'project')) && p('code,type') && e('project1,project'); //获取ID等于11的项目
+r($tester->project->getByID(0, 'project')) && p('code,type') && e('0'); //获取不存在的项目
+r($tester->project->getByID(1, 'program')) && p('code,type') && e('program1,program'); //获取ID等于1的项目集
+r($tester->project->getByID(0, 'program')) && p('code,type') && e('0'); //获取不存在的项目集
+r($tester->project->getByID(101, 'sprint')) && p('code,type') && e('project1,sprint'); //获取ID等于101的冲刺
+r($tester->project->getByID(0, 'sprint')) && p('code,type') && e('0'); //获取不存在的冲刺
+r($tester->project->getByID(131, 'stage')) && p('code,type') && e('project31,stage'); //获取ID等于131的阶段
+r($tester->project->getByID(0, 'stage')) && p('code,type') && e('0'); //获取不存在的阶段
+r($tester->project->getByID(161, 'kanban')) && p('code,type') && e('project61,kanban'); //获取ID等于161的阶段
+r($tester->project->getByID(0, 'kanban')) && p('code,type') && e('0'); //获取不存在的看板
\ No newline at end of file
diff --git a/module/project/test/model/getbyidlist.php b/module/project/test/model/getbyidlist.php
new file mode 100755
index 0000000000..a4945fa549
--- /dev/null
+++ b/module/project/test/model/getbyidlist.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+> 项目1;项目2;项目3
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$projectIdList = array(11,12,13);
+
+r(($tester->project->getByIdList($projectIdList))) && p('11:name;12:name;13:name') && e('项目1;项目2;项目3'); //获取projectIdList对应的项目名称
\ No newline at end of file
diff --git a/module/project/test/model/getinfolist.php b/module/project/test/model/getinfolist.php
new file mode 100755
index 0000000000..179a55ed9d
--- /dev/null
+++ b/module/project/test/model/getinfolist.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+> 44
+查询wait状态的Id为11的项目名称 >> 项目1
+查询暂停状态的项目数量 >> 11
+查询关闭状态的项目数量 >> 11
+查询所有状态的项目数量 >> 110
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$doingProjects = $tester->project->getInfoList('doing');
+$waitProjects = $tester->project->getInfoList('wait');
+$suspendedProjects = $tester->project->getInfoList('suspended');
+$closedProjects = $tester->project->getInfoList('closed');
+$allProjects = $tester->project->getInfoList('all');
+
+r(count($doingProjects)) && p() && e('44'); //查询正在进行的项目数量
+r($waitProjects) && p('11:name') && e('项目1'); //查询wait状态的Id为11的项目名称
+r(count($suspendedProjects)) && p() && e('11'); //查询暂停状态的项目数量
+r(count($closedProjects)) && p() && e('11'); //查询关闭状态的项目数量
+r(count($allProjects)) && p() && e('110'); //查询所有状态的项目数量
diff --git a/module/project/test/model/getmembers2import.php b/module/project/test/model/getmembers2import.php
new file mode 100755
index 0000000000..712ec98e4d
--- /dev/null
+++ b/module/project/test/model/getmembers2import.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getMembers2Import();
+cid=1
+pid=1
+
+获取id为11的项目团队成员个数,排除admin >> 1
+获取id为11的项目团队成员的角色 >> 项目经理
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$members = $tester->project->getMembers2Import(11, array('admin'));
+
+r(count($members)) && p() && e('1'); // 获取id为11的项目团队成员个数,排除admin
+r($members) && p('pm92:role') && e('项目经理'); // 获取id为11的项目团队成员的角色
diff --git a/module/project/test/model/getmultilinkedproducts.php b/module/project/test/model/getmultilinkedproducts.php
new file mode 100755
index 0000000000..52cc5ae03b
--- /dev/null
+++ b/module/project/test/model/getmultilinkedproducts.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+> 0
+查询项目11的关联产品数量 >> 3
+查询项目11关联的产品名称 >> 正常产品1,多平台产品91,多平台产品81
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$products1 = $tester->project->getMultiLinkedProducts(1);
+$products2 = $tester->project->getMultiLinkedProducts(11);
+
+r(count($products1)) && p() && e('0'); //查询项目1的关联产品数量
+r(count($products2)) && p() && e('3'); //查询项目11的关联产品数量
+r($products2) && p('1,91,81') && e('正常产品1,多平台产品91,多平台产品81'); //查询项目11关联的产品名称
\ No newline at end of file
diff --git a/module/project/test/model/getoverviewlist.php b/module/project/test/model/getoverviewlist.php
new file mode 100755
index 0000000000..34a7f42f3b
--- /dev/null
+++ b/module/project/test/model/getoverviewlist.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+> 15
+获取状态不为done和closed的项目数量 >> 15
+根据项目ID获取项目 >> 1
+获取不存在的项目 >> 0
+按照ID正序获取项目列表,查看排第一个的项目详情 >> 11,项目1
+按照项目名称倒序获取项目列表,查看排第一个的项目详情 >> 100,项目90
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$byStatus1 = $tester->project->getOverviewList('byStatus', 'wait');
+$byStatus2 = $tester->project->getOverviewList('byStatus', 'undone');
+
+$byId1 = $tester->project->getOverviewList('byid', '11');
+$byId2 = $tester->project->getOverviewList('byid', '10000');
+
+$byOrder1 = $tester->project->getOverviewList('byStatus', 'all', 'id_asc');
+$byOrder2 = $tester->project->getOverviewList('byStatus', 'all', 'name_desc');
+
+r(count($byStatus1)) && p() && e('15'); // 获取未开始的项目数量
+r(count($byStatus2)) && p() && e('15'); // 获取状态不为done和closed的项目数量
+r(count($byId1)) && p() && e('1'); // 根据项目ID获取项目
+r(count($byId2)) && p() && e('0'); // 获取不存在的项目
+r(current($byOrder1)) && p('id,name') && e('11,项目1'); // 按照ID正序获取项目列表,查看排第一个的项目详情
+r(current($byOrder2)) && p('id,name') && e('100,项目90'); // 按照项目名称倒序获取项目列表,查看排第一个的项目详情
\ No newline at end of file
diff --git a/module/project/test/model/getpairsbyidlist.php b/module/project/test/model/getpairsbyidlist.php
new file mode 100755
index 0000000000..ed2b6f6b9c
--- /dev/null
+++ b/module/project/test/model/getpairsbyidlist.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getPairsByIdList();
+cid=1
+pid=1
+
+查找ID为0、11、12、13的项目数量 >> 3
+查找所有项目数量 >> 110
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$projectIdList = array(0, 11, 12, 13);
+
+r(count($tester->project->getPairsByIdList($projectIdList))) && p() && e('3'); //查找ID为0、11、12、13的项目数量
+r(count($tester->project->getPairsByIdList(array()))) && p() && e('110'); //查找所有项目数量
\ No newline at end of file
diff --git a/module/project/test/model/getpairsbymodel.php b/module/project/test/model/getpairsbymodel.php
new file mode 100755
index 0000000000..8b0b3ec7f8
--- /dev/null
+++ b/module/project/test/model/getpairsbymodel.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getPairsByModel();
+cid=1
+pid=1
+
+获取项目集1下的所有项目数量 >> 9
+获取项目集1下的项目名称 >> 项目集1 / 项目11
+获取项目集1下的所有瀑布项目数量 >> 3
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r(count($tester->project->getPairsByModel('all', 1))) && p() && e('9'); // 获取项目集1下的所有项目数量
+r($tester->project->getPairsByModel('all', 1)) && p('21') && e('项目集1 / 项目11'); // 获取项目集1下的项目名称
+r(count($tester->project->getPairsByModel('waterfall', 1))) && p() && e('3'); // 获取项目集1下的所有瀑布项目数量
\ No newline at end of file
diff --git a/module/project/test/model/getpairsbyprogram.php b/module/project/test/model/getpairsbyprogram.php
new file mode 100755
index 0000000000..98678b3bee
--- /dev/null
+++ b/module/project/test/model/getpairsbyprogram.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getPairsByProgram();
+cid=1
+pid=1
+
+查找管理员可查看的所有项目数量 >> 110
+查找独立项目数量 >> 0
+查找管理员可查看的所属项目集ID为1的项目数量 >> 9
+查找管理员可查看的所属项目集ID为1且状态为wait的项目数量 >> 3
+查找管理员可查看的所属项目集ID为1且状态不为closed的项目数量 >> 9
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r(count($tester->project->getPairsByProgram('', 'all', true))) && p() && e('110'); // 查找管理员可查看的所有项目数量
+r(count($tester->project->getPairsByProgram(0))) && p() && e('0'); // 查找独立项目数量
+r(count($tester->project->getPairsByProgram(1))) && p() && e('9'); // 查找管理员可查看的所属项目集ID为1的项目数量
+r(count($tester->project->getPairsByProgram(1, 'wait'))) && p() && e('3'); // 查找管理员可查看的所属项目集ID为1且状态为wait的项目数量
+r(count($tester->project->getPairsByProgram(1, 'noclosed'))) && p() && e('9'); // 查找管理员可查看的所属项目集ID为1且状态不为closed的项目数量
diff --git a/module/project/test/model/getparentprogram.php b/module/project/test/model/getparentprogram.php
new file mode 100755
index 0000000000..5bb2f5674a
--- /dev/null
+++ b/module/project/test/model/getparentprogram.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+> 项目集1
+获取id为1的项目父项目名字 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$project1 = $tester->project->getById(11);
+$project2 = $tester->project->getById(1);
+
+r($tester->project->getParentProgram($project1)) && p('name') && e('项目集1'); // 获取id为11的项目父项目名字
+r($tester->project->getParentProgram($project2)) && p('name') && e('0'); // 获取id为1的项目父项目名字
\ No newline at end of file
diff --git a/module/project/test/model/getprojectsconsumed.php b/module/project/test/model/getprojectsconsumed.php
new file mode 100755
index 0000000000..7e2adf1a51
--- /dev/null
+++ b/module/project/test/model/getprojectsconsumed.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+> 0
+批量获取各个项目的总计消耗工时 >> 0
+批量获取各个项目的总计消耗工时 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projectIdList = array(11, 12, 13);
+
+r($tester->project->getProjectsConsumed($projectIdList)) && p('11:totalConsumed') && e('0'); // 批量获取各个项目的总计消耗工时
+r($tester->project->getProjectsConsumed($projectIdList)) && p('12:totalConsumed') && e('0'); // 批量获取各个项目的总计消耗工时
+r($tester->project->getProjectsConsumed($projectIdList)) && p('13:totalConsumed') && e('0'); // 批量获取各个项目的总计消耗工时
diff --git a/module/project/test/model/getstatdata.php b/module/project/test/model/getstatdata.php
new file mode 100755
index 0000000000..8d52ba7992
--- /dev/null
+++ b/module/project/test/model/getstatdata.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getStatData();
+cid=1
+pid=1
+
+统计id=13的项目bug数量 >> 4
+任务数量 >> 13
+未开始数量 >> 2
+进行的数量 >> 2
+完成的数量 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->getStatData(13)) && p('bugCount') && e('4'); //统计id=13的项目bug数量
+r($tester->project->getStatData(13)) && p('taskCount') && e('13'); //任务数量
+r($tester->project->getStatData(13)) && p('waitCount') && e('2'); //未开始数量
+r($tester->project->getStatData(13)) && p('doingCount') && e('2'); //进行的数量
+r($tester->project->getStatData(13)) && p('finishedCount') && e('0'); //完成的数量
\ No newline at end of file
diff --git a/module/project/test/model/getstats4kanban.php b/module/project/test/model/getstats4kanban.php
new file mode 100755
index 0000000000..658484da1d
--- /dev/null
+++ b/module/project/test/model/getstats4kanban.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getStats4Kanban();
+cid=1
+pid=1
+
+统计获取到的看板数据的分组数量 >> 2
+统计获取到的看板数据的其他数量 >> 11
+统计获取到的看板数据的其他下的项目集1下的wait的项目数量 >> 3
+统计获取到的看板数据的其他下的项目集1下的doing的项目数量 >> 4
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$kanbanGroup = $tester->project->getStats4Kanban();
+
+r(count($kanbanGroup['kanbanGroup'])) && p() && e('2'); //统计获取到的看板数据的分组数量
+r(count($kanbanGroup['kanbanGroup']['other'])) && p() && e('11'); //统计获取到的看板数据的其他数量
+r(count($kanbanGroup['kanbanGroup']['other'][1]['wait'])) && p() && e('3'); //统计获取到的看板数据的其他下的项目集1下的wait的项目数量
+r(count($kanbanGroup['kanbanGroup']['other'][1]['doing'])) && p() && e('4'); //统计获取到的看板数据的其他下的项目集1下的doing的项目数量
\ No newline at end of file
diff --git a/module/project/test/model/getstoriesbyproject.php b/module/project/test/model/getstoriesbyproject.php
new file mode 100755
index 0000000000..ca2d810a5d
--- /dev/null
+++ b/module/project/test/model/getstoriesbyproject.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getStoriesByProject();
+cid=1
+pid=1
+
+获取项目11关联的所有产品数量 >> 2
+获取项目11关联的产品ID为91的详情 >> 91
+获取项目11关联的产品ID为91的需求ID >> 362,364
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$result = $tester->project->getStoriesByProject(11);
+
+r(count($result)) && p() && e('2'); // 获取项目11关联的所有产品数量
+r($result[91]) && p('0:product') && e('91'); // 获取项目11关联的产品ID为91的详情
+r($result[91]) && p('0:storyIDList') && e('362,364'); // 获取项目11关联的产品ID为91的需求ID
diff --git a/module/project/test/model/getswitcher.php b/module/project/test/model/getswitcher.php
new file mode 100755
index 0000000000..5faa3d888e
--- /dev/null
+++ b/module/project/test/model/getswitcher.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+> 0
+获取项目ID为11的迭代列表页面的项目下拉菜单,查看项目1下拉框出现的位置 >> 137
+
+*/
+
+$project = $tester->loadModel('project');
+
+r($project->getSwitcher(11, 'project', 'browse')) && p() && e('0'); // 获取项目下拉菜单,项目列表页面没有项目下拉菜单
+r(strpos($project->getSwitcher(11, 'project', 'execution'), "
项目1")) && p() && e('137'); // 获取项目ID为11的迭代列表页面的项目下拉菜单,查看项目1下拉框出现的位置
\ No newline at end of file
diff --git a/module/project/test/model/getteammemberpairs.php b/module/project/test/model/getteammemberpairs.php
new file mode 100755
index 0000000000..f1c4a0e561
--- /dev/null
+++ b/module/project/test/model/getteammemberpairs.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getTeamMemberPairs();
+cid=1
+pid=1
+
+获取id为11的项目团队成员个数 >> 3
+获取id为11的项目团队成员的详细信息 >> 产品经理92
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$members = $tester->project->getTeamMemberPairs(11);
+
+r(count($members)) && p() && e('3'); // 获取id为11的项目团队成员个数
+r($members) && p('pm92') && e('产品经理92'); // 获取id为11的项目团队成员的详细信息
\ No newline at end of file
diff --git a/module/project/test/model/getteammembers.php b/module/project/test/model/getteammembers.php
new file mode 100755
index 0000000000..591e401295
--- /dev/null
+++ b/module/project/test/model/getteammembers.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 2
+获取id为11的项目团队成员的详细信息 >> 项目经理,123.0,产品经理92
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$members = $tester->project->getTeamMembers(11);
+
+r(count($members)) && p() && e('2'); // 获取id为11的项目团队成员个数
+r($members) && p('pm92:role,totalHours,realname') && e('项目经理,123.0,产品经理92'); // 获取id为11的项目团队成员的详细信息
diff --git a/module/project/test/model/gettotalbugbyproject.php b/module/project/test/model/gettotalbugbyproject.php
new file mode 100755
index 0000000000..afa2ad47f2
--- /dev/null
+++ b/module/project/test/model/gettotalbugbyproject.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getTotalBugByProject();
+cid=1
+pid=1
+
+获取id为11的项目下激活的bug数量 >> 4
+获取id为27的项目下激活的bug数量 >> 1
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projectIdList = array(11, 12, 13, 14, 15, 16, 27);
+$result = $tester->project->getTotalBugByProject($projectIdList, 'active');
+
+r($result[11]) && p('allBugs') && e('4'); //获取id为11的项目下激活的bug数量
+r($result[27]) && p('allBugs') && e('1'); //获取id为27的项目下激活的bug数量
diff --git a/module/project/test/model/gettotalstoriesbyproject.php b/module/project/test/model/gettotalstoriesbyproject.php
new file mode 100755
index 0000000000..ab928b35dc
--- /dev/null
+++ b/module/project/test/model/gettotalstoriesbyproject.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+> 4
+传入产品ID列表,获取项目11下的所有需求数量 >> 4;4
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projectIdList = array(12,13);
+$stories1 = $tester->project->getTotalStoriesByProject(11);
+$stories2 = $tester->project->getTotalStoriesByProject($projectIdList);
+
+r($stories1[11]) && p('allStories') && e('4'); // 不传入产品ID列表,获取项目11下的所有需求数量
+r($stories2) && p('12:allStories;13:allStories') && e('4;4'); // 传入产品ID列表,获取项目11下的所有需求数量
diff --git a/module/project/test/model/gettotaltaskbyproject.php b/module/project/test/model/gettotaltaskbyproject.php
new file mode 100755
index 0000000000..e7dd6cb4c9
--- /dev/null
+++ b/module/project/test/model/gettotaltaskbyproject.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getTotalTaskByProject();
+cid=1
+pid=1
+
+获取id为11的项目下进行中的task数量 >> 4
+获取id为15的项目下完成的task数量 >> 2
+获取id为27的项目下激活的task数量 >> 8
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projectIdList = array(11, 12, 13, 14, 15, 16, 27);
+$result = $tester->project->getTotalTaskByProject($projectIdList);
+
+r($result[11]) && p('doingTasks') && e('4'); // 获取id为11的项目下进行中的task数量
+r($result[15]) && p('doneTasks') && e('2'); // 获取id为15的项目下完成的task数量
+r($result[27]) && p('leftTasks') && e('8'); // 获取id为27的项目下激活的task数量
diff --git a/module/project/test/model/gettreemenu.php b/module/project/test/model/gettreemenu.php
new file mode 100755
index 0000000000..7d6d1d7d68
--- /dev/null
+++ b/module/project/test/model/gettreemenu.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getTreeMenu();
+cid=1
+pid=1
+
+查看获取到的menu option的字符串数量 >> 1756
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$lastMenu = $tester->project->getTreeMenu(0, array('projectmodel', 'createManageLink'));
+
+r(strlen($lastMenu)) && p() && e('1756'); // 查看获取到的menu option的字符串数量
diff --git a/module/project/test/model/getwaterfallpvevac.php b/module/project/test/model/getwaterfallpvevac.php
new file mode 100755
index 0000000000..5362908f0c
--- /dev/null
+++ b/module/project/test/model/getwaterfallpvevac.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getWaterfallPVEVAC();
+cid=1
+pid=1
+
+测试projectID值为0 >> 0.00,0.00,0.00
+测试projectID值为11 >> 97.00,53.94,108.00
+测试projectID值为41 >> 52.00,19.87,33.00
+
+*/
+
+$projectIDList = array(0, 11, 41);
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->getWaterfallPVEVAC($projectIDList[0])) && p('PV,EV,AC') && e('0.00,0.00,0.00'); //测试projectID值为0
+r($tester->project->getWaterfallPVEVAC($projectIDList[1])) && p('PV,EV,AC') && e('97.00,53.94,108.00'); //测试projectID值为11
+r($tester->project->getWaterfallPVEVAC($projectIDList[2])) && p('PV,EV,AC') && e('52.00,19.87,33.00'); //测试projectID值为41
+
diff --git a/module/project/test/model/getworkhour.php b/module/project/test/model/getworkhour.php
new file mode 100755
index 0000000000..6950126488
--- /dev/null
+++ b/module/project/test/model/getworkhour.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> 61.0
+获取项目ID为13的消耗工时,95.0小时 >> 95.0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+r($tester->project->getWorkHour(13)) && p('totalEstimate') && e('61.0'); //获取项目ID为13的预计工时,61.0小时
+r($tester->project->getWorkHour(13)) && p('totalConsumed') && e('95.0'); //获取项目ID为13的消耗工时,95.0小时
+r($tester->project->getWorkHour(1000)) && p('totalEstimate') && e(''); //测试不存在的项目
\ No newline at end of file
diff --git a/module/project/test/model/isclickable.php b/module/project/test/model/isclickable.php
new file mode 100755
index 0000000000..0c0858de1a
--- /dev/null
+++ b/module/project/test/model/isclickable.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+> 1
+检查未开始项目的完成按钮 >> 1
+检查未开始项目的关闭按钮 >> 1
+检查未开始项目的暂停按钮 >> 1
+检查未开始项目的激活按钮 >> 0
+检查进行中项目的开始按钮 >> 0
+检查进行中项目的完成按钮 >> 1
+检查进行中项目的关闭按钮 >> 1
+检查进行中项目的暂停按钮 >> 1
+检查进行中项目的激活按钮 >> 0
+检查已暂停项目的开始按钮 >> 1
+检查已暂停项目的完成按钮 >> 0
+检查已暂停项目的关闭按钮 >> 1
+检查已暂停项目的暂停按钮 >> 0
+检查已暂停项目的激活按钮 >> 0
+检查已关闭项目的开始按钮 >> 0
+检查已关闭项目的完成按钮 >> 0
+检查已关闭项目的关闭按钮 >> 0
+检查已关闭项目的暂停按钮 >> 0
+检查已关闭项目的激活按钮 >> 1
+
+*/
+
+$projectModel = $tester->loadModel('project');
+
+$waitProject = $projectModel->getByID(11);
+$doingProject = $projectModel->getByID(13);
+$suspendProject = $projectModel->getByID(17);
+$closedProject = $projectModel->getByID(18);
+$status = array('start', 'finish', 'close', 'suspend', 'activate', );
+
+r($projectModel->isClickable($waitProject, $status[0])) && p() && e('1'); // 检查未开始项目的开始按钮
+r($projectModel->isClickable($waitProject, $status[1])) && p() && e('1'); // 检查未开始项目的完成按钮
+r($projectModel->isClickable($waitProject, $status[2])) && p() && e('1'); // 检查未开始项目的关闭按钮
+r($projectModel->isClickable($waitProject, $status[3])) && p() && e('1'); // 检查未开始项目的暂停按钮
+r($projectModel->isClickable($waitProject, $status[4])) && p() && e('0'); // 检查未开始项目的激活按钮
+r($projectModel->isClickable($doingProject, $status[0])) && p() && e('0'); // 检查进行中项目的开始按钮
+r($projectModel->isClickable($doingProject, $status[1])) && p() && e('1'); // 检查进行中项目的完成按钮
+r($projectModel->isClickable($doingProject, $status[2])) && p() && e('1'); // 检查进行中项目的关闭按钮
+r($projectModel->isClickable($doingProject, $status[3])) && p() && e('1'); // 检查进行中项目的暂停按钮
+r($projectModel->isClickable($doingProject, $status[4])) && p() && e('0'); // 检查进行中项目的激活按钮
+r($projectModel->isClickable($suspendProject, $status[0])) && p() && e('1'); // 检查已暂停项目的开始按钮
+r($projectModel->isClickable($suspendProject, $status[1])) && p() && e('0'); // 检查已暂停项目的完成按钮
+r($projectModel->isClickable($suspendProject, $status[2])) && p() && e('1'); // 检查已暂停项目的关闭按钮
+r($projectModel->isClickable($suspendProject, $status[3])) && p() && e('0'); // 检查已暂停项目的暂停按钮
+r($projectModel->isClickable($suspendProject, $status[4])) && p() && e('0'); // 检查已暂停项目的激活按钮
+r($projectModel->isClickable($closedProject, $status[0])) && p() && e('0'); // 检查已关闭项目的开始按钮
+r($projectModel->isClickable($closedProject, $status[1])) && p() && e('0'); // 检查已关闭项目的完成按钮
+r($projectModel->isClickable($closedProject, $status[2])) && p() && e('0'); // 检查已关闭项目的关闭按钮
+r($projectModel->isClickable($closedProject, $status[3])) && p() && e('0'); // 检查已关闭项目的暂停按钮
+r($projectModel->isClickable($closedProject, $status[4])) && p() && e('1'); // 检查已关闭项目的激活按钮
\ No newline at end of file
diff --git a/module/project/test/model/managemembers.php b/module/project/test/model/managemembers.php
new file mode 100755
index 0000000000..b4fa8492a2
--- /dev/null
+++ b/module/project/test/model/managemembers.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+unlinkMember();
+cid=1
+pid=1
+
+查看维护团队之后的成员数量 >> 4
+查看维护团队之后的成员详情 >> 开发1
+查看维护团队之后的成员详情 >> 测试2
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$_POST['accounts'] = array('test2', 'user10', 'dev1');
+$_POST['roles'] = array('测试', '市场', '研发');
+$_POST['days'] = array('10', '12', '11');
+$_POST['hours'] = array('7.5', '8', '8.5');
+$_POST['removeExecution'] = 'no';
+
+$tester->project->manageMembers(11);
+$members = $tester->project->getTeamMemberPairs(11);
+
+r(count($members)) && p('') && e('4'); // 查看维护团队之后的成员数量
+r($members) && p('dev1') && e('开发1'); // 查看维护团队之后的成员详情
+r($members) && p('test2') && e('测试2'); // 查看维护团队之后的成员详情
diff --git a/module/project/test/model/putoff.php b/module/project/test/model/putoff.php
new file mode 100755
index 0000000000..17c92ccbfb
--- /dev/null
+++ b/module/project/test/model/putoff.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+start();
+cid=1
+pid=1
+
+延期ID为81的项目,查看延期后的日期 >> 2023-07-01
+延期ID为0的项目,返回空 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$_POST['end'] = '2023-07-01';
+
+$changes1 = $tester->project->putoff(81);
+$changes2 = $tester->project->putoff(0);
+
+r($changes1[0]) && p('new') && e('2023-07-01'); // 延期ID为81的项目,查看延期后的日期
+r($changes2) && p() && e('0'); // 延期ID为0的项目,返回空
diff --git a/module/project/test/model/savestate.php b/module/project/test/model/savestate.php
new file mode 100755
index 0000000000..dbc438e2af
--- /dev/null
+++ b/module/project/test/model/savestate.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+> 99
+不传入ID,保存session,返回第一个key >> 20
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$projects = array(20 => 20, 21 => 21, 22 => 22);
+
+r($tester->project->saveState(99)) && p() && e('99'); //传入存在ID的值99,保存session,返回session
+r($tester->project->saveState(0, $projects)) && p() && e('20'); //不传入ID,保存session,返回第一个key
diff --git a/module/project/test/model/start.php b/module/project/test/model/start.php
new file mode 100755
index 0000000000..7560e926ac
--- /dev/null
+++ b/module/project/test/model/start.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+start();
+cid=1
+pid=1
+
+开始id为81状态是suspended的项目 >> 项目71,doing
+开始id为82状态是closed的项目 >> 0
+开始id为83状态是wait的项目 >> 项目73,doing
+开始id为85状态是doing的项目 >> 0
+
+*/
+
+$project = new Project();
+
+r($project->start(81)) && p('name,status') && e('项目71,doing'); // 开始id为81状态是suspended的项目
+r($project->start(82)) && p() && e('0'); // 开始id为82状态是closed的项目
+r($project->start(83)) && p('name,status') && e('项目73,doing'); // 开始id为83状态是wait的项目
+r($project->start(85)) && p() && e('0'); // 开始id为85状态是doing的项目
diff --git a/module/project/test/model/suspend.php b/module/project/test/model/suspend.php
new file mode 100755
index 0000000000..87b6bc752e
--- /dev/null
+++ b/module/project/test/model/suspend.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+suspend();
+cid=1
+pid=1
+
+挂起id为56状态是doing的项目 >> suspended
+挂起id为73状态是suspended的项目 >> suspendedDate
+挂起id为74状态是closed的项目 >> suspended
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$changes1 = $tester->project->suspend(56);
+$changes2 = $tester->project->suspend(73);
+$changes3 = $tester->project->suspend(74);
+
+r($changes1[0]) && p('new') && e('suspended'); // 挂起id为56状态是doing的项目
+r($changes2[0]) && p('field') && e('suspendedDate'); // 挂起id为73状态是suspended的项目
+r($changes3[0]) && p('new') && e('suspended'); // 挂起id为74状态是closed的项目
diff --git a/module/project/test/model/unlinkmember.php b/module/project/test/model/unlinkmember.php
new file mode 100755
index 0000000000..c965e2f87b
--- /dev/null
+++ b/module/project/test/model/unlinkmember.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+unlinkMember();
+cid=1
+pid=1
+
+查看移除团队成员之前的ID为11的项目团队成员数量 >> 3
+查看移除团队成员之后的ID为11的项目团队成员数量 >> 2
+查看项目ID为11的团队成员的真实姓名 >> 产品经理92
+查看项目ID为11的团队成员的真实姓名 >> 产品经理92
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$beforeMembers = $tester->project->getTeamMemberPairs(11);
+$tester->project->unlinkMember(11, 'admin', false);
+$afterMembers = $tester->project->getTeamMemberPairs(11);
+
+r(count($beforeMembers)) && p('') && e('3'); // 查看移除团队成员之前的ID为11的项目团队成员数量
+r(count($afterMembers)) && p('') && e('2'); // 查看移除团队成员之后的ID为11的项目团队成员数量
+r($beforeMembers) && p('pm92') && e('产品经理92'); // 查看项目ID为11的团队成员的真实姓名
+r($afterMembers) && p('pm92') && e('产品经理92'); // 查看项目ID为11的团队成员的真实姓名
diff --git a/module/project/test/model/update.php b/module/project/test/model/update.php
new file mode 100755
index 0000000000..2bef13797a
--- /dev/null
+++ b/module/project/test/model/update.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+> 测试更新项目十
+未关联产品的项目 >> 最少关联一个产品
+更新项目名称为空时 >> 『项目名称』不能为空。
+当计划完成为空时更新项目信息 >> 『计划开始』不能为空。
+当项目的完成日期小于执行的完成日期时 >> 项目的完成日期应大于等于执行的最大完成日期:2022-10-26
+当项目的开始日期大于执行的开始日期时 >> 项目的开始日期应小于等于执行的最小开始日期:2022-07-07
+
+*/
+
+global $tester;
+$tester->app->loadConfig('execution');
+
+$project = new Project();
+
+$data = array(
+ 'parent' => '0',
+ 'name' => '测试更新项目十',
+ 'begin' => '2022-07-06',
+ 'end' => '2022-10-26',
+ 'acl' => 'private',
+ 'budget' => '100',
+ 'budgetUnit' => 'CNY',
+ 'PM' => 'admin',
+ 'products' => array(1, 2, 3),
+ 'whitelist' => array('dev10', 'dev12')
+);
+
+$normalProject = $data;
+
+$noProductProject = $data;
+$noProductProject['products'] = array();
+
+$emptyTitleProject = $data;
+$emptyTitleProject['name'] = '';
+
+$emptyBeginProject = $data;
+$emptyBeginProject['begin'] = '';
+
+$emptyEndProject = $data;
+$emptyEndProject['end'] = '';
+
+$beginGtExecutionBegin = $data;
+$beginGtExecutionBegin['begin'] = '2022-08-06';
+
+r($project->update(20, $normalProject)) && p('name') && e('测试更新项目十'); // 正常更新项目的情况
+r($project->update(20, $noProductProject)) && p('message:0') && e('最少关联一个产品'); // 未关联产品的项目
+r($project->update(20, $emptyTitleProject)) && p('message[name]:0') && e('『项目名称』不能为空。'); // 更新项目名称为空时
+r($project->update(20, $emptyBeginProject)) && p('message[begin]:0') && e('『计划开始』不能为空。'); // 当计划完成为空时更新项目信息
+r($project->update(20, $emptyEndProject)) && p('message:end') && e('项目的完成日期应大于等于执行的最大完成日期:2022-10-26'); // 当项目的完成日期小于执行的完成日期时
+r($project->update(20, $beginGtExecutionBegin)) && p('message:begin') && e('项目的开始日期应小于等于执行的最小开始日期:2022-07-07'); // 当项目的开始日期大于执行的开始日期时
diff --git a/module/project/test/model/updateproductprogram.php b/module/project/test/model/updateproductprogram.php
new file mode 100755
index 0000000000..cd1ee89e36
--- /dev/null
+++ b/module/project/test/model/updateproductprogram.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+updateProductProgram();
+cid=1
+pid=1
+
+查看被更新了项目集的产品数量 >> 4
+查看被更新了项目集的产品详情 >> 1,正常产品1
+查看被更新了项目集的产品详情 >> 1,正常产品2
+查看被更新了项目集的产品详情 >> 1,正常产品3
+查看被更新了项目集的产品详情 >> 1,正常产品4
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+
+$productIdList = array(1, 2, 3, 4);
+$tester->project->updateProductProgram(7, 1, $productIdList);
+
+$products = $tester->loadModel('product')->getByIdList($productIdList);
+
+r(count($products)) && p('') && e('4'); // 查看被更新了项目集的产品数量
+r($products) && p('1:program,name') && e('1,正常产品1'); // 查看被更新了项目集的产品详情
+r($products) && p('2:program,name') && e('1,正常产品2'); // 查看被更新了项目集的产品详情
+r($products) && p('3:program,name') && e('1,正常产品3'); // 查看被更新了项目集的产品详情
+r($products) && p('4:program,name') && e('1,正常产品4'); // 查看被更新了项目集的产品详情
diff --git a/module/project/test/model/updateproducts.php b/module/project/test/model/updateproducts.php
new file mode 100755
index 0000000000..b3de3810db
--- /dev/null
+++ b/module/project/test/model/updateproducts.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+updateProducts();
+cid=1
+pid=1
+
+查看更新项目关联的产品之前的产品数量 >> 3
+查看更新项目关联的产品之后的产品数量 >> 4
+查看更新项目关联的产品之前的产品名称 >> 多平台产品81
+查看更新项目关联的产品之后的产品名称 >> 正常产品4
+
+*/
+
+global $tester;
+$tester->loadModel('project');
+$tester->loadModel('product');
+
+$beforeProducts = $tester->product->getProductPairsByProject(11);
+
+$productIdList = array(1, 2, 3, 4);
+$tester->project->updateProducts(11, $productIdList);
+
+$afterProducts = $tester->product->getProductPairsByProject(11);
+
+r(count($beforeProducts)) && p() && e('3'); // 查看更新项目关联的产品之前的产品数量
+r(count($afterProducts)) && p() && e('4'); // 查看更新项目关联的产品之后的产品数量
+r($beforeProducts) && p('81') && e('多平台产品81'); // 查看更新项目关联的产品之前的产品名称
+r($afterProducts) && p('4') && e('正常产品4'); // 查看更新项目关联的产品之后的产品名称
diff --git a/module/project/test/project.class.php b/module/project/test/project.class.php
new file mode 100644
index 0000000000..8abf7d2773
--- /dev/null
+++ b/module/project/test/project.class.php
@@ -0,0 +1,106 @@
+project = $tester->loadModel('project');
+ }
+
+ /**
+ * Test start a project.
+ *
+ * @param int $projectID
+ * @access public
+ * @return void
+ */
+ public function start($projectID)
+ {
+ $_POST['realBegan'] = helper::today();
+ $oldProject = $this->project->getById($projectID);
+ if($oldProject->status != 'suspended' and $oldProject->status != 'wait') return false;
+
+ $changes = $this->project->start($projectID);
+
+ return $this->project->getById($projectID);
+ }
+
+ /**
+ * Test create project.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function create($params)
+ {
+ $_POST = $params;
+
+ $projectID = $this->project->create();
+ unset($_POST);
+
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $this->project->getById($projectID);
+ }
+
+ /**
+ * Update a project.
+ *
+ * @param int $projectID
+ * @param array $data
+ * @access public
+ * @return void
+ */
+ public function update($projectID, $data)
+ {
+ $_POST = $data;
+ $this->project->update($projectID);
+
+ unset($_POST);
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $this->project->getByID($projectID);
+ }
+
+ /**
+ * Batch update projects.
+ *
+ * @param array $data
+ * @access public
+ * @return void
+ */
+ public function batchUpdate($data)
+ {
+ $_POST = $data;
+ $this->project->batchUpdate();
+
+ unset($_POST);
+ if(dao::isError()) return array('message' => dao::getError());
+
+ return $this->project->getByIdList($data['projectIdList']);
+ }
+
+ /**
+ * Test get all the projects under the program set to which an project belongs
+ *
+ * @param object $project
+ * @access public
+ * @return void
+ */
+ public function getBrotherProjectsTest($project)
+ {
+ $projectIds = $this->project->getBrotherProjects($project);
+
+ if(dao::isError()) return array('message' => dao::getError());
+ return $projectIds;
+ }
+}
diff --git a/module/projectrelease/test/model/getbyid.php b/module/projectrelease/test/model/getbyid.php
new file mode 100755
index 0000000000..622f1e9d02
--- /dev/null
+++ b/module/projectrelease/test/model/getbyid.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+根据releaseID查找发布详情,能查询到结果 >> 产品1正常的发布1
+根据releaseID查找发布详情,不能查询到结果 >> 0
+
+*/
+
+$releaseID = array(1, 100);
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->getByIDTest($releaseID[0])) && p('name') && e('产品1正常的发布1'); //根据releaseID查找发布详情,能查询到结果
+r($projectrelease->getByIDTest($releaseID[1])) && p('name') && e('0'); //根据releaseID查找发布详情,不能查询到结果
diff --git a/module/projectrelease/test/model/getlast.php b/module/projectrelease/test/model/getlast.php
new file mode 100755
index 0000000000..ea617316e7
--- /dev/null
+++ b/module/projectrelease/test/model/getlast.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getLast();
+cid=1
+pid=1
+
+执行projectID正常存在 >> 产品1发布9
+执行projectID不存在 >> 0
+执行projectID为空 >> 8
+
+*/
+
+$projectID = array(11, 1000, '');
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->getLastTest($projectID[0])) && p('name') && e('产品1发布9'); //执行projectID正常存在
+r($projectrelease->getLastTest($projectID[1])) && p() && e('0'); //执行projectID不存在
+r($projectrelease->getLastTest($projectID[2])) && p('id') && e('8'); //执行projectID为空
diff --git a/module/projectrelease/test/model/getlist.php b/module/projectrelease/test/model/getlist.php
new file mode 100755
index 0000000000..638f78531f
--- /dev/null
+++ b/module/projectrelease/test/model/getlist.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+查询projectID正常存在,type为all的发布 >> 产品1发布9,normal
+查询projectID正常存在,type为normal的发布 >> 产品1发布9,normal
+查询projectID正常存在,type为terminate的发布 >> 0
+查询projectID正常存在,type为''的发布 >> 0
+查询projectID正常存在的发布 >> 产品1发布9,normal
+查询projectID不存在,type为all的发布 >> 0
+查询projectID为空,type为all的发布 >> 8
+
+*/
+
+$projectID = array(11, 1000, '');
+$type = array('all', 'normal', 'terminate', '');
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->getListTest($projectID[0], $type[0])) && p('0:name,status') && e('产品1发布9,normal'); //查询projectID正常存在,type为all的发布
+r($projectrelease->getListTest($projectID[0], $type[1])) && p('0:name,status') && e('产品1发布9,normal'); //查询projectID正常存在,type为normal的发布
+r($projectrelease->getListTest($projectID[0], $type[2])) && p() && e('0'); //查询projectID正常存在,type为terminate的发布
+r($projectrelease->getListTest($projectID[0], $type[3])) && p() && e('0'); //查询projectID正常存在,type为''的发布
+r($projectrelease->getListTest($projectID[0])) && p('0:name,status') && e('产品1发布9,normal'); //查询projectID正常存在的发布
+r($projectrelease->getListTest($projectID[1], $type[0])) && p() && e('0'); //查询projectID不存在,type为all的发布
+r($projectrelease->getListTest($projectID[2], $type[0])) && p('0:id') && e('8'); //查询projectID为空,type为all的发布
diff --git a/module/projectrelease/test/model/getreleasedbuilds.php b/module/projectrelease/test/model/getreleasedbuilds.php
new file mode 100755
index 0000000000..b301c1a55a
--- /dev/null
+++ b/module/projectrelease/test/model/getreleasedbuilds.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getReleasedBuilds();
+cid=1
+pid=1
+
+执行projectID正常存在 >> 2
+执行projectID不存在 >> 0
+执行projectID为空 >> 1
+
+*/
+
+$projectID = array(131, 1000, '');
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->getReleasedBuildsTest($projectID[0])) && p('1') && e('2'); //执行projectID正常存在
+r($projectrelease->getReleasedBuildsTest($projectID[1])) && p() && e('0'); //执行projectID不存在
+r($projectrelease->getReleasedBuildsTest($projectID[2])) && p() && e('1'); //执行projectID为空
\ No newline at end of file
diff --git a/module/projectrelease/test/model/linkbug.php b/module/projectrelease/test/model/linkbug.php
new file mode 100755
index 0000000000..1e8760792a
--- /dev/null
+++ b/module/projectrelease/test/model/linkbug.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+linkBug();
+cid=1
+pid=1
+
+测试normal状态的发布,releaseID正常存在,type为bug >> ,1,2
+测试normal状态的发布,releaseID正常存在,type为leftBug >> ,1,2
+测试normal状态的发布,releaseID正常存在,type为空 >> ,1,2,
+测试terminate状态的发布,releaseID正常存在,type为bug >> ,1,2
+测试terminate状态的发布,releaseID正常存在,type为leftBug >> ,1,2
+测试terminate状态的发布,releaseID正常存在,type为空 >> ,1,2,
+
+*/
+$releaseID = array(1, 10);
+$type = array('bug', 'leftBug', '');
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->linkBugTest($releaseID[0],$type[0])) && p('bugs') && e(',1,2'); //测试normal状态的发布,releaseID正常存在,type为bug
+r($projectrelease->linkBugTest($releaseID[0],$type[1])) && p('leftBugs') && e(',1,2'); //测试normal状态的发布,releaseID正常存在,type为leftBug
+r($projectrelease->linkBugTest($releaseID[0],$type[2])) && p('leftBugs') && e(',1,2,'); //测试normal状态的发布,releaseID正常存在,type为空
+r($projectrelease->linkBugTest($releaseID[1],$type[0])) && p('bugs') && e(',1,2'); //测试terminate状态的发布,releaseID正常存在,type为bug
+r($projectrelease->linkBugTest($releaseID[1],$type[1])) && p('leftBugs') && e(',1,2'); //测试terminate状态的发布,releaseID正常存在,type为leftBug
+r($projectrelease->linkBugTest($releaseID[1],$type[2])) && p('leftBugs') && e(',1,2,'); //测试terminate状态的发布,releaseID正常存在,type为空
diff --git a/module/projectrelease/test/model/linkstory.php b/module/projectrelease/test/model/linkstory.php
new file mode 100755
index 0000000000..f80fa4e49d
--- /dev/null
+++ b/module/projectrelease/test/model/linkstory.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+linkStory();
+cid=1
+pid=1
+
+测试normal状态的发布,releaseID正常存在 >> ,1,2
+测试terminate状态的发布,releaseID正常存在 >> ,1,2
+
+*/
+$releaseID = array(1, 10);
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->linkStoryTest($releaseID[0])) && p('stories') && e(',1,2'); //测试normal状态的发布,releaseID正常存在
+r($projectrelease->linkStoryTest($releaseID[1])) && p('stories') && e(',1,2'); //测试terminate状态的发布,releaseID正常存在
diff --git a/module/projectrelease/test/model/unlinkstory.php b/module/projectrelease/test/model/unlinkstory.php
new file mode 100755
index 0000000000..954a0854a3
--- /dev/null
+++ b/module/projectrelease/test/model/unlinkstory.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+unlinkStory();
+cid=1
+pid=1
+
+测试normal状态的发布,正常存在的storyID值为2,可移除 >> 1
+测试normal状态的发布,不存在的storyID值为100,不可移除 >> 1,2
+测试normal状态的发布,不存在的storyID值为空,不可移除 >> 1,2
+测试terminate状态的发布,正常存在的storyID值为2,可移除 >> 1
+测试terminate状态的发布,不存在的storyID值为100,不可移除 >> 1,2
+测试terminate状态的发布,不存在的storyID值为空,不可移除 >> 1,2
+
+*/
+$releaseID = array(1, 10);
+$storyID = array(2, 100, 0);
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->unlinkStoryTest($releaseID[0], $storyID[0])) && p('stories') && e('1'); //测试normal状态的发布,正常存在的storyID值为2,可移除
+r($projectrelease->unlinkStoryTest($releaseID[0], $storyID[1])) && p('stories') && e('1,2'); //测试normal状态的发布,不存在的storyID值为100,不可移除
+r($projectrelease->unlinkStoryTest($releaseID[0], $storyID[2])) && p('stories') && e('1,2'); //测试normal状态的发布,不存在的storyID值为空,不可移除
+r($projectrelease->unlinkStoryTest($releaseID[1], $storyID[0])) && p('stories') && e('1'); //测试terminate状态的发布,正常存在的storyID值为2,可移除
+r($projectrelease->unlinkStoryTest($releaseID[1], $storyID[1])) && p('stories') && e('1,2'); //测试terminate状态的发布,不存在的storyID值为100,不可移除
+r($projectrelease->unlinkStoryTest($releaseID[1], $storyID[2])) && p('stories') && e('1,2'); //测试terminate状态的发布,不存在的storyID值为空,不可移除
diff --git a/module/projectrelease/test/model/update.php b/module/projectrelease/test/model/update.php
new file mode 100755
index 0000000000..c0e60a0193
--- /dev/null
+++ b/module/projectrelease/test/model/update.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试releaseID不存在,name在发布中不存在,date正常存在,不可修改 >> 没有数据更新
+测试releaseID为空,name在发布中不存在,date正常存在,不可修改 >> 没有数据更新
+测试releaseID正常存在,name在当前发布存在,date正常存在,可修改 >> date,2022-03-31
+测试releaseID正常存在,name在当前发布存在,date为空,不可修改 >> 『date』不能为空。
+测试releaseID正常存在,name在发布中不存在,date正常存在,可修改 >> name,产品正常的正常的发布2
+测试releaseID正常存在,name在发布中不存在,date为空,不可修改 >> 『date』不能为空。
+测试releaseID正常存在,name为空,date正常存在,不可修改 >> 『name』不能为空。
+测试releaseID正常存在,name为空,date为空,不可修改 >> 『name』不能为空。;『date』不能为空。
+测试releaseID正常存在,name在其他发布存在,date正常,不可修改 >> 『name』已经有『产品1发布9』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+$releaseID = array(1, 100, '');
+$name = array('产品1正常的发布1', '产品1发布9', '产品正常的正常的发布2', '');
+$date = array('2022-03-31', '');
+
+$projectrelease = new projectreleaseTest();
+
+r($projectrelease->updateTest($releaseID[1], $name[2], $date[0])) && p() && e('没有数据更新'); //测试releaseID不存在,name在发布中不存在,date正常存在,不可修改
+r($projectrelease->updateTest($releaseID[2], $name[2], $date[0])) && p() && e('没有数据更新'); //测试releaseID为空,name在发布中不存在,date正常存在,不可修改
+r($projectrelease->updateTest($releaseID[0], $name[0], $date[0])) && p('0:field,new') && e('date,2022-03-31'); //测试releaseID正常存在,name在当前发布存在,date正常存在,可修改
+r($projectrelease->updateTest($releaseID[0], $name[0], $date[1])) && p('date:0') && e('『date』不能为空。'); //测试releaseID正常存在,name在当前发布存在,date为空,不可修改
+r($projectrelease->updateTest($releaseID[0], $name[2], $date[0])) && p('0:field,new') && e('name,产品正常的正常的发布2'); //测试releaseID正常存在,name在发布中不存在,date正常存在,可修改
+r($projectrelease->updateTest($releaseID[0], $name[2], $date[1])) && p('date:0') && e('『date』不能为空。'); //测试releaseID正常存在,name在发布中不存在,date为空,不可修改
+r($projectrelease->updateTest($releaseID[0], $name[3], $date[0])) && p('name:0') && e('『name』不能为空。'); //测试releaseID正常存在,name为空,date正常存在,不可修改
+r($projectrelease->updateTest($releaseID[0], $name[3], $date[1])) && p('name:0;date:0') && e('『name』不能为空。;『date』不能为空。'); //测试releaseID正常存在,name为空,date为空,不可修改
+
+r($projectrelease->updateTest($releaseID[0], $name[1], $date[0])) && p('name:0') && e('『name』已经有『产品1发布9』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); //测试releaseID正常存在,name在其他发布存在,date正常,不可修改
+
diff --git a/module/projectrelease/test/projectrelease.class.php b/module/projectrelease/test/projectrelease.class.php
new file mode 100644
index 0000000000..14e68da432
--- /dev/null
+++ b/module/projectrelease/test/projectrelease.class.php
@@ -0,0 +1,195 @@
+objectModel = $tester->loadModel('projectrelease');
+ }
+
+ /**
+ * Test get release by id.
+ *
+ * @param int $releaseID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($releaseID)
+ {
+ $objects = $this->objectModel->getByID($releaseID);
+
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+
+ return $objects;
+ }
+
+ /**
+ * Test get list of releases.
+ *
+ * @param int $projectID
+ * @param string $type
+ * @access public
+ * @return array
+ */
+ public function getListTest($projectID, $type = 'all')
+ {
+ $objects = $this->objectModel->getList($projectID, $type);
+
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+
+ return $objects;
+ }
+
+ /**
+ * Test get last release.
+ *
+ * @param int $projectID
+ * @access public
+ * @return object
+ */
+ public function getLastTest($projectID)
+ {
+ $objects = $this->objectModel->getLast($projectID);
+
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+
+ return $objects;
+ }
+
+ /**
+ * Test get released builds from project.
+ *
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+ public function getReleasedBuildsTest($projectID)
+ {
+ $objects = $this->objectModel->getReleasedBuilds($projectID);
+
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ if(count($objects) == 1)
+ {
+ return count($objects);
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test update a release.
+ *
+ * @param int $releaseID
+ * @param string $name
+ * @param string $date
+ * @access public
+ * @return array
+ */
+ public function updateTest($releaseID, $name = '', $date = '')
+ {
+ global $app;
+ $app->loadConfig('release');
+
+ $updateFields['name'] = $name;
+ $updateFields['build'] = 1;
+ $updateFields['date'] = $date;
+ $updateFields['status'] = 'normal';
+ $updateFields['desc'] = '';
+ $updateFields['labels'] = array();
+ $updateFields['files'] = array();
+ $updateFields['uid'] = '62450877d0a27';
+ $updateFields['product'] = 1;
+ foreach($updateFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ $objects = $this->objectModel->update($releaseID);
+ if($objects == array()) $objects = '没有数据更新';
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test link stories
+ *
+ * @param int $releaseID
+ * @access public
+ * @return array
+ */
+ public function linkStoryTest($releaseID)
+ {
+ $_POST['stories'] = array(1, 2);
+ $this->objectModel->linkStory($releaseID);
+
+ global $tester;
+ $objects = $tester->dao->select('stories')->from(TABLE_RELEASE)->where('id')->eq((int)$releaseID)->fetch();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test unlink stories
+ *
+ * @param int $releaseID
+ * @param int $storyID
+ * @access public
+ * @return array
+ */
+ public function unlinkStoryTest($releaseID, $storyID)
+ {
+ $this->linkStoryTest($releaseID);
+ $this->objectModel->unlinkStory($releaseID, $storyID);
+
+ global $tester;
+ $objects = $tester->dao->select('stories')->from(TABLE_RELEASE)->where('id')->eq((int)$releaseID)->fetch();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test link bugs.
+ *
+ * @param int $releaseID
+ * @param string $type
+ * @access public
+ * @return array
+ */
+ public function linkBugTest($releaseID, $type = 'bug')
+ {
+ $_POST['bugs'] = array(1, 2);
+ $this->objectModel->linkBug($releaseID, $type);
+
+ global $tester;
+ $field = $type == 'bug' ? 'bugs' : 'leftBugs';
+ $objects = $tester->dao->select($field)->from(TABLE_RELEASE)->where('id')->eq((int)$releaseID)->fetch();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/projectstory/test/model/getexecutionstories.php b/module/projectstory/test/model/getexecutionstories.php
new file mode 100755
index 0000000000..7ef331b2a6
--- /dev/null
+++ b/module/projectstory/test/model/getexecutionstories.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+getExecutionStories();
+cid=1
+pid=1
+
+这里取出了id13的项目下需求id10名称 >> 软件需求10
+这里取出了id13的项目下需求id12名称 >> 软件需求12
+这里取出了id14的项目下需求id14名称 >> 软件需求14
+这里取出了id14的项目下需求id16名称 >> 软件需求16
+当项目id不存在时 >> 0
+当需求id不存在时 >> 0
+
+*/
+
+$projectstory = new projectstoryTest();
+
+$projectID = array();
+$projectID[0] = 13;
+$projectID[1] = 14;
+$projectID[2] = 1000;
+
+$storyID = array();
+$storyID[0] = array(10, 12);
+$storyID[1] = array(14, 16);
+$storyID[2] = array(1000, 1001);
+
+r($projectstory->getExecutionStoriesTest($projectID[0], $storyID[0])) && p('10:title') && e('软件需求10'); //这里取出了id13的项目下需求id10名称
+r($projectstory->getExecutionStoriesTest($projectID[0], $storyID[0])) && p('12:title') && e('软件需求12'); //这里取出了id13的项目下需求id12名称
+r($projectstory->getExecutionStoriesTest($projectID[1], $storyID[1])) && p('14:title') && e('软件需求14'); //这里取出了id14的项目下需求id14名称
+r($projectstory->getExecutionStoriesTest($projectID[1], $storyID[1])) && p('16:title') && e('软件需求16'); //这里取出了id14的项目下需求id16名称
+r($projectstory->getExecutionStoriesTest($projectID[2], $storyID[0])) && p('10:title') && e('0'); //当项目id不存在时
+r($projectstory->getExecutionStoriesTest($projectID[0], $storyID[2])) && p('1000:title') && e('0'); //当需求id不存在时
\ No newline at end of file
diff --git a/module/projectstory/test/model/setmenu.php b/module/projectstory/test/model/setmenu.php
new file mode 100755
index 0000000000..22d7952afa
--- /dev/null
+++ b/module/projectstory/test/model/setmenu.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+setMenu();
+cid=1
+pid=1
+
+这里返回一个页面,项目外的情况 >> 您无权访问该产品
+
+*/
+
+$projectstory = new projectstoryTest('admin');
+
+r($projectstory->setMenuTest(array(3, 83))) && p() && e('您无权访问该产品'); //这里返回一个页面,项目外的情况
\ No newline at end of file
diff --git a/module/projectstory/test/projectstory.class.php b/module/projectstory/test/projectstory.class.php
new file mode 100644
index 0000000000..68c2881d6c
--- /dev/null
+++ b/module/projectstory/test/projectstory.class.php
@@ -0,0 +1,44 @@
+objectModel = $tester->loadModel('projectstory');
+ }
+
+ /**
+ * Set menu test
+ *
+ * @param array $products
+ * @param int $productID
+ * @param int $branch
+ * @access public
+ * @return xml
+ */
+ public function setMenuTest($products = array(), $productID = 0, $branch = 0)
+ {
+ $objects = $this->objectModel->setMenu($products, $productID, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get execution stories test
+ *
+ * @param int mixed $projectID
+ * @param array $storyIdList
+ * @access public
+ * @return array
+ */
+ public function getExecutionStoriesTest($projectID, $storyIdList = array())
+ {
+ $objects = $this->objectModel->getExecutionStories($projectID, $storyIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/release/test/model/batchunlinkbug.php b/module/release/test/model/batchunlinkbug.php
new file mode 100755
index 0000000000..0a8ca1f5c7
--- /dev/null
+++ b/module/release/test/model/batchunlinkbug.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+batchUnlinkBug();
+cid=1
+pid=1
+
+正常任务批量移除解决的Bug >> 1,
+正常任务批量移除遗留的Bug >> 1,
+停止维护任务批量移除解决的Bug >> 6,
+停止维护任务批量移除遗留的Bug >> 6,
+
+*/
+
+$releaseID = array('1','6');
+$bugs = array('314','315');
+$type = array('bug', 'leftBug');
+
+$release = new releaseTest();
+
+r($release->batchUnlinkBugTest($releaseID[0], $bugs ,$type[0])) && p('id,bugs,leftBugs') && e('1,'); //正常任务批量移除解决的Bug
+r($release->batchUnlinkBugTest($releaseID[0], $bugs ,$type[1])) && p('id,bugs,leftBugs') && e('1,'); //正常任务批量移除遗留的Bug
+r($release->batchUnlinkBugTest($releaseID[1], $bugs ,$type[0])) && p('id,bugs,leftBugs') && e('6,'); //停止维护任务批量移除解决的Bug
+r($release->batchUnlinkBugTest($releaseID[1], $bugs ,$type[1])) && p('id,bugs,leftBugs') && e('6,'); //停止维护任务批量移除遗留的Bug
+
diff --git a/module/release/test/model/batchunlinkstory.php b/module/release/test/model/batchunlinkstory.php
new file mode 100755
index 0000000000..2ead33babd
--- /dev/null
+++ b/module/release/test/model/batchunlinkstory.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+batchUnlinkStory();
+cid=1
+pid=1
+
+正常任务批量移除关联需求 >> 1,
+停止维护任务批量移除关联需求 >> 6,
+
+*/
+
+$releaseID = array('1','6');
+$stories = array('2','4');
+
+$release = new releaseTest();
+
+r($release->batchUnlinkStoryTest($releaseID[0],$stories)) && p('id,stories') && e('1,'); //正常任务批量移除关联需求
+r($release->batchUnlinkStoryTest($releaseID[1],$stories)) && p('id,stories') && e('6,'); //停止维护任务批量移除关联需求
+
diff --git a/module/release/test/model/changestatus.php b/module/release/test/model/changestatus.php
new file mode 100755
index 0000000000..f87e12519e
--- /dev/null
+++ b/module/release/test/model/changestatus.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+changeStatus();
+cid=1
+pid=1
+
+正常任务批量移除遗留的Bug >> 1,terminate
+停止维护任务批量移除解决的Bug >> 6,normal
+
+*/
+
+$releaseID = array('1','6');
+$status = array('normal','terminate');
+
+$release = new releaseTest();
+
+r($release->changeStatusTest($releaseID[0], $status[1])) && p('id,status') && e('1,terminate'); //正常任务批量移除遗留的Bug
+r($release->changeStatusTest($releaseID[1], $status[0])) && p('id,status') && e('6,normal'); //停止维护任务批量移除解决的Bug
\ No newline at end of file
diff --git a/module/release/test/model/create.php b/module/release/test/model/create.php
new file mode 100755
index 0000000000..e2ada0d371
--- /dev/null
+++ b/module/release/test/model/create.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+执行版本新增发布 >> 11,新增执行版本发布,13
+项目版本新增发布 >> 12,新增项目版本发布,3
+创建里程碑发布 >> 13,新增里程碑发布,13
+创建将版本中完成的研发需求和已解决的Bug关联的发布 >> 14,新增关联发布,13
+创建将版本中完成的研发需求和已解决的Bug不关联的发布 >> 15,新增不关联发布,13
+名称为空测试 >> 『发布名称』不能为空。
+名称重复测试 >> 『发布名称』已经有『新增执行版本发布』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+
+$productID = 3;
+$branch = 'all';
+$projectID = '0';
+
+$release = new releaseTest();
+
+$executionRelease = array('name' => '新增执行版本发布', 'marker' => '0', 'build' => '13', 'desc' => '', 'sync' => true);
+$projectRelease = array('name' => '新增项目版本发布', 'marker' => '0', 'build' => '3', 'desc' => '', 'sync' => true);
+$markerRelease = array('name' => '新增里程碑发布', 'marker' => '1', 'build' => '13', 'desc' => '', 'sync' => true);
+$syncRelease = array('name' => '新增关联发布', 'marker' => '0', 'build' => '13', 'desc' => '', 'sync' => true);
+$noSyncnormalRelease = array('name' => '新增不关联发布', 'marker' => '0', 'build' => '13', 'desc' => '', 'sync' => false);
+$noNameRelease = array('name' => '', 'marker' => '0', 'build' => '13', 'desc' => '', 'sync' => true);
+
+r($release->createTest($projectID, $branch, $projectID, $executionRelease)) && p('id,name,build') && e('11,新增执行版本发布,13'); //执行版本新增发布
+r($release->createTest($projectID, $branch, $projectID, $projectRelease)) && p('id,name,build') && e('12,新增项目版本发布,3'); //项目版本新增发布
+r($release->createTest($projectID, $branch, $projectID, $markerRelease)) && p('id,name,build') && e('13,新增里程碑发布,13'); //创建里程碑发布
+r($release->createTest($projectID, $branch, $projectID, $syncRelease)) && p('id,name,build') && e('14,新增关联发布,13'); //创建将版本中完成的研发需求和已解决的Bug关联的发布
+r($release->createTest($projectID, $branch, $projectID, $noSyncnormalRelease)) && p('id,name,build') && e('15,新增不关联发布,13'); //创建将版本中完成的研发需求和已解决的Bug不关联的发布
+r($release->createTest($projectID, $branch, $projectID, $noNameRelease)) && p('name:0') && e('『发布名称』不能为空。'); //名称为空测试
+r($release->createTest($projectID, $branch, $projectID, $executionRelease)) && p('name:0') && e('『发布名称』已经有『新增执行版本发布』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); //名称重复测试
diff --git a/module/release/test/model/getbyid.php b/module/release/test/model/getbyid.php
new file mode 100755
index 0000000000..92dbfee3da
--- /dev/null
+++ b/module/release/test/model/getbyid.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+正常发布查询 >> 产品1正常的发布1,terminate
+停止维护查询 >> 项目1停止维护的里程碑发布6,normal
+无ID查询 >> 0
+图片字段传字符串测试 >> 产品1正常的发布1,terminate
+
+*/
+$releaseID = array('1', '6');
+
+$release = new releaseTest();
+
+r($release->getByIDTest($releaseID[0],true)) && p('name,status') && e('产品1正常的发布1,terminate'); //正常发布查询
+r($release->getByIDTest($releaseID[1],false)) && p('name,status') && e('项目1停止维护的里程碑发布6,normal'); //停止维护查询
+r($release->getByIDTest('',true)) && p('') && e('0'); //无ID查询
+r($release->getByIDTest($releaseID[0],'true')) && p('name,status') && e('产品1正常的发布1,terminate'); //图片字段传字符串测试
diff --git a/module/release/test/model/getlast.php b/module/release/test/model/getlast.php
new file mode 100755
index 0000000000..94c7ab138a
--- /dev/null
+++ b/module/release/test/model/getlast.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getLast();
+cid=1
+pid=1
+
+产品ID正常查询 >> 9,产品1发布9
+产品ID为空查询 >> 0
+产品ID不存在查询 >> 0
+
+*/
+
+$productID = array('1', '10000');
+
+$release = new releaseTest();
+
+r($release->getLastTest($productID[0])) && p('id,name') && e('9,产品1发布9'); //产品ID正常查询
+r($release->getLastTest('')) && p('') && e('0'); //产品ID为空查询
+r($release->getLastTest($productID[1])) && p('') && e('0'); //产品ID不存在查询
diff --git a/module/release/test/model/getlist.php b/module/release/test/model/getlist.php
new file mode 100755
index 0000000000..3f48679942
--- /dev/null
+++ b/module/release/test/model/getlist.php
@@ -0,0 +1,65 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+branch为'all'并且type为'all'时数据查询 >> 1,产品1正常的发布1
+branch为'all'并且type为'normal'时数据查询 >> 5,产品1正常的里程碑发布5
+branch为'all'并且type为'terminate'时数据查询 >> 1,产品1正常的发布1
+branch为'all'并且type为空时数据查询 >> 0
+branch为0并且type为'all'时数据查询 >> 1,产品1正常的发布1
+branch为0并且type为'normal'时数据查询 >> 3,产品1正常的发布3
+branch为0并且type为'terminate'时数据查询 >> 1,产品1正常的发布1
+branch为0并且type为空时数据查询 >> 0
+branch为1并且type为'all'时数据查询 >> 0
+branch为1并且type为'normal'时数据查询 >> 0
+branch为1并且type为'terminate'时数据查询 >> 0
+branch为1并且type为空时数据查询 >> 0
+branch为2并且type为'all'时数据查询 >> 0
+branch为2并且type为'normal'时数据查询 >> 0
+branch为2并且type为'terminate'时数据查询 >> 0
+branch为2并且type为空时数据查询 >> 0
+branch为空并且type为'all'时数据查询 >> 1,产品1正常的发布1
+branch为空并且type为'normal'时数据查询 >> ,产品1正常的发布3
+branch为空并且type为'terminate'时数据查询 >> 1,产品1正常的发布1
+branch为空并且type为空时数据查询 >> 0
+产品ID为空数据查询 >> 1,产品1正常的发布1
+产品ID不存在数据查询 >> 0
+
+*/
+
+$productID = ['','1','10000'];
+$branchArray = ['all','0','1','2',''];
+$typeArray = ['all','normal','terminate',''];
+
+$release = new releaseTest();
+
+r($release->getListTest($productID[1], $branchArray[0], $typeArray[0])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为'all'并且type为'all'时数据查询
+r($release->getListTest($productID[1], $branchArray[0], $typeArray[1])) && p('1:id,name') && e('5,产品1正常的里程碑发布5'); //branch为'all'并且type为'normal'时数据查询
+r($release->getListTest($productID[1], $branchArray[0], $typeArray[2])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为'all'并且type为'terminate'时数据查询
+r($release->getListTest($productID[1], $branchArray[0], $typeArray[3])) && p() && e('0'); //branch为'all'并且type为空时数据查询
+r($release->getListTest($productID[1], $branchArray[1], $typeArray[0])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为0并且type为'all'时数据查询
+r($release->getListTest($productID[1], $branchArray[1], $typeArray[1])) && p('0:id,name') && e('3,产品1正常的发布3'); //branch为0并且type为'normal'时数据查询
+r($release->getListTest($productID[1], $branchArray[1], $typeArray[2])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为0并且type为'terminate'时数据查询
+r($release->getListTest($productID[1], $branchArray[1], $typeArray[3])) && p() && e('0'); //branch为0并且type为空时数据查询
+r($release->getListTest($productID[1], $branchArray[2], $typeArray[0])) && p() && e('0'); //branch为1并且type为'all'时数据查询
+r($release->getListTest($productID[1], $branchArray[2], $typeArray[1])) && p() && e('0'); //branch为1并且type为'normal'时数据查询
+r($release->getListTest($productID[1], $branchArray[2], $typeArray[2])) && p() && e('0'); //branch为1并且type为'terminate'时数据查询
+r($release->getListTest($productID[1], $branchArray[2], $typeArray[3])) && p() && e('0'); //branch为1并且type为空时数据查询
+r($release->getListTest($productID[1], $branchArray[3], $typeArray[0])) && p() && e('0'); //branch为2并且type为'all'时数据查询
+r($release->getListTest($productID[1], $branchArray[3], $typeArray[1])) && p() && e('0'); //branch为2并且type为'normal'时数据查询
+r($release->getListTest($productID[1], $branchArray[3], $typeArray[2])) && p() && e('0'); //branch为2并且type为'terminate'时数据查询
+r($release->getListTest($productID[1], $branchArray[3], $typeArray[3])) && p() && e('0'); //branch为2并且type为空时数据查询
+r($release->getListTest($productID[1], $branchArray[4], $typeArray[0])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为空并且type为'all'时数据查询
+r($release->getListTest($productID[1], $branchArray[4], $typeArray[1])) && p('0:id,name') && e('3,产品1正常的发布3'); //branch为空并且type为'normal'时数据查询
+r($release->getListTest($productID[1], $branchArray[4], $typeArray[2])) && p('0:id,name') && e('1,产品1正常的发布1'); //branch为空并且type为'terminate'时数据查询
+r($release->getListTest($productID[1], $branchArray[4], $typeArray[3])) && p() && e('0'); //branch为空并且type为空时数据查询
+r($release->getListTest($productID[0], $branchArray[0], $typeArray[0])) && p('0:id,name') && e('1,产品1正常的发布1'); //产品ID为空数据查询
+r($release->getListTest($productID[2], $branchArray[0], $typeArray[0])) && p() && e('0'); //产品ID不存在数据查询
diff --git a/module/release/test/model/getnotifypersons.php b/module/release/test/model/getnotifypersons.php
new file mode 100755
index 0000000000..2846a66f44
--- /dev/null
+++ b/module/release/test/model/getnotifypersons.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getNotifyPersons();
+cid=1
+pid=1
+
+项目版本正常发布数据查询 >> po1
+项目版本停止维护数据查询 >> 0
+执行版本正常发布数据查询 >> po1
+执行版本停止发布数据查询 >> 0
+buildID为空查询 >> 0
+releaseID为空查询 >> 0
+buildID不存在查询 >> po1
+releaseID不存在查询 >> 0
+
+*/
+
+$releaseID = array('1','6','20','');
+
+$release = new releaseTest();
+
+r($release->getNotifyPersonsTest($releaseID[0])) && p('po1') && e('po1');//项目版本正常发布数据查询
+r($release->getNotifyPersonsTest($releaseID[1])) && p('po1') && e('0'); //项目版本停止维护数据查询
+r($release->getNotifyPersonsTest($releaseID[0])) && p('po1') && e('po1');//执行版本正常发布数据查询
+r($release->getNotifyPersonsTest($releaseID[1])) && p('po1') && e('0'); //执行版本停止发布数据查询
+r($release->getNotifyPersonsTest($releaseID[1])) && p('po1') && e('0'); //buildID为空查询
+r($release->getNotifyPersonsTest($releaseID[3])) && p('po1') && e('0'); //releaseID为空查询
+r($release->getNotifyPersonsTest($releaseID[0])) && p('po1') && e('po1');//buildID不存在查询
+r($release->getNotifyPersonsTest($releaseID[2])) && p('po1') && e('0'); //releaseID不存在查询
diff --git a/module/release/test/model/getreleasedbuilds.php b/module/release/test/model/getreleasedbuilds.php
new file mode 100755
index 0000000000..5dc1e9f75c
--- /dev/null
+++ b/module/release/test/model/getreleasedbuilds.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getReleasedBuilds();
+cid=1
+pid=1
+
+branch为'all'时数据查询查询 >> 1,3
+branch为'0'时数据查询查询 >> 1,3
+branch为'1'时数据查询查询 >> 0
+branch为'2'时数据查询查询 >> 0
+branch为''时数据查询查询 >> 1,3
+产品ID为空查询 >> 0
+产品ID不存在查询 >> 0
+
+*/
+
+$productID = array('','1','10000');
+$brachArray = array('all','0','1','2','');
+
+$release = new releaseTest();
+r($release->getReleasedBuildsTest($productID[1], $brachArray[0])) && p('0,1') && e('1,3'); //branch为'all'时数据查询查询
+r($release->getReleasedBuildsTest($productID[1], $brachArray[1])) && p('0,1') && e('1,3'); //branch为'0'时数据查询查询
+r($release->getReleasedBuildsTest($productID[1], $brachArray[2])) && p() && e('0'); //branch为'1'时数据查询查询
+r($release->getReleasedBuildsTest($productID[1], $brachArray[3])) && p() && e('0'); //branch为'2'时数据查询查询
+r($release->getReleasedBuildsTest($productID[1], $brachArray[4])) && p('0,1') && e('1,3'); //branch为''时数据查询查询
+r($release->getReleasedBuildsTest($productID[0], $brachArray[0])) && p() && e('0'); //产品ID为空查询
+r($release->getReleasedBuildsTest($productID[2], $brachArray[0])) && p() && e('0'); //产品ID不存在查询
\ No newline at end of file
diff --git a/module/release/test/model/gettoandcclist.php b/module/release/test/model/gettoandcclist.php
new file mode 100755
index 0000000000..90954aaf9e
--- /dev/null
+++ b/module/release/test/model/gettoandcclist.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getToAndCcList();
+cid=1
+pid=1
+
+正常发布发信列表 >> admin;
+停止维护发布发信列表 >> admin;
+
+*/
+$releaseID = array('1','6');
+
+$release = new releaseTest();
+r($release->getToAndCcListTest($releaseID[0])) && p('0;1') && e('admin;'); //正常发布发信列表
+r($release->getToAndCcListTest($releaseID[1])) && p('0;1') && e('admin;'); //停止维护发布发信列表
\ No newline at end of file
diff --git a/module/release/test/model/linkbug.php b/module/release/test/model/linkbug.php
new file mode 100755
index 0000000000..d90a1d6426
--- /dev/null
+++ b/module/release/test/model/linkbug.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+linkBug();
+cid=1
+pid=1
+
+正常任务关联解决Bug >> 1,,311,312
+正常任务关联遗留Bug >> 1,,311,312,,311,312
+停止维护任务关联解决Bug >> 6,,311,312
+停止维护任务关联遗留Bug >> 6,,311,312,,311,312
+
+*/
+$releaseID = array('1', '6');
+$bugs = array('311', '312');
+$type = array('bug', 'leftBug');
+
+$release = new releaseTest();
+
+r($release->linkBugTest($releaseID[0], $type[0], $bugs)) && p('id,bugs,leftBugs') && e('1,,311,312'); //正常任务关联解决Bug
+r($release->linkBugTest($releaseID[0], $type[1], $bugs)) && p('id,bugs,leftBugs') && e('1,,311,312,,311,312'); //正常任务关联遗留Bug
+r($release->linkBugTest($releaseID[1], $type[0], $bugs)) && p('id,bugs,leftBugs') && e('6,,311,312'); //停止维护任务关联解决Bug
+r($release->linkBugTest($releaseID[1], $type[1], $bugs)) && p('id,bugs,leftBugs') && e('6,,311,312,,311,312'); //停止维护任务关联遗留Bug
+
diff --git a/module/release/test/model/linkstory.php b/module/release/test/model/linkstory.php
new file mode 100755
index 0000000000..827ef8f042
--- /dev/null
+++ b/module/release/test/model/linkstory.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+linkStory();
+cid=1
+pid=1
+
+正常任务关联需求 >> 1,,2,4
+停止维护任务关联需求 >> 6,,2,4
+
+*/
+
+$releaseID = array('1','6');
+$stories = array('2','4');
+
+$release = new releaseTest();
+
+r($release->linkStoryTest($releaseID[0],$stories)) && p('id,stories') && e('1,,2,4'); //正常任务关联需求
+r($release->linkStoryTest($releaseID[1],$stories)) && p('id,stories') && e('6,,2,4'); //停止维护任务关联需求
+
diff --git a/module/release/test/model/unlinkbug.php b/module/release/test/model/unlinkbug.php
new file mode 100755
index 0000000000..3965aee582
--- /dev/null
+++ b/module/release/test/model/unlinkbug.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+unlinkBug();
+cid=1
+pid=1
+
+正常发布批量移除解决的Bug >> 1,
+正常发布批量移除遗留的Bug >> 1,
+停止维护发布批量移除解决的Bug >> 6,
+停止维护发布批量移除遗留的Bug >> 6,
+
+*/
+$releaseID = array('1','6');
+$bugs = array('314');
+$type = array('bug', 'leftBug');
+
+$release = new releaseTest();
+
+r($release->unlinkBugTest($releaseID[0], $bugs ,$type[0])) && p('id,bugs,leftBugs') && e('1,'); //正常发布批量移除解决的Bug
+r($release->unlinkBugTest($releaseID[0], $bugs ,$type[1])) && p('id,bugs,leftBugs') && e('1,'); //正常发布批量移除遗留的Bug
+r($release->unlinkBugTest($releaseID[1], $bugs ,$type[0])) && p('id,bugs,leftBugs') && e('6,'); //停止维护发布批量移除解决的Bug
+r($release->unlinkBugTest($releaseID[1], $bugs ,$type[1])) && p('id,bugs,leftBugs') && e('6,'); //停止维护发布批量移除遗留的Bug
diff --git a/module/release/test/model/unlinkstory.php b/module/release/test/model/unlinkstory.php
new file mode 100755
index 0000000000..5444093d3e
--- /dev/null
+++ b/module/release/test/model/unlinkstory.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+unlinkStory();
+cid=1
+pid=1
+
+正常任务移除关联需求 >> 1,
+停止维护任务移除关联需求 >> 6,
+
+*/
+
+$releaseID = array('1','6');
+$stories = array('2');
+
+$release = new releaseTest();
+
+r($release->unlinkStoryTest($releaseID[0],$stories)) && p('id,stories') && e('1,'); //正常任务移除关联需求
+r($release->unlinkStoryTest($releaseID[1],$stories)) && p('id,stories') && e('6,'); //停止维护任务移除关联需求
+
diff --git a/module/release/test/model/update.php b/module/release/test/model/update.php
new file mode 100755
index 0000000000..285f0e8bd7
--- /dev/null
+++ b/module/release/test/model/update.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+修改正常发布 >> 1,修改正常发布,1
+修改停止维护发布 >> 6,修改停止维护发布,11
+任务ID为空测试 >> 0
+名称为空测试 >> 『发布名称』不能为空。
+
+*/
+$releaseID = array('1', '6', '');
+
+$release = new releaseTest();
+
+$normalRelease = array('name' => '修改正常发布', 'marker' => '0', 'build' => '1', 'status' => 'normal', 'product' => '1' );
+$terminateRelease = array('name' => '修改停止维护发布', 'marker' => '1', 'build' => '11', 'status' => 'terminate', 'product' => '1' );
+$noReleaseID = array('name' => '测试任务ID为空', 'marker' => '0', 'build' => '1', 'status' => 'normal', 'product' => '1' );
+$noName = array('name' => '', 'marker' => '0', 'build' => '1', 'status' => 'normal', 'product' => '1' );
+
+r($release->updateTest($releaseID[0], $normalRelease)) && p('id,name,build') && e('1,修改正常发布,1'); //修改正常发布
+r($release->updateTest($releaseID[1], $terminateRelease)) && p('id,name,build') && e('6,修改停止维护发布,11'); //修改停止维护发布
+r($release->updateTest($releaseID[2], $noReleaseID)) && p() && e('0'); //任务ID为空测试
+r($release->updateTest($releaseID[0], $noName)) && p('name:0') && e('『发布名称』不能为空。'); //名称为空测试
+
diff --git a/module/release/test/release.class.php b/module/release/test/release.class.php
new file mode 100644
index 0000000000..e0dbebc20c
--- /dev/null
+++ b/module/release/test/release.class.php
@@ -0,0 +1,336 @@
+objectModel = $tester->loadModel('release');
+ }
+
+ /**
+ * function getByIDTest by release
+ *
+ * @param string $releaseID
+ * @param beel $setImgSize
+ * @access public
+ * @return array
+ */
+ public function getByIDTest($releaseID, $setImgSize = false)
+ {
+ $objects = $this->objectModel->getByID($releaseID, $setImgSize);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * function getListTest by release
+ *
+ * @param string $productID
+ * @param string $branch
+ * @param string $type
+ * @access public
+ * @return array
+ */
+
+ public function getListTest($productID, $branch = 'all', $type = 'all', $orderBy = 't1.date_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getList($productID, $branch, $type, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * function getLastTest by release
+ *
+ * @param string $productID
+ * @param string $branch
+ * @access public
+ * @return array
+ */
+ public function getLastTest($productID, $branch = 0)
+ {
+ $objects = $this->objectModel->getLast($productID, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get released test builds from product .
+ *
+ * @param int $productID
+ * @param string|int $branch
+ * @access public
+ * @return void
+ */
+ public function getReleasedBuildsTest($productID, $branch = 'all')
+ {
+ $objects = $this->objectModel->getReleasedBuilds($productID, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Create a release.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param int $projectID
+ * @access public
+ * @return array
+ */
+
+ public function createTest($productID = 0, $branch = 0, $projectID = 0, $param = array())
+ {
+
+ $date = date('Y-m-d');
+ $labels = array();
+ $files = array();
+ $mailto = array();
+
+ $createFields = array('name' => '','marker' => '1', 'build' => '', 'date' => $date, 'desc' => '', 'mailto' => $mailto , 'labels' => $labels, 'files' => $files);
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectsID = $this->objectModel->create($productID, $branch, $projectID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($objectsID);
+
+ return $objects;
+ }
+ /**
+ * Update a release.
+ *
+ * @param int $releaseID
+ * @access public
+ * @return array
+ */
+
+ public function updateTest($releaseID, $param = array())
+ {
+ $date = date('Y-m-d');
+ $labels = array();
+ $files = array();
+ $mailto = array();
+
+ $createFields = array('name' => '','marker' => '1', 'build' => '', 'date' => $date, 'desc' => '', 'mailto' => $mailto , 'labels' => $labels, 'files' => $files);
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $this->objectModel->update($releaseID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Get notify persons.
+ *
+ * @param string $notfiyList
+ * @param int $productID
+ * @param int $buildID
+ * @param int $releaseID
+ * @access public
+ * @return array
+ */
+
+ public function getNotifyPersonsTest($releaseID)
+ {
+ $release = $this->objectModel->getById($releaseID);
+ $objects = $this->objectModel->getNotifyPersons($release);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Link stories
+ *
+ * @param int $releaseID
+ * @access public
+ * @return array
+ */
+
+ public function linkStoryTest($releaseID, $stories)
+ {
+ $_POST['stories'] = $stories;
+ $this->objectModel->linkStory($releaseID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Unlink story
+ *
+ * @param int $releaseID
+ * @param int $storyID
+ * @access public
+ * @return array
+ */
+ public function unlinkStoryTest($releaseID, $storyID)
+ {
+ $_POST['stories'] = $storyID;
+ $this->objectModel->linkStory($releaseID);
+ unset($_POST);
+
+ $this->objectModel->unlinkStory($releaseID, $storyID[0]);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Batch unlink story.
+ *
+ * @param int $releaseID
+ * @access public
+ * @return array
+ */
+
+ public function batchUnlinkStoryTest($releaseID, $stories)
+ {
+ $_POST['stories'] = $stories;
+ $this->objectModel->linkStory($releaseID);
+ unset($_POST);
+
+ $_POST['storyIdList'] = $stories;
+ $this->objectModel->batchUnlinkStory($releaseID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+
+ return $objects;
+ }
+
+ /**
+ * Link bugs.
+ *
+ * @param int $releaseID
+ * @param string $type
+ * @param string $bugs
+ * @access public
+ * @return array
+ */
+
+ public function linkBugTest($releaseID, $type = 'bug', $bugs = '')
+ {
+ $_POST['bugs'] = $bugs;
+ $this->objectModel->linkBug($releaseID, $type);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Unlink bug.
+ *
+ * @param int $releaseID
+ * @param int $bugID
+ * @param string $type
+ * @access public
+ * @return void
+ */
+
+ public function unlinkBugTest($releaseID, $bugID, $type = 'bug')
+ {
+ $_POST['bugs'] = $bugID;
+ $this->objectModel->linkBug($releaseID);
+ unset($_POST);
+
+ $this->objectModel->unlinkBug($releaseID, $bugID[0], $type);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Batch unlink bug.
+ *
+ * @param int $releaseID
+ * @param string $type
+ * @param string $bugs
+ * @access public
+ * @return array
+ */
+ public function batchUnlinkBugTest($releaseID, $type = 'bug', $bugs = '')
+ {
+ $_POST['bugs'] = $bugs;
+ $this->objectModel->linkBug($releaseID);
+ unset($_POST);
+
+ $_POST['unlinkBugs'] = $bugs;
+ $this->objectModel->batchUnlinkBug($releaseID, $type);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Change status.
+ *
+ * @param int $releaseID
+ * @param string $status
+ * @access public
+ * @return bool
+ */
+
+ public function changeStatusTest($releaseID, $status)
+ {
+ $this->objectModel->changeStatus($releaseID, $status);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($releaseID);
+ return $objects;
+ }
+
+ /**
+ * Get toList and ccList.
+ *
+ * @param object $release
+ * @access public
+ * @return bool|array
+ */
+ public function getToAndCcListTest($releaseID)
+ {
+ $release = $this->objectModel->getByID($releaseID);
+
+ $objects = $this->objectModel->getToAndCcList($release);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/repo/test/model/addlink.php b/module/repo/test/model/addlink.php
new file mode 100644
index 0000000000..9c11e82321
--- /dev/null
+++ b/module/repo/test/model/addlink.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+addLink();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+$commentTask = 'Finish task #1.';
+$commentStory = 'Effort story #1 Cost 1h.';
+$commentBug = 'Fix bug #1.';
+$commentElse = 'Anything else.';
+r($repo->addLinkTest($commentTask, 'task')) && p('') && e("task #
1"); //任务链接
+r($repo->addLinkTest($commentStory, 'story')) && p('') && e("story #
1"); //需求链接
+r($repo->addLinkTest($commentBug, 'bug')) && p('') && e("bug #
1"); //Bug链接
+r($repo->addLinkTest($commentElse, 'task')) && p('') && e("empty"); //无链接
diff --git a/module/repo/test/model/buildurl.php b/module/repo/test/model/buildurl.php
new file mode 100644
index 0000000000..3c6afe6569
--- /dev/null
+++ b/module/repo/test/model/buildurl.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+buildURL();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->buildURLTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/checkclient.php b/module/repo/test/model/checkclient.php
new file mode 100644
index 0000000000..3d0910912f
--- /dev/null
+++ b/module/repo/test/model/checkclient.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+checkClient();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->checkClientTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/checkconnection.php b/module/repo/test/model/checkconnection.php
new file mode 100644
index 0000000000..c704ae9212
--- /dev/null
+++ b/module/repo/test/model/checkconnection.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+checkConnection();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->checkConnectionTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/checkpriv.php b/module/repo/test/model/checkpriv.php
new file mode 100755
index 0000000000..67bcaeb633
--- /dev/null
+++ b/module/repo/test/model/checkpriv.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+checkPriv();
+cid=1
+pid=1
+
+检查用户权限,返回布尔值 >> 0
+
+*/
+
+$checkPriv = new repoTest();
+$repo = new stdclass();
+$repo->acl = new stdclass();
+$repo->acl->groups = '管理员';
+$repo->acl->user = 'admin';
+
+$result = $checkPriv->checkPrivTest($repo);
+
+r($result) && p($result) && e('0'); //检查用户权限,返回布尔值
\ No newline at end of file
diff --git a/module/repo/test/model/create.php b/module/repo/test/model/create.php
new file mode 100755
index 0000000000..f1f03b89bd
--- /dev/null
+++ b/module/repo/test/model/create.php
@@ -0,0 +1,59 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+正常创建gitlab版本库 >> 1
+当已有版本库时提示已有记录 >> 『名称』已经有『jktest』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+当数据类型为Gitea时提示写版本号 >> 因为安全原因,需要检测客户端版本,请将版本号写入文件
+
+*/
+
+$repo = new repoTest();
+
+$list = array(
+ 'product' => '1',
+ 'SCM' => 'Gitlab',
+ 'serviceHost' => '2',
+ 'serviceProject' => '971',
+ 'name' => 'zzxx',
+ 'path' => '',
+ 'encoding' => 'utf-8',
+ 'client' => '/usr/bin/git',
+ 'account' => '',
+ 'password' => '',
+ 'encrypt' => 'base64',
+ 'desc' => '',
+ 'uid' => '6321819c78be5'
+);
+
+$listOne = array(
+ 'SCM' => 'Gitea',
+ 'serviceHost' => 2,
+ 'serviceProject' => 'root/Demo',
+ 'name' => 'Demo',
+ 'path' => '',
+ 'encoding' => 'utf-8',
+ 'client' => '/usr/bin/git',
+ 'account' => '',
+ 'password' => '',
+ 'encrypt' => 'base64',
+ 'desc' => '',
+ 'uid' => '6322b184f3a72'
+);
+
+$resultOne = $repo->createTest($list);
+$resultTwo = $repo->createTest($list);
+$resultThree = $repo->createTest($listOne);
+
+r($resultOne) && p($resultOne) && e('1'); //正常创建gitlab版本库
+r($resultTwo) && p('name:0') && e('『名称』已经有『jktest』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); //当已有版本库时提示已有记录
+r($resultThree) && p($resultThree) && e('因为安全原因,需要检测客户端版本,请将版本号写入文件'); //当数据类型为Gitea时提示写版本号
+
diff --git a/module/repo/test/model/createactionchanges.php b/module/repo/test/model/createactionchanges.php
new file mode 100644
index 0000000000..e4ebfdf05a
--- /dev/null
+++ b/module/repo/test/model/createactionchanges.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+createActionChanges();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->createActionChangesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/createlink.php b/module/repo/test/model/createlink.php
new file mode 100644
index 0000000000..7f9bdcfb25
--- /dev/null
+++ b/module/repo/test/model/createlink.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+createLink();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->createLinkTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/decodepath.php b/module/repo/test/model/decodepath.php
new file mode 100644
index 0000000000..25d1728959
--- /dev/null
+++ b/module/repo/test/model/decodepath.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+decodePath();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->decodePathTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/encodepath.php b/module/repo/test/model/encodepath.php
new file mode 100644
index 0000000000..e0583e28d0
--- /dev/null
+++ b/module/repo/test/model/encodepath.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+encodePath();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->encodePathTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/fixcommit.php b/module/repo/test/model/fixcommit.php
new file mode 100644
index 0000000000..60acb57b6e
--- /dev/null
+++ b/module/repo/test/model/fixcommit.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+fixCommit();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->fixCommitTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getbranches.php b/module/repo/test/model/getbranches.php
new file mode 100644
index 0000000000..54205cec8c
--- /dev/null
+++ b/module/repo/test/model/getbranches.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getBranches();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getBranchesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getbugproductsandexecutions.php b/module/repo/test/model/getbugproductsandexecutions.php
new file mode 100644
index 0000000000..eae0a674b3
--- /dev/null
+++ b/module/repo/test/model/getbugproductsandexecutions.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getBugProductsAndExecutions();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getBugProductsAndExecutionsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getbyidlist.php b/module/repo/test/model/getbyidlist.php
new file mode 100644
index 0000000000..cd3a0b84ff
--- /dev/null
+++ b/module/repo/test/model/getbyidlist.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getByIdList();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getByIdListTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getcachefile.php b/module/repo/test/model/getcachefile.php
new file mode 100644
index 0000000000..23f61dcf6b
--- /dev/null
+++ b/module/repo/test/model/getcachefile.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getCacheFile();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getCacheFileTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getcloneurl.php b/module/repo/test/model/getcloneurl.php
new file mode 100644
index 0000000000..21cdd7d1b3
--- /dev/null
+++ b/module/repo/test/model/getcloneurl.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getCloneUrl();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+$result1 = $repo->getCloneUrlTest(1);
+$result2 = $repo->getCloneUrlTest(2);
+$result3 = $repo->getCloneUrlTest(3);
+$result4 = $repo->getCloneUrlTest(4);
+$result5 = $repo->getCloneUrlTest(7);
+$result6 = $repo->getCloneUrlTest(11);
+$result7 = $repo->getCloneUrlTest(0);
+
+r($result1) && p('http') && e('');
+r($result2) && p('http') && e('');
+r($result3) && p('http') && e('');
+r($result4) && p('http') && e('');
+r($result5) && p('http') && e('');
+r($result6) && p('http') && e('');
+r($result7) && p('http') && e('');
diff --git a/module/repo/test/model/getcommits.php b/module/repo/test/model/getcommits.php
new file mode 100755
index 0000000000..62c4f79919
--- /dev/null
+++ b/module/repo/test/model/getcommits.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+> 1
+通过repo,path,获取commit数量 >> 1
+
+*/
+
+$repoModel = $tester->loadModel('repo');
+
+$repoID = 1;
+$repo = $repoModel->getRepoByID($repoID);
+$path = '';
+
+$result = $repoModel->getCommits($repo, $path);
+$firstResult = array_shift($result);
+r(isset($firstResult->commit)) && p() && e('1'); //通过repo,path,获取commit列表
+r(count($result) > 0) && p() && e('1'); //通过repo,path,获取commit数量
\ No newline at end of file
diff --git a/module/repo/test/model/getexecutionpairs.php b/module/repo/test/model/getexecutionpairs.php
new file mode 100644
index 0000000000..8d3a70b778
--- /dev/null
+++ b/module/repo/test/model/getexecutionpairs.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getExecutionPairs();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getExecutionPairsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getgitlabproductsbyprojects.php b/module/repo/test/model/getgitlabproductsbyprojects.php
new file mode 100644
index 0000000000..eea239c669
--- /dev/null
+++ b/module/repo/test/model/getgitlabproductsbyprojects.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getGitlabProductsByProjects();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getGitlabProductsByProjectsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getgitrevisionname.php b/module/repo/test/model/getgitrevisionname.php
new file mode 100644
index 0000000000..4979418d37
--- /dev/null
+++ b/module/repo/test/model/getgitrevisionname.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getGitRevisionName();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getGitRevisionNameTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/gethistory.php b/module/repo/test/model/gethistory.php
new file mode 100644
index 0000000000..69ccf4ab78
--- /dev/null
+++ b/module/repo/test/model/gethistory.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getHistory();
+cid=1
+pid=1
+
+*/
+
+global $tester, $dao;
+$repo = $tester->loadModel('repo')->getRepoByID(1);
+$logs = $tester->repo->getUnsyncedCommits($repo);
+$revision = 1;
+$revisions = array();
+foreach($logs as $log)
+{
+ $tester->repo->saveOneCommit($repo->id, $log, $revision);
+ $revisions[] = $log->revision;
+ $revision ++;
+}
+
+$repoTest = new repoTest();
+
+r($repoTest->getHistoryTest(1, $revisions)) && p('1') && e('d5789b703dc09c44be1e89a991c3506de1f678e3'); //查询全部提交信息
+r($repoTest->getHistoryTest(1, array())) && p('') && e('empty'); //传空数据查询信息
+
+$dao->exec('truncate table zt_repohistory');
+$dao->exec('truncate table zt_repobranch');
diff --git a/module/repo/test/model/getlatestcommit.php b/module/repo/test/model/getlatestcommit.php
new file mode 100644
index 0000000000..f780e590bb
--- /dev/null
+++ b/module/repo/test/model/getlatestcommit.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getLatestCommit();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getLatestCommitTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getlist.php b/module/repo/test/model/getlist.php
new file mode 100644
index 0000000000..972a85703e
--- /dev/null
+++ b/module/repo/test/model/getlist.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getListTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getlistbyscm.php b/module/repo/test/model/getlistbyscm.php
new file mode 100644
index 0000000000..3109c9e521
--- /dev/null
+++ b/module/repo/test/model/getlistbyscm.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getListBySCM();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+$result1 = $repo->getListBySCMTest('Gitlab');
+$result2 = $repo->getListBySCMTest('gogs');
+$result3 = $repo->getListBySCMTest('empty');
+
+r($result1) && p('') && e('723test');
+r($result2) && p('') && e('empty');
+r($result3) && p('') && e('empty');
diff --git a/module/repo/test/model/getpreandnext.php b/module/repo/test/model/getpreandnext.php
new file mode 100644
index 0000000000..bca96a9289
--- /dev/null
+++ b/module/repo/test/model/getpreandnext.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getPreAndNext();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getPreAndNextTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getproductsbyrepo.php b/module/repo/test/model/getproductsbyrepo.php
new file mode 100644
index 0000000000..15759347b0
--- /dev/null
+++ b/module/repo/test/model/getproductsbyrepo.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getProductsByRepo();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getProductsByRepoTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrepobyid.php b/module/repo/test/model/getrepobyid.php
new file mode 100644
index 0000000000..53690b8f02
--- /dev/null
+++ b/module/repo/test/model/getrepobyid.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRepoByID();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRepoByIDTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrepobyurl.php b/module/repo/test/model/getrepobyurl.php
new file mode 100755
index 0000000000..93c7e7c1a0
--- /dev/null
+++ b/module/repo/test/model/getrepobyurl.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+> Url is empty.
+使用错误的MR >> No matched gitlab.
+使用正确的MR >> return normal
+
+*/
+
+$repoModel = $tester->loadModel('repo');
+
+$url = '';
+$result = $repoModel->getRepoByUrl($url);
+r($result) && p('message') && e('Url is empty.'); //使用空的MR
+
+$url = 'http://192.168.1.161:51080/gitlab-instance-f9325ed1/azalea723test.git';
+$result = $repoModel->getRepoByUrl($url);
+r($result) && p('message') && e('No matched gitlab.'); //使用错误的MR
+
+$url = 'http://192.168.1.161:51080/root/azalea723test.git';
+$result = $repoModel->getRepoByUrl($url);
+if(!empty($result))
+{
+ if($result['result'] == 'fail' and $result['message'] != 'No matched gitlab.') $result = 'return normal';
+ if(is_array($result) and $result['result'] == 'success') $result = 'return normal';
+}
+r($result) && p() && e('return normal'); //使用正确的MR
\ No newline at end of file
diff --git a/module/repo/test/model/getrepogroup.php b/module/repo/test/model/getrepogroup.php
new file mode 100644
index 0000000000..207f9f69fe
--- /dev/null
+++ b/module/repo/test/model/getrepogroup.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRepoGroup();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRepoGroupTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrepolistbyclient.php b/module/repo/test/model/getrepolistbyclient.php
new file mode 100644
index 0000000000..78bf9860b8
--- /dev/null
+++ b/module/repo/test/model/getrepolistbyclient.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRepoListByClient();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRepoListByClientTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrepolistbyurl.php b/module/repo/test/model/getrepolistbyurl.php
new file mode 100644
index 0000000000..86d4b1db5a
--- /dev/null
+++ b/module/repo/test/model/getrepolistbyurl.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRepoListByUrl();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRepoListByUrlTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrepopairs.php b/module/repo/test/model/getrepopairs.php
new file mode 100644
index 0000000000..09d2422a52
--- /dev/null
+++ b/module/repo/test/model/getrepopairs.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRepoPairs();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRepoPairsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getrevisionsfromdb.php b/module/repo/test/model/getrevisionsfromdb.php
new file mode 100644
index 0000000000..6d49430cb0
--- /dev/null
+++ b/module/repo/test/model/getrevisionsfromdb.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getRevisionsFromDB();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getRevisionsFromDBTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getswitcher.php b/module/repo/test/model/getswitcher.php
new file mode 100644
index 0000000000..70897bcd28
--- /dev/null
+++ b/module/repo/test/model/getswitcher.php
@@ -0,0 +1,15 @@
+#!/usr/bin/env php
+getSwitcher();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
diff --git a/module/repo/test/model/gettaskproductsandexecutions.php b/module/repo/test/model/gettaskproductsandexecutions.php
new file mode 100644
index 0000000000..1bddbfee8b
--- /dev/null
+++ b/module/repo/test/model/gettaskproductsandexecutions.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getTaskProductsAndExecutions();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getTaskProductsAndExecutionsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/getunsyncedcommits.php b/module/repo/test/model/getunsyncedcommits.php
new file mode 100644
index 0000000000..bdb21c1946
--- /dev/null
+++ b/module/repo/test/model/getunsyncedcommits.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getUnsyncedCommits();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->getUnsyncedCommitsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/handlewebhook.php b/module/repo/test/model/handlewebhook.php
new file mode 100644
index 0000000000..b6af289a48
--- /dev/null
+++ b/module/repo/test/model/handlewebhook.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+handleWebhook();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->handleWebhookTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/iconvcomment.php b/module/repo/test/model/iconvcomment.php
new file mode 100644
index 0000000000..407bf92ae1
--- /dev/null
+++ b/module/repo/test/model/iconvcomment.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+iconvComment();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->iconvCommentTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/isbinary.php b/module/repo/test/model/isbinary.php
new file mode 100644
index 0000000000..229367169d
--- /dev/null
+++ b/module/repo/test/model/isbinary.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+isBinary();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->isBinaryTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/marksynced.php b/module/repo/test/model/marksynced.php
new file mode 100644
index 0000000000..78f69a60fa
--- /dev/null
+++ b/module/repo/test/model/marksynced.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+markSynced();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->markSyncedTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/parsecomment.php b/module/repo/test/model/parsecomment.php
new file mode 100644
index 0000000000..a642137d2b
--- /dev/null
+++ b/module/repo/test/model/parsecomment.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+parseComment();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->parseCommentTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/processgitservice.php b/module/repo/test/model/processgitservice.php
new file mode 100644
index 0000000000..85d9487ccc
--- /dev/null
+++ b/module/repo/test/model/processgitservice.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+processGitService();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->processGitServiceTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/processrules.php b/module/repo/test/model/processrules.php
new file mode 100644
index 0000000000..bc33ccb7e8
--- /dev/null
+++ b/module/repo/test/model/processrules.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+processRules();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->processRulesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/replacecommentlink.php b/module/repo/test/model/replacecommentlink.php
new file mode 100644
index 0000000000..95b978cc06
--- /dev/null
+++ b/module/repo/test/model/replacecommentlink.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+replaceCommentLink();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->replaceCommentLinkTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/rmclientversionfile.php b/module/repo/test/model/rmclientversionfile.php
new file mode 100644
index 0000000000..2af499ac52
--- /dev/null
+++ b/module/repo/test/model/rmclientversionfile.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+rmClientVersionFile();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->rmClientVersionFileTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/saveaction2pms.php b/module/repo/test/model/saveaction2pms.php
new file mode 100644
index 0000000000..f3a028e627
--- /dev/null
+++ b/module/repo/test/model/saveaction2pms.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveAction2PMS();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveAction2PMSTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/savecommit.php b/module/repo/test/model/savecommit.php
new file mode 100644
index 0000000000..89fc335495
--- /dev/null
+++ b/module/repo/test/model/savecommit.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveCommit();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveCommitTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/saveexistcommits4branch.php b/module/repo/test/model/saveexistcommits4branch.php
new file mode 100644
index 0000000000..8123aae5eb
--- /dev/null
+++ b/module/repo/test/model/saveexistcommits4branch.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveExistCommits4Branch();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveExistCommits4BranchTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/saveonecommit.php b/module/repo/test/model/saveonecommit.php
new file mode 100644
index 0000000000..0ae860a8bd
--- /dev/null
+++ b/module/repo/test/model/saveonecommit.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveOneCommit();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveOneCommitTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/saverecord.php b/module/repo/test/model/saverecord.php
new file mode 100644
index 0000000000..6da8144010
--- /dev/null
+++ b/module/repo/test/model/saverecord.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveRecord();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveRecordTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/savestate.php b/module/repo/test/model/savestate.php
new file mode 100644
index 0000000000..2863f8f76d
--- /dev/null
+++ b/module/repo/test/model/savestate.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+saveState();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->saveStateTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/setbacksession.php b/module/repo/test/model/setbacksession.php
new file mode 100644
index 0000000000..8bc9c32046
--- /dev/null
+++ b/module/repo/test/model/setbacksession.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+setBackSession();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->setBackSessionTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/setmenu.php b/module/repo/test/model/setmenu.php
new file mode 100644
index 0000000000..723641ae26
--- /dev/null
+++ b/module/repo/test/model/setmenu.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+setMenu();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->setMenuTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/setrepobranch.php b/module/repo/test/model/setrepobranch.php
new file mode 100644
index 0000000000..f82bd0236b
--- /dev/null
+++ b/module/repo/test/model/setrepobranch.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+setRepoBranch();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->setRepoBranchTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/synccommit.php b/module/repo/test/model/synccommit.php
new file mode 100644
index 0000000000..5fd8a7df08
--- /dev/null
+++ b/module/repo/test/model/synccommit.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+syncCommit();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->syncCommitTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/update.php b/module/repo/test/model/update.php
new file mode 100644
index 0000000000..73c2df2760
--- /dev/null
+++ b/module/repo/test/model/update.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->updateTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/model/updatecommitcount.php b/module/repo/test/model/updatecommitcount.php
new file mode 100644
index 0000000000..8484ca3b33
--- /dev/null
+++ b/module/repo/test/model/updatecommitcount.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+updateCommitCount();
+cid=1
+pid=1
+
+*/
+
+$repo = new repoTest();
+
+r($repo->updateCommitCountTest()) && p() && e();
\ No newline at end of file
diff --git a/module/repo/test/repo.class.php b/module/repo/test/repo.class.php
new file mode 100644
index 0000000000..c0ef4b6bc9
--- /dev/null
+++ b/module/repo/test/repo.class.php
@@ -0,0 +1,559 @@
+objectModel = $tester->loadModel('repo');
+ }
+
+ /**
+ * Check priv test.
+ *
+ * @param object $repo
+ * @access public
+ * @return bool
+ */
+ public function checkPrivTest($repo)
+ {
+ $objects = $this->objectModel->checkPriv($repo);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function setMenuTest($repos, $repoID = '', $showSeleter = true)
+ {
+ $objects = $this->objectModel->setMenu($repos, $repoID, $showSeleter);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get switcher test.
+ *
+ * @param int $repoID
+ * @access public
+ * @return object
+ */
+ public function getSwitcherTest($repoID)
+ {
+ $objects = $this->objectModel->getSwitcher($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getListTest($projectID = 0, $SCM = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getList($projectID , $SCM, $orderBy , $pager );
+
+ if(dao::isError()) return dao::getError();
+
+ if(!empty($objects))
+ {
+ return $objects[1]->name;
+ }
+ else
+ {
+ return 'empty';
+ }
+ }
+
+ public function getListBySCMTest($scm, $type = 'all')
+ {
+ $objects = $this->objectModel->getListBySCM($scm, $type = 'all');
+
+ if(dao::isError()) return dao::getError();
+
+ if(!empty($objects))
+ {
+ return $objects[0]->name;
+ }
+ else
+ {
+ return 'empty';
+ }
+ }
+
+ public function createTest($list)
+ {
+ $init = array('SCM' => '', 'serviceHost' => '', 'serviceProject' => '', 'name' => '', 'path' => '', 'encoding' => '', 'client' => '', 'account' => '', 'password' => '', 'encrypt' => '', 'desc' => '', 'uid' => '');
+
+ foreach($init as $filed => $defaultvalue) $_POST[$filed] = $defaultvalue;
+ foreach($list as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->create();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function updateTest($id)
+ {
+ $objects = $this->objectModel->update($id);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveStateTest($repoID = 0, $objectID = 0)
+ {
+ $objects = $this->objectModel->saveState($repoID, $objectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoPairsTest($type, $projectID = 0)
+ {
+ $objects = $this->objectModel->getRepoPairs($type, $projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoGroupTest($type, $projectID = 0)
+ {
+ $objects = $this->objectModel->getRepoGroup($type, $projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoByIDTest($repoID)
+ {
+ $objects = $this->objectModel->getRepoByID($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoByUrlTest($url)
+ {
+ $objects = $this->objectModel->getRepoByUrl($url);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoListByUrlTest($url = '')
+ {
+ $objects = $this->objectModel->getRepoListByUrl($url = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getByIdListTest($idList)
+ {
+ $objects = $this->objectModel->getByIdList($idList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getBranchesTest($repo, $printLabel = false)
+ {
+ $objects = $this->objectModel->getBranches($repo, $printLabel);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getCommitsTest($repo, $entry, $revision = 'HEAD', $type = 'dir', $pager = null, $begin = 0, $end = 0)
+ {
+ $objects = $this->objectModel->getCommits($repo, $entry, $revision, $type, $pager, $begin, $end);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getLatestCommitTest($repoID)
+ {
+ $objects = $this->objectModel->getLatestCommit($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRevisionsFromDBTest($repoID, $limit = '', $maxRevision = '', $minRevision = '')
+ {
+ $objects = $this->objectModel->getRevisionsFromDB($repoID, $limit = '', $maxRevision = '', $minRevision = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getHistoryTest($repoID, $revisions)
+ {
+ $objects = $this->objectModel->getHistory($repoID, $revisions);
+
+ if(dao::isError()) return dao::getError();
+
+ return !empty($objects) ? array_keys($objects) : 'empty';
+ }
+
+ public function getGitRevisionNameTest($revision, $commit)
+ {
+ $objects = $this->objectModel->getGitRevisionName($revision, $commit);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getCacheFileTest($repoID, $path, $revision)
+ {
+ $objects = $this->objectModel->getCacheFile($repoID, $path, $revision);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getProductsByRepoTest($repoID)
+ {
+ $objects = $this->objectModel->getProductsByRepo($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveCommitTest($repoID, $logs, $version, $branch = '')
+ {
+ $objects = $this->objectModel->saveCommit($repoID, $logs, $version, $branch = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveOneCommitTest($repoID, $commit, $version, $branch = '')
+ {
+ $objects = $this->objectModel->saveOneCommit($repoID, $commit, $version, $branch = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveExistCommits4BranchTest($repoID, $branch)
+ {
+ $objects = $this->objectModel->saveExistCommits4Branch($repoID, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function updateCommitCountTest($repoID, $count)
+ {
+ $objects = $this->objectModel->updateCommitCount($repoID, $count);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getUnsyncedCommitsTest($repo)
+ {
+ $objects = $this->objectModel->getUnsyncedCommits($repo);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getPreAndNextTest($repo, $entry, $revision = 'HEAD', $fileType = 'dir', $method = 'view')
+ {
+ $objects = $this->objectModel->getPreAndNext($repo, $entry, $revision, $fileType, $method);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function createLinkTest($method, $params = '', $viewType = '', $onlybody = false)
+ {
+ $objects = $this->objectModel->createLink($method, $params, $viewType, $onlybody);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function setBackSessionTest($type = 'list', $withOtherModule = false)
+ {
+ $objects = $this->objectModel->setBackSession($type, $withOtherModule);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function setRepoBranchTest($branch)
+ {
+ $objects = $this->objectModel->setRepoBranch($branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function markSyncedTest($repoID)
+ {
+ $objects = $this->objectModel->markSynced($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function fixCommitTest($repoID)
+ {
+ $objects = $this->objectModel->fixCommit($repoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function encodePathTest($path = '')
+ {
+ $objects = $this->objectModel->encodePath($path);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function decodePathTest($path = '')
+ {
+ $objects = $this->objectModel->decodePath($path);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function isBinaryTest($content, $suffix = '')
+ {
+ $objects = $this->objectModel->isBinary($content, $suffix);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function checkClientTest()
+ {
+ $objects = $this->objectModel->checkClient();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function rmClientVersionFileTest()
+ {
+ $objects = $this->objectModel->rmClientVersionFile();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function checkConnectionTest()
+ {
+ $objects = $this->objectModel->checkConnection();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function replaceCommentLinkTest($comment)
+ {
+ $objects = $this->objectModel->replaceCommentLink($comment);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function addLinkTest($comment, $type)
+ {
+ $rules = $this->objectModel->processRules();
+ $objectReg = '/' . $rules[$type . 'Reg'] . '/i';
+ if(preg_match_all($objectReg, $comment, $result))
+ {
+ $links = $this->objectModel->addLink($result, $type);
+ foreach($links as $link) return $link;
+ }
+
+ return 'empty';
+ }
+
+ public function parseCommentTest($comment)
+ {
+ $objects = $this->objectModel->parseComment($comment);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function iconvCommentTest($comment, $encodings)
+ {
+ $objects = $this->objectModel->iconvComment($comment, $encodings);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function processRulesTest()
+ {
+ $objects = $this->objectModel->processRules();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveAction2PMSTest($objects, $log, $repoRoot = '', $encodings = 'utf-8', $scm = 'svn', $gitlabAccountPairs = array())
+ {
+ $objects = $this->objectModel->saveAction2PMS($objects, $log, $repoRoot, $encodings, $scm, $gitlabAccountPairs);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function saveRecordTest($action, $changes)
+ {
+ $objects = $this->objectModel->saveRecord($action, $changes);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function createActionChangesTest($log, $repoRoot, $scm = 'svn')
+ {
+ $objects = $this->objectModel->createActionChanges($log, $repoRoot, $scm);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getTaskProductsAndExecutionsTest($tasks)
+ {
+ $objects = $this->objectModel->getTaskProductsAndExecutions($tasks);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getBugProductsAndExecutionsTest($bugs)
+ {
+ $objects = $this->objectModel->getBugProductsAndExecutions($bugs);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function buildURLTest($methodName, $url, $revision, $scm = 'svn')
+ {
+ $objects = $this->objectModel->buildURL($methodName, $url, $revision, $scm);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function processGitServiceTest($repo)
+ {
+ $objects = $this->objectModel->processGitService($repo);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRepoListByClientTest($gitlabID, $projectID = 0)
+ {
+ $objects = $this->objectModel->getRepoListByClient($gitlabID, $projectID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function handleWebhookTest($event, $token, $data, $repo)
+ {
+ $objects = $this->objectModel->handleWebhook($event, $token, $data, $repo);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getGitlabProductsByProjectsTest($projectIDs)
+ {
+ $objects = $this->objectModel->getGitlabProductsByProjects($projectIDs);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function syncCommitTest($repoID, $branchID)
+ {
+ $objects = $this->objectModel->syncCommit($repoID, $branchID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getExecutionPairsTest($product, $branch = 0)
+ {
+ $objects = $this->objectModel->getExecutionPairs($product, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getCloneUrlTest($repo)
+ {
+ $objects = $this->objectModel->getCloneUrl($repo);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/report/test/model/computepercent.php b/module/report/test/model/computepercent.php
new file mode 100755
index 0000000000..f1fa01815d
--- /dev/null
+++ b/module/report/test/model/computepercent.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+computePercent();
+cid=1
+pid=1
+
+测试 bug按照 模块 分组 的百分比 >> 0:0.9714;1821:0.0032;1822:0.0032;1823:0.0032;1825:0.0032;1826:0.0032;1827:0.0032;1831:0.0032;1832:0.0032;1833:0.003;
+测试 bug按照 版本 分组 的百分比 >> 0:0.0095;trunk:0.9238;1:0.019;11:0.019;12:0.0032;13:0.0032;14:0.0032;15:0.0032;16:0.0032;17:0.0032;18:0.0032;19:0.0032;20:0.0031;
+测试 bug按照 严重程度 分组 的百分比 >> 1:0.2508;2:0.2508;3:0.2508;4:0.2476;
+测试 bug按照 解决方案 分组 的百分比 >> fixed:0.3;duplicate:0.2;bydesign:0.12;external:0.12;willnotfix:0.12;postponed:0.08;notrepro:0.06;
+测试 bug按照 优先级 分组 的百分比 >> 1:0.2508;2:0.2508;3:0.2508;4:0.2476;
+测试 bug按照 类型 分组 的百分比 >> codeerror:0.1556;config:0.1079;install:0.1079;security:0.1048;performance:0.1048;standard:0.1048;automation:0.1048;designdefect:0.1048;others:0.10
+
+*/
+$report = new reportTest();
+
+global $tester;
+$bug = $tester->loadModel('bug');
+
+$bugsPerModule = $bug->getDataOfBugsPerModule();
+$bugsPerBuild = $bug->getDataOfBugsPerBuild();
+$bugsPerSeverity = $bug->getDataOfBugsPerSeverity();
+$bugsPerResolution = $bug->getDataOfBugsPerResolution();
+$bugsPerPri = $bug->getDataOfBugsPerPri();
+$bugsPerType = $bug->getDataOfBugsPerType();
+
+r($report->computePercentTest($bugsPerModule)) && p() && e('0:0.9714;1821:0.0032;1822:0.0032;1823:0.0032;1825:0.0032;1826:0.0032;1827:0.0032;1831:0.0032;1832:0.0032;1833:0.003;'); // 测试 bug按照 模块 分组 的百分比
+r($report->computePercentTest($bugsPerBuild)) && p() && e('0:0.0095;trunk:0.9238;1:0.019;11:0.019;12:0.0032;13:0.0032;14:0.0032;15:0.0032;16:0.0032;17:0.0032;18:0.0032;19:0.0032;20:0.0031;'); // 测试 bug按照 版本 分组 的百分比
+r($report->computePercentTest($bugsPerSeverity)) && p() && e('1:0.2508;2:0.2508;3:0.2508;4:0.2476;'); // 测试 bug按照 严重程度 分组 的百分比
+r($report->computePercentTest($bugsPerResolution)) && p() && e('fixed:0.3;duplicate:0.2;bydesign:0.12;external:0.12;willnotfix:0.12;postponed:0.08;notrepro:0.06;'); // 测试 bug按照 解决方案 分组 的百分比
+r($report->computePercentTest($bugsPerPri)) && p() && e('1:0.2508;2:0.2508;3:0.2508;4:0.2476;'); // 测试 bug按照 优先级 分组 的百分比
+r($report->computePercentTest($bugsPerType)) && p() && e('codeerror:0.1556;config:0.1079;install:0.1079;security:0.1048;performance:0.1048;standard:0.1048;automation:0.1048;designdefect:0.1048;others:0.10'); // 测试 bug按照 类型 分组 的百分比
\ No newline at end of file
diff --git a/module/report/test/model/convertformat.php b/module/report/test/model/convertformat.php
new file mode 100755
index 0000000000..5bd2ae56cd
--- /dev/null
+++ b/module/report/test/model/convertformat.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+convertFormat();
+cid=1
+pid=1
+
+测试获取 2022-01-01 到 2022-01-05 的日期列表 >> 2022-01-03,2022-01-04,2022-01-05
+测试获取 2022-01-06 到 2022-01-10 的日期列表 >> 2022-01-06,2022-01-07,2022-01-10
+测试获取 2022-01-11 到 2022-01-15 的日期列表 >> 2022-01-11,2022-01-12,2022-01-13,2022-01-14
+测试获取 2022-01-16 到 2022-01-20 的日期列表 >> 2022-01-17,2022-01-18,2022-01-19,2022-01-20
+测试获取 2022-01-01 到 2022-01-05 的日期列表 >> 2022-01-01,2022-01-02,2022-01-03,2022-01-04,2022-01-05
+测试获取 2022-01-06 到 2022-01-10 的日期列表 >> 2022-01-06,2022-01-07,2022-01-08,2022-01-09,2022-01-10
+测试获取 2022-01-11 到 2022-01-15 的日期列表 >> 2022-01-11,2022-01-12,2022-01-13,2022-01-14,2022-01-15
+测试获取 2022-01-16 到 2022-01-20 的日期列表 >> 2022-01-16,2022-01-17,2022-01-18,2022-01-19,2022-01-20
+
+*/
+$report = new reportTest();
+
+global $tester;
+$execution = $tester->loadModel('execution');
+
+$date1 = $execution->getDateList('2022-01-01', '2022-01-05', 'noweekend');
+$date2 = $execution->getDateList('2022-01-06', '2022-01-10', 'noweekend');
+$date3 = $execution->getDateList('2022-01-11', '2022-01-15', 'noweekend');
+$date4 = $execution->getDateList('2022-01-16', '2022-01-20', 'noweekend');
+$date5 = $execution->getDateList('2022-01-01', '2022-01-05', 'withweekend');
+$date6 = $execution->getDateList('2022-01-06', '2022-01-10', 'withweekend');
+$date7 = $execution->getDateList('2022-01-11', '2022-01-15', 'withweekend');
+$date8 = $execution->getDateList('2022-01-16', '2022-01-20', 'withweekend');
+
+r($report->convertFormatTest($date1[0])) && p() && e('2022-01-03,2022-01-04,2022-01-05'); // 测试获取 2022-01-01 到 2022-01-05 的日期列表
+r($report->convertFormatTest($date2[0])) && p() && e('2022-01-06,2022-01-07,2022-01-10'); // 测试获取 2022-01-06 到 2022-01-10 的日期列表
+r($report->convertFormatTest($date3[0])) && p() && e('2022-01-11,2022-01-12,2022-01-13,2022-01-14'); // 测试获取 2022-01-11 到 2022-01-15 的日期列表
+r($report->convertFormatTest($date4[0])) && p() && e('2022-01-17,2022-01-18,2022-01-19,2022-01-20'); // 测试获取 2022-01-16 到 2022-01-20 的日期列表
+r($report->convertFormatTest($date5[0])) && p() && e('2022-01-01,2022-01-02,2022-01-03,2022-01-04,2022-01-05'); // 测试获取 2022-01-01 到 2022-01-05 的日期列表
+r($report->convertFormatTest($date6[0])) && p() && e('2022-01-06,2022-01-07,2022-01-08,2022-01-09,2022-01-10'); // 测试获取 2022-01-06 到 2022-01-10 的日期列表
+r($report->convertFormatTest($date7[0])) && p() && e('2022-01-11,2022-01-12,2022-01-13,2022-01-14,2022-01-15'); // 测试获取 2022-01-11 到 2022-01-15 的日期列表
+r($report->convertFormatTest($date8[0])) && p() && e('2022-01-16,2022-01-17,2022-01-18,2022-01-19,2022-01-20'); // 测试获取 2022-01-16 到 2022-01-20 的日期列表
\ No newline at end of file
diff --git a/module/report/test/model/createsinglejson.php b/module/report/test/model/createsinglejson.php
new file mode 100755
index 0000000000..40cfce18e2
--- /dev/null
+++ b/module/report/test/model/createsinglejson.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+createSingleJSON();
+cid=1
+pid=1
+
+测试获取执行 101 的json数据 >> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36]
+测试获取执行 102 的json数据 >> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4]
+测试获取执行 103 的json数据 >> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23]
+测试获取执行 104 的json数据 >> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12]
+测试获取执行 105 的json数据 >> [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6]
+
+*/
+
+$report = new reportTest();
+
+$executionID = array(101, 102, 103, 104, 105);
+
+r($report->createSingleJSONTest($executionID[0])) && p() && e('[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36]'); // 测试获取执行 101 的json数据
+r($report->createSingleJSONTest($executionID[1])) && p() && e('[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4]'); // 测试获取执行 102 的json数据
+r($report->createSingleJSONTest($executionID[2])) && p() && e('[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23]'); // 测试获取执行 103 的json数据
+r($report->createSingleJSONTest($executionID[3])) && p() && e('[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12]'); // 测试获取执行 104 的json数据
+r($report->createSingleJSONTest($executionID[4])) && p() && e('[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6]'); // 测试获取执行 105 的json数据
\ No newline at end of file
diff --git a/module/report/test/model/getalltimestatusstat.php b/module/report/test/model/getalltimestatusstat.php
new file mode 100755
index 0000000000..cbb5ec8145
--- /dev/null
+++ b/module/report/test/model/getalltimestatusstat.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getAllTimeStatusStat();
+cid=1
+pid=1
+
+测试获取 需求 的状态分组个数 >> changed:81;active:93;draft:51;
+测试获取 任务 的状态分组个数 >> wait:152;doing:152;done:152;pause:152;cancel:151;closed:151;
+测试获取 bug 的状态分组个数 >> active:135;resolved:90;closed:60;
+
+*/
+
+$report = new reportTest();
+
+r($report->getAllTimeStatusStatTest()) && p('story') && e('changed:81;active:93;draft:51;'); // 测试获取 需求 的状态分组个数
+r($report->getAllTimeStatusStatTest()) && p('task') && e('wait:152;doing:152;done:152;pause:152;cancel:151;closed:151;'); // 测试获取 任务 的状态分组个数
+r($report->getAllTimeStatusStatTest()) && p('bug') && e('active:135;resolved:90;closed:60;'); // 测试获取 bug 的状态分组个数
\ No newline at end of file
diff --git a/module/report/test/model/getbugassign.php b/module/report/test/model/getbugassign.php
new file mode 100755
index 0000000000..c898e70bfe
--- /dev/null
+++ b/module/report/test/model/getbugassign.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getBugAssign();
+cid=1
+pid=1
+
+获取指派给 admin 的bug数量 >> 85
+获取指派给 dev1 的bug数量 >> 35
+获取指派给 test1 的bug数量 >> 5
+
+*/
+
+$report = new reportTest();
+
+r($report->getBugAssignTest()) && p('admin') && e('85'); // 获取指派给 admin 的bug数量
+r($report->getBugAssignTest()) && p('dev1') && e('35'); // 获取指派给 dev1 的bug数量
+r($report->getBugAssignTest()) && p('test1') && e('5'); // 获取指派给 test1 的bug数量
\ No newline at end of file
diff --git a/module/report/test/model/getbugs.php b/module/report/test/model/getbugs.php
new file mode 100755
index 0000000000..41d5a61fbf
--- /dev/null
+++ b/module/report/test/model/getbugs.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getBugs();
+cid=1
+pid=1
+
+测试获取 -40 day 到 -29 day 产品 1 执行 101 的bug >> :4;all:4;validRate:0;
+测试获取 -28 day 到 -25 day 产品 2 执行 102 的bug >> :3;all:3;validRate:0;
+测试获取 -24 day 到 -21 day 产品 3 执行 103 的bug >> :2;all:2;validRate:0;
+测试获取 -20 day 到 -19 day 产品 4 执行 104 的bug >> :1;all:1;validRate:0;
+测试获取 -20 day 到 -16 day 产品 5 执行 105 的bug >> :3;all:3;validRate:0;
+
+*/
+
+$begin = array(' -40 day', ' -28 day', ' -24 day', ' -20 day', ' -20 day');
+$end = array(' -29 day', ' -25 day', ' -21 day', ' -19 day', ' -16 day');
+$productID = array(1, 2, 3, 4, 5);
+$executionID = array(101, 102, 103, 104, 105);
+
+$report = new reportTest();
+
+r($report->getBugsTest($begin[0], $end[0], $productID[0], $executionID[0])) && p('admin') && e(':4;all:4;validRate:0;'); // 测试获取 -40 day 到 -29 day 产品 1 执行 101 的bug
+r($report->getBugsTest($begin[1], $end[1], $productID[1], $executionID[1])) && p('admin') && e(':3;all:3;validRate:0;'); // 测试获取 -28 day 到 -25 day 产品 2 执行 102 的bug
+r($report->getBugsTest($begin[2], $end[2], $productID[2], $executionID[2])) && p('admin') && e(':2;all:2;validRate:0;'); // 测试获取 -24 day 到 -21 day 产品 3 执行 103 的bug
+r($report->getBugsTest($begin[3], $end[3], $productID[3], $executionID[3])) && p('admin') && e(':1;all:1;validRate:0;'); // 测试获取 -20 day 到 -19 day 产品 4 执行 104 的bug
+r($report->getBugsTest($begin[4], $end[4], $productID[4], $executionID[4])) && p('admin') && e(':3;all:3;validRate:0;'); // 测试获取 -20 day 到 -16 day 产品 5 执行 105 的bug
\ No newline at end of file
diff --git a/module/report/test/model/getexecutions.php b/module/report/test/model/getexecutions.php
new file mode 100755
index 0000000000..225049a0b0
--- /dev/null
+++ b/module/report/test/model/getexecutions.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getExecutions();
+cid=1
+pid=1
+
+测试查询 开始时间 0 结束时间 0 的执行 >> 151:30,15,项目51;183:15,30,项目83;121:27,15,项目21;111:27,12,项目11;107:30,35,项目7;103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;
+测试查询 开始时间大于 -40 day 结束时间小于 -10 day 的执行 >> 103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;
+测试查询 开始时间大于 -28 day 结束时间小于 +5 day 的执行 >> 107:30,35,项目7;103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;
+测试查询 开始时间大于 -24 day 结束时间小于 +10 day 的执行 >> 111:27,12,项目11;107:30,35,项目7;
+测试查询 开始时间大于 -20 day 结束时间小于 +15 day 的执行 >> 111:27,12,项目11;
+测试查询 开始时间大于 -20 day 结束时间小于 +20 day 的执行 >> 121:27,15,项目21;
+
+*/
+
+$begin = array('0', ' -70 day', ' -60 day', ' -55 day', ' -50 day', ' -40 day');
+$end = array('0', ' +10 day', ' +15 day', ' +20 day', ' +25 day', ' +30 day');
+
+$report = new reportTest();
+
+r($report->getExecutionsTest($begin[0], $end[0])) && p() && e('151:30,15,项目51;183:15,30,项目83;121:27,15,项目21;111:27,12,项目11;107:30,35,项目7;103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;'); // 测试查询 开始时间 0 结束时间 0 的执行
+r($report->getExecutionsTest($begin[1], $end[1])) && p() && e('103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;'); // 测试查询 开始时间大于 -40 day 结束时间小于 -10 day 的执行
+r($report->getExecutionsTest($begin[2], $end[2])) && p() && e('107:30,35,项目7;103:23,35,项目3;102:9,18,项目2;101:3,15,项目1;'); // 测试查询 开始时间大于 -28 day 结束时间小于 +5 day 的执行
+r($report->getExecutionsTest($begin[3], $end[3])) && p() && e('111:27,12,项目11;107:30,35,项目7;'); // 测试查询 开始时间大于 -24 day 结束时间小于 +10 day 的执行
+r($report->getExecutionsTest($begin[4], $end[4])) && p() && e('111:27,12,项目11;'); // 测试查询 开始时间大于 -20 day 结束时间小于 +15 day 的执行
+r($report->getExecutionsTest($begin[5], $end[5])) && p() && e('121:27,15,项目21;'); // 测试查询 开始时间大于 -20 day 结束时间小于 +20 day 的执行
\ No newline at end of file
diff --git a/module/report/test/model/getoutput4api.php b/module/report/test/model/getoutput4api.php
new file mode 100755
index 0000000000..6887f6043b
--- /dev/null
+++ b/module/report/test/model/getoutput4api.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getOutput4API();
+cid=1
+pid=1
+
+测试获取 admin 2022 的输出 >> case:70;
+测试获取 dev17 2022 的输出 >> bug:1;case:0;
+测试获取 test18 2022 的输出 >> productplan:1;case:0;
+
+*/
+$account = array('admin', 'dev17', 'test18');
+$year = 2022;
+
+$report = new reportTest();
+
+r($report->getOutput4APITest($account[0], $year)) && p() && e('case:70;'); // 测试获取 admin 2022 的输出
+r($report->getOutput4APITest($account[1], $year)) && p() && e('bug:1;case:0;'); // 测试获取 dev17 2022 的输出
+r($report->getOutput4APITest($account[2], $year)) && p() && e('productplan:1;case:0;'); // 测试获取 test18 2022 的输出
\ No newline at end of file
diff --git a/module/report/test/model/getproducts.php b/module/report/test/model/getproducts.php
new file mode 100755
index 0000000000..50dd3dacb3
--- /dev/null
+++ b/module/report/test/model/getproducts.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getProducts();
+cid=1
+pid=1
+
+测试获取 story 产品 >> product:80;plan:39
+测试获取 story closedProduct 产品 >> product:120;plan:44
+测试获取 story overduePlan 产品 >> product:80;plan:93
+测试获取 requirement 产品 >> product:80;plan:39
+测试获取 requirement closedProduct 产品 >> product:120;plan:44
+测试获取 requirement overduePlan 产品 >> product:80;plan:93
+
+*/
+$conditions = array('', 'closedProduct', 'overduePlan');
+$storyType = 'requirement';
+
+$report = new reportTest();
+
+r($report->getProductsTest($conditions[0])) && p() && e('product:80;plan:39'); // 测试获取 story 产品
+r($report->getProductsTest($conditions[1])) && p() && e('product:120;plan:44'); // 测试获取 story closedProduct 产品
+r($report->getProductsTest($conditions[2])) && p() && e('product:80;plan:93'); // 测试获取 story overduePlan 产品
+r($report->getProductsTest($conditions[0], $storyType)) && p() && e('product:80;plan:39'); // 测试获取 requirement 产品
+r($report->getProductsTest($conditions[1], $storyType)) && p() && e('product:120;plan:44'); // 测试获取 requirement closedProduct 产品
+r($report->getProductsTest($conditions[2], $storyType)) && p() && e('product:80;plan:93'); // 测试获取 requirement overduePlan 产品
\ No newline at end of file
diff --git a/module/report/test/model/getprojectexecutions.php b/module/report/test/model/getprojectexecutions.php
new file mode 100755
index 0000000000..1293f6d619
--- /dev/null
+++ b/module/report/test/model/getprojectexecutions.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getProjectExecutions();
+cid=1
+pid=1
+
+获取项目执行对 101 >> 项目1/迭代1
+获取项目执行对 102 >> 项目2/迭代2
+获取项目执行对 201 >> 项目11/迭代101
+获取项目执行对 301 >> 项目21/迭代201
+获取项目执行对 401 >> 项目31/阶段301
+获取项目执行个数 >> 450
+
+*/
+
+$count = true;
+
+$executionID = array(101, 102, 201, 301, 401);
+
+$report = new reportTest();
+
+r($report->getProjectExecutionsTest()) && p('101') && e('项目1/迭代1'); // 获取项目执行对 101
+r($report->getProjectExecutionsTest()) && p('102') && e('项目2/迭代2'); // 获取项目执行对 102
+r($report->getProjectExecutionsTest()) && p('201') && e('项目11/迭代101'); // 获取项目执行对 201
+r($report->getProjectExecutionsTest()) && p('301') && e('项目21/迭代201'); // 获取项目执行对 301
+r($report->getProjectExecutionsTest()) && p('401') && e('项目31/阶段301'); // 获取项目执行对 401
+r($report->getProjectExecutionsTest($count)) && p() && e('450'); // 获取项目执行个数
\ No newline at end of file
diff --git a/module/report/test/model/getprojectstatusoverview.php b/module/report/test/model/getprojectstatusoverview.php
new file mode 100755
index 0000000000..c5bf81ffa1
--- /dev/null
+++ b/module/report/test/model/getprojectstatusoverview.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getProjectStatusOverview();
+cid=1
+pid=1
+
+获取项目状态 >> wait:24;doing:44;suspended:11;closed:11;
+获取 admin pm92 pm1 为团队成员的项目状态 >> wait:1;
+获取 user1 user10 为团队成员的项目状态 >> wait:1;
+获取 pm92 po2 为团队成员的项目状态 >> wait:1;doing:1;
+获取 user20 user21 为团队成员的项目状态 >> doing:2;
+获取 pm92 po10 为团队成员的项目状态 >> wait:1;doing:1;
+
+*/
+$account = array('admin,pm92,pm1', 'user1,user10', ' pm92,po2', 'user20,user21', 'pm92,po10');
+
+$report = new reportTest();
+
+r($report->getProjectStatusOverviewTest()) && p() && e('wait:24;doing:44;suspended:11;closed:11;'); // 获取项目状态
+r($report->getProjectStatusOverviewTest($account[0])) && p() && e('wait:1;'); // 获取 admin pm92 pm1 为团队成员的项目状态
+r($report->getProjectStatusOverviewTest($account[1])) && p() && e('wait:1;'); // 获取 user1 user10 为团队成员的项目状态
+r($report->getProjectStatusOverviewTest($account[2])) && p() && e('wait:1;doing:1;'); // 获取 pm92 po2 为团队成员的项目状态
+r($report->getProjectStatusOverviewTest($account[3])) && p() && e('doing:2;'); // 获取 user20 user21 为团队成员的项目状态
+r($report->getProjectStatusOverviewTest($account[4])) && p() && e('wait:1;doing:1;'); // 获取 pm92 po10 为团队成员的项目状态
\ No newline at end of file
diff --git a/module/report/test/model/getstatusoverview.php b/module/report/test/model/getstatusoverview.php
new file mode 100755
index 0000000000..0fcb13d9e3
--- /dev/null
+++ b/module/report/test/model/getstatusoverview.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getStatusOverview();
+cid=1
+pid=1
+
+测试获取 story 状态数量 >> 总需求 21
未完成 16
+测试获取 task 状态数量 >> 总任务 21
未完成 6
+测试获取 bug 状态数量 >> 总Bug 21
未解决 1
+
+*/
+$objectType = array('story', 'task', 'bug');
+$statusStat = array('active' => 1, 'wait' => 2, 'doing' => 3, 'done' => 4, 'closed' => 5, 'cancel' => 6);
+
+$report = new reportTest();
+
+r($report->getStatusOverviewTest($objectType[0], $statusStat)) && p() && e('总需求 21
未完成 16'); // 测试获取 story 状态数量
+r($report->getStatusOverviewTest($objectType[1], $statusStat)) && p() && e('总任务 21
未完成 6'); // 测试获取 task 状态数量
+r($report->getStatusOverviewTest($objectType[2], $statusStat)) && p() && e('总Bug 21
未解决 1'); // 测试获取 bug 状态数量
\ No newline at end of file
diff --git a/module/report/test/model/getuserbugs.php b/module/report/test/model/getuserbugs.php
new file mode 100755
index 0000000000..0afdfe7fa3
--- /dev/null
+++ b/module/report/test/model/getuserbugs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserBugs();
+cid=1
+pid=1
+
+获取人员bug数 >> admin:79;dev1:52;test1:77
+
+*/
+
+$report = new reportTest();
+
+r($report->getUserBugsTest()) && p() && e('admin:79;dev1:52;test1:77'); // 获取人员bug数
\ No newline at end of file
diff --git a/module/report/test/model/getusertasks.php b/module/report/test/model/getusertasks.php
new file mode 100755
index 0000000000..edec45dec0
--- /dev/null
+++ b/module/report/test/model/getusertasks.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserTasks();
+cid=1
+pid=1
+
+获取人员任务数 >> po82:2;user92:2;
+
+*/
+
+$report = new reportTest();
+
+r($report->getUserTasksTest()) && p() && e('po82:2;user92:2;'); // 获取人员任务数
\ No newline at end of file
diff --git a/module/report/test/model/getusertesttasks.php b/module/report/test/model/getusertesttasks.php
new file mode 100755
index 0000000000..b21cc73bfb
--- /dev/null
+++ b/module/report/test/model/getusertesttasks.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserTestTasks();
+cid=1
+pid=1
+
+测试获取测试任务数 >> user3:9;user4:9;user7:8;user8:8;user11:8;user12:8;
+
+*/
+
+$report = new reportTest();
+
+r($report->getUserTestTasksTest()) && p() && e('user3:9;user4:9;user7:8;user8:8;user11:8;user12:8;'); // 测试获取测试任务数
\ No newline at end of file
diff --git a/module/report/test/model/getusertodos.php b/module/report/test/model/getusertodos.php
new file mode 100755
index 0000000000..e09fad7be6
--- /dev/null
+++ b/module/report/test/model/getusertodos.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getUserTodos();
+cid=1
+pid=1
+
+测试获取用户待办数 >> admin:2;
+测试获取用户待办数 >> dev1:2;dev2:2;dev5:2;dev6:2;dev9:2;dev10:2;
+测试获取用户待办数 >> test1:2;test2:2;test5:2;test6:2;test9:2;test10:2;
+测试获取用户待办数 >> user4:2;user5:2;user8:2;user9:2;
+测试获取用户待办数 >> pm1:2;pm2:2;pm5:2;pm6:2;pm9:2;pm10:2;
+测试获取用户待办数 >> po1:2;po2:2;po5:2;po6:2;po9:2;po10:2;
+
+*/
+
+$userType = array('admin', 'dev', 'test', 'user', 'pm', 'po');
+
+$report = new reportTest();
+
+r($report->getUserTodosTest($userType[0])) && p() && e('admin:2;'); // 测试获取用户待办数
+r($report->getUserTodosTest($userType[1])) && p() && e('dev1:2;dev2:2;dev5:2;dev6:2;dev9:2;dev10:2; '); // 测试获取用户待办数
+r($report->getUserTodosTest($userType[2])) && p() && e('test1:2;test2:2;test5:2;test6:2;test9:2;test10:2;'); // 测试获取用户待办数
+r($report->getUserTodosTest($userType[3])) && p() && e('user4:2;user5:2;user8:2;user9:2;'); // 测试获取用户待办数
+r($report->getUserTodosTest($userType[4])) && p() && e('pm1:2;pm2:2;pm5:2;pm6:2;pm9:2;pm10:2;'); // 测试获取用户待办数
+r($report->getUserTodosTest($userType[5])) && p() && e('po1:2;po2:2;po5:2;po6:2;po9:2;po10:2;'); // 测试获取用户待办数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearactions.php b/module/report/test/model/getuseryearactions.php
new file mode 100755
index 0000000000..3322efbc52
--- /dev/null
+++ b/module/report/test/model/getuseryearactions.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearActions();
+cid=1
+pid=1
+
+测试获取本年度 admin 的操作数 >> 34
+测试获取本年度 dev17 的操作数 >> 33
+测试获取本年度 test18 的操作数 >> 33
+测试获取本年度 admin dev17 的操作数 >> 67
+测试获取本年度 admin test18 的操作数 >> 67
+
+*/
+$accounts = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+
+$report = new reportTest();
+
+r($report->getUserYearActionsTest($accounts[0])) && p() && e('34'); // 测试获取本年度 admin 的操作数
+r($report->getUserYearActionsTest($accounts[1])) && p() && e('33'); // 测试获取本年度 dev17 的操作数
+r($report->getUserYearActionsTest($accounts[2])) && p() && e('33'); // 测试获取本年度 test18 的操作数
+r($report->getUserYearActionsTest($accounts[3])) && p() && e('67'); // 测试获取本年度 admin dev17 的操作数
+r($report->getUserYearActionsTest($accounts[4])) && p() && e('67'); // 测试获取本年度 admin test18 的操作数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearcontributions.php b/module/report/test/model/getuseryearcontributions.php
new file mode 100755
index 0000000000..49385a75e1
--- /dev/null
+++ b/module/report/test/model/getuseryearcontributions.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearContributions();
+cid=1
+pid=1
+
+测试获取本年度 admin 的贡献数 >> repo:svnCommit:1;doc:create:1;case:run:70;
+测试获取本年度 dev17 的贡献数 >> bug:close:1;product:close:1;repo:gitCommit:1;case:run:0;
+测试获取本年度 test18 的贡献数 >> productplan:create:1;case:run:0;
+测试获取本年度 admin dev17 的贡献数 >> bug:close:1;repo:svnCommit:1,gitCommit:1;doc:create:1;product:close:1;case:run:70;
+测试获取本年度 admin test18 的贡献数 >> repo:svnCommit:1;doc:create:1;productplan:create:1;case:run:70;
+
+*/
+$account = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+
+$report = new reportTest();
+
+r($report->getUserYearContributionsTest($account[0])) && p() && e('repo:svnCommit:1;doc:create:1;case:run:70;'); // 测试获取本年度 admin 的贡献数
+r($report->getUserYearContributionsTest($account[1])) && p() && e('bug:close:1;product:close:1;repo:gitCommit:1;case:run:0;'); // 测试获取本年度 dev17 的贡献数
+r($report->getUserYearContributionsTest($account[2])) && p() && e('productplan:create:1;case:run:0;'); // 测试获取本年度 test18 的贡献数
+r($report->getUserYearContributionsTest($account[3])) && p() && e('bug:close:1;repo:svnCommit:1,gitCommit:1;doc:create:1;product:close:1;case:run:70;'); // 测试获取本年度 admin dev17 的贡献数
+r($report->getUserYearContributionsTest($account[4])) && p() && e('repo:svnCommit:1;doc:create:1;productplan:create:1;case:run:70;'); // 测试获取本年度 admin test18 的贡献数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearefforts.php b/module/report/test/model/getuseryearefforts.php
new file mode 100755
index 0000000000..8d933b629d
--- /dev/null
+++ b/module/report/test/model/getuseryearefforts.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearEfforts();
+cid=1
+pid=1
+
+获取本年度 admin 任务数 >> 599,4188
+获取本年度 po82 任务数 >> 1,3
+获取本年度 user92 任务数 >> 0,0
+获取本年度 admin po82 任务数 >> 600,4191
+获取本年度 admin user92 任务数 >> 599,4188
+
+*/
+$account = array('admin', 'po82', 'user92', 'admin,po82', 'admin,user92');
+
+$report = new reportTest();
+
+r($report->getUserYearEffortsTest($account[0])) && p('count,consumed') && e('599,4188'); // 获取本年度 admin 任务数
+r($report->getUserYearEffortsTest($account[1])) && p('count,consumed') && e('1,3'); // 获取本年度 po82 任务数
+r($report->getUserYearEffortsTest($account[2])) && p('count,consumed') && e('0,0'); // 获取本年度 user92 任务数
+r($report->getUserYearEffortsTest($account[3])) && p('count,consumed') && e('600,4191'); // 获取本年度 admin po82 任务数
+r($report->getUserYearEffortsTest($account[4])) && p('count,consumed') && e('599,4188'); // 获取本年度 admin user92 任务数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearexecutions.php b/module/report/test/model/getuseryearexecutions.php
new file mode 100755
index 0000000000..29dc29bbcc
--- /dev/null
+++ b/module/report/test/model/getuseryearexecutions.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearExecutions();
+cid=1
+pid=1
+
+测试获取本年度 admin 的执行id >> 120
+测试获取本年度 dev17 的执行id >> 0
+测试获取本年度 test18 的执行id >> 127
+测试获取本年度 admin dev17 的执行id >> 120
+测试获取本年度 admin test18 的执行id >> 127,120
+
+*/
+$account = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+
+$report = new reportTest();
+
+r($report->getUserYearExecutionsTest($account[0])) && p() && e('120'); // 测试获取本年度 admin 的执行id
+r($report->getUserYearExecutionsTest($account[1])) && p() && e('0'); // 测试获取本年度 dev17 的执行id
+r($report->getUserYearExecutionsTest($account[2])) && p() && e('127'); // 测试获取本年度 test18 的执行id
+r($report->getUserYearExecutionsTest($account[3])) && p() && e('120'); // 测试获取本年度 admin dev17 的执行id
+r($report->getUserYearExecutionsTest($account[4])) && p() && e('127,120'); // 测试获取本年度 admin test18 的执行id
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearlogins.php b/module/report/test/model/getuseryearlogins.php
new file mode 100755
index 0000000000..25f7872b56
--- /dev/null
+++ b/module/report/test/model/getuseryearlogins.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearLogins();
+cid=1
+pid=1
+
+测试获取本年度 admin 的登录次数 >> 0
+测试获取本年度 dev17 的登录次数 >> 0
+测试获取本年度 test18 的登录次数 >> 0
+测试获取本年度 admin dev17 的登录次数 >> 0
+测试获取本年度 admin test18 的登录次数 >> 0
+
+*/
+$account = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+
+$report = new reportTest();
+
+r($report->getUserYearLoginsTest($account[0])) && p() && e('0');// 测试获取本年度 admin 的登录次数
+r($report->getUserYearLoginsTest($account[1])) && p() && e('0');// 测试获取本年度 dev17 的登录次数
+r($report->getUserYearLoginsTest($account[2])) && p() && e('0');// 测试获取本年度 test18 的登录次数
+r($report->getUserYearLoginsTest($account[3])) && p() && e('0');// 测试获取本年度 admin dev17 的登录次数
+r($report->getUserYearLoginsTest($account[4])) && p() && e('0');// 测试获取本年度 admin test18 的登录次数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryearproducts.php b/module/report/test/model/getuseryearproducts.php
new file mode 100755
index 0000000000..63ed87b658
--- /dev/null
+++ b/module/report/test/model/getuseryearproducts.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearProducts();
+cid=1
+pid=1
+
+测试获取本年度 po1 的产品数 >> 1,11,21,31,41,51,61,71,81,91,101,111
+测试获取本年度 dev17 的产品数 >> 17,117
+测试获取本年度 test18 的产品数 >> 18,118
+测试获取本年度 po1 dev17 的产品数 >> 1,11,17,21,31,41,51,61,71,81,91,101,111,117
+测试获取本年度 po1 test18 的产品数 >> 1,11,18,21,31,41,51,61,71,81,91,101,111,118
+
+*/
+$account = array('po1', 'dev17', 'test18', 'po1,dev17', 'po1,test18');
+
+$report = new reportTest();
+
+r($report->getUserYearProductsTest($account[0])) && p() && e('1,11,21,31,41,51,61,71,81,91,101,111'); // 测试获取本年度 po1 的产品数
+r($report->getUserYearProductsTest($account[1])) && p() && e('17,117'); // 测试获取本年度 dev17 的产品数
+r($report->getUserYearProductsTest($account[2])) && p() && e('18,118'); // 测试获取本年度 test18 的产品数
+r($report->getUserYearProductsTest($account[3])) && p() && e('1,11,17,21,31,41,51,61,71,81,91,101,111,117'); // 测试获取本年度 po1 dev17 的产品数
+r($report->getUserYearProductsTest($account[4])) && p() && e('1,11,18,21,31,41,51,61,71,81,91,101,111,118'); // 测试获取本年度 po1 test18 的产品数
\ No newline at end of file
diff --git a/module/report/test/model/getuseryeartodos.php b/module/report/test/model/getuseryeartodos.php
new file mode 100755
index 0000000000..4ec1ce7982
--- /dev/null
+++ b/module/report/test/model/getuseryeartodos.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getUserYearTodos();
+cid=1
+pid=1
+
+测试获取本年度 admin 的产品数 >> count:3;undone:3;done:0;
+测试获取本年度 dev17 的产品数 >> count:2;undone:2;done:0;
+测试获取本年度 dev20 的产品数 >> count:2;undone:2;done:0;
+测试获取本年度 admin dev17 的产品数 >> count:5;undone:5;done:0;
+测试获取本年度 admin dev20 的产品数 >> count:5;undone:5;done:0;
+
+*/
+$account = array('admin', 'dev17', 'dev20', 'admin,dev17', 'admin,dev20');
+
+$report = new reportTest();
+
+r($report->getUserYearTodosTest($account[0])) && p() && e('count:3;undone:3;done:0;'); // 测试获取本年度 admin 的产品数
+r($report->getUserYearTodosTest($account[1])) && p() && e('count:2;undone:2;done:0;'); // 测试获取本年度 dev17 的产品数
+r($report->getUserYearTodosTest($account[2])) && p() && e('count:2;undone:2;done:0;'); // 测试获取本年度 dev20 的产品数
+r($report->getUserYearTodosTest($account[3])) && p() && e('count:5;undone:5;done:0;'); // 测试获取本年度 admin dev17 的产品数
+r($report->getUserYearTodosTest($account[4])) && p() && e('count:5;undone:5;done:0;'); // 测试获取本年度 admin dev20 的产品数
\ No newline at end of file
diff --git a/module/report/test/model/getworkload.php b/module/report/test/model/getworkload.php
new file mode 100755
index 0000000000..0c53d8432f
--- /dev/null
+++ b/module/report/test/model/getworkload.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getWorkload();
+cid=1
+pid=1
+
+测试获取dept 10 的工作量 >> user92:count:7,manhour:23;
+测试获取dept 49 的工作量 >> po82:count:6,manhour:12;
+测试获取dept 10 非指派人 的工作量 >> user93:count:0,manhour:0;user94:count:0,manhour:0;
+测试获取dept 49 非指派人 的工作量 >> po83:count:0,manhour:0;po84:count:0,manhour:0;
+
+*/
+$dept = array(10, 49);
+$assign = 'noassign';
+
+$report = new reportTest();
+
+r($report->getWorkloadTest($dept[0])) && p() && e('user92:count:7,manhour:23;'); // 测试获取dept 10 的工作量
+r($report->getWorkloadTest($dept[1])) && p() && e('po82:count:6,manhour:12;'); // 测试获取dept 49 的工作量
+r($report->getWorkloadTest($dept[0], $assign)) && p() && e('user93:count:0,manhour:0;user94:count:0,manhour:0;'); // 测试获取dept 10 非指派人 的工作量
+r($report->getWorkloadTest($dept[1], $assign)) && p() && e('po83:count:0,manhour:0;po84:count:0,manhour:0;'); // 测试获取dept 49 非指派人 的工作量
\ No newline at end of file
diff --git a/module/report/test/model/getyearcasestat.php b/module/report/test/model/getyearcasestat.php
new file mode 100755
index 0000000000..d0b81cb207
--- /dev/null
+++ b/module/report/test/model/getyearcasestat.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getYearCaseStat();
+cid=1
+pid=1
+
+测试获取本年度 admin 的用例数 >> pass:40;fail:30;
+测试获取本年度 dev17 的用例数 >> 0
+测试获取本年度 test18 的用例数 >> 0
+测试获取本年度 admin dev17 的用例数 >> pass:40;fail:30;
+测试获取本年度 admin test18 的用例数 >> pass:40;fail:30;
+
+*/
+$account = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+
+$report = new reportTest();
+
+r($report->getYearCaseStatTest($account[0])) && p() && e('pass:40;fail:30;'); // 测试获取本年度 admin 的用例数
+r($report->getYearCaseStatTest($account[1])) && p() && e('0'); // 测试获取本年度 dev17 的用例数
+r($report->getYearCaseStatTest($account[2])) && p() && e('0'); // 测试获取本年度 test18 的用例数
+r($report->getYearCaseStatTest($account[3])) && p() && e('pass:40;fail:30;'); // 测试获取本年度 admin dev17 的用例数
+r($report->getYearCaseStatTest($account[4])) && p() && e('pass:40;fail:30;'); // 测试获取本年度 admin test18 的用例数
\ No newline at end of file
diff --git a/module/report/test/model/getyearmonths.php b/module/report/test/model/getyearmonths.php
new file mode 100755
index 0000000000..6147acbfc7
--- /dev/null
+++ b/module/report/test/model/getyearmonths.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getYearMonths();
+cid=1
+pid=1
+
+测试获取 2020 的月份 >> 2020-01,2020-02,2020-03,2020-04,2020-05,2020-06,2020-07,2020-08,2020-09,2020-10,2020-11,2020-12
+测试获取 2021 的月份 >> 2021-01,2021-02,2021-03,2021-04,2021-05,2021-06,2021-07,2021-08,2021-09,2021-10,2021-11,2021-12
+测试获取 2022 的月份 >> 2022-01,2022-02,2022-03,2022-04,2022-05,2022-06,2022-07,2022-08,2022-09,2022-10,2022-11,2022-12
+测试获取 2023 的月份 >> 2023-01,2023-02,2023-03,2023-04,2023-05,2023-06,2023-07,2023-08,2023-09,2023-10,2023-11,2023-12
+测试获取 2024 的月份 >> 2024-01,2024-02,2024-03,2024-04,2024-05,2024-06,2024-07,2024-08,2024-09,2024-10,2024-11,2024-12
+
+*/
+$year = array(2020, 2021, 2022, 2023, 2024);
+
+$report = new reportTest();
+
+r($report->getYearMonthsTest($year[0])) && p() && e('2020-01,2020-02,2020-03,2020-04,2020-05,2020-06,2020-07,2020-08,2020-09,2020-10,2020-11,2020-12'); // 测试获取 2020 的月份
+r($report->getYearMonthsTest($year[1])) && p() && e('2021-01,2021-02,2021-03,2021-04,2021-05,2021-06,2021-07,2021-08,2021-09,2021-10,2021-11,2021-12'); // 测试获取 2021 的月份
+r($report->getYearMonthsTest($year[2])) && p() && e('2022-01,2022-02,2022-03,2022-04,2022-05,2022-06,2022-07,2022-08,2022-09,2022-10,2022-11,2022-12'); // 测试获取 2022 的月份
+r($report->getYearMonthsTest($year[3])) && p() && e('2023-01,2023-02,2023-03,2023-04,2023-05,2023-06,2023-07,2023-08,2023-09,2023-10,2023-11,2023-12'); // 测试获取 2023 的月份
+r($report->getYearMonthsTest($year[4])) && p() && e('2024-01,2024-02,2024-03,2024-04,2024-05,2024-06,2024-07,2024-08,2024-09,2024-10,2024-11,2024-12'); // 测试获取 2024 的月份
\ No newline at end of file
diff --git a/module/report/test/model/getyearobjectstat.php b/module/report/test/model/getyearobjectstat.php
new file mode 100755
index 0000000000..76fc244c84
--- /dev/null
+++ b/module/report/test/model/getyearobjectstat.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+getYearObjectStat();
+cid=1
+pid=1
+
+测试获取 admin story >> active:1;
+测试获取 admin task >> 0
+测试获取 admin bug >> 0
+测试获取 dev17 story >> 0
+测试获取 dev17 task >> 0
+测试获取 dev17 bug >> active:1;
+测试获取 test18 story >> 0
+测试获取 test18 task >> 0
+测试获取 test18 bug >> 0
+测试获取 admin dev17 story >> active:1;
+测试获取 admin dev17 task >> 0
+测试获取 admin dev17 bug >> active:1;
+测试获取 admin test18 story >> active:1;
+测试获取 admin test18 task >> 0
+测试获取 admin test18 bug >> 0
+
+*/
+$accounts = array('admin', 'dev17', 'test18', 'admin,dev17', 'admin,test18');
+$objectType = array('story', 'task', 'bug');
+
+$report = new reportTest();
+
+r($report->getYearObjectStatTest($accounts[0], $objectType[0])) && p() && e('active:1;'); // 测试获取 admin story
+r($report->getYearObjectStatTest($accounts[0], $objectType[1])) && p() && e('0'); // 测试获取 admin task
+r($report->getYearObjectStatTest($accounts[0], $objectType[2])) && p() && e('0'); // 测试获取 admin bug
+r($report->getYearObjectStatTest($accounts[1], $objectType[0])) && p() && e('0'); // 测试获取 dev17 story
+r($report->getYearObjectStatTest($accounts[1], $objectType[1])) && p() && e('0'); // 测试获取 dev17 task
+r($report->getYearObjectStatTest($accounts[1], $objectType[2])) && p() && e('active:1;'); // 测试获取 dev17 bug
+r($report->getYearObjectStatTest($accounts[2], $objectType[0])) && p() && e('0'); // 测试获取 test18 story
+r($report->getYearObjectStatTest($accounts[2], $objectType[1])) && p() && e('0'); // 测试获取 test18 task
+r($report->getYearObjectStatTest($accounts[2], $objectType[2])) && p() && e('0'); // 测试获取 test18 bug
+r($report->getYearObjectStatTest($accounts[3], $objectType[0])) && p() && e('active:1;'); // 测试获取 admin dev17 story
+r($report->getYearObjectStatTest($accounts[3], $objectType[1])) && p() && e('0'); // 测试获取 admin dev17 task
+r($report->getYearObjectStatTest($accounts[3], $objectType[2])) && p() && e('active:1;'); // 测试获取 admin dev17 bug
+r($report->getYearObjectStatTest($accounts[4], $objectType[0])) && p() && e('active:1;'); // 测试获取 admin test18 story
+r($report->getYearObjectStatTest($accounts[4], $objectType[1])) && p() && e('0'); // 测试获取 admin test18 task
+r($report->getYearObjectStatTest($accounts[4], $objectType[2])) && p() && e('0'); // 测试获取 admin test18 bug
\ No newline at end of file
diff --git a/module/report/test/report.class.php b/module/report/test/report.class.php
new file mode 100644
index 0000000000..1bdf2caa4e
--- /dev/null
+++ b/module/report/test/report.class.php
@@ -0,0 +1,542 @@
+objectModel = $tester->loadModel('report');
+ $tester->dao->delete()->from(TABLE_ACTION)->where('id')->gt(100)->exec();
+ }
+
+ /**
+ * Test compute percent of every item.
+ *
+ * @param array $datas
+ * @access public
+ * @return string
+ */
+ public function computePercentTest($datas)
+ {
+ $objects = $this->objectModel->computePercent($datas);
+
+ if(dao::isError()) return dao::getError();
+
+ $percents = '';
+ foreach($objects as $moduleID => $object) $percents .= "$moduleID:$object->percent;";
+ return $percents;
+ }
+
+ /**
+ * Test create json data of single charts.
+ *
+ * @param int $executionID
+ * @access public
+ * @return string
+ */
+ public function createSingleJSONTest($executionID)
+ {
+ global $tester;
+ $this->execution = $tester->loadModel('execution');
+
+ $execution = $this->execution->getByID($executionID);
+ $sets = $this->execution->getBurnDataFlot($executionID, 'left');
+ $dateList = $this->execution->getDateList($execution->begin, $execution->end, 'noweekend', 0, 'Y-m-d');
+
+ $objects = $this->objectModel->createSingleJSON($sets, $dateList[0]);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test convert date format.
+ *
+ * @param array $dateList
+ * @param string $format
+ * @access public
+ * @return string
+ */
+ public function convertFormatTest($dateList, $format = 'Y-m-d')
+ {
+ $objects = $this->objectModel->convertFormat($dateList, $format = 'Y-m-d');
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get executions.
+ *
+ * @param int $begin
+ * @param int $end
+ * @access public
+ * @return void
+ */
+ public function getExecutionsTest($begin = 0, $end = 0)
+ {
+ global $tester;
+ $tester->dao->update(TABLE_EXECUTION)->set('`status`')->eq('closed')->where('`id`')->in('101,102,103,107,111,121,151,183')->exec();
+
+ $begin = $begin != 0 ? date('Y-m-d', strtotime(date('Y-m-d') . $begin)) : 0;
+ $end = $end != 0 ? date('Y-m-d', strtotime(date('Y-m-d') . $end)) : 0;
+ $objects = $this->objectModel->getExecutions($begin, $end);
+
+ $tester->dao->update(TABLE_EXECUTION)->set('`status`')->eq('wait')->where('`id`')->in('101,103,107,111,121,151,183')->exec();
+ $tester->dao->update(TABLE_EXECUTION)->set('`status`')->eq('doing')->where('`id`')->in('102')->exec();
+
+ if(dao::isError()) return dao::getError();
+
+ $executions = '';
+ foreach($objects as $executionID => $execution) $executions .= "$executionID:$execution->estimate,$execution->consumed,$execution->projectName;";
+ return $executions;
+ }
+
+ /**
+ * Test get products.
+ *
+ * @param string $conditions
+ * @param string $storyType
+ * @access public
+ * @return string
+ */
+ public function getProductsTest($conditions, $storyType = 'story')
+ {
+ $objects = $this->objectModel->getProducts($conditions, $storyType);
+
+ if(dao::isError()) return dao::getError();
+
+ $planCount = 0;
+ foreach($objects as $object)
+ {
+ if(isset($object->plans)) $planCount += count($object->plans);
+ }
+ return 'product:' . count($objects) . ';plan:' . $planCount;
+ }
+
+ /**
+ * Test get bugs.
+ *
+ * @param string $begin
+ * @param string $end
+ * @param int $product
+ * @param int $execution
+ * @access public
+ * @return array
+ */
+ public function getBugsTest($begin, $end, $product, $execution)
+ {
+ $begin = date('Y-m-d', strtotime(date('Y-m-d') . $begin));
+ $end = date('Y-m-d', strtotime(date('Y-m-d') . $end));
+ $objects = $this->objectModel->getBugs($begin, $end, $product, $execution);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = array();
+ foreach($objects as $user => $types)
+ {
+ $count[$user] = '';
+ foreach($types as $type => $typeCount) $count[$user] .= "$type:$typeCount;";
+ }
+ return $count;
+ }
+
+ /**
+ * Test get workload.
+ *
+ * @param int $dept
+ * @param string $assign
+ * @access public
+ * @return string
+ */
+ public function getWorkloadTest($dept = 0, $assign = 'assign')
+ {
+ $objects = $this->objectModel->getWorkload($dept, $assign);
+
+ if(dao::isError()) return dao::getError();
+
+ $workload = '';
+ foreach($objects as $user => $work)
+ {
+ if(strlen($workload) > 40) break;
+
+ $workload .= "$user:";
+ foreach($work['total'] as $key => $value) $workload .= "$key:$value,";
+ $workload = trim($workload, ',');
+ $workload .= ';';
+ }
+ return $workload;
+ }
+
+ /**
+ * Test get bug assign.
+ *
+ * @access public
+ * @return void
+ */
+ public function getBugAssignTest()
+ {
+ $objects = $this->objectModel->getBugAssign();
+
+ if(dao::isError()) return dao::getError();
+
+ $count = array();
+ foreach($objects as $user => $object) $count[$user] = $object['total']['count'];
+ return $count;
+ }
+
+ /**
+ * Test get user bugs.
+ *
+ * @access public
+ * @return string
+ */
+ public function getUserBugsTest()
+ {
+ $objects = $this->objectModel->getUserBugs();
+
+ if(dao::isError()) return dao::getError();
+
+ $counts = '';
+ foreach($objects as $user => $bugs) $counts .= "$user:" . count($bugs) . ';';
+ return $counts;
+ }
+
+ /**
+ * Test get user tasks.
+ *
+ * @access public
+ * @return string
+ */
+ public function getUserTasksTest()
+ {
+ $objects = $this->objectModel->getUserTasks();
+
+ if(dao::isError()) return dao::getError();
+
+ $counts = '';
+ foreach($objects as $user => $tasks) $counts .= "$user:" . count($tasks) . ';';
+ return $counts;
+ }
+
+ /**
+ * Test get user todos.
+ *
+ * @access public
+ * @return string
+ */
+ public function getUserTodosTest($userType)
+ {
+ $objects = $this->objectModel->getUserTodos();
+
+ if(dao::isError()) return dao::getError();
+
+ $counts = '';
+ foreach($objects as $user => $todos)
+ {
+ if(strpos($user, $userType) !== false and str_replace($userType, '', $user) < 11) $counts .= "$user:" . count($todos) . ';';
+ }
+ return $counts;
+ }
+
+ /**
+ * Test get user test tasks.
+ *
+ * @access public
+ * @return string
+ */
+ public function getUserTestTasksTest()
+ {
+ $objects = $this->objectModel->getUserTestTasks();
+
+ if(dao::isError()) return dao::getError();
+
+ $counts = '';
+ foreach($objects as $user => $testtasks) $counts .= "$user:" . count($testtasks) . ';';
+ return $counts;
+ }
+
+ /**
+ * Test get user login count in this year.
+ *
+ * @param string $accounts
+ * @access public
+ * @return int
+ */
+ public function getUserYearLoginsTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getUserYearLogins($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get user action count in this year.
+ *
+ * @param array $accounts
+ * @access public
+ * @return void
+ */
+ public function getUserYearActionsTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getUserYearActions($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get user contributions in this year.
+ *
+ * @param array $accounts
+ * @access public
+ * @return string
+ */
+ public function getUserYearContributionsTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getUserYearContributions($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ $contributions = '';
+ foreach($objects as $type => $contributionTypes)
+ {
+ $contributions .= "$type:";
+ foreach($contributionTypes as $contributionType => $count) $contributions .= "$contributionType:$count,";
+ $contributions = trim($contributions, ',') . ';';
+ }
+ return $contributions;
+ }
+
+ /**
+ * Test get user todo stat in this year.
+ *
+ * @param array $accounts
+ * @access public
+ * @return string
+ */
+ public function getUserYearTodosTest($accounts)
+ {
+ $year = date('Y');
+ $objects = $this->objectModel->getUserYearTodos($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ $count = '';
+ foreach($objects as $type => $value) $count .= "$type:$value;";
+ return $count;
+ }
+
+ /**
+ * Test get user effort stat in this error.
+ *
+ * @param string $accounts
+ * @access public
+ * @return object
+ */
+ public function getUserYearEffortsTest($accounts)
+ {
+ $year = date('Y');
+
+ $object = $this->objectModel->getUserYearEfforts($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get count of created story,plan and closed story by accounts every product in this year.
+ *
+ * @param mixed $accounts
+ * @access public
+ * @return void
+ */
+ public function getUserYearProductsTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getUserYearProducts($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', array_keys($objects));
+ }
+
+ /**
+ * Test get count of finished task, story and resolved bug by accounts every executions in this years.
+ *
+ * @param string $accounts
+ * @access public
+ * @return string
+ */
+ public function getUserYearExecutionsTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getUserYearExecutions($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', array_keys($objects));
+ }
+
+ /**
+ * Test get status stat that is all time, include story, task and bug.
+ *
+ * @access public
+ * @return array
+ */
+ public function getAllTimeStatusStatTest()
+ {
+ $objects = $this->objectModel->getAllTimeStatusStat();
+
+ if(dao::isError()) return dao::getError();
+
+ $types = array();
+ foreach($objects as $type => $status)
+ {
+ $types[$type] = '';
+ foreach($status as $statusType => $statusCount) $types[$type] .= "$statusType:$statusCount;";
+ }
+ return $types;
+ }
+
+ /**
+ * Test get year object stat, include status and action stat.
+ *
+ * @param string $accounts
+ * @param string $objectType
+ * @access public
+ * @return string
+ */
+ public function getYearObjectStatTest($accounts, $objectType)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getYearObjectStat($accounts, $year, $objectType);
+
+ if(dao::isError()) return dao::getError();
+
+ $stats = '';
+ foreach($objects['statusStat'] as $stat => $count) $stats .= "$stat:$count;";
+ return $stats;
+ }
+
+ /**
+ * Test get year case stat, include result and action stat.
+ *
+ * @param string $accounts
+ * @access public
+ * @return string
+ */
+ public function getYearCaseStatTest($accounts)
+ {
+ $year = date('Y');
+
+ $objects = $this->objectModel->getYearCaseStat($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ $result = '';
+ foreach($objects['resultStat'] as $type => $value) $result .= "$type:$value;";
+ return $result;
+ }
+
+ /**
+ * Test get year months.
+ *
+ * @param string $year
+ * @access public
+ * @return string
+ */
+ public function getYearMonthsTest($year)
+ {
+ $objects = $this->objectModel->getYearMonths($year);
+
+ if(dao::isError()) return dao::getError();
+
+ return implode(',', $objects);
+ }
+
+ /**
+ * Test get status overview.
+ *
+ * @param string $objectType
+ * @param array $statusStat
+ * @access public
+ * @return string
+ */
+ public function getStatusOverviewTest($objectType, $statusStat)
+ {
+ $object = $this->objectModel->getStatusOverview($objectType, $statusStat);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get project status overview.
+ *
+ * @param array $accounts
+ * @access public
+ * @return string
+ */
+ public function getProjectStatusOverviewTest($accounts = array())
+ {
+ $objects = $this->objectModel->getProjectStatusOverview($accounts);
+
+ if(dao::isError()) return dao::getError();
+
+ $counts = '';
+ foreach($objects as $type => $count) $counts .= "$type:$count;";
+ return $counts;
+ }
+
+ /**
+ * Test get output data for API.
+ *
+ * @param string $accounts
+ * @param string $year
+ * @access public
+ * @return string
+ */
+ public function getOutput4APITest($accounts)
+ {
+ $year = date('Y');
+ $objects = $this->objectModel->getOutput4API($accounts, $year);
+
+ if(dao::isError()) return dao::getError();
+
+ $output = '';
+ foreach($objects as $objectType => $object) $output .= "$objectType:" . $object['total'] . ";";
+ return $output;
+ }
+
+ /**
+ * Test get project and execution name.
+ *
+ * @param bool $count
+ * @access public
+ * @return int|array
+ */
+ public function getProjectExecutionsTest($count = false)
+ {
+ $objects = $this->objectModel->getProjectExecutions();
+
+ if(dao::isError()) return dao::getError();
+
+ return $count ? count($objects) : $objects;
+ }
+}
diff --git a/module/score/test/model/create.php b/module/score/test/model/create.php
new file mode 100755
index 0000000000..3d3034d955
--- /dev/null
+++ b/module/score/test/model/create.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+关闭一个不存在创建者的需求 >> 0
+关闭一个存在创建者的需求 >> 2
+ID为601 的任务有子任务,完成不计算积分 >> 0
+ID为2 的任务,优先级为2,消耗4h, 预计1h >> 2
+确认严重程度为1的bug >> 4
+在截止时间内关闭一个项目经理为admin的执行 >> 30
+product模块的edit方法不存在与积分规则中,不计算积分 >> 0
+
+*/
+
+$moduleList = array('user', 'story', 'task', 'bug', 'execution', 'product');
+$methodList = array('login', 'close', 'finish', 'confirmBug', 'close', 'edit');
+$accountList = array('admin', 'dev10', 'test10', 'top10');
+
+$bug = new stdclass();
+$bug->id = '1';
+$bug->openedBy = 'admin';
+$bug->severity = '1';
+
+$execution = new stdclass();
+$execution->id = '701';
+$execution->PM = 'admin';
+$execution->end = '2022-05-14';
+
+$score = new scoreTest();
+
+r($score->createTest($moduleList[1], $methodList[1], '402')) && p('') && e('0'); // 关闭一个不存在创建者的需求
+r($score->createTest($moduleList[1], $methodList[1], '9')) && p('score') && e('2'); // 关闭一个存在创建者的需求
+r($score->createTest($moduleList[2], $methodList[2], '601')) && p('') && e('0'); // ID为601 的任务有子任务,完成不计算积分
+r($score->createTest($moduleList[2], $methodList[2], '2')) && p('score') && e('2'); // ID为2 的任务,优先级为2,消耗4h, 预计1h
+r($score->createTest($moduleList[3], $methodList[3], $bug)) && p('score') && e('4'); // 确认严重程度为1的bug
+r($score->createTest($moduleList[4], $methodList[4], $execution, 'admin', '2022-05-11')) && p('score') && e('30'); // 在截止时间内关闭一个项目经理为admin的执行
+r($score->createTest($moduleList[5], $methodList[5])) && p('') && e('0'); // product模块的edit方法不存在与积分规则中,不计算积分
\ No newline at end of file
diff --git a/module/score/test/model/fixkey.php b/module/score/test/model/fixkey.php
new file mode 100755
index 0000000000..26f34c6008
--- /dev/null
+++ b/module/score/test/model/fixkey.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+fixKey();
+cid=1
+pid=1
+
+action为created >> create
+action为opened >> create
+action为bugconfirmed >> confirmBug
+action为fixed, 不存在于strings中 >> fixed
+
+*/
+
+$actionList = array('created', 'opened', 'bugconfirmed', 'fixed');
+
+$score = new scoreTest();
+
+r($score->fixKeyTest($actionList[0])) && p('') && e('create'); // action为created
+r($score->fixKeyTest($actionList[1])) && p('') && e('create'); // action为opened
+r($score->fixKeyTest($actionList[2])) && p('') && e('confirmBug'); // action为bugconfirmed
+r($score->fixKeyTest($actionList[3])) && p('') && e('fixed'); // action为fixed, 不存在于strings中
\ No newline at end of file
diff --git a/module/score/test/model/getlistbyaccount.php b/module/score/test/model/getlistbyaccount.php
new file mode 100755
index 0000000000..bad9848e6d
--- /dev/null
+++ b/module/score/test/model/getlistbyaccount.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getListByAccount();
+cid=1
+pid=1
+
+查看account为admin,每页展示15条,第一页的第一条数据 >> admin
+查看account为dev10, 每页展示15条,第一页的数据总量 >> 15
+查看account为top10, 不传pager(默认分页)的第一条数据 >> top10
+查看account为adminn(不存在的用户)的数据 >> 0
+
+*/
+global $tester;
+$tester->app->loadClass('pager', $static = true);
+
+$score = new scoreTest();
+$accountList = array('admin', 'dev10', 'top10', 'adminn');
+$pager = new pager(0, 15, 1);
+
+r($score->getListByAccountTest($accountList[0], $pager)) && p('0:account') && e('admin'); // 查看account为admin,每页展示15条,第一页的第一条数据
+r($score->getListByAccountTest($accountList[1], $pager, true)) && p('') && e('15'); // 查看account为dev10, 每页展示15条,第一页的数据总量
+r($score->getListByAccountTest($accountList[2], null)) && p('0:account') && e('top10'); // 查看account为top10, 不传pager(默认分页)的第一条数据
+r($score->getListByAccountTest($accountList[3], null)) && p('0:account') && e('0'); // 查看account为adminn(不存在的用户)的数据
\ No newline at end of file
diff --git a/module/score/test/model/reset.php b/module/score/test/model/reset.php
new file mode 100755
index 0000000000..34018adba6
--- /dev/null
+++ b/module/score/test/model/reset.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+reset();
+cid=1
+pid=1
+
+重置积分成功 >> finish,0
+
+*/
+
+$score = new scoreTest();
+
+r($score->resetTest()) && p('status,number') && e('finish,0'); // 重置积分成功
\ No newline at end of file
diff --git a/module/score/test/score.class.php b/module/score/test/score.class.php
new file mode 100644
index 0000000000..cd69a37abc
--- /dev/null
+++ b/module/score/test/score.class.php
@@ -0,0 +1,96 @@
+objectModel = $tester->loadModel('score');
+ }
+
+ /**
+ * Get user score list.
+ *
+ * @param string $account
+ * @param object $pager
+ * @param bool $needCount
+ *
+ * @access public
+ * @return array|int
+ */
+ public function getListByAccountTest($account, $pager, $needCount = false)
+ {
+ $objects = $this->objectModel->getListByAccount($account, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $needCount ? count($objects) : $objects;
+ }
+
+ /**
+ * Add score logs.
+ *
+ * @param string $module
+ * @param string $method
+ * @param string $param
+ * @param string $account
+ * @param string $time
+ *
+ * @access public
+ * @return string|object
+ */
+ public function createTest($module = '', $method = '', $param = '', $account = '', $time = '')
+ {
+ global $tester;
+
+ $object = $this->objectModel->create($module, $method, $param, $account, $time);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = (!empty((array) $object) and is_object($object)) ? $object : '';
+ }
+
+ return $object;
+ }
+
+ /**
+ * Score reset.
+ *
+ * @param int $lastID
+ *
+ * @access public
+ * @return array
+ */
+ public function resetTest($lastID = 0)
+ {
+ $result = $this->objectModel->reset($lastID);
+ while($result['status'] != 'finish')
+ {
+ $result = $this->objectModel->reset($result['lastID']);
+ }
+
+ if(dao::isError()) return dao::getError();
+
+ return $result;
+ }
+
+ /**
+ * Fix action type for score.
+ *
+ * @param $string
+ *
+ * @access public
+ * @return string
+ */
+ public function fixKeyTest($string)
+ {
+ $objects = $this->objectModel->fixKey($string);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/search/test/model/buildindexquery.php b/module/search/test/model/buildindexquery.php
new file mode 100755
index 0000000000..6a1e8ef9b1
--- /dev/null
+++ b/module/search/test/model/buildindexquery.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+buildIndexQuery();
+cid=1
+pid=1
+
+构建未删除项目集的sql语句 >> SELECT t1.* FROM `zt_project` AS t1 WHERE 1 AND type = 'program' AND t1.deleted = '0'
+构建需求的sql语句 >> SELECT DISTINCT t1.*,t2.spec,t2.verify FROM `zt_story` AS t1 LEFT JOIN `zt_storyspec` AS t2 ON t1.id=t2.story WHERE t1.deleted = '0' AND t1.version=t2.version
+构建需求的sql语句 >> SELECT DISTINCT t1.*,t2.content,t2.digest FROM `zt_doc` AS t1 LEFT JOIN `zt_doccontent` AS t2 ON t1.id=t2.doc WHERE t1.deleted = '0' AND t1.version=t2.version
+构建查询所有项目的sql语句 >> SELECT t1.* FROM `zt_project` AS t1 WHERE 1 AND type = 'project'
+
+*/
+
+global $tester;
+$search = $tester->loadModel('search');
+
+r($search->buildIndexQuery('program')->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE 1 AND type = 'program' AND t1.deleted = '0'"); //构建未删除项目集的sql语句
+r($search->buildIndexQuery('story')->get()) && p() && e("SELECT DISTINCT t1.*,t2.spec,t2.verify FROM `zt_story` AS t1 LEFT JOIN `zt_storyspec` AS t2 ON t1.id=t2.story WHERE t1.deleted = '0' AND t1.version=t2.version"); //构建需求的sql语句
+r($search->buildIndexQuery('doc')->get()) && p() && e("SELECT DISTINCT t1.*,t2.content,t2.digest FROM `zt_doc` AS t1 LEFT JOIN `zt_doccontent` AS t2 ON t1.id=t2.doc WHERE t1.deleted = '0' AND t1.version=t2.version"); //构建需求的sql语句
+r($search->buildIndexQuery('project', false)->get()) && p() && e("SELECT t1.* FROM `zt_project` AS t1 WHERE 1 AND type = 'project'"); //构建查询所有项目的sql语句
\ No newline at end of file
diff --git a/module/search/test/model/decode.php b/module/search/test/model/decode.php
new file mode 100755
index 0000000000..dbb9a98402
--- /dev/null
+++ b/module/search/test/model/decode.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+decode();
+cid=1
+pid=1
+
+测试将搜索字转化为正确的汉字 >> 产
+
+*/
+
+$search = new searchTest();
+
+r($search->decodeTest(20135)) && p() && e('产'); //测试将搜索字转化为正确的汉字
\ No newline at end of file
diff --git a/module/search/test/model/deletequery.php b/module/search/test/model/deletequery.php
new file mode 100755
index 0000000000..55a9b33e93
--- /dev/null
+++ b/module/search/test/model/deletequery.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+deleteQuery();
+cid=1
+pid=1
+
+测试删除ID为1的数据后剩余的数量 >> 5
+测试删除ID为2的数据后剩余的数量 >> 4
+
+*/
+
+$search = new searchTest();
+
+$queryIDList = array('1', '2');
+
+r($search->deleteQueryTest($queryIDList[0])) && p() && e('5'); //测试删除ID为1的数据后剩余的数量
+r($search->deleteQueryTest($queryIDList[1])) && p() && e('4'); //测试删除ID为2的数据后剩余的数量
+
diff --git a/module/search/test/model/getbyid.php b/module/search/test/model/getbyid.php
new file mode 100755
index 0000000000..8252d0fe3c
--- /dev/null
+++ b/module/search/test/model/getbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+查询ID为1的模块名及条件名 >> task,任务查询测试条件
+查询ID为2的模块名及条件名 >> executionStory,需求查找条件
+查询ID为3的模块名及条件名 >> user,用户测试条件
+查询ID为4的模块名及条件名 >> projectBuild,项目版本搜索
+查询ID为5的模块名及条件名 >> executionBuild,执行版本搜索
+查询ID为6的模块名及条件名 >> design,设计搜索
+
+*/
+
+$search = new searchTest();
+
+$queryIDList = array('1', '2', '3', '4', '5', '6');
+
+r($search->getByIDTest($queryIDList[0])) && p('module,title') && e('task,任务查询测试条件'); //查询ID为1的模块名及条件名
+r($search->getByIDTest($queryIDList[1])) && p('module,title') && e('executionStory,需求查找条件'); //查询ID为2的模块名及条件名
+r($search->getByIDTest($queryIDList[2])) && p('module,title') && e('user,用户测试条件'); //查询ID为3的模块名及条件名
+r($search->getByIDTest($queryIDList[3])) && p('module,title') && e('projectBuild,项目版本搜索'); //查询ID为4的模块名及条件名
+r($search->getByIDTest($queryIDList[4])) && p('module,title') && e('executionBuild,执行版本搜索'); //查询ID为5的模块名及条件名
+r($search->getByIDTest($queryIDList[5])) && p('module,title') && e('design,设计搜索'); //查询ID为6的模块名及条件名
\ No newline at end of file
diff --git a/module/search/test/model/getlist.php b/module/search/test/model/getlist.php
new file mode 100755
index 0000000000..ec728f3061
--- /dev/null
+++ b/module/search/test/model/getlist.php
@@ -0,0 +1,75 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+测试在全部类型中搜索带有任务字体的条数 >> 1246
+测试在任务类型中搜索带有任务字体的条数 >> 910
+测试在bug类型中搜索带有bug字体的条数 >> 239
+测试在用例类型中搜索带有用例字体的条数 >> 97
+测试在文档类型中搜索带有文档字体的条数 >> 900
+测试在待办类型中搜索带有待办字体的条数 >> 1680
+测试在版本类型中搜索带有版本字体的条数 >> 20
+测试在用例库类型中搜索带有用例库字体的条数 >> 0
+测试在产品类型中搜索带有产品字体的条数 >> 120
+测试在发布类型中搜索带有发布字体的条数 >> 10
+测试在测试单类型中搜索带有测试单字体的条数 >> 100
+测试在测试套件类型中搜索带有测试套件字体的条数 >> 201
+测试在测试报告类型中搜索带有测试报告字体的条数 >> 10
+测试在计划类型中搜索带有计划字体的条数 >> 0
+测试在项目集类型中搜索带有项目集字体的条数 >> 10
+测试在项目类型中搜索带有项目字体的条数 >> 110
+测试在迭代类型中搜索带有迭代字体的条数 >> 630
+测试在需求类型中搜索带有需求字体的条数 >> 450
+
+*/
+
+$search = new searchTest();
+
+$searchType = array();
+$searchType[] = 'all';
+$searchType[] = array('task');
+$searchType[] = array('bug');
+$searchType[] = array('case');
+$searchType[] = array('doc');
+$searchType[] = array('todo');
+$searchType[] = array('build');
+$searchType[] = array('caselib');
+$searchType[] = array('product');
+$searchType[] = array('release');
+$searchType[] = array('testtask');
+$searchType[] = array('testsuite');
+$searchType[] = array('testreport');
+$searchType[] = array('productplan');
+$searchType[] = array('program');
+$searchType[] = array('project');
+$searchType[] = array('execution');
+$searchType[] = array('story');
+
+$searchWords = array('任务','bug','用例','文档','待办','版本','用例库','产品','发布','测试单','测试套件','测试报告','计划','项目集','项目','迭代','需求');
+
+r($search->getListTest($searchWords[0], $searchType[0])) && p() && e('1246'); //测试在全部类型中搜索带有任务字体的条数
+r($search->getListTest($searchWords[0], $searchType[1])) && p() && e('910'); //测试在任务类型中搜索带有任务字体的条数
+r($search->getListTest($searchWords[1], $searchType[2])) && p() && e('239'); //测试在bug类型中搜索带有bug字体的条数
+r($search->getListTest($searchWords[2], $searchType[3])) && p() && e('97'); //测试在用例类型中搜索带有用例字体的条数
+r($search->getListTest($searchWords[3], $searchType[4])) && p() && e('900'); //测试在文档类型中搜索带有文档字体的条数
+r($search->getListTest($searchWords[4], $searchType[5])) && p() && e('1680'); //测试在待办类型中搜索带有待办字体的条数
+r($search->getListTest($searchWords[5], $searchType[6])) && p() && e('20'); //测试在版本类型中搜索带有版本字体的条数
+r($search->getListTest($searchWords[6], $searchType[7])) && p() && e('0'); //测试在用例库类型中搜索带有用例库字体的条数
+r($search->getListTest($searchWords[7], $searchType[8])) && p() && e('120'); //测试在产品类型中搜索带有产品字体的条数
+r($search->getListTest($searchWords[8], $searchType[9])) && p() && e('10'); //测试在发布类型中搜索带有发布字体的条数
+r($search->getListTest($searchWords[9], $searchType[10])) && p() && e('100'); //测试在测试单类型中搜索带有测试单字体的条数
+r($search->getListTest($searchWords[10], $searchType[11])) && p() && e('201'); //测试在测试套件类型中搜索带有测试套件字体的条数
+r($search->getListTest($searchWords[11], $searchType[12])) && p() && e('10'); //测试在测试报告类型中搜索带有测试报告字体的条数
+r($search->getListTest($searchWords[12], $searchType[13])) && p() && e('0'); //测试在计划类型中搜索带有计划字体的条数
+r($search->getListTest($searchWords[13], $searchType[14])) && p() && e('10'); //测试在项目集类型中搜索带有项目集字体的条数
+r($search->getListTest($searchWords[14], $searchType[15])) && p() && e('110'); //测试在项目类型中搜索带有项目字体的条数
+r($search->getListTest($searchWords[15], $searchType[16])) && p() && e('630'); //测试在迭代类型中搜索带有迭代字体的条数
+r($search->getListTest($searchWords[16], $searchType[17])) && p() && e('450'); //测试在需求类型中搜索带有需求字体的条数
\ No newline at end of file
diff --git a/module/search/test/model/getquery.php b/module/search/test/model/getquery.php
new file mode 100755
index 0000000000..11bb195472
--- /dev/null
+++ b/module/search/test/model/getquery.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getQuery();
+cid=1
+pid=1
+
+查询ID为1的搜索条件名称及查询数量 >> 任务查询测试条件,27
+查询ID为2的搜索条件名称及查询数量 >> 需求查找条件,1
+查询ID为3的搜索条件名称及查询数量 >> 用户测试条件,1
+查询ID为4的搜索条件名称及查询数量 >> 项目版本搜索,1
+查询ID为5的搜索条件名称及查询数量 >> 执行版本搜索,1
+查询ID为6的搜索条件名称及查询数量 >> 设计搜索,32
+
+*/
+
+$search = new searchTest();
+
+$queryIDList = array('1', '2', '3', '4', '5', '6');
+
+r($search->getQueryTest($queryIDList[0])) && p('title,queryCount') && e('任务查询测试条件,27'); //查询ID为1的搜索条件名称及查询数量
+r($search->getQueryTest($queryIDList[1])) && p('title,queryCount') && e('需求查找条件,1'); //查询ID为2的搜索条件名称及查询数量
+r($search->getQueryTest($queryIDList[2])) && p('title,queryCount') && e('用户测试条件,1'); //查询ID为3的搜索条件名称及查询数量
+r($search->getQueryTest($queryIDList[3])) && p('title,queryCount') && e('项目版本搜索,1'); //查询ID为4的搜索条件名称及查询数量
+r($search->getQueryTest($queryIDList[4])) && p('title,queryCount') && e('执行版本搜索,1'); //查询ID为5的搜索条件名称及查询数量
+r($search->getQueryTest($queryIDList[5])) && p('title,queryCount') && e('设计搜索,32'); //查询ID为6的搜索条件名称及查询数量
\ No newline at end of file
diff --git a/module/search/test/model/getquerypairs.php b/module/search/test/model/getquerypairs.php
new file mode 100755
index 0000000000..d8b715284f
--- /dev/null
+++ b/module/search/test/model/getquerypairs.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getQueryPairs();
+cid=1
+pid=1
+
+查询module为task的键值对 >> 任务查询测试条件
+查询module为executionStory的键值对 >> 需求查找条件
+查询module为user的键值对 >> 用户测试条件
+查询module为projectBuild的键值对 >> 项目版本搜索
+查询module为executionBuild的键值对 >> 执行版本搜索
+查询module为design的键值对 >> 设计搜索
+查询module不存在的情况 >> 我的查询
+
+*/
+
+$search = new searchTest();
+
+$queryIDList = array('task','executionStory','user','projectBuild','executionBuild','design','nullValue');
+
+r($search->getQueryPairsTest($queryIDList[0])) && p('1') && e('任务查询测试条件'); //查询module为task的键值对
+r($search->getQueryPairsTest($queryIDList[1])) && p('2') && e('需求查找条件'); //查询module为executionStory的键值对
+r($search->getQueryPairsTest($queryIDList[2])) && p('3') && e('用户测试条件'); //查询module为user的键值对
+r($search->getQueryPairsTest($queryIDList[3])) && p('4') && e('项目版本搜索'); //查询module为projectBuild的键值对
+r($search->getQueryPairsTest($queryIDList[4])) && p('5') && e('执行版本搜索'); //查询module为executionBuild的键值对
+r($search->getQueryPairsTest($queryIDList[5])) && p('6') && e('设计搜索'); //查询module为design的键值对
+r($search->getQueryPairsTest($queryIDList[6])) && p('') && e('我的查询'); //查询module不存在的情况
\ No newline at end of file
diff --git a/module/search/test/model/getsummary.php b/module/search/test/model/getsummary.php
new file mode 100755
index 0000000000..16f267f5f5
--- /dev/null
+++ b/module/search/test/model/getsummary.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getSummary();
+cid=1
+pid=1
+
+测试搜索的内容中不带关键字的结果展示 >> 【步骤】【结果】【期望】
+测试搜索的内容中带关键字的结果展示 >> 【步
骤 】【结果】【期望】
+
+*/
+
+$search = new searchTest();
+
+r($search->getSummaryTest(1, 0)) && p() && e('【步骤】【结果】【期望】'); //测试搜索的内容中不带关键字的结果展示
+r($search->getSummaryTest(1, 39588)) && p() && e("【步
骤 】【结果】【期望】"); //测试搜索的内容中带关键字的结果展示
\ No newline at end of file
diff --git a/module/search/test/model/markkeywords.php b/module/search/test/model/markkeywords.php
new file mode 100755
index 0000000000..99b58fe384
--- /dev/null
+++ b/module/search/test/model/markkeywords.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+markKeywords();
+cid=1
+pid=1
+
+测试查找带骤字的bug >> 12304 27493
骤 12305 12304 32467 26524 12305 12304 26399 26395 12305
+
+*/
+
+$search = new searchTest();
+
+r($search->markKeywordsTest(1, 39588)) && p() && e("12304 27493
骤 12305 12304 32467 26524 12305 12304 26399 26395 12305"); //测试查找带骤字的bug
\ No newline at end of file
diff --git a/module/search/test/model/savedict.php b/module/search/test/model/savedict.php
new file mode 100755
index 0000000000..8d120b2b87
--- /dev/null
+++ b/module/search/test/model/savedict.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+saveDict();
+cid=1
+pid=1
+
+创建我是标题的搜索索引 >> 4
+创建特殊字符的搜索索引 >> 0
+
+*/
+
+$search = new searchTest();
+
+r($search->saveDictTest('我是标题')) && p() && e('4'); //创建我是标题的搜索索引
+r($search->saveDictTest('!@#$%^&*()_+')) && p() && e('0'); //创建特殊字符的搜索索引
\ No newline at end of file
diff --git a/module/search/test/model/saveindex.php b/module/search/test/model/saveindex.php
new file mode 100755
index 0000000000..2f782e2bbf
--- /dev/null
+++ b/module/search/test/model/saveindex.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+saveIndex();
+cid=1
+pid=1
+
+创建ID为10的bug的索引 >> 1
+创建ID为10的任务的索引 >> 1
+
+*/
+
+$search = new searchTest();
+
+r($search->saveIndexTest('bug', 10)) && p() && e('1'); //创建ID为10的bug的索引
+r($search->saveIndexTest('task', 10)) && p() && e('1'); //创建ID为10的任务的索引
\ No newline at end of file
diff --git a/module/search/test/search.class.php b/module/search/test/search.class.php
new file mode 100644
index 0000000000..9021e13d66
--- /dev/null
+++ b/module/search/test/search.class.php
@@ -0,0 +1,281 @@
+objectModel = $tester->loadModel('search');
+ }
+
+ /**
+ * Test get query.
+ *
+ * @param int $queryID
+ * @access public
+ * @return array
+ */
+ public function getQueryTest($queryID)
+ {
+ $objects = $this->objectModel->getQuery($queryID);
+
+ global $tester;
+ $objectType = $objects->module;
+ if($objects->module == 'executionStory') $objectType = 'story';
+ if($objects->module == 'projectBuild') $objectType = 'build';
+ if($objects->module == 'executionBuild') $objectType = 'build';
+
+ $table = $tester->config->objectTables[$objectType];
+ $objects->queryCount = $tester->dao->select('count(*) as count')->from($table)->where($objects->sql)->fetch('count');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get by ID.
+ *
+ * @param int $queryID
+ * @access public
+ * @return array
+ */
+ public function getByIDTest($queryID)
+ {
+ $objects = $this->objectModel->getByID($queryID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test delete query.
+ *
+ * @param int $queryID
+ * @access public
+ * @return int
+ */
+ public function deleteQueryTest($queryID)
+ {
+ global $tester;
+ $this->objectModel->deleteQuery($queryID);
+ if(dao::isError()) return dao::getError();
+
+ $count = $tester->dao->select('count(*) as count')->from(TABLE_USERQUERY)->fetch('count');
+ if(dao::isError()) return dao::getError();
+ return $count;
+ }
+
+ /**
+ * Test get query pairs.
+ *
+ * @param string $module
+ * @access public
+ * @return array
+ */
+ public function getQueryPairsTest($module)
+ {
+ $objects = $this->objectModel->getQueryPairs($module);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get list.
+ *
+ * @param string $keywords
+ * @param sreing $type
+ * @access public
+ * @return int
+ */
+ public function getListTest($keywords, $type)
+ {
+ $result = array();
+ while(!isset($result['finished']))
+ {
+ if(empty($result))
+ {
+ $result = $this->objectModel->buildAllIndex();
+ }
+ else
+ {
+ $result = $this->objectModel->buildAllIndex($result['type'], $result['lastID']);
+ }
+ }
+
+ $objects = $this->objectModel->getList($keywords, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ return count($objects);
+ }
+
+ /**
+ * Test save index.
+ *
+ * @param string $objectType
+ * @param int $objectID
+ * @access public
+ * @return bool
+ */
+ public function saveIndexTest($objectType, $objectID)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ $table = $tester->config->objectTables[$objectType];
+ $object = $tester->dao->select('*')->from($table)->where('id')->eq($objectID)->fetch();
+ $object->comment = '';
+
+ $objects = $this->objectModel->saveIndex($objectType, $object);
+ if(dao::isError()) return dao::getError();
+
+ $insertedIndex = $tester->dao->select('*')->from(TABLE_SEARCHINDEX)->where('objectType')->eq($objectType)->andWhere('objectID')->eq($objectID)->fetch();
+
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ if($insertedIndex) return true;
+ }
+
+ /**
+ * Test save dict.
+ *
+ * @param string $word
+ * @access public
+ * @return int
+ */
+ public function saveDictTest($word)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ $spliter = $tester->app->loadClass('spliter');
+ $titleSplited = $spliter->utf8Split($word);
+
+ $objects = $this->objectModel->saveDict($titleSplited['dict']);
+ if(dao::isError()) return dao::getError();
+
+ $count = $tester->dao->select("count('*') as count")->from(TABLE_SEARCHDICT)->fetch('count');
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+ return $count;
+ }
+
+ /**
+ * Test decode.
+ *
+ * @param int $key
+ * @access public
+ * @return string
+ */
+ public function decodeTest($key)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ $result = array();
+ while(!isset($result['finished']))
+ {
+ if(empty($result))
+ {
+ $result = $this->objectModel->buildAllIndex();
+ }
+ else
+ {
+ $result = $this->objectModel->buildAllIndex($result['type'], $result['lastID']);
+ }
+ }
+
+ $objects = $this->objectModel->decode($key);
+ if(dao::isError()) return dao::getError();
+
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ return $objects;
+ }
+
+ /**
+ * Test get summary.
+ *
+ * @param int $indexID
+ * @param string $words
+ * @access public
+ * @return array
+ */
+ public function getSummaryTest($indexID, $words)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ $result = array();
+ while(!isset($result['finished']))
+ {
+ if(empty($result))
+ {
+ $result = $this->objectModel->buildAllIndex();
+ }
+ else
+ {
+ $result = $this->objectModel->buildAllIndex($result['type'], $result['lastID']);
+ }
+ }
+
+ $searchIndex = $tester->dao->select('*')->from(TABLE_SEARCHINDEX)->where('id')->eq($indexID)->fetch();
+
+ $objects = $this->objectModel->getSummary($searchIndex->content, $words);
+ if(dao::isError()) return dao::getError();
+
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ return $objects;
+ }
+
+ /**
+ * Test mark keywords.
+ *
+ * @param int $indexID
+ * @param string $keywords
+ * @access public
+ * @return string
+ */
+ public function markKeywordsTest($indexID, $keywords)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ $result = array();
+ while(!isset($result['finished']))
+ {
+ if(empty($result))
+ {
+ $result = $this->objectModel->buildAllIndex();
+ }
+ else
+ {
+ $result = $this->objectModel->buildAllIndex($result['type'], $result['lastID']);
+ }
+ }
+
+ $searchIndex = $tester->dao->select('*')->from(TABLE_SEARCHINDEX)->where('id')->eq($indexID)->fetch();
+
+ $objects = $this->objectModel->markKeywords($searchIndex->content, $keywords);
+ if(dao::isError()) return dao::getError();
+
+ $tester->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
+ $tester->dao->delete()->from(TABLE_SEARCHDICT)->exec();
+
+ return $objects;
+ }
+}
diff --git a/module/setting/test/model/createdao.php b/module/setting/test/model/createdao.php
new file mode 100755
index 0000000000..54de9cbde5
--- /dev/null
+++ b/module/setting/test/model/createdao.php
@@ -0,0 +1,88 @@
+#!/usr/bin/env php
+createDAO();
+cid=1
+pid=1
+
+测试查询参数包含vision、owner、module、section、key的config数据 >> rnd,system,common,global,version
+测试查询参数包含vision、owner、module、key的config数据 >> 0
+测试查询参数包含owner、module、section、key的config数据 >> rnd,system,common,global,mode
+测试查询参数包含owner、module、key的config数据 >> rnd,system,common,,CRProduct
+测试查询参数包含module、section、key的config数据 >> rnd,system,common,global,sn
+测试查询参数包含module、key的config数据 >> 0
+测试查询参数包含section、key的config数据 >> rnd,system,common,safe,mode
+测试查询参数包含key的config数据 >> rnd,system,custom,,URSR
+测试查询参数包含module的config数据 >> rnd,system,story,,reviewRules
+测试查询参数包含section的config数据 >> rnd,system,common,xuanxuan,chatPort
+测试查询参数包含owner的config数据 >> rnd,admin,my,common,blockInited
+测试查询参数包含vision的config数据 >> rnd,admin,my,common,blockInited
+测试查询参数为空的config数据 >> rnd,admin,my,common,blockInited
+测试查询参数包含vision、owner、module、section、key的config数据 >> rnd,system,common,global,version
+测试删除参数包含vision、owner、module、key的config数据 >> 0
+测试删除参数包含owner、module、section、key的config数据 >> 1
+测试删除参数包含owner、module、key的config数据 >> 1
+测试删除参数包含module、section、key的config数据 >> 1
+测试删除参数包含module、key的config数据 >> 0
+测试删除参数包含section、key的config数据 >> 1
+测试删除参数包含key的config数据 >> 2
+测试删除参数包含module的config数据 >> 1
+测试删除参数包含section的config数据 >> 7
+测试删除参数包含owner的config数据 >> 7
+测试删除参数包含vision的config数据 >> 13
+测试删除参数为空的config数据 >> 0
+
+*/
+
+$paramString = array();
+$paramString[0] = "vision=rnd&owner=system&module=common§ion=global&key=version";
+$paramString[1] = "vision=rnd&owner=system&module=common&key=hourPoint";
+$paramString[2] = "owner=system&module=common§ion=global&key=mode";
+$paramString[3] = "owner=system&module=common&key=CRProduct";
+$paramString[4] = "module=common§ion=global&key=sn";
+$paramString[5] = "module=common&key=CRExection";
+$paramString[6] = "section=safe&key=mode";
+$paramString[7] = "key=URSR";
+$paramString[8] = "module=story";
+$paramString[9] = "section=xuanxuan";
+$paramString[10] = "owner=admin";
+$paramString[11] = "vision=rnd";
+$paramString[12] = "";
+
+$method = array('select', 'delete');
+$print = 'vision,owner,module,section,key';
+
+$setting = new settingTest();
+
+r($setting->createDAOTest($paramString[0], $method[0])) && p($print) && e('rnd,system,common,global,version'); //测试查询参数包含vision、owner、module、section、key的config数据
+r($setting->createDAOTest($paramString[1], $method[0])) && p() && e('0'); //测试查询参数包含vision、owner、module、key的config数据
+r($setting->createDAOTest($paramString[2], $method[0])) && p($print) && e('rnd,system,common,global,mode'); //测试查询参数包含owner、module、section、key的config数据
+r($setting->createDAOTest($paramString[3], $method[0])) && p($print) && e('rnd,system,common,,CRProduct'); //测试查询参数包含owner、module、key的config数据
+r($setting->createDAOTest($paramString[4], $method[0])) && p($print) && e('rnd,system,common,global,sn'); //测试查询参数包含module、section、key的config数据
+r($setting->createDAOTest($paramString[5], $method[0])) && p() && e('0'); //测试查询参数包含module、key的config数据
+r($setting->createDAOTest($paramString[6], $method[0])) && p($print) && e('rnd,system,common,safe,mode'); //测试查询参数包含section、key的config数据
+r($setting->createDAOTest($paramString[7], $method[0])) && p($print) && e('rnd,system,custom,,URSR'); //测试查询参数包含key的config数据
+r($setting->createDAOTest($paramString[8], $method[0])) && p($print) && e('rnd,system,story,,reviewRules'); //测试查询参数包含module的config数据
+r($setting->createDAOTest($paramString[9], $method[0])) && p($print) && e('rnd,system,common,xuanxuan,chatPort'); //测试查询参数包含section的config数据
+r($setting->createDAOTest($paramString[10], $method[0])) && p($print) && e('rnd,admin,my,common,blockInited'); //测试查询参数包含owner的config数据
+r($setting->createDAOTest($paramString[11], $method[0])) && p($print) && e('rnd,admin,my,common,blockInited'); //测试查询参数包含vision的config数据
+r($setting->createDAOTest($paramString[12], $method[0])) && p($print) && e('rnd,admin,my,common,blockInited'); //测试查询参数为空的config数据
+r($setting->createDAOTest($paramString[0], $method[0])) && p($print) && e('rnd,system,common,global,version'); //测试查询参数包含vision、owner、module、section、key的config数据
+r($setting->createDAOTest($paramString[1], $method[1])) && p() && e('0'); //测试删除参数包含vision、owner、module、key的config数据
+r($setting->createDAOTest($paramString[2], $method[1])) && p() && e('1'); //测试删除参数包含owner、module、section、key的config数据
+r($setting->createDAOTest($paramString[3], $method[1])) && p() && e('1'); //测试删除参数包含owner、module、key的config数据
+r($setting->createDAOTest($paramString[4], $method[1])) && p() && e('1'); //测试删除参数包含module、section、key的config数据
+r($setting->createDAOTest($paramString[5], $method[1])) && p() && e('0'); //测试删除参数包含module、key的config数据
+r($setting->createDAOTest($paramString[6], $method[1])) && p() && e('1'); //测试删除参数包含section、key的config数据
+r($setting->createDAOTest($paramString[7], $method[1])) && p() && e('2'); //测试删除参数包含key的config数据
+r($setting->createDAOTest($paramString[8], $method[1])) && p() && e('1'); //测试删除参数包含module的config数据
+r($setting->createDAOTest($paramString[9], $method[1])) && p() && e('7'); //测试删除参数包含section的config数据
+r($setting->createDAOTest($paramString[10], $method[1])) && p() && e('7'); //测试删除参数包含owner的config数据
+r($setting->createDAOTest($paramString[11], $method[1])) && p() && e('13'); //测试删除参数包含vision的config数据
+r($setting->createDAOTest($paramString[12], $method[1])) && p() && e('0'); //测试删除参数为空的config数据
+
diff --git a/module/setting/test/model/deleteitems.php b/module/setting/test/model/deleteitems.php
new file mode 100755
index 0000000000..e757c17af1
--- /dev/null
+++ b/module/setting/test/model/deleteitems.php
@@ -0,0 +1,59 @@
+#!/usr/bin/env php
+deleteItems();
+cid=1
+pid=1
+
+删除键是version的common模块下的系统数据 >> 0
+删除键是hourPoint的common模块下的系统数据 >> 0
+删除键是mode的common模块下的系统数据 >> 0
+删除键是CRProduct的common模块下的系统数据 >> 0
+删除键是sn的common模块下的数据 >> 0
+删除键是CRExection的common模块下的数据 >> 0
+删除键是mode、附件条件是safe的数据 >> 0
+删除键是URSR的数据 >> 0
+删除模块是story的数据 >> 0
+删除附加条件是xuanxuan的数据 >> 0
+删除所有者是admin的数据 >> 0
+删除视图是rnd的数据 >> 0
+删除所有的数据 >> 0
+
+*/
+
+$setting = new settingTest();
+
+$params = array();
+$params[0] = "vision=rnd&owner=system&module=common§ion=global&key=version";
+$params[1] = "vision=rnd&owner=system&module=common&key=hourPoint";
+$params[2] = "owner=system&module=common§ion=global&key=mode";
+$params[3] = "owner=system&module=common&key=CRProduct";
+$params[4] = "module=common§ion=global&key=sn";
+$params[5] = "module=common&key=CRExection";
+$params[6] = "section=safe&key=mode";
+$params[7] = "key=URSR";
+$params[8] = "module=story";
+$params[9] = "section=xuanxuan";
+$params[10] = "owner=admin";
+$params[11] = "vision=rnd";
+$params[12] = "";
+
+r($setting->deleteItemsTest($params[0])) && p() && e('0'); // 删除键是version的common模块下的系统数据
+r($setting->deleteItemsTest($params[1])) && p() && e('0'); // 删除键是hourPoint的common模块下的系统数据
+r($setting->deleteItemsTest($params[2])) && p() && e('0'); // 删除键是mode的common模块下的系统数据
+r($setting->deleteItemsTest($params[3])) && p() && e('0'); // 删除键是CRProduct的common模块下的系统数据
+r($setting->deleteItemsTest($params[4])) && p() && e('0'); // 删除键是sn的common模块下的数据
+r($setting->deleteItemsTest($params[5])) && p() && e('0'); // 删除键是CRExection的common模块下的数据
+r($setting->deleteItemsTest($params[6])) && p() && e('0'); // 删除键是mode、附件条件是safe的数据
+r($setting->deleteItemsTest($params[7])) && p() && e('0'); // 删除键是URSR的数据
+r($setting->deleteItemsTest($params[8])) && p() && e('0'); // 删除模块是story的数据
+r($setting->deleteItemsTest($params[9])) && p() && e('0'); // 删除附加条件是xuanxuan的数据
+r($setting->deleteItemsTest($params[10])) && p() && e('0'); // 删除所有者是admin的数据
+r($setting->deleteItemsTest($params[11])) && p() && e('0'); // 删除视图是rnd的数据
+r($setting->deleteItemsTest($params[12])) && p() && e('0'); // 删除所有的数据
+
diff --git a/module/setting/test/model/getitem.php b/module/setting/test/model/getitem.php
new file mode 100755
index 0000000000..13097e799b
--- /dev/null
+++ b/module/setting/test/model/getitem.php
@@ -0,0 +1,88 @@
+#!/usr/bin/env php
+getItem();
+cid=1
+pid=1
+
+查询所有数据的第一条 >> 1
+查询所有者是系统的第一条数据 >> 1
+查询所有者是系统的第一条数据 >> 1
+查询所属模块是custom的第一条数据 >> 1
+查询附加条件是global的第一条数据 >> 1
+查询值是CRProduct的第一条数据 >> 1
+查询研发界面中所有者是系统的第一条数据 >> 1
+查询研发界面中所属模块是custom的第一条数据 >> 1
+查询研发界面中附加条件是global的第一条数据 >> 1
+查询研发界面中值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是custom的第一条数据 >> 1
+查询所有者是系统并且附加条件是global的第一条数据 >> 1
+查询所有者是系统并且值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是common、附加条件是global的第一条数据 >> 1
+查询所有者是系统并且所属模块是common、值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是common、附加条件是global、值是version的第一条数据 >> 1
+查询所有者是admin并且所属模块是common、值是URSR的第一条数据 >> 1
+查询所有者是admin并且所属模块是my、附加条件是block、值是initVersion的第一条数据 >> 1
+查询不存在的界面配置 >> 0
+查询不存在的所有者配置 >> 0
+查询不存在的模块配置 >> 0
+查询不存在的附加条件配置 >> 0
+查询不存在的值配置 >> 0
+
+*/
+
+$setting = new settingTest();
+
+$items = array();
+$items[0] = "";
+$items[1] = "vision=rnd";
+$items[2] = "owner=system";
+$items[3] = "module=custom";
+$items[4] = "section=global";
+$items[5] = "key=CRProduct";
+$items[6] = "vision=rnd&owner=system";
+$items[7] = "vision=rnd&module=custom";
+$items[8] = "vision=rnd§ion=global";
+$items[9] = "vision=rnd&key=CRProduct";
+$items[10] = "owner=system&module=custom";
+$items[11] = "owner=system§ion=global";
+$items[12] = "owner=system&key=CRProduct";
+$items[13] = "owner=system&module=common§ion=global";
+$items[14] = "owner=system&module=common&key=CRExecution";
+$items[15] = "owner=system&module=common§ion=global&key=version";
+$items[16] = "owner=admin&module=common&key=URSR";
+$items[17] = "owner=admin&module=my§ion=block&key=initVersion";
+$items[18] = "vision=test";
+$items[19] = "owner=test";
+$items[20] = "module=test";
+$items[21] = "section=test";
+$items[22] = "key=test";
+
+r($setting->getItemTest($items[0])) && p() && e('1'); // 查询所有数据的第一条
+r($setting->getItemTest($items[1])) && p() && e('1'); // 查询所有者是系统的第一条数据
+r($setting->getItemTest($items[2])) && p() && e('1'); // 查询所有者是系统的第一条数据
+r($setting->getItemTest($items[3])) && p() && e('1'); // 查询所属模块是custom的第一条数据
+r($setting->getItemTest($items[4])) && p() && e('1'); // 查询附加条件是global的第一条数据
+r($setting->getItemTest($items[5])) && p() && e('1'); // 查询值是CRProduct的第一条数据
+r($setting->getItemTest($items[6])) && p() && e('1'); // 查询研发界面中所有者是系统的第一条数据
+r($setting->getItemTest($items[7])) && p() && e('1'); // 查询研发界面中所属模块是custom的第一条数据
+r($setting->getItemTest($items[8])) && p() && e('1'); // 查询研发界面中附加条件是global的第一条数据
+r($setting->getItemTest($items[9])) && p() && e('1'); // 查询研发界面中值是CRProduct的第一条数据
+r($setting->getItemTest($items[10])) && p() && e('1'); // 查询所有者是系统并且所属模块是custom的第一条数据
+r($setting->getItemTest($items[11])) && p() && e('1'); // 查询所有者是系统并且附加条件是global的第一条数据
+r($setting->getItemTest($items[12])) && p() && e('1'); // 查询所有者是系统并且值是CRProduct的第一条数据
+r($setting->getItemTest($items[13])) && p() && e('1'); // 查询所有者是系统并且所属模块是common、附加条件是global的第一条数据
+r($setting->getItemTest($items[14])) && p() && e('1'); // 查询所有者是系统并且所属模块是common、值是CRProduct的第一条数据
+r($setting->getItemTest($items[15])) && p() && e('1'); // 查询所有者是系统并且所属模块是common、附加条件是global、值是version的第一条数据
+r($setting->getItemTest($items[16])) && p() && e('1'); // 查询所有者是admin并且所属模块是common、值是URSR的第一条数据
+r($setting->getItemTest($items[17])) && p() && e('1'); // 查询所有者是admin并且所属模块是my、附加条件是block、值是initVersion的第一条数据
+r($setting->getItemTest($items[18])) && p() && e('0'); // 查询不存在的界面配置
+r($setting->getItemTest($items[19])) && p() && e('0'); // 查询不存在的所有者配置
+r($setting->getItemTest($items[20])) && p() && e('0'); // 查询不存在的模块配置
+r($setting->getItemTest($items[21])) && p() && e('0'); // 查询不存在的附加条件配置
+r($setting->getItemTest($items[22])) && p() && e('0'); // 查询不存在的值配置
\ No newline at end of file
diff --git a/module/setting/test/model/getitems.php b/module/setting/test/model/getitems.php
new file mode 100755
index 0000000000..5288da3854
--- /dev/null
+++ b/module/setting/test/model/getitems.php
@@ -0,0 +1,88 @@
+#!/usr/bin/env php
+getItems();
+cid=1
+pid=1
+
+查询所有数据中的第一条数据 >> 0
+查询所有者是系统的第一条数据 >> 0
+查询所有者是系统的第一条数据 >> 0
+查询所属模块是custom的第一条数据 >> 0
+查询附加条件是global的第一条数据 >> new
+查询值是CRProduct的第一条数据 >> 1
+查询研发界面中所有者是系统的第一条数据 >> 1
+查询研发界面中所属模块是custom的第一条数据 >> 0
+查询研发界面中附加条件是global的第一条数据 >> new
+查询研发界面中值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是custom的第一条数据 >> 0
+查询所有者是系统并且附加条件是global的第一条数据 >> new
+查询所有者是系统并且值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是common、附加条件是global的第一条数据 >> new
+查询所有者是系统并且所属模块是common、值是CRProduct的第一条数据 >> 1
+查询所有者是系统并且所属模块是common、附加条件是global、值是version的第一条数据 >> 16.5
+查询所有者是admin并且所属模块是common、值是URSR的第一条数据 >> 2
+查询所有者是admin并且所属模块是my、附加条件是block、值是initVersion的第一条数据 >> 2
+查询不存在的界面配置 >> 0
+查询不存在的所有者配置 >> 0
+查询不存在的模块配置 >> 0
+查询不存在的附加条件配置 >> 0
+查询不存在的值配置 >> 0
+
+*/
+
+$setting = new settingTest();
+
+$items = array();
+$items[0] = "";
+$items[1] = "vision=rnd";
+$items[2] = "owner=system";
+$items[3] = "module=custom";
+$items[4] = "section=global";
+$items[5] = "key=CRProduct";
+$items[6] = "vision=rnd&owner=system";
+$items[7] = "vision=rnd&module=custom";
+$items[8] = "vision=rnd§ion=global";
+$items[9] = "vision=rnd&key=CRProduct";
+$items[10] = "owner=system&module=custom";
+$items[11] = "owner=system§ion=global";
+$items[12] = "owner=system&key=CRProduct";
+$items[13] = "owner=system&module=common§ion=global";
+$items[14] = "owner=system&module=common&key=CRExecution";
+$items[15] = "owner=system&module=common§ion=global&key=version";
+$items[16] = "owner=admin&module=common&key=URSR";
+$items[17] = "owner=admin&module=my§ion=block&key=initVersion";
+$items[18] = "vision=test";
+$items[19] = "owner=test";
+$items[20] = "module=test";
+$items[21] = "section=test";
+$items[22] = "key=test";
+
+r($setting->getItemsTest($items[0])) && p('1:value') && e('0'); // 查询所有数据中的第一条数据
+r($setting->getItemsTest($items[1])) && p('1:value') && e('0'); // 查询所有者是系统的第一条数据
+r($setting->getItemsTest($items[2])) && p('1:value') && e('0'); // 查询所有者是系统的第一条数据
+r($setting->getItemsTest($items[3])) && p('1:value') && e('0'); // 查询所属模块是custom的第一条数据
+r($setting->getItemsTest($items[4])) && p('9:value') && e('new'); // 查询附加条件是global的第一条数据
+r($setting->getItemsTest($items[5])) && p('2:value') && e('1'); // 查询值是CRProduct的第一条数据
+r($setting->getItemsTest($items[6])) && p('3:value') && e('1'); // 查询研发界面中所有者是系统的第一条数据
+r($setting->getItemsTest($items[7])) && p('1:value') && e('0'); // 查询研发界面中所属模块是custom的第一条数据
+r($setting->getItemsTest($items[8])) && p('9:value') && e('new'); // 查询研发界面中附加条件是global的第一条数据
+r($setting->getItemsTest($items[9])) && p('2:value') && e('1'); // 查询研发界面中值是CRProduct的第一条数据
+r($setting->getItemsTest($items[10])) && p('1:value') && e('0'); // 查询所有者是系统并且所属模块是custom的第一条数据
+r($setting->getItemsTest($items[11])) && p('9:value') && e('new'); // 查询所有者是系统并且附加条件是global的第一条数据
+r($setting->getItemsTest($items[12])) && p('2:value') && e('1'); // 查询所有者是系统并且值是CRProduct的第一条数据
+r($setting->getItemsTest($items[13])) && p('9:value') && e('new'); // 查询所有者是系统并且所属模块是common、附加条件是global的第一条数据
+r($setting->getItemsTest($items[14])) && p('3:value') && e('1'); // 查询所有者是系统并且所属模块是common、值是CRProduct的第一条数据
+r($setting->getItemsTest($items[15])) && p('10:value') && e('16.5'); // 查询所有者是系统并且所属模块是common、附加条件是global、值是version的第一条数据
+r($setting->getItemsTest($items[16])) && p('25:value') && e('2'); // 查询所有者是admin并且所属模块是common、值是URSR的第一条数据
+r($setting->getItemsTest($items[17])) && p('32:value') && e('2'); // 查询所有者是admin并且所属模块是my、附加条件是block、值是initVersion的第一条数据
+r($setting->getItemsTest($items[18])) && p() && e('0'); // 查询不存在的界面配置
+r($setting->getItemsTest($items[19])) && p() && e('0'); // 查询不存在的所有者配置
+r($setting->getItemsTest($items[20])) && p() && e('0'); // 查询不存在的模块配置
+r($setting->getItemsTest($items[21])) && p() && e('0'); // 查询不存在的附加条件配置
+r($setting->getItemsTest($items[22])) && p() && e('0'); // 查询不存在的值配置
\ No newline at end of file
diff --git a/module/setting/test/model/getsysandpersonalconfig.php b/module/setting/test/model/getsysandpersonalconfig.php
new file mode 100755
index 0000000000..d9b14df799
--- /dev/null
+++ b/module/setting/test/model/getsysandpersonalconfig.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getSysAndPersonalConfig();
+cid=1
+pid=1
+
+测试account值为system,可正常查询system的数据 >> 1
+测试account值为admin,可正常查询system和admin的数据 >> 1
+测试account值为dev,可正常查询system和dev的数据 >> 1
+测试account值为空,可正常查询system的数据 >> 1
+
+*/
+
+$accountList = array('system', 'admin', 'dev', '');
+
+$setting = new settingTest();
+
+r($setting->getSysAndPersonalConfigTest($accountList[0])) && p() && e('1'); //测试account值为system,可正常查询system的数据
+r($setting->getSysAndPersonalConfigTest($accountList[1])) && p() && e('1'); //测试account值为admin,可正常查询system和admin的数据
+r($setting->getSysAndPersonalConfigTest($accountList[2])) && p() && e('1'); //测试account值为dev,可正常查询system和dev的数据
+r($setting->getSysAndPersonalConfigTest($accountList[3])) && p() && e('1'); //测试account值为空,可正常查询system的数据
\ No newline at end of file
diff --git a/module/setting/test/model/getursr.php b/module/setting/test/model/getursr.php
new file mode 100755
index 0000000000..bc1fda7630
--- /dev/null
+++ b/module/setting/test/model/getursr.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getURSR();
+cid=1
+pid=1
+
+测试正常查询URSR >> 2
+
+*/
+
+$setting = new settingTest();
+
+r($setting->getURSRTest()) && p() && e('2'); //测试正常查询URSR
\ No newline at end of file
diff --git a/module/setting/test/model/getversion.php b/module/setting/test/model/getversion.php
new file mode 100755
index 0000000000..6915bfcb7e
--- /dev/null
+++ b/module/setting/test/model/getversion.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getVersion();
+cid=1
+pid=1
+
+测试正常查询version >> 16.5
+
+*/
+
+$setting = new settingTest();
+
+r($setting->getVersionTest()) && p() && e('16.5'); //测试正常查询version
\ No newline at end of file
diff --git a/module/setting/test/model/parseitemparam.php b/module/setting/test/model/parseitemparam.php
new file mode 100755
index 0000000000..70d9f3f27c
--- /dev/null
+++ b/module/setting/test/model/parseitemparam.php
@@ -0,0 +1,58 @@
+#!/usr/bin/env php
+parseItemParam();
+cid=1
+pid=1
+
+解析参数包含vision、owner、module、section、key的数据 >> rnd,system,common,global,version
+解析参数包含vision、owner、module、key的数据 >> rnd,system,common,,hourPoint
+解析参数包含owner、module、section、key的数据 >> ,system,common,global,mode
+解析参数包含owner、module、key的数据 >> ,system,common,,CRProduct
+解析参数包含module、section、key的数据 >> ,,common,global,sn
+解析参数包含module、key的数据 >> ,,common,,CRExection
+解析参数包含section、key的数据 >> ,,,safe,mode
+解析参数包含key的数据 >> ,,,,URSR
+解析参数包含module的数据 >> ,,story,,
+解析参数包含section的数据 >> ,,,xuanxuan,
+解析参数包含owner的数据 >> ,admin,,,
+解析参数包含vision的数据 >> rnd,,,,
+解析空数据 >> ,,,,
+
+*/
+
+$setting = new settingTest();
+
+$params = array();
+$params[0] = "vision=rnd&owner=system&module=common§ion=global&key=version";
+$params[1] = "vision=rnd&owner=system&module=common&key=hourPoint";
+$params[2] = "owner=system&module=common§ion=global&key=mode";
+$params[3] = "owner=system&module=common&key=CRProduct";
+$params[4] = "module=common§ion=global&key=sn";
+$params[5] = "module=common&key=CRExection";
+$params[6] = "section=safe&key=mode";
+$params[7] = "key=URSR";
+$params[8] = "module=story";
+$params[9] = "section=xuanxuan";
+$params[10] = "owner=admin";
+$params[11] = "vision=rnd";
+$params[12] = "";
+
+r($setting->parseItemParamTest($params[0])) && p('vision,owner,module,section,key') && e('rnd,system,common,global,version'); // 解析参数包含vision、owner、module、section、key的数据
+r($setting->parseItemParamTest($params[1])) && p('vision,owner,module,section,key') && e('rnd,system,common,,hourPoint'); // 解析参数包含vision、owner、module、key的数据
+r($setting->parseItemParamTest($params[2])) && p('vision,owner,module,section,key') && e(',system,common,global,mode'); // 解析参数包含owner、module、section、key的数据
+r($setting->parseItemParamTest($params[3])) && p('vision,owner,module,section,key') && e(',system,common,,CRProduct'); // 解析参数包含owner、module、key的数据
+r($setting->parseItemParamTest($params[4])) && p('vision,owner,module,section,key') && e(',,common,global,sn'); // 解析参数包含module、section、key的数据
+r($setting->parseItemParamTest($params[5])) && p('vision,owner,module,section,key') && e(',,common,,CRExection'); // 解析参数包含module、key的数据
+r($setting->parseItemParamTest($params[6])) && p('vision,owner,module,section,key') && e(',,,safe,mode'); // 解析参数包含section、key的数据
+r($setting->parseItemParamTest($params[7])) && p('vision,owner,module,section,key') && e(',,,,URSR'); // 解析参数包含key的数据
+r($setting->parseItemParamTest($params[8])) && p('vision,owner,module,section,key') && e(',,story,,'); // 解析参数包含module的数据
+r($setting->parseitemparamtest($params[9])) && p('vision,owner,module,section,key') && e(',,,xuanxuan,'); // 解析参数包含section的数据
+r($setting->parseitemparamtest($params[10])) && p('vision,owner,module,section,key') && e(',admin,,,'); // 解析参数包含owner的数据
+r($setting->parseitemparamtest($params[11])) && p('vision,owner,module,section,key') && e('rnd,,,,'); // 解析参数包含vision的数据
+r($setting->parseitemparamtest($params[12])) && p('vision,owner,module,section,key') && e(',,,,'); // 解析空数据
\ No newline at end of file
diff --git a/module/setting/test/model/parseitempath.php b/module/setting/test/model/parseitempath.php
new file mode 100755
index 0000000000..abe919a16a
--- /dev/null
+++ b/module/setting/test/model/parseitempath.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+parseItemPath();
+cid=1
+pid=1
+
+解析参数包含vision、owner、module、section、key的数据 >> rnd,system,common,global,version
+解析参数包含vision、owner、module、key的数据 >> rnd,system,common,,hourPoint
+解析参数包含owner、module、section、key的数据 >> system,common,global,mode
+解析参数包含owner、module、key的数据 >> system,common,,CRProduct
+
+*/
+
+$setting = new settingTest();
+
+$params = array();
+$params[0] = "system.common.global.version@rnd";
+$params[1] = "system.common.hourPoint@rnd";
+$params[2] = "system.common.global.mode";
+$params[3] = "system.common.CRProduct";
+
+r($setting->parseItemPathTest($params[0])) && p('vision,owner,module,section,key') && e('rnd,system,common,global,version'); // 解析参数包含vision、owner、module、section、key的数据
+r($setting->parseItemPathTest($params[1])) && p('vision,owner,module,section,key') && e('rnd,system,common,,hourPoint'); // 解析参数包含vision、owner、module、key的数据
+r($setting->parseItemPathTest($params[2])) && p('owner,module,section,key') && e('system,common,global,mode'); // 解析参数包含owner、module、section、key的数据
+r($setting->parseItemPathTest($params[3])) && p('owner,module,section,key') && e('system,common,,CRProduct'); // 解析参数包含owner、module、key的数据
diff --git a/module/setting/test/model/setitem.php b/module/setting/test/model/setitem.php
new file mode 100755
index 0000000000..0df4db9122
--- /dev/null
+++ b/module/setting/test/model/setitem.php
@@ -0,0 +1,74 @@
+#!/usr/bin/env php
+setItem();
+cid=1
+pid=1
+
+设置没有vision的空数据 >> 0
+设置没有vision的只有视图的数据 >> 0
+设置没有vision的所有者是system的数据 >> 0
+设置没有vision的my模块的系统数据 >> 0
+设置没有vision的project模块的系统数据 >> test4
+设置没有vision的product模块的系统数据 >> test5
+设置没有vision的所有者是admin的数据 >> 0
+设置没有vision的common模块的admin配置数据 >> 0
+设置没有vision的project模块的admin配置数据 >> test8
+设置没有vision的product模块的admin配置数据 >> test9
+设置有vision的所有者是system的数据 >> 0
+设置有vision的my模块的系统数据 >> 0
+设置有vision的project模块的系统数据 >> test12
+设置有vision的product模块的系统数据 >> test13
+设置有vision的所有者是admin的数据 >> 0
+设置有vision的common模块的admin配置数据 >> 0
+设置有vision的project模块的admin配置数据 >> test16
+设置有vision的product模块的admin配置数据 >> test17
+
+*/
+
+$setting = new settingTest();
+
+$pathList = array();
+$pathList[0] = "";
+$pathList[1] = "@rnd";
+$pathList[2] = "system";
+$pathList[3] = "system.my";
+$pathList[4] = "system.project.list";
+$pathList[5] = "system.product.global.story";
+$pathList[6] = "admin";
+$pathList[7] = "admin.common";
+$pathList[8] = "admin.project.list";
+$pathList[9] = "admin.product.global.story";
+$pathList[10] = "system@rnd";
+$pathList[11] = "system.my@rnd";
+$pathList[12] = "system.project.list@rnd";
+$pathList[13] = "system.product.global.story@rnd";
+$pathList[14] = "admin@rnd";
+$pathList[15] = "admin.common@rnd";
+$pathList[16] = "admin.project.list@rnd";
+$pathList[17] = "admin.product.global.story@rnd";
+
+r($setting->setItemTest($pathList[0], 'test0')) && p() && e('0'); // 设置没有vision的空数据
+r($setting->setItemTest($pathList[1], 'test1')) && p() && e('0'); // 设置没有vision的只有视图的数据
+r($setting->setItemTest($pathList[2], 'test2')) && p() && e('0'); // 设置没有vision的所有者是system的数据
+r($setting->setItemTest($pathList[3], 'test3')) && p() && e('0'); // 设置没有vision的my模块的系统数据
+r($setting->setItemTest($pathList[4], 'test4')) && p() && e('test4'); // 设置没有vision的project模块的系统数据
+r($setting->setItemTest($pathList[5], 'test5')) && p() && e('test5'); // 设置没有vision的product模块的系统数据
+r($setting->setItemTest($pathList[6], 'test6')) && p() && e('0'); // 设置没有vision的所有者是admin的数据
+r($setting->setItemTest($pathList[7], 'test7')) && p() && e('0'); // 设置没有vision的common模块的admin配置数据
+r($setting->setItemTest($pathList[8], 'test8')) && p() && e('test8'); // 设置没有vision的project模块的admin配置数据
+r($setting->setItemTest($pathList[9], 'test9')) && p() && e('test9'); // 设置没有vision的product模块的admin配置数据
+r($setting->setItemTest($pathList[10], 'test10')) && p() && e('0'); // 设置有vision的所有者是system的数据
+r($setting->setItemTest($pathList[11], 'test11')) && p() && e('0'); // 设置有vision的my模块的系统数据
+r($setting->setItemTest($pathList[12], 'test12')) && p() && e('test12'); // 设置有vision的project模块的系统数据
+r($setting->setItemTest($pathList[13], 'test13')) && p() && e('test13'); // 设置有vision的product模块的系统数据
+r($setting->setItemTest($pathList[14], 'test14')) && p() && e('0'); // 设置有vision的所有者是admin的数据
+r($setting->setItemTest($pathList[15], 'test15')) && p() && e('0'); // 设置有vision的common模块的admin配置数据
+r($setting->setItemTest($pathList[16], 'test16')) && p() && e('test16'); // 设置有vision的project模块的admin配置数据
+r($setting->setItemTest($pathList[17], 'test17')) && p() && e('test17'); // 设置有vision的product模块的admin配置数据
+
diff --git a/module/setting/test/model/setitems.php b/module/setting/test/model/setitems.php
new file mode 100755
index 0000000000..f73e387a2c
--- /dev/null
+++ b/module/setting/test/model/setitems.php
@@ -0,0 +1,92 @@
+#!/usr/bin/env php
+setItems();
+cid=1
+pid=1
+
+创建空数据 >> 1
+创建没有vision,只有视图且值为空的数据 >> 1
+创建没有vision,只有所有者且值为空的数据 >> 1
+创建没有vision,my模块且值为空的数据 >> 1
+创建没有vision,只有所有者且值为空的数据 >> 1
+创建没有vision,common模块且值为空的数据 >> 1
+创建有vision,只有所有者且值为空的数据 >> 1
+创建有vision,my模块且值为空的数据 >> 1
+创建有vision,只有所有者且值为空的数据 >> 1
+创建有vision,common模块且值为空的数据 >> 1
+创建没有vision,只有视图且值project的数据 >> 1
+创建没有vision,只有所有者且值为project的数据 >> 1
+创建没有vision,my模块且值为project的数据 >> 1
+创建没有vision,只有所有者且值为project的数据 >> 1
+创建没有vision,common模块且值为project的数据 >> 1
+创建有vision,只有所有者且值为project的数据 >> 1
+创建有vision,my模块且值为project的数据 >> 1
+创建有vision,只有所有者且值为project的数据 >> 1
+创建有vision,common模块且值为project的数据 >> 1
+创建没有vision,只有视图且值project和story的数据 >> 1
+创建没有vision,只有所有者且值为project和story的数据 >> 1
+创建没有vision,my模块且值为project和story的数据 >> 1
+创建没有vision,只有所有者且值为project和story的数据 >> 1
+创建没有vision,common模块且值为project和story的数据 >> 1
+创建有vision,只有所有者且值为project和story的数据 >> 1
+创建有vision,my模块且值为project和story的数据 >> 1
+创建有vision,只有所有者且值为project和story的数据 >> 1
+创建有vision,common模块且值为project和story的数据 >> 1
+
+*/
+
+$setting = new settingTest();
+
+$pathList = array();
+$pathList[0] = "";
+$pathList[1] = "@rnd";
+$pathList[2] = "system";
+$pathList[3] = "system.my";
+$pathList[4] = "admin";
+$pathList[5] = "admin.common";
+$pathList[6] = "system@rnd";
+$pathList[7] = "system.my@rnd";
+$pathList[8] = "admin@rnd";
+$pathList[9] = "admin.common@rnd";
+
+$items = new stdclass();
+r($setting->setItemsTest($pathList[0], $items)) && p() && e('1'); // 创建空数据
+r($setting->setItemsTest($pathList[1], $items)) && p() && e('1'); // 创建没有vision,只有视图且值为空的数据
+r($setting->setItemsTest($pathList[2], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为空的数据
+r($setting->setItemsTest($pathList[3], $items)) && p() && e('1'); // 创建没有vision,my模块且值为空的数据
+r($setting->setItemsTest($pathList[4], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为空的数据
+r($setting->setItemsTest($pathList[5], $items)) && p() && e('1'); // 创建没有vision,common模块且值为空的数据
+r($setting->setItemsTest($pathList[6], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为空的数据
+r($setting->setItemsTest($pathList[7], $items)) && p() && e('1'); // 创建有vision,my模块且值为空的数据
+r($setting->setItemsTest($pathList[8], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为空的数据
+r($setting->setItemsTest($pathList[9], $items)) && p() && e('1'); // 创建有vision,common模块且值为空的数据
+
+$items->projectList = 'project';
+r($setting->setItemsTest($pathList[1], $items)) && p() && e('1'); // 创建没有vision,只有视图且值project的数据
+r($setting->setItemsTest($pathList[2], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为project的数据
+r($setting->setItemsTest($pathList[3], $items)) && p() && e('1'); // 创建没有vision,my模块且值为project的数据
+r($setting->setItemsTest($pathList[4], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为project的数据
+r($setting->setItemsTest($pathList[5], $items)) && p() && e('1'); // 创建没有vision,common模块且值为project的数据
+r($setting->setItemsTest($pathList[6], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为project的数据
+r($setting->setItemsTest($pathList[7], $items)) && p() && e('1'); // 创建有vision,my模块且值为project的数据
+r($setting->setItemsTest($pathList[8], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为project的数据
+r($setting->setItemsTest($pathList[9], $items)) && p() && e('1'); // 创建有vision,common模块且值为project的数据
+
+$items->global = new stdclass();
+$items->global->productList = 'story';
+r($setting->setItemsTest($pathList[1], $items)) && p() && e('1'); // 创建没有vision,只有视图且值project和story的数据
+r($setting->setItemsTest($pathList[2], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为project和story的数据
+r($setting->setItemsTest($pathList[3], $items)) && p() && e('1'); // 创建没有vision,my模块且值为project和story的数据
+r($setting->setItemsTest($pathList[4], $items)) && p() && e('1'); // 创建没有vision,只有所有者且值为project和story的数据
+r($setting->setItemsTest($pathList[5], $items)) && p() && e('1'); // 创建没有vision,common模块且值为project和story的数据
+r($setting->setItemsTest($pathList[6], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为project和story的数据
+r($setting->setItemsTest($pathList[7], $items)) && p() && e('1'); // 创建有vision,my模块且值为project和story的数据
+r($setting->setItemsTest($pathList[8], $items)) && p() && e('1'); // 创建有vision,只有所有者且值为project和story的数据
+r($setting->setItemsTest($pathList[9], $items)) && p() && e('1'); // 创建有vision,common模块且值为project和story的数据
+
diff --git a/module/setting/test/model/setsn.php b/module/setting/test/model/setsn.php
new file mode 100755
index 0000000000..e0be4f847a
--- /dev/null
+++ b/module/setting/test/model/setsn.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+setSN();
+cid=1
+pid=1
+
+测试正常设置SN >> 1
+
+*/
+
+$setting = new settingTest();
+
+r($setting->setSNTest()) && p() && e('1'); //测试正常设置SN
+
diff --git a/module/setting/test/model/snneededupdate.php b/module/setting/test/model/snneededupdate.php
new file mode 100755
index 0000000000..3d2e2b7c42
--- /dev/null
+++ b/module/setting/test/model/snneededupdate.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+snNeededUpdate();
+cid=1
+pid=1
+
+测试sn值为空,返回true >> 1
+测试sn值为281602d8ff5ee7533eeafd26eda4e776,返回true >> 1
+测试sn值为9bed3108092c94a0db2b934a46268b4a,返回true >> 1
+测试sn值为8522dd4d76762a49d02261ddbe4ad432,返回true >> 1
+测试sn值为13593e340ee2bdffed640d0c4eed8bec,返回true >> 1
+测试sn值为error,返回false >> 0
+
+*/
+
+$snList = array('', '281602d8ff5ee7533eeafd26eda4e776', '9bed3108092c94a0db2b934a46268b4a', '8522dd4d76762a49d02261ddbe4ad432', '13593e340ee2bdffed640d0c4eed8bec', 'error');
+
+$setting = new settingTest();
+
+r($setting->snNeededUpdateTest($snList[0])) && p() && e('1'); //测试sn值为空,返回true
+r($setting->snNeededUpdateTest($snList[1])) && p() && e('1'); //测试sn值为281602d8ff5ee7533eeafd26eda4e776,返回true
+r($setting->snNeededUpdateTest($snList[2])) && p() && e('1'); //测试sn值为9bed3108092c94a0db2b934a46268b4a,返回true
+r($setting->snNeededUpdateTest($snList[3])) && p() && e('1'); //测试sn值为8522dd4d76762a49d02261ddbe4ad432,返回true
+r($setting->snNeededUpdateTest($snList[4])) && p() && e('1'); //测试sn值为13593e340ee2bdffed640d0c4eed8bec,返回true
+r($setting->snNeededUpdateTest($snList[5])) && p() && e('0'); //测试sn值为error,返回false
\ No newline at end of file
diff --git a/module/setting/test/model/updateversion.php b/module/setting/test/model/updateversion.php
new file mode 100755
index 0000000000..560c49c834
--- /dev/null
+++ b/module/setting/test/model/updateversion.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+updateVersion();
+cid=1
+pid=1
+
+测试version值为16.5,添加数据 >> 16.5
+测试version值为max3.0,更新数据 >> max3.0
+测试version值为max2.0,更新数据 >> max2.0
+测试version值为biz6.5,更新数据 >> biz6.5
+测试version值为0,更新数据 >> 0
+
+*/
+
+$versionList = array('16.5', 'max3.0', 'max2.0', 'biz6.5', '0');
+
+$setting = new settingTest();
+
+r($setting->updateVersionTest($versionList[0])) && p('1:value') && e('16.5'); //测试version值为16.5,添加数据
+r($setting->updateVersionTest($versionList[1])) && p('1:value') && e('max3.0'); //测试version值为max3.0,更新数据
+r($setting->updateVersionTest($versionList[2])) && p('1:value') && e('max2.0'); //测试version值为max2.0,更新数据
+r($setting->updateVersionTest($versionList[3])) && p('1:value') && e('biz6.5'); //测试version值为biz6.5,更新数据
+r($setting->updateVersionTest($versionList[4])) && p('1:value') && e('0'); //测试version值为0,更新数据
+
diff --git a/module/setting/test/setting.class.php b/module/setting/test/setting.class.php
new file mode 100644
index 0000000000..bd3fb39806
--- /dev/null
+++ b/module/setting/test/setting.class.php
@@ -0,0 +1,273 @@
+objectModel = $tester->loadModel('setting');
+ }
+
+ /**
+ * Get value of an item.
+ *
+ * @param string $paramString see parseItemParam();
+ * @access public
+ * @return bool
+ */
+ public function getItemTest($paramString)
+ {
+ $objects = $this->objectModel->getItem($paramString);
+
+ if(dao::isError()) return dao::getError();
+
+ if($objects or $objects === 0 or $objects === '0') return true;
+ return false;
+ }
+
+ /**
+ * Get some items.
+ *
+ * @param string $paramString see parseItemParam();
+ * @access public
+ * @return array|string
+ */
+ public function getItemsTest($paramString)
+ {
+ $objects = $this->objectModel->getItems($paramString);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Set value of an item.
+ *
+ * @param string $path system.common.global.sn | system.common.sn | system.common.global.sn@rnd
+ * @param string $value
+ * @access public
+ * @return misc
+ */
+ public function setItemTest($path, $value = '')
+ {
+ $this->objectModel->setItem($path, $value);
+
+ if(dao::isError()) return dao::getError();
+
+ /* Determine vision of config item. */
+ $pathVision = explode('@', $path);
+ $vision = isset($pathVision[1]) ? $pathVision[1] : '';
+ $path = $pathVision[0];
+ $level = substr_count($path, '.');
+ $section = '';
+
+ if($level <= 1) return false;
+ if($level == 2) list($owner, $module, $key) = explode('.', $path);
+ if($level == 3) list($owner, $module, $section, $key) = explode('.', $path);
+ $paramString = "vision=$vision&owner=$owner&module=$module§ion=$section&key=$key";
+ $objects = $this->objectModel->getItem($paramString);
+
+ return $objects;
+ }
+
+ /**
+ * Batch set items, the example:
+ *
+ * $path = 'system.mail';
+ * $items->turnon = true;
+ * $items->smtp->host = 'localhost';
+ *
+ * @param string $path like system.mail
+ * @param array|object $items the items array or object, can be mixed by one level or two levels.
+ * @access public
+ * @return bool|string
+ */
+ public function setItemsTest($path, $items)
+ {
+ $result = $this->objectModel->setItems($path, $items);
+
+ if(dao::isError()) return dao::getError();
+
+ return $result;
+ }
+
+ /**
+ * Delete items.
+ *
+ * @param string $paramString see parseItemParam();
+ * @access public
+ * @return misc
+ */
+ public function deleteItemsTest($paramString)
+ {
+ $this->objectModel->deleteItems($paramString);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->getItemTest($paramString);
+ return $object;
+ }
+
+ /**
+ * Parse item path test.
+ *
+ * @param string $path
+ * @access public
+ * @return object
+ */
+ public function parseItemPathTest($path)
+ {
+ $object = $this->objectModel->parseItemPath($path);
+ return $object;
+ }
+
+ /**
+ * Parse the param string for select or delete items.
+ *
+ * @param string $paramString owner=xxx&key=sn and so on.
+ * @access public
+ * @return array
+ */
+ public function parseItemParamTest($paramString)
+ {
+ $objects = $this->objectModel->parseItemParam($paramString);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test create a DAO object to select or delete one or more records.
+ *
+ * @param string $paramString
+ * @param string $method select|delete.
+ * @access public
+ * @return array|int
+ */
+ public function createDAOTest($paramString, $method = 'select')
+ {
+ $params = $this->objectModel->parseItemParam($paramString);
+ if($method == 'delete')
+ {
+ $objects = $this->objectModel->createDAO($params, $method)->exec();
+ }
+ else
+ {
+ $objects = $this->objectModel->createDAO($params, $method)->orderBy('key')->fetch();
+ }
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get config of system and one user.
+ *
+ * @param string $account
+ * @access public
+ * @return bool
+ */
+ public function getSysAndPersonalConfigTest($account = '')
+ {
+ $objects = $this->objectModel->getSysAndPersonalConfig($account);
+
+ if(dao::isError()) return dao::getError();
+
+ return !empty($objects) ? true : false;
+ }
+
+ /**
+ * Test get the version of current zentaopms.
+ *
+ * Since the version field not saved in db. So if empty, return 0.3 beta.
+ *
+ * @access public
+ * @return void
+ */
+ public function getVersionTest()
+ {
+ $objects = $this->objectModel->getVersion();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get URSR.
+ *
+ * @access public
+ * @return int
+ */
+ public function getURSRTest()
+ {
+ $objects = $this->objectModel->getURSR();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test update version
+ *
+ * @param string $version
+ * @access public
+ * @return array
+ */
+ public function updateVersionTest($version)
+ {
+ $this->objectModel->updateVersion($version);
+
+ if(dao::isError()) return dao::getError();
+
+ $params['owner'] = 'system';
+ $params['module'] = 'common';
+ $params['section'] = 'global';
+ $params['key'] = 'version';
+
+ $objects = $this->objectModel->createDAO($params)->fetchAll();
+
+ return $objects;
+ }
+
+ /**
+ * Test set the sn of current zentaopms.
+ *
+ * @access public
+ * @return bool
+ */
+ public function setSNTest()
+ {
+ $this->objectModel->setSN();
+
+ if(dao::isError()) return dao::getError();
+
+ $params['owner'] = 'system';
+ $params['module'] = 'common';
+ $params['section'] = 'global';
+ $params['key'] = 'sn';
+
+ $objects = $this->objectModel->createDAO($params)->fetchAll();
+
+ return !empty($objects) ? true : false;
+ }
+
+ /**
+ * Test judge a sn needed update or not.
+ *
+ * @param string $sn
+ * @access public
+ * @return bool
+ */
+ public function snNeededUpdateTest($sn)
+ {
+ $objects = $this->objectModel->snNeededUpdate($sn);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/sonarqube/test/model/apicreateproject.php b/module/sonarqube/test/model/apicreateproject.php
new file mode 100755
index 0000000000..317300a9ad
--- /dev/null
+++ b/module/sonarqube/test/model/apicreateproject.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> return false
+使用空的sonarqubeID、正确的项目对象创建sonarqube项目 >> return false
+使用正确的sonarqubeID,项目对象创建sonarqube项目 >> unit test
+使用重复的项目对象创建sonarqube项目 >> Could not create Project, key already exists: unit_test
+
+*/
+
+$sonarqubeID = 2;
+
+$t_empty_project = array();
+$t_project = array('projectName' => 'unit_test', 'projectKey' => 'unit_test');
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->apiCreateProjectTest(0, $t_empty_project)) && p() && e('return false'); //使用空的sonarqubeID、项目对象创建sonarqube项目
+r($sonarqube->apiCreateProjectTest(0, $t_project)) && p() && e('return false'); //使用空的sonarqubeID、正确的项目对象创建sonarqube项目
+$sonarqube->apiDeleteProjectTest($sonarqubeID, 'unit_test');
+r($sonarqube->apiCreateProjectTest($sonarqubeID, $t_project)) && p('project:key') && e('unit test'); //使用正确的sonarqubeID,项目对象创建sonarqube项目
+r($sonarqube->apiCreateProjectTest($sonarqubeID, $t_project)) && p('0:msg') && e("Could not create Project, key already exists: unit_test"); //使用重复的项目对象创建sonarqube项目
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apideleteproject.php b/module/sonarqube/test/model/apideleteproject.php
new file mode 100755
index 0000000000..88b5f312d4
--- /dev/null
+++ b/module/sonarqube/test/model/apideleteproject.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+> return false
+正确的sonarqubeID,空的projectKey,删除SonarQube项目 >> The 'project' parameter is missing
+正确的sonarqubeID,不存在的projectKey,删除SonarQube项目 >> Project 'no_project' not found
+正确的sonarqubeID、projectKey,删除SonarQube项目 >> return true
+
+*/
+
+$sonarqubeID = 2;
+
+$t_empty_projectkey = '';
+$t_no_projectkey = 'no_project';
+$t_projectkey = 'new_project';
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->apiDeleteProjectTest(0, $t_empty_projectkey)) && p() && e('return false'); //通过不正确的sonarqubeID、projectKey,删除SonarQube项目
+r($sonarqube->apiDeleteProjectTest($sonarqubeID, $t_empty_projectkey)) && p('0:msg') && e("The 'project' parameter is missing"); //正确的sonarqubeID,空的projectKey,删除SonarQube项目
+r($sonarqube->apiDeleteProjectTest($sonarqubeID, $t_no_projectkey)) && p('0:msg') && e("Project 'no_project' not found"); //正确的sonarqubeID,不存在的projectKey,删除SonarQube项目
+$sonarqube->apiCreateProjectTest($sonarqubeID, array('projectName' => $t_projectkey, 'projectKey' => $t_projectkey));
+r($sonarqube->apiDeleteProjectTest($sonarqubeID, $t_projectkey)) && p() && e("return true"); //正确的sonarqubeID、projectKey,删除SonarQube项目
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apigetissues.php b/module/sonarqube/test/model/apigetissues.php
new file mode 100755
index 0000000000..e5421c1b24
--- /dev/null
+++ b/module/sonarqube/test/model/apigetissues.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+> 1
+通过sonarqubeID,项目key获取SonarQube问题列表 >> 1
+当sonarqubeID为0时,获取SonarQube问题列表 >> return empty
+
+*/
+
+$sonarqubeID = 2;
+$projectKey = 'zentaopms';
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->apiGetIssuesTest($sonarqubeID)) && p() && e('1'); //通过sonarqubeID,获取SonarQube问题列表
+r($sonarqube->apiGetIssuesTest($sonarqubeID, $projectKey)) && p() && e('1'); //通过sonarqubeID,项目key获取SonarQube问题列表
+r($sonarqube->apiGetIssuesTest(0)) && p() && e('return empty'); //当sonarqubeID为0时,获取SonarQube问题列表
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apigetprojects.php b/module/sonarqube/test/model/apigetprojects.php
new file mode 100755
index 0000000000..fddd45e6f5
--- /dev/null
+++ b/module/sonarqube/test/model/apigetprojects.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+> 1
+通过sonarqubeID,获取SonarQube项目数量 >> 1
+通过sonarqubeID,关键字,搜索获取SonarQube项目 >> 1
+当sonarqubeID为0时,获取SonarQube项目列表 >> return empty
+
+*/
+
+$sonarqubeID = 2;
+$keyword = '02';
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->apiGetProjectsTest($sonarqubeID)) && p() && e('1'); //通过sonarqubeID,获取SonarQube项目列表
+r(count($sonarqube->apiGetProjectsTest($sonarqubeID)) > 0) && p() && e('1'); //通过sonarqubeID,获取SonarQube项目数量
+r($sonarqube->apiGetProjectsTest($sonarqubeID, $keyword)) && p() && e('1'); //通过sonarqubeID,关键字,搜索获取SonarQube项目
+r($sonarqube->apiGetProjectsTest(0)) && p() && e('return empty'); //当sonarqubeID为0时,获取SonarQube项目列表
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apigetqualitygate.php b/module/sonarqube/test/model/apigetqualitygate.php
new file mode 100755
index 0000000000..a9fb9e58e1
--- /dev/null
+++ b/module/sonarqube/test/model/apigetqualitygate.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+> return empty
+通过正确的sonarqubeID,不存在的projectKey查询sonarqube质量门信息 >> Project 'wrong_project' not found
+通过正确的sonarqubeID、projectKey查询sonarqube质量门信息 >> success
+
+*/
+
+$sonarqube = $tester->loadModel('sonarqube');
+
+$sonarqubeID = 0;
+$projectKey = '';
+$result = $sonarqube->apiGetQualitygate($sonarqubeID, $projectKey);
+if(empty($result)) $result = 'return empty';
+r($result) && p() && e('return empty'); //通过错误的sonarqubeID、projectKey,查询sonarqube质量门信息
+
+$sonarqubeID = 2;
+$projectKey = 'wrong_project';
+$result = $sonarqube->apiGetQualitygate($sonarqubeID, $projectKey);
+r($result->errors) && p('0:msg') && e("Project 'wrong_project' not found"); //通过正确的sonarqubeID,不存在的projectKey查询sonarqube质量门信息
+
+$projectKey = 'zentaopms';
+$result = $sonarqube->apiGetReport($sonarqubeID, $projectKey);
+if(!empty($result->component)) $result = 'success';
+r($result) && p() && e("success"); //通过正确的sonarqubeID、projectKey查询sonarqube质量门信息
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apigetreport.php b/module/sonarqube/test/model/apigetreport.php
new file mode 100755
index 0000000000..4c2a6dd25e
--- /dev/null
+++ b/module/sonarqube/test/model/apigetreport.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+> return empty
+通过正确的sonarqubeID,不存在的projectKey查询sonarqube报告 >> Component key 'wrong_project' not found
+通过正确的sonarqubeID、projectKey,不正确的metricKeys查询sonarqube报告 >> The following metric keys are not found: wrong_params
+通过正确的sonarqubeID、projectKey、metricKeys,查询sonarqube报告 >> success
+
+*/
+
+$sonarqube = $tester->loadModel('sonarqube');
+
+$sonarqubeID = 0;
+$projectKey = '';
+$result = $sonarqube->apiGetReport($sonarqubeID, $projectKey);
+if(empty($result)) $result = 'return empty';
+r($result) && p() && e('return empty'); //通过错误的sonarqubeID、projectKey,查询sonarqube报告
+
+$sonarqubeID = 2;
+$projectKey = 'wrong_project';
+$result = $sonarqube->apiGetReport($sonarqubeID, $projectKey);
+r($result->errors) && p('0:msg') && e("Component key 'wrong_project' not found"); //通过正确的sonarqubeID,不存在的projectKey查询sonarqube报告
+
+$projectKey = 'zentaopms';
+$metricKeys = 'wrong_params';
+$result = $sonarqube->apiGetReport($sonarqubeID, $projectKey, $metricKeys);
+r($result->errors) && p('0:msg') && e("The following metric keys are not found: wrong_params"); //通过正确的sonarqubeID、projectKey,不正确的metricKeys查询sonarqube报告
+
+$metricKeys = 'bugs';
+$result = $sonarqube->apiGetReport($sonarqubeID, $projectKey, $metricKeys);
+if(!empty($result->component)) $result = 'success';
+r($result) && p() && e('success'); //通过正确的sonarqubeID、projectKey、metricKeys,查询sonarqube报告
\ No newline at end of file
diff --git a/module/sonarqube/test/model/apivalidate.php b/module/sonarqube/test/model/apivalidate.php
new file mode 100755
index 0000000000..dcc4a5468c
--- /dev/null
+++ b/module/sonarqube/test/model/apivalidate.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+> success
+通过正确的host,错误的token获取api权限 >> return false
+通过正确的host,非管理员权限的token获取api权限 >> return false
+
+*/
+
+$sonarqubeID = 2;
+
+$errorToken = 'abc';
+$noAdminToken = 'dGVzdDoxMjM0NTY=';
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->apiValidateTest($sonarqubeID)) && p() && e('success'); //通过host,token检验api权限
+r($sonarqube->apiValidateTest($sonarqubeID, '', $errorToken)) && p() && e('return false'); //通过正确的host,错误的token获取api权限
+r($sonarqube->apiValidateTest($sonarqubeID, '', $noAdminToken)) && p() && e('return false'); //通过正确的host,非管理员权限的token获取api权限
\ No newline at end of file
diff --git a/module/sonarqube/test/model/createproject.php b/module/sonarqube/test/model/createproject.php
new file mode 100755
index 0000000000..a795535f7f
--- /dev/null
+++ b/module/sonarqube/test/model/createproject.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+> 『项目名称』不能为空
+使用错误项目数据,正确的sonarqubeID创建Sonarqube项目 >> return error
+使用正确的项目数据,空的sonarqubeID创建Sonarqube项目 >> return false
+
+*/
+
+$sonarqubeID = 2;
+
+$empty_post = array('projectName' => '', 'projectKey' => '');
+$error_post = array('projectName' => 'unit_test', 'projectKey' => '@#');
+$true_post = array('projectName' => 'unit_test', 'projectKey' => 'unit_test');
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->createProjectTest(0, $empty_post)) && p('projectName:0') && e('『项目名称』不能为空'); //使用空的项目数据,空的sonarqubeID创建Sonarqube项目
+r($sonarqube->createProjectTest($sonarqubeID, $error_post)) && p() && e("return error"); //使用错误项目数据,正确的sonarqubeID创建Sonarqube项目
+r($sonarqube->createProjectTest(0, $true_post)) && p() && e('return false'); //使用正确的项目数据,空的sonarqubeID创建Sonarqube项目
+$sonarqube->apiDeleteProjectTest($sonarqubeID, 'unit_test');
+r($sonarqube->createProjectTest($sonarqubeID, $true_post)) && p() && e(1); //使用正确的sonarqubeID和Sonarqube项目信息创建Sonarqube项目
\ No newline at end of file
diff --git a/module/sonarqube/test/model/getapibase.php b/module/sonarqube/test/model/getapibase.php
new file mode 100755
index 0000000000..5298e80cc7
--- /dev/null
+++ b/module/sonarqube/test/model/getapibase.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+> http://192.168.1.161:59001/api/%s
+当sonarqubeID为0时,获取SonarQube url和header >> return empty
+
+*/
+
+$sonarqubeID = 2;
+
+$sonarqube = new sonarqubeTest();
+r($sonarqube->getApiBaseTest($sonarqubeID)) && p() && e('http://192.168.1.161:59001/api/%s'); //通过sonarqubeID,获取SonarQube url和header
+r($sonarqube->getApiBaseTest(0)) && p() && e('return empty'); //当sonarqubeID为0时,获取SonarQube url和header
\ No newline at end of file
diff --git a/module/sonarqube/test/model/getcachefile.php b/module/sonarqube/test/model/getcachefile.php
new file mode 100755
index 0000000000..86c2e643f3
--- /dev/null
+++ b/module/sonarqube/test/model/getcachefile.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getCacheFileTest($sonarqubeID, $projectKey)) && p('') && e(1); //使用正确的sonarqubeID,项目key获取缓存文件
\ No newline at end of file
diff --git a/module/sonarqube/test/model/getlinkedproducts.php b/module/sonarqube/test/model/getlinkedproducts.php
new file mode 100755
index 0000000000..e87bb04155
--- /dev/null
+++ b/module/sonarqube/test/model/getlinkedproducts.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+> return false
+通过正确的sonarqubeID和projectKey获取关联产品ID >> 1
+
+*/
+
+$sonarqube = $tester->loadModel('sonarqube');
+
+$sonarqubeID = 0;
+$projectKey = '';
+$result = $sonarqube->getLinkedProducts($sonarqubeID, $projectKey);
+if(empty($result)) $result = 'return false';
+r($result) && p() && e('return false'); //通过错误的sonarqubeID和projectKey获取关联产品ID
+
+$sonarqubeID = 2;
+$projectKey = 'zentaopms';
+$result = $sonarqube->getLinkedProducts($sonarqubeID, $projectKey);
+r($result) && p() && e('1'); //通过正确的sonarqubeID和projectKey获取关联产品ID
\ No newline at end of file
diff --git a/module/sonarqube/test/sonarqube.class.php b/module/sonarqube/test/sonarqube.class.php
new file mode 100644
index 0000000000..16abf5082f
--- /dev/null
+++ b/module/sonarqube/test/sonarqube.class.php
@@ -0,0 +1,99 @@
+objectModel = $tester->loadModel('sonarqube');
+ }
+
+ public function apiCreateProjectTest($sonarqubeID, $project = array())
+ {
+ $result = $this->objectModel->apiCreateProject($sonarqubeID, (object)$project);
+
+ if($result === false) $result = 'return false';
+ if(isset($result->errors)) $result = $result->errors;
+ return $result;
+ }
+
+ public function createProjectTest($sonarqubeID, $post)
+ {
+ $_POST['projectName'] = $post['projectName'];
+ $_POST['projectKey'] = $post['projectKey'];
+
+ $result = $this->objectModel->createProject($sonarqubeID);
+ $errors = dao::getError();
+ if($errors)
+ {
+ if(current($errors) == "项目标识的格式不正确。允许的字符为字母、数字、'-'、''、'.'和“:”,至少有一个非数字。") return 'return error';
+ if(current($errors) == false) return 'return false';
+ return $errors;
+ }
+ else
+ {
+ if(empty($result)) $result = 'return false';
+ return $result;
+ }
+ }
+
+ public function apiDeleteProjectTest($sonarqubeID, $projectKey)
+ {
+ $result = $this->objectModel->apiDeleteProject($sonarqubeID, $projectKey);
+
+ if($result === false) $result = 'return false';
+ if($result === null) $result = 'return true';
+ if(isset($result->errors)) $result = $result->errors;
+ return $result;
+ }
+
+ public function apiGetIssuesTest($sonarqubeID, $projectKey = '')
+ {
+ $result = $this->objectModel->apiGetIssues($sonarqubeID, $projectKey);
+
+ if(empty($result)) $result = 'return empty';
+ if(isset($result[0]->message)) $result = true;
+ return $result;
+ }
+
+ public function apiGetProjectsTest($sonarqubeID, $keyword = '')
+ {
+ $result = $this->objectModel->apiGetProjects($sonarqubeID, $keyword);
+
+ if(empty($result)) $result = 'return empty';
+ if($keyword == '' and isset($result[0]->name)) $result = true;
+ if($keyword != '' and strpos($result[0]->name, $keyword) !== false) $result = true;
+ return $result;
+ }
+
+ public function apiValidateTest($sonarqubeID, $url = '', $token = '')
+ {
+ global $tester;
+ $sonarqubeServer = $tester->loadModel('pipeline')->getByID($sonarqubeID);
+ $url = $url ? $url : $sonarqubeServer->url;
+ $token = $token ? $token : $sonarqubeServer->token;
+
+ $result = $this->objectModel->apiValidate($url, $token);
+
+ if(empty($result)) $result = 'success';
+ if(isset($result['password'])) $result = 'return false';
+ if(isset($result['account'])) $result = 'return false';
+ return $result;
+ }
+
+ public function getApiBaseTest($sonarqubeID)
+ {
+ list($apiRoot, $header) = $this->objectModel->getApiBase($sonarqubeID);
+
+ if(empty($apiRoot)) return 'return empty';
+ return $apiRoot;
+ }
+
+ public function getCacheFile($sonarqubeID, $projectKey)
+ {
+ $result = $this->objectModel->getCacheFile($sonarqubeID, $projectKey);
+
+ if(strPos($result, '/' . $sonarqubeID . '-' ) !== false) return true;
+ return $result;
+ }
+}
diff --git a/module/sso/test/model/createuser.php b/module/sso/test/model/createuser.php
new file mode 100755
index 0000000000..b373caff22
--- /dev/null
+++ b/module/sso/test/model/createuser.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+createUser();
+cid=1
+pid=1
+
+用户存在的情况 >> fail
+用户信息错误的情况 >> fail
+用户不存在的情况 >> bindUser1
+
+*/
+
+$sso = new ssoTest();
+
+$existsUser = array(
+ 'account' => 'admin'
+);
+
+$newUser = array(
+ 'account' => 'bindUser1',
+ 'realname' => '绑定用户1',
+ 'email' => 'user@test.com',
+ 'gender' => 'm',
+ 'ranzhi' => 'bindUser1'
+);
+
+$failUser = array(
+ 'account' => 'bindUser2',
+ 'realname' => '绑定用户2',
+ 'email' => 'user@test.com',
+ 'gender' => '',
+ 'ranzhi' => 'bindUser2'
+);
+
+r($sso->createTest($existsUser)) && p('status') && e('fail'); // 用户存在的情况
+r($sso->createTest($failUser)) && p('status') && e('fail'); // 用户信息错误的情况
+r($sso->createTest($newUser)) && p('account') && e('bindUser1'); // 用户不存在的情况
diff --git a/module/sso/test/model/getbinduser.php b/module/sso/test/model/getbinduser.php
new file mode 100755
index 0000000000..e862579f12
--- /dev/null
+++ b/module/sso/test/model/getbinduser.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getBindUser();
+cid=1
+pid=1
+
+用户不存在绑定的情况 >> not user
+用户存在绑定的情况 >> admin
+
+*/
+
+$sso = $tester->loadModel('sso');
+
+$emptyUser = '';
+$realUser = 'admin';
+
+$res = $sso->getBindUser($emptyUser);
+if(!$res) $res = 'not user';
+r($res) && p() && e('not user'); // 用户不存在绑定的情况
+r($sso->getBindUser($realUser)) && p('account') && e('admin'); // 用户存在绑定的情况
\ No newline at end of file
diff --git a/module/sso/test/model/getbindusers.php b/module/sso/test/model/getbindusers.php
new file mode 100755
index 0000000000..f31bd7c8ad
--- /dev/null
+++ b/module/sso/test/model/getbindusers.php
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getBindUsers();
+cid=1
+pid=1
+
+获取第一条记录账号 >> admin
+
+*/
+
+$sso = $tester->loadModel('sso');
+
+r($sso->getBindUsers()) && p('admin') && e('admin'); // 获取第一条记录账号
\ No newline at end of file
diff --git a/module/sso/test/sso.class.php b/module/sso/test/sso.class.php
new file mode 100644
index 0000000000..57753a8b63
--- /dev/null
+++ b/module/sso/test/sso.class.php
@@ -0,0 +1,29 @@
+objectModel = $tester->loadModel('sso');
+ }
+
+ /**
+ * Test create a user.
+ *
+ * @param array $param
+ * @access public
+ * @return void
+ */
+ public function createTest($param = array())
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $result = $this->objectModel->createUser();
+
+ unset($_POST);
+ if($result['status'] == 'fail') return 'fail';
+
+ $object = $this->objectModel->getBindUser($param['account']);
+ return $object;
+ }
+}
diff --git a/module/stage/test/model/batchcreate.php b/module/stage/test/model/batchcreate.php
new file mode 100755
index 0000000000..2e1b39d99f
--- /dev/null
+++ b/module/stage/test/model/batchcreate.php
@@ -0,0 +1,82 @@
+#!/usr/bin/env php
+gen(0);
+
+/**
+
+title=测试 stageModel->batchCreate();
+cid=1
+pid=1
+
+测试批量创建瀑布项目的阶段 1 >> 2
+测试批量创建瀑布项目的阶段 2 >> 4
+测试批量创建瀑布项目的阶段 3 >> 6
+测试批量创建瀑布项目的阶段 4 >> 7
+测试批量创建瀑布项目的百分比为空的阶段 >> 『工作量占比』不能为空。
+测试批量创建瀑布项目的类型为空的阶段 >> 『阶段类型』不能为空。
+测试批量创建瀑布项目的百分比非法的阶段 >> 『工作量占比』应当是数字,可以是小数。
+测试批量创建瀑布项目的百分比超出100的阶段 >> 工作量占比累计不应当超过100%
+测试批量创建融合瀑布项目的阶段 1 >> 2
+测试批量创建融合瀑布项目的阶段 2 >> 4
+测试批量创建融合瀑布项目的阶段 3 >> 6
+测试批量创建融合瀑布项目的阶段 4 >> 7
+测试批量创建融合瀑布项目的百分比为空的阶段 >> 『工作量占比』不能为空。
+测试批量创建融合瀑布项目的类型为空的阶段 >> 『阶段类型』不能为空。
+测试批量创建融合瀑布项目的百分比非法的阶段 >> 『工作量占比』应当是数字,可以是小数。
+测试批量创建融合瀑布项目的百分比超出100的阶段 >> 工作量占比累计不应当超过100%
+
+*/
+$name1 = array('1' => '批量创建的需求', '2' => '批量创建的设计', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$percent1 = array('1' => '1', '2' => '2', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$type1 = array('1' => 'request', '2' => 'design', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+
+$name2 = array('1' => '批量创建的开发', '2' => '批量创建的测试', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$percent2 = array('1' => '3', '2' => '4', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$type2 = array('1' => 'dev', '2' => 'qa', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+
+$name3 = array('1' => '批量创建的发布', '2' => '批量创建的总结评审', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$percent3 = array('1' => '5', '2' => '6', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$type3 = array('1' => 'release', '2' => 'review', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+
+$name4 = array('1' => '', '2' => '批量创建的其他', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$percent4 = array('1' => '1', '2' => '7', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$type4 = array('1' => 'request', '2' => 'other', '3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+
+$emptyPercent = array('1' => '', '2' => '','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$emptyType = array('1' => '', '2' => '','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$IllegalPercent = array('1' => 'a', '2' => 'b','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+$percentOver = array('1' => '111', '2' => '2','3' => '', '4' => '', '5' => '', '6' => '', '7' => '', '8' => '', '9' => '', '10' => '');
+
+
+$param1 = array('name' => $name1, 'percent' => $percent1, 'type' => $type1);
+$param2 = array('name' => $name2, 'percent' => $percent2, 'type' => $type2);
+$param3 = array('name' => $name3, 'percent' => $percent3, 'type' => $type3);
+$param4 = array('name' => $name4, 'percent' => $percent4, 'type' => $type4);
+$param5 = array('name' => $name1, 'percent' => $emptyPercent, 'type' => $type1);
+$param6 = array('name' => $name1, 'percent' => $percent1, 'type' => $emptyType);
+$param7 = array('name' => $name1, 'percent' => $IllegalPercent, 'type' => $type1);
+$param8 = array('name' => $name1, 'percent' => $percentOver, 'type' => $type1);
+
+
+$stage = new stageTest();
+
+r($stage->batchCreateTest($param1)) && p() && e('2'); // 测试批量创建瀑布项目的阶段 1
+r($stage->batchCreateTest($param2)) && p() && e('4'); // 测试批量创建瀑布项目的阶段 2
+r($stage->batchCreateTest($param3)) && p() && e('6'); // 测试批量创建瀑布项目的阶段 3
+r($stage->batchCreateTest($param4)) && p() && e('7'); // 测试批量创建瀑布项目的阶段 4
+r($stage->batchCreateTest($param5)) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试批量创建瀑布项目的百分比为空的阶段
+r($stage->batchCreateTest($param6)) && p('type:0') && e('『阶段类型』不能为空。'); // 测试批量创建瀑布项目的类型为空的阶段
+r($stage->batchCreateTest($param7)) && p('percent:0') && e('『工作量占比』应当是数字,可以是小数。'); // 测试批量创建瀑布项目的百分比非法的阶段
+r($stage->batchCreateTest($param8)) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试批量创建瀑布项目的百分比超出100的阶段
+r($stage->batchCreateTest($param1, 'waterfallplus')) && p() && e('2'); // 测试批量创建融合瀑布项目的阶段 1
+r($stage->batchCreateTest($param2, 'waterfallplus')) && p() && e('4'); // 测试批量创建融合瀑布项目的阶段 2
+r($stage->batchCreateTest($param3, 'waterfallplus')) && p() && e('6'); // 测试批量创建融合瀑布项目的阶段 3
+r($stage->batchCreateTest($param4, 'waterfallplus')) && p() && e('7'); // 测试批量创建融合瀑布项目的阶段 4
+r($stage->batchCreateTest($param5, 'waterfallplus')) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试批量创建融合瀑布项目的百分比为空的阶段
+r($stage->batchCreateTest($param6, 'waterfallplus')) && p('type:0') && e('『阶段类型』不能为空。'); // 测试批量创建融合瀑布项目的类型为空的阶段
+r($stage->batchCreateTest($param7, 'waterfallplus')) && p('percent:0') && e('『工作量占比』应当是数字,可以是小数。'); // 测试批量创建融合瀑布项目的百分比非法的阶段
+r($stage->batchCreateTest($param8, 'waterfallplus')) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试批量创建融合瀑布项目的百分比超出100的阶段
diff --git a/module/stage/test/model/create.php b/module/stage/test/model/create.php
new file mode 100755
index 0000000000..60ce932aa4
--- /dev/null
+++ b/module/stage/test/model/create.php
@@ -0,0 +1,127 @@
+#!/usr/bin/env php
+gen(0);
+
+/**
+
+title=测试 stageModel->create();
+cid=1
+pid=1
+
+测试新建瀑布项目一个需求阶段 >> 新建的需求,1,request
+测试新建瀑布项目一个设计阶段 >> 新建的设计,2,design
+测试新建瀑布项目一个开发阶段 >> 新建的开发,3,dev
+测试新建瀑布项目一个测试阶段 >> 新建的测试,4,qa
+测试新建瀑布项目一个发布阶段 >> 新建的发布,5,release
+测试新建瀑布项目一个总结评审阶段 >> 新建的总结评审,6,review
+测试新建瀑布项目一个其他阶段 >> 新建的其他,7,other
+测试新建瀑布项目名称为空 >> 『阶段名称』不能为空。
+测试新建瀑布项目类型为空 >> 『工作量占比』不能为空。
+测试新建瀑布项目百分比为空 >> 『阶段类型』不能为空。
+测试新建瀑布项目非数字的百分比 >> 工作量占比应当是数字
+测试新建瀑布项目总百分比超过100 >> 工作量占比累计不应当超过100%
+测试新建融合瀑布项目一个需求阶段 >> 新建的需求,1,request
+测试新建融合瀑布项目一个设计阶段 >> 新建的设计,2,design
+测试新建融合瀑布项目一个开发阶段 >> 新建的开发,3,dev
+测试新建融合瀑布项目一个测试阶段 >> 新建的测试,4,qa
+测试新建融合瀑布项目一个发布阶段 >> 新建的发布,5,release
+测试新建融合瀑布项目一个总结评审阶段 >> 新建的总结评审,6,review
+测试新建融合瀑布项目一个其他阶段 >> 新建的其他,7,other
+测试新建融合瀑布项目名称为空 >> 『阶段名称』不能为空。
+测试新建融合瀑布项目类型为空 >> 『工作量占比』不能为空。
+测试新建融合瀑布项目百分比为空 >> 『阶段类型』不能为空。
+测试新建融合瀑布项目非数字的百分比 >> 工作量占比应当是数字
+测试新建融合瀑布项目总百分比超过100 >> 工作量占比累计不应当超过100%
+
+*/
+
+$stage1 = new stdclass();
+$stage1->name = '新建的需求';
+$stage1->percent = 1;
+$stage1->type = 'request';
+
+$stage2 = new stdclass();
+$stage2->name = '新建的设计';
+$stage2->percent = 2;
+$stage2->type = 'design';
+
+$stage3 = new stdclass();
+$stage3->name = '新建的开发';
+$stage3->percent = 3;
+$stage3->type = 'dev';
+
+$stage4 = new stdclass();
+$stage4->name = '新建的测试';
+$stage4->percent = 4;
+$stage4->type = 'qa';
+
+$stage5 = new stdclass();
+$stage5->name = '新建的发布';
+$stage5->percent = 5;
+$stage5->type = 'release';
+
+$stage6 = new stdclass();
+$stage6->name = '新建的总结评审';
+$stage6->percent = 6;
+$stage6->type = 'review';
+
+$stage7 = new stdclass();
+$stage7->name = '新建的其他';
+$stage7->percent = 7;
+$stage7->type = 'other';
+
+$emptyName = new stdclass();
+$emptyName->name = '';
+$emptyName->percent = 7;
+$emptyName->type = 'other';
+
+$emptyPercent = new stdclass();
+$emptyPercent->name = '1';
+$emptyPercent->percent = 0;
+$emptyPercent->type = 'other';
+
+$emptyType = new stdclass();
+$emptyType->name = '1';
+$emptyType->percent = 7;
+$emptyType->type = '';
+
+$IllegalPercent = new stdclass();
+$IllegalPercent->name = '一个名称';
+$IllegalPercent->percent = 'a';
+$IllegalPercent->type = 'other';
+
+$percentOver = new stdclass();
+$percentOver->name = '一个名称';
+$percentOver->percent = 101;
+$percentOver->type = 'other';
+
+$stage = new stageTest();
+
+r($stage->createTest($stage1)) && p('name,percent,type') && e('新建的需求,1,request'); // 测试新建瀑布项目一个需求阶段
+r($stage->createTest($stage2)) && p('name,percent,type') && e('新建的设计,2,design'); // 测试新建瀑布项目一个设计阶段
+r($stage->createTest($stage3)) && p('name,percent,type') && e('新建的开发,3,dev'); // 测试新建瀑布项目一个开发阶段
+r($stage->createTest($stage4)) && p('name,percent,type') && e('新建的测试,4,qa'); // 测试新建瀑布项目一个测试阶段
+r($stage->createTest($stage5)) && p('name,percent,type') && e('新建的发布,5,release'); // 测试新建瀑布项目一个发布阶段
+r($stage->createTest($stage6)) && p('name,percent,type') && e('新建的总结评审,6,review'); // 测试新建瀑布项目一个总结评审阶段
+r($stage->createTest($stage7)) && p('name,percent,type') && e('新建的其他,7,other'); // 测试新建瀑布项目一个其他阶段
+r($stage->createTest($emptyName)) && p('name:0') && e('『阶段名称』不能为空。'); // 测试新建瀑布项目名称为空
+r($stage->createTest($emptyPercent)) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试新建瀑布项目类型为空
+r($stage->createTest($emptyType)) && p('type:0') && e('『阶段类型』不能为空。'); // 测试新建瀑布项目百分比为空
+r($stage->createTest($IllegalPercent)) && p('message:0') && e('工作量占比应当是数字'); // 测试新建瀑布项目非数字的百分比
+r($stage->createTest($percentOver)) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试新建瀑布项目总百分比超过100
+r($stage->createTest($stage1, 'waterfallplus')) && p('name,percent,type') && e('新建的需求,1,request'); // 测试新建融合瀑布项目一个需求阶段
+r($stage->createTest($stage2, 'waterfallplus')) && p('name,percent,type') && e('新建的设计,2,design'); // 测试新建融合瀑布项目一个设计阶段
+r($stage->createTest($stage3, 'waterfallplus')) && p('name,percent,type') && e('新建的开发,3,dev'); // 测试新建融合瀑布项目一个开发阶段
+r($stage->createTest($stage4, 'waterfallplus')) && p('name,percent,type') && e('新建的测试,4,qa'); // 测试新建融合瀑布项目一个测试阶段
+r($stage->createTest($stage5, 'waterfallplus')) && p('name,percent,type') && e('新建的发布,5,release'); // 测试新建融合瀑布项目一个发布阶段
+r($stage->createTest($stage6, 'waterfallplus')) && p('name,percent,type') && e('新建的总结评审,6,review'); // 测试新建融合瀑布项目一个总结评审阶段
+r($stage->createTest($stage7, 'waterfallplus')) && p('name,percent,type') && e('新建的其他,7,other'); // 测试新建融合瀑布项目一个其他阶段
+r($stage->createTest($emptyName, 'waterfallplus')) && p('name:0') && e('『阶段名称』不能为空。'); // 测试新建融合瀑布项目名称为空
+r($stage->createTest($emptyPercent, 'waterfallplus')) && p('percent:0') && e('『工作量占比』不能为空。'); // 测试新建融合瀑布项目类型为空
+r($stage->createTest($emptyType, 'waterfallplus')) && p('type:0') && e('『阶段类型』不能为空。'); // 测试新建融合瀑布项目百分比为空
+r($stage->createTest($IllegalPercent, 'waterfallplus')) && p('message:0') && e('工作量占比应当是数字'); // 测试新建融合瀑布项目非数字的百分比
+r($stage->createTest($percentOver, 'waterfallplus')) && p('message:0') && e('工作量占比累计不应当超过100%'); // 测试新建融合瀑布项目总百分比超过100
diff --git a/module/stage/test/model/getbyid.php b/module/stage/test/model/getbyid.php
new file mode 100755
index 0000000000..3720d5ee26
--- /dev/null
+++ b/module/stage/test/model/getbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+测试获取阶段 1 >> 需求,10,request
+测试获取阶段 2 >> 设计,10,design
+测试获取阶段 3 >> 开发,50,dev
+测试获取阶段 4 >> 测试,15,qa
+测试获取阶段 5 >> 发布,10,release
+测试获取阶段 6 >> 总结评审,5,review
+
+*/
+
+$stageIDList = array(1, 2, 3, 4, 5, 6);
+
+$stage = new stageTest();
+
+r($stage->getByIDTest($stageIDList[0])) && p('name,percent,type') && e('需求,10,request'); // 测试获取阶段 1
+r($stage->getByIDTest($stageIDList[1])) && p('name,percent,type') && e('设计,10,design'); // 测试获取阶段 2
+r($stage->getByIDTest($stageIDList[2])) && p('name,percent,type') && e('开发,50,dev'); // 测试获取阶段 3
+r($stage->getByIDTest($stageIDList[3])) && p('name,percent,type') && e('测试,15,qa'); // 测试获取阶段 4
+r($stage->getByIDTest($stageIDList[4])) && p('name,percent,type') && e('发布,10,release'); // 测试获取阶段 5
+r($stage->getByIDTest($stageIDList[5])) && p('name,percent,type') && e('总结评审,5,review'); // 测试获取阶段 6
\ No newline at end of file
diff --git a/module/stage/test/model/getpairs.php b/module/stage/test/model/getpairs.php
new file mode 100755
index 0000000000..5ea715efb0
--- /dev/null
+++ b/module/stage/test/model/getpairs.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+测试获取阶段 1 >> 需求
+测试获取阶段 2 >> 设计
+测试获取阶段 3 >> 开发
+测试获取阶段 4 >> 测试
+测试获取阶段 5 >> 发布
+测试获取阶段 6 >> 总结评审
+
+*/
+
+$stage = new stageTest();
+
+r($stage->getPairsTest()) && p('1') && e('需求'); // 测试获取阶段 1
+r($stage->getPairsTest()) && p('2') && e('设计'); // 测试获取阶段 2
+r($stage->getPairsTest()) && p('3') && e('开发'); // 测试获取阶段 3
+r($stage->getPairsTest()) && p('4') && e('测试'); // 测试获取阶段 4
+r($stage->getPairsTest()) && p('5') && e('发布'); // 测试获取阶段 5
+r($stage->getPairsTest()) && p('6') && e('总结评审'); // 测试获取阶段 6
\ No newline at end of file
diff --git a/module/stage/test/model/getstages.php b/module/stage/test/model/getstages.php
new file mode 100755
index 0000000000..0cf975f9f0
--- /dev/null
+++ b/module/stage/test/model/getstages.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getStages();
+cid=1
+pid=1
+
+测试获取阶段 1 >> 需求,10,request
+测试获取阶段 2 >> 设计,10,design
+测试获取阶段 3 >> 开发,50,dev
+测试获取阶段 4 >> 测试,15,qa
+测试获取阶段 5 >> 发布,10,release
+测试获取阶段 6 >> 总结评审,5,review
+
+*/
+
+zdTable('stage')->gen(10);
+
+$stage = new stageTest();
+
+r($stage->getStagesTest()) && p('1:name,percent,type') && e('需求,10,request'); // 测试获取阶段 1
+r($stage->getStagesTest()) && p('2:name,percent,type') && e('设计,10,design'); // 测试获取阶段 2
+r($stage->getStagesTest()) && p('3:name,percent,type') && e('开发,50,dev'); // 测试获取阶段 3
+r($stage->getStagesTest()) && p('4:name,percent,type') && e('测试,15,qa'); // 测试获取阶段 4
+r($stage->getStagesTest()) && p('5:name,percent,type') && e('发布,10,release'); // 测试获取阶段 5
+r($stage->getStagesTest()) && p('6:name,percent,type') && e('总结评审,5,review'); // 测试获取阶段 6
diff --git a/module/stage/test/model/gettotalpercent.php b/module/stage/test/model/gettotalpercent.php
new file mode 100644
index 0000000000..e1d1c89e27
--- /dev/null
+++ b/module/stage/test/model/gettotalpercent.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+id->range('1-10');
+$stage->percent->range('10-20');
+$stage->projectType->range('waterfall{5}, waterfallplus{5}');
+$stage->deleted->range('0-1');
+$stage->gen(10);
+
+/**
+
+title=测试 stageModel->getTotalPercent();
+cid=1
+pid=1
+
+测试获取瀑布项目的总百分比 >> 36
+测试获取融合瀑布项目的总百分比 >> 34
+
+*/
+
+$stage = new stageTest();
+
+r($stage->getTotalPercentTest('waterfall')) && p() && e('36'); // 测试获取瀑布项目的总百分比
+r($stage->getTotalPercentTest('waterfallplus')) && p() && e('34'); // 测试获取融合瀑布项目的总百分比
diff --git a/module/stage/test/model/update.php b/module/stage/test/model/update.php
new file mode 100755
index 0000000000..67143c4ccd
--- /dev/null
+++ b/module/stage/test/model/update.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试修改名称 >> name,需求,修改后的需求
+测试修改工作量占比 >> percent,10,15
+测试修改阶段分类 >> type,request,other
+
+*/
+
+$stageID = 1;
+
+$changeName = array('name' => '修改后的需求');
+$changePercent = array('percent' => '15');
+$changeType = array('type' => 'other');
+
+$stage = new stageTest();
+
+r($stage->updateTest($stageID, $changeName)) && p('0:field,old,new') && e('name,需求,修改后的需求'); // 测试修改名称
+r($stage->updateTest($stageID, $changePercent)) && p('0:field,old,new') && e('percent,10,15'); // 测试修改工作量占比
+r($stage->updateTest($stageID, $changeType)) && p('0:field,old,new') && e('type,request,other'); // 测试修改阶段分类
diff --git a/module/stage/test/stage.class.php b/module/stage/test/stage.class.php
new file mode 100644
index 0000000000..13901a41a6
--- /dev/null
+++ b/module/stage/test/stage.class.php
@@ -0,0 +1,137 @@
+objectModel = $tester->loadModel('stage');
+ }
+
+ /**
+ * Test create a stage.
+ *
+ * @param object $stage
+ * @param string $type
+ * @access public
+ * @return object
+ */
+ public function createTest($stage, $type = 'waterfall')
+ {
+ foreach($stage as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create($type);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($objectID, $type);
+ return $object;
+ }
+
+ /**
+ * Test batch create stages.
+ *
+ * @param array $param
+ * @param string $type
+ * @access public
+ * @return int
+ */
+ public function batchCreateTest($param ,$type = 'waterfall')
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->batchCreate($type);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getStages('id_desc', 0, $type);
+ return count($objects);
+ }
+
+ /**
+ * Test update a stage.
+ *
+ * @param int $stageID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateTest($stageID, $param)
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->update($stageID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get stages.
+ *
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getStagesTest($orderBy = 'id_desc')
+ {
+ $objects = $this->objectModel->getStages($orderBy = 'id_desc');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get pairs of stage.
+ *
+ * @access public
+ * @return array
+ */
+ public function getPairsTest()
+ {
+ $objects = $this->objectModel->getPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get a stage by id.
+ *
+ * @param int $stageID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($stageID)
+ {
+ $object = $this->objectModel->getByID($stageID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get a stage by id.
+ *
+ * @param string $projectType
+ * @access public
+ * @return object
+ */
+ public function getTotalPercentTest($projectType)
+ {
+ $object = $this->objectModel->getTotalPercent($projectType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+}
diff --git a/module/stakeholder/test/model/batchcreate.php b/module/stakeholder/test/model/batchcreate.php
new file mode 100755
index 0000000000..726ad191b3
--- /dev/null
+++ b/module/stakeholder/test/model/batchcreate.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+batchCreate();
+cid=1
+pid=1
+
+ >> 6
+ >> 6
+ >> 6
+ >> 6
+
+*/
+$projectIDList = array('11', '31', '61');
+$realnames = array('开发38', '开发29', '开发30');
+$accounts = array('test28', 'test29', 'test30', 'dev1', 'dev13', 'dev12');
+
+$normalStakeholder = array('realnames' => $realnames, 'accounts' => $accounts);
+$noRealnames = array('accounts' => $accounts);
+
+$stakeholder = new stakeholderTest();
+r(count($stakeholder->batchCreateTest($projectIDList[0], $normalStakeholder))) && p() && e('6');
+r(count($stakeholder->batchCreateTest($projectIDList[1], $normalStakeholder))) && p() && e('6');
+r(count($stakeholder->batchCreateTest($projectIDList[2], $normalStakeholder))) && p() && e('6');
+r(count($stakeholder->batchCreateTest($projectIDList[0], $noRealnames))) && p() && e('6');
+
diff --git a/module/stakeholder/test/model/communicate.php b/module/stakeholder/test/model/communicate.php
new file mode 100755
index 0000000000..969e33fd2b
--- /dev/null
+++ b/module/stakeholder/test/model/communicate.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+communicate();
+cid=1
+pid=1
+
+ >> 沟通内容
+ >> 『对象ID』应当是数字。
+
+*/
+$userIDList = array('10', '', '17');
+$comment = array('comment' => '沟通内容');
+
+$stakeholder = new stakeholderTest();
+r($stakeholder->communicateTest($userIDList[0], $comment)) && p('0:comment') && e('沟通内容');
+r($stakeholder->communicateTest($userIDList[2])) && p('0:comment') && e('');
+r($stakeholder->communicateTest($userIDList[1], $comment)) && p('objectID:0') && e('『对象ID』应当是数字。');
+
diff --git a/module/stakeholder/test/model/create.php b/module/stakeholder/test/model/create.php
new file mode 100755
index 0000000000..737bcb2c5b
--- /dev/null
+++ b/module/stakeholder/test/model/create.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+项目集添加干系人 >> 1
+项目添加干系人 >> dev17
+执行添加干系人 >> outside
+输入错误的from >> test
+输入不存在的用户名 >> autotest
+不输入用户 >> 用户不能为空!
+输入错误的key值 >> 『key』不符合格式,应当为:『/0|1/』。
+创建相同的干系人 >> 『用户』已经有『po22』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+
+*/
+$objectIDList = array('1', '11', '101');
+
+$froms = array('team', 'company', 'outside', 'test');
+$key = array('0', '1');
+$user = array('po22', 'dev17', 'outside1', 'autotest', 'dev27');
+
+$teamStakeholder = array('from' => $froms[0], 'key' => $key[0], 'user' => $user[0], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$companyStakeholder = array('from' => $froms[1], 'key' => $key[1], 'user' => $user[1], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$outsideStakeholder = array('from' => $froms[2], 'key' => $key[0], 'user' => $user[2], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$errorFrom = array('from' => $froms[3], 'key' => $key[0], 'user' => $user[0], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$errorUser = array('from' => $froms[0], 'key' => $key[0], 'user' => $user[3], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$noUser = array('from' => $froms[0], 'key' => $key[0], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+$noKey = array('from' => $froms[0], 'user' => $user[3], 'nature' => '性格特征', 'analysis' => '影响分析', 'strategy' => '应对策略');
+
+$stakeholder = new stakeholderTest();
+r($stakeholder->createTest($objectIDList[0],$teamStakeholder)) && p('objectID') && e('1'); //项目集添加干系人
+r($stakeholder->createTest($objectIDList[1],$companyStakeholder)) && p('user') && e('dev17'); //项目添加干系人
+r($stakeholder->createTest($objectIDList[2],$outsideStakeholder)) && p('type') && e('outside'); //执行添加干系人
+r($stakeholder->createTest($objectIDList[2],$errorFrom)) && p('from') && e('test'); //输入错误的from
+r($stakeholder->createTest($objectIDList[0],$errorUser)) && p('user') && e('autotest'); //输入不存在的用户名
+r($stakeholder->createTest($objectIDList[0],$noUser)[0]) && p() && e('用户不能为空!'); //不输入用户
+r($stakeholder->createTest($objectIDList[2],$noKey)) && p('key:0') && e('『key』不符合格式,应当为:『/0|1/』。');//输入错误的key值
+r($stakeholder->createTest($objectIDList[0],$teamStakeholder)) && p('user:0') && e('『用户』已经有『po22』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。');//创建相同的干系人
+
diff --git a/module/stakeholder/test/model/deleteexpect.php.bak b/module/stakeholder/test/model/deleteexpect.php.bak
new file mode 100644
index 0000000000..61d5e050d5
--- /dev/null
+++ b/module/stakeholder/test/model/deleteexpect.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+deleteExpect();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->deleteExpectTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/edit.php b/module/stakeholder/test/model/edit.php
new file mode 100755
index 0000000000..292566ecd4
--- /dev/null
+++ b/module/stakeholder/test/model/edit.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+edit();
+cid=1
+pid=1
+
+修改关键干系人 >> key,0,1
+修改nature >> 0
+修改analysis >> key,1,0
+修改strategy >> 0
+不输入是否关键干系人 >> 『key』不符合格式,应当为:『/0|1/』。
+
+*/
+$stakeholderID = array('7', '17');
+
+$updateKey = array('key' => '1');
+$updateNature = array('key' => '0', 'nature' => '修改nature');
+$updateAnalysis = array('key' => '0', 'analysis' => '修改analysis');
+$updateStrategy = array('key' => '0', 'strategy' => '修改strategy');
+$noKey = array('key' => '');
+
+$stakeholder = new stakeholderTest();
+r($stakeholder->editTest($stakeholderID[0], $updateKey)) && p('0:field,old,new') && e('key,0,1'); //修改关键干系人
+r($stakeholder->editTest($stakeholderID[1], $updateNature)) && p() && e('0'); //修改nature
+r($stakeholder->editTest($stakeholderID[0], $updateAnalysis)) && p('0:field,old,new') && e('key,1,0'); //修改analysis
+r($stakeholder->editTest($stakeholderID[1], $updateStrategy)) && p() && e('0'); //修改strategy
+r($stakeholder->editTest($stakeholderID[0], $noKey)) && p('key:0') && e('『key』不符合格式,应当为:『/0|1/』。');//不输入是否关键干系人
+
diff --git a/module/stakeholder/test/model/editexpect.php.bak b/module/stakeholder/test/model/editexpect.php.bak
new file mode 100644
index 0000000000..55e50605bd
--- /dev/null
+++ b/module/stakeholder/test/model/editexpect.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+editExpect();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->editExpectTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/expect.php.bak b/module/stakeholder/test/model/expect.php.bak
new file mode 100644
index 0000000000..6dffb3a242
--- /dev/null
+++ b/module/stakeholder/test/model/expect.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+expect();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->expectTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getactivities.php.bak b/module/stakeholder/test/model/getactivities.php.bak
new file mode 100644
index 0000000000..73d543f91f
--- /dev/null
+++ b/module/stakeholder/test/model/getactivities.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getActivities();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getActivitiesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getbyid.php b/module/stakeholder/test/model/getbyid.php
new file mode 100755
index 0000000000..0f479d80db
--- /dev/null
+++ b/module/stakeholder/test/model/getbyid.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+正常根据id查询干系人 >> 测试59
+查询id不存在的干系人 >> 0
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$stakeholderIDList = array('0', '17');
+
+r($stakeholder->getByID($stakeholderIDList[1])) && p('name') && e('测试59');//正常根据id查询干系人
+r($stakeholder->getByID($stakeholderIDList[0])) && p() && e('0'); //查询id不存在的干系人
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getexpectbyid.php b/module/stakeholder/test/model/getexpectbyid.php
new file mode 100755
index 0000000000..b1c4503f29
--- /dev/null
+++ b/module/stakeholder/test/model/getexpectbyid.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getExpectByID();
+cid=1
+pid=1
+
+查询不存在的期望数据 >> 0
+正常查询期望数据 >> 期望内容17
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$expectIDList = array('0', '17');
+
+r($stakeholder->getExpectByID($expectIDList[0])) && p() && e('0'); //查询不存在的期望数据
+r($stakeholder->getExpectByID($expectIDList[1])) && p('expect') && e('期望内容17');//正常查询期望数据
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getexpectbyuser.php b/module/stakeholder/test/model/getexpectbyuser.php
new file mode 100755
index 0000000000..aa244f7e21
--- /dev/null
+++ b/module/stakeholder/test/model/getexpectbyuser.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getExpectByUser();
+cid=1
+pid=1
+
+查询不存在的期望 >> 0
+正常查询期望 >> 11
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$stakeholderIDList = array('0', '32');
+
+r($stakeholder->getExpectByUser($stakeholderIDList[0])) && p() && e('0'); //查询不存在的期望
+r($stakeholder->getExpectByUser($stakeholderIDList[1])) && p('0:project') && e('11');//正常查询期望
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getexpectlist.php.bak b/module/stakeholder/test/model/getexpectlist.php.bak
new file mode 100644
index 0000000000..0148638160
--- /dev/null
+++ b/module/stakeholder/test/model/getexpectlist.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getExpectList();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getExpectListTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getissues.php.bak b/module/stakeholder/test/model/getissues.php.bak
new file mode 100644
index 0000000000..80238b9030
--- /dev/null
+++ b/module/stakeholder/test/model/getissues.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getIssues();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getIssuesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getlistbytype.php.bak b/module/stakeholder/test/model/getlistbytype.php.bak
new file mode 100644
index 0000000000..f44f4de928
--- /dev/null
+++ b/module/stakeholder/test/model/getlistbytype.php.bak
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getListByType();
+cid=1
+pid=1
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+var_dump($stakeholder->getListByType());die;
+r($stakeholder->getListByTypeTest()) && p() && e();
diff --git a/module/stakeholder/test/model/getparentstakeholdergroup.php b/module/stakeholder/test/model/getparentstakeholdergroup.php
new file mode 100755
index 0000000000..faa62eba68
--- /dev/null
+++ b/module/stakeholder/test/model/getparentstakeholdergroup.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getParentStakeholderGroup();
+cid=1
+pid=1
+
+正常输入项目项目集参数查询 >> user9
+不输入项目集项目参数查询 >> 0
+正常输入项目项目集参数查询统计 >> 2
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$objectIDList = array('11', '31', '100', '1');
+$noObjectIDList = array();
+
+r($stakeholder->getParentStakeholderGroup($objectIDList)) && p('31:user9') && e('user9');//正常输入项目项目集参数查询
+r($stakeholder->getParentStakeholderGroup($noObjectIDList)) && p() && e('0'); //不输入项目集项目参数查询
+r(count($stakeholder->getParentStakeholderGroup($objectIDList))) && p() && e('2'); //正常输入项目项目集参数查询统计
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getplans.php.bak b/module/stakeholder/test/model/getplans.php.bak
new file mode 100644
index 0000000000..709b81a505
--- /dev/null
+++ b/module/stakeholder/test/model/getplans.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getPlans();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getPlansTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getprocess.php.bak b/module/stakeholder/test/model/getprocess.php.bak
new file mode 100644
index 0000000000..e6e73dcc38
--- /dev/null
+++ b/module/stakeholder/test/model/getprocess.php.bak
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getProcess();
+cid=1
+pid=1
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+var_dump($stakeholder->getProcess());die;
+r($stakeholder->getProcess()) && p() && e();
diff --git a/module/stakeholder/test/model/getprocessgroup.php.bak b/module/stakeholder/test/model/getprocessgroup.php.bak
new file mode 100644
index 0000000000..f0e5cc1668
--- /dev/null
+++ b/module/stakeholder/test/model/getprocessgroup.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getProcessGroup();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getProcessGroupTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholdergroup.php b/module/stakeholder/test/model/getstakeholdergroup.php
new file mode 100755
index 0000000000..3dd41322fc
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholdergroup.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getStakeholderGroup();
+cid=1
+pid=1
+
+正常查询干系人分组 >> admin
+正常查询干系人分组统计 >> 4
+空数组查询 >> 0
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$objectIDList = array('11', '31', '100', '1');
+$noObjectIDList = array();
+
+r($stakeholder->getStakeholderGroup($objectIDList)) && p('11:admin') && e('admin');//正常查询干系人分组
+r(count($stakeholder->getStakeholderGroup($objectIDList))) && p() && e('4'); //正常查询干系人分组统计
+r($stakeholder->getStakeholderGroup($noObjectIDList)) && p() && e('0'); //空数组查询
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholderissue.php.bak b/module/stakeholder/test/model/getstakeholderissue.php.bak
new file mode 100644
index 0000000000..89390d8d28
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholderissue.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getStakeholderIssue();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getStakeholderIssueTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholderpairs.php b/module/stakeholder/test/model/getstakeholderpairs.php
new file mode 100755
index 0000000000..1c9ba9948d
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholderpairs.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getStakeHolderPairs();
+cid=1
+pid=1
+
+敏捷项目查询干系人 >> 开发8
+瀑布项目查询干系人 >> 产品经理8
+外部干系人查询 >> 用户1
+项目集干系人查询 >> 测试7
+敏捷项目查询干系人统 计 >> 4
+瀑布项目查询干系人统计 >> 3
+外部干系人查询统计 >> 3
+项目集干系人查询统计 >> 3
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$projectIDList = array('11', '31', '100', '1');
+
+r($stakeholder->getStakeHolderPairs($projectIDList[0])) && p('test8') && e('开发8'); //敏捷项目查询干系人
+r($stakeholder->getStakeHolderPairs($projectIDList[1])) && p('pm8') && e('产品经理8');//瀑布项目查询干系人
+r($stakeholder->getStakeHolderPairs($projectIDList[2])) && p('outside1') && e('用户1'); //外部干系人查询
+r($stakeholder->getStakeHolderPairs($projectIDList[3])) && p('user7') && e('测试7'); //项目集干系人查询
+r(count($stakeholder->getStakeHolderPairs($projectIDList[0]))) && p() && e('4'); //敏捷项目查询干系人统 计
+r(count($stakeholder->getStakeHolderPairs($projectIDList[1]))) && p() && e('3'); //瀑布项目查询干系人统计
+r(count($stakeholder->getStakeHolderPairs($projectIDList[2]))) && p() && e('3'); //外部干系人查询统计
+r(count($stakeholder->getStakeHolderPairs($projectIDList[3]))) && p() && e('3'); //项目集干系人查询统计
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholders.php b/module/stakeholder/test/model/getstakeholders.php
new file mode 100755
index 0000000000..3988b4be81
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholders.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+getStakeholders();
+cid=1
+pid=1
+
+敏捷项目干系人查询 >> 11,project
+瀑布项目inside干系人查询 >> 31,产品经理10
+outside干系人查询 >> project,用户1
+关键干系人查询 >> 1,admin
+项目集干系人查询 >> 1,program
+敏捷项目干系人查询统计 >> 4
+瀑布项目inside干系人查询统计 >> 3
+outside干系人查询统计 >> 1
+关键干系人查询统计 >> 1
+项目集干系人查询统计 >> 3
+
+*/
+global $tester;
+$stakeholder = $tester->loadModel('stakeholder');
+
+$projectIDList = array('11', '31', '100', '1');
+$browseType = array('all', 'inside', 'outside', 'key', 'qt');
+$orderBy = array('id_desc', 'name_desc');
+
+r($stakeholder->getStakeholders($projectIDList[0], $browseType[0], $orderBy[0])) && p('1:objectID,objectType') && e('11,project'); //敏捷项目干系人查询
+r($stakeholder->getStakeholders($projectIDList[1], $browseType[1], $orderBy[1])) && p('92:objectID,name') && e('31,产品经理10');//瀑布项目inside干系人查询
+r($stakeholder->getStakeholders($projectIDList[2], $browseType[2], $orderBy[1])) && p('301:objectType,name') && e('project,用户1');//outside干系人查询
+r($stakeholder->getStakeholders($projectIDList[0], $browseType[3], $orderBy[0])) && p('1:key,name') && e('1,admin'); //关键干系人查询
+r($stakeholder->getStakeholders($projectIDList[3], $browseType[0], $orderBy[0])) && p('2:objectID,objectType') && e('1,program'); //项目集干系人查询
+r(count($stakeholder->getStakeholders($projectIDList[0], $browseType[0], $orderBy[0]))) && p() && e('4'); //敏捷项目干系人查询统计
+r(count($stakeholder->getStakeholders($projectIDList[1], $browseType[1], $orderBy[1]))) && p() && e('3'); //瀑布项目inside干系人查询统计
+r(count($stakeholder->getStakeholders($projectIDList[2], $browseType[2], $orderBy[1]))) && p() && e('1'); //outside干系人查询统计
+r(count($stakeholder->getStakeholders($projectIDList[0], $browseType[3], $orderBy[0]))) && p() && e('1'); //关键干系人查询统计
+r(count($stakeholder->getStakeholders($projectIDList[3], $browseType[0], $orderBy[0]))) && p() && e('3'); //项目集干系人查询统计
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholders4issue.php.bak b/module/stakeholder/test/model/getstakeholders4issue.php.bak
new file mode 100644
index 0000000000..43a267e204
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholders4issue.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getStakeholders4Issue();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getStakeholders4IssueTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/model/getstakeholderusers.php.bak b/module/stakeholder/test/model/getstakeholderusers.php.bak
new file mode 100644
index 0000000000..36329238b3
--- /dev/null
+++ b/module/stakeholder/test/model/getstakeholderusers.php.bak
@@ -0,0 +1,17 @@
+#!/usr/bin/env php
+getStakeholderUsers();
+cid=1
+pid=1
+
+*/
+
+$stakeholder = new stakeholderTest();
+
+r($stakeholder->getStakeholderUsersTest()) && p() && e();
\ No newline at end of file
diff --git a/module/stakeholder/test/stakeholder.class.php b/module/stakeholder/test/stakeholder.class.php
new file mode 100644
index 0000000000..22a70a6087
--- /dev/null
+++ b/module/stakeholder/test/stakeholder.class.php
@@ -0,0 +1,113 @@
+objectModel = $tester->loadModel('stakeholder');
+ }
+
+ /**
+ * Function create test by stakeholder
+ *
+ * @param int $objectID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function createTest($objectID, $param = array())
+ {
+ $createFields = array('from' => '', 'key' => '', 'user' => '', 'name' => '', 'phone' => '', 'qq' => '', 'weixin' => '',
+ 'email' => '', 'company' => '', 'nature' => '', 'analysis' => '', 'strategy' => '');
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create($objectID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($objectID);
+
+ return $objects;
+ }
+
+ /**
+ * Function batchCreate test by stakeholder
+ *
+ * @param int $projectID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function batchCreateTest($projectID, $param = array())
+ {
+ $realnames = array();
+ $accounts = array();
+
+ $createFields = array('realnames' => $realnames, 'accounts' => $accounts);
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->batchCreate($projectID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function edit test by stakeholder
+ *
+ * @param int $stakeholderID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function editTest($stakeholderID, $param = array())
+ {
+ $createFields = array('key' => '', 'nature' => '', 'analysis' => '', 'strategy' => '');
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->edit($stakeholderID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Function communicate test by stakeholder
+ *
+ * @param int $stakeholderID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function communicateTest($stakeholderID, $param = array())
+ {
+ global $tester;
+ $createFields = array('comment' => '');
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->communicate($stakeholderID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $tester->dao->select('*')->from(TABLE_ACTION)->where('objectID')->eq($stakeholderID)->andwhere('objectType')->eq('stakeholder')->fetchAll();
+ return $objects;
+ }
+}
diff --git a/module/story/test/model/activate.php b/module/story/test/model/activate.php
new file mode 100755
index 0000000000..667b414fc5
--- /dev/null
+++ b/module/story/test/model/activate.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+activate();
+cid=1
+pid=1
+
+查看激活之前的需求状态 >> active
+查看激活之前的需求状态 >> closed
+查看激活之前的需求状态 >> changed
+查看激活之前的需求状态 >> draft
+查看激活之后的需求状态 >> active
+查看激活之后的需求状态 >> active
+查看激活之后的需求状态 >> active
+查看激活之后的需求状态 >> active
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$beforeActivate2 = $tester->story->getById(2);
+$beforeActivate63 = $tester->story->getById(63);
+$beforeActivate100 = $tester->story->getById(100);
+$beforeActivate301 = $tester->story->getById(301);
+
+$_POST['status'] = 'active';
+$tester->story->activate(2);
+$tester->story->activate(63);
+$tester->story->activate(100);
+$tester->story->activate(301);
+
+$afterActivate2 = $tester->story->getById(2);
+$afterActivate63 = $tester->story->getById(63);
+$afterActivate100 = $tester->story->getById(100);
+$afterActivate301 = $tester->story->getById(301);
+
+r($beforeActivate2) && p('status') && e('active'); //查看激活之前的需求状态
+r($beforeActivate63) && p('status') && e('closed'); //查看激活之前的需求状态
+r($beforeActivate100) && p('status') && e('changed'); //查看激活之前的需求状态
+r($beforeActivate301) && p('status') && e('draft'); //查看激活之前的需求状态
+r($afterActivate2) && p('status') && e('active'); //查看激活之后的需求状态
+r($afterActivate63) && p('status') && e('active'); //查看激活之后的需求状态
+r($afterActivate100) && p('status') && e('active'); //查看激活之后的需求状态
+r($afterActivate301) && p('status') && e('active'); //查看激活之后的需求状态
+
diff --git a/module/story/test/model/assign.php b/module/story/test/model/assign.php
new file mode 100755
index 0000000000..159fb2e72e
--- /dev/null
+++ b/module/story/test/model/assign.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+assign();
+cid=1
+pid=1
+
+指派需求,查看返回的指派人信息 >> 2,test2
+指派需求,查看返回的指派人信息 >> 4,
+指派需求,查看返回的指派人信息 >> 5,user10
+指派需求,查看返回的指派人信息 >> 10,admin
+指派需求,查看返回的指派人信息 >> 100,user50
+指派需求,查看返回的指派人信息 >> 101,pm1
+
+*/
+
+$story = new storyTest();
+
+r($story->assignTest(2, 'test2')) && p('id,assignedTo') && e('2,test2'); //指派需求,查看返回的指派人信息
+r($story->assignTest(4, '')) && p('id,assignedTo') && e('4,'); //指派需求,查看返回的指派人信息
+r($story->assignTest(5, 'user10')) && p('id,assignedTo') && e('5,user10'); //指派需求,查看返回的指派人信息
+r($story->assignTest(10, 'admin')) && p('id,assignedTo') && e('10,admin'); //指派需求,查看返回的指派人信息
+r($story->assignTest(100, 'user50')) && p('id,assignedTo') && e('100,user50'); //指派需求,查看返回的指派人信息
+r($story->assignTest(101, 'pm1')) && p('id,assignedTo') && e('101,pm1'); //指派需求,查看返回的指派人信息
+
diff --git a/module/story/test/model/batchassignto.php b/module/story/test/model/batchassignto.php
new file mode 100755
index 0000000000..d19854e847
--- /dev/null
+++ b/module/story/test/model/batchassignto.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+batchAssignTo();
+cid=1
+pid=1
+
+批量指派6个需求,查看修改成功的需求数量 >> 6
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+批量指派6个需求,查看修改成功的需求指派人 >> test20
+
+*/
+
+$story = new storyTest();
+
+$params['assignedTo'] = 'test20';
+$params['storyIdList'] = array(1, 2, 3, 4, 5, 6);
+
+$stories = $story->batchAssignToTest($params);
+
+r(count($stories)) && p() && e('6'); // 批量指派6个需求,查看修改成功的需求数量
+r($stories) && p('1:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+r($stories) && p('2:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+r($stories) && p('3:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+r($stories) && p('4:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+r($stories) && p('5:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+r($stories) && p('6:assignedTo') && e('test20'); // 批量指派6个需求,查看修改成功的需求指派人
+
diff --git a/module/story/test/model/batchchangebranch.php b/module/story/test/model/batchchangebranch.php
new file mode 100755
index 0000000000..c2e80dda02
--- /dev/null
+++ b/module/story/test/model/batchchangebranch.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+batchChangeBranch();
+cid=1
+pid=1
+
+批量修改需求的所属分支,判断被修改分支需求的数量 >> 3
+批量修改需求的所属分支,判断需求2修改后的分支ID >> 2
+批量修改需求的所属分支,判断需求4修改后的分支ID >> 2
+批量修改需求的所属分支,判断需求6修改后的分支ID >> 2
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(2, 4, 6);
+
+$stories = $story->batchChangeBranchTest($storyIdList, 2);
+
+r(count($stories)) && p() && e('3'); // 批量修改需求的所属分支,判断被修改分支需求的数量
+r($stories) && p('2:branch') && e('2'); // 批量修改需求的所属分支,判断需求2修改后的分支ID
+r($stories) && p('4:branch') && e('2'); // 批量修改需求的所属分支,判断需求4修改后的分支ID
+r($stories) && p('6:branch') && e('2'); // 批量修改需求的所属分支,判断需求6修改后的分支ID
diff --git a/module/story/test/model/batchchangemodule.php b/module/story/test/model/batchchangemodule.php
new file mode 100755
index 0000000000..caeaaa894d
--- /dev/null
+++ b/module/story/test/model/batchchangemodule.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+batchChangeModule();
+cid=1
+pid=1
+
+批量修改6个需求的模块,查看被修改模块的需求数量 >> 6
+批量修改6个需求的模块,查看需求1修改后的模块ID >> 1366
+批量修改6个需求的模块,查看需求2修改后的模块ID >> 1366
+批量修改6个需求的模块,查看需求3修改后的模块ID >> 1366
+批量修改6个需求的模块,查看需求4修改后的模块ID >> 1366
+批量修改6个需求的模块,查看需求5修改后的模块ID >> 1366
+批量修改6个需求的模块,查看需求6修改后的模块ID >> 1366
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(1, 2, 3, 4, 5, 6);
+$stories = $story->batchChangeModuleTest($storyIdList, 1366);
+
+r(count($stories)) && p() && e('6'); // 批量修改6个需求的模块,查看被修改模块的需求数量
+r($stories) && p('1:module') && e('1366'); // 批量修改6个需求的模块,查看需求1修改后的模块ID
+r($stories) && p('2:module') && e('1366'); // 批量修改6个需求的模块,查看需求2修改后的模块ID
+r($stories) && p('3:module') && e('1366'); // 批量修改6个需求的模块,查看需求3修改后的模块ID
+r($stories) && p('4:module') && e('1366'); // 批量修改6个需求的模块,查看需求4修改后的模块ID
+r($stories) && p('5:module') && e('1366'); // 批量修改6个需求的模块,查看需求5修改后的模块ID
+r($stories) && p('6:module') && e('1366'); // 批量修改6个需求的模块,查看需求6修改后的模块ID
diff --git a/module/story/test/model/batchchangeplan.php b/module/story/test/model/batchchangeplan.php
new file mode 100755
index 0000000000..a634bed7d6
--- /dev/null
+++ b/module/story/test/model/batchchangeplan.php
@@ -0,0 +1,48 @@
+#!/usr/bin/env php
+batchChangePlan();
+cid=1
+pid=1
+
+批量修改6个需求的计划,查看被修改计划的需求数量 >> 6
+批量修改6个需求的计划,查看被修改计划的需求数量 >> 6
+批量修改6个需求的计划,查看需求1修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求2修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求3修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求4修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求5修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求6修改后的计划ID >> ,1366
+批量修改6个需求的计划,查看需求1修改后的计划ID >> ,1366,1400
+批量修改6个需求的计划,查看需求2修改后的计划ID >> ,1366,1400
+批量修改6个需求的计划,查看需求3修改后的计划ID >> ,1366,1400
+批量修改6个需求的计划,查看需求4修改后的计划ID >> ,1366,1400
+批量修改6个需求的计划,查看需求5修改后的计划ID >> ,1366,1400
+批量修改6个需求的计划,查看需求6修改后的计划ID >> ,1366,1400
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(1, 2, 3, 4, 5, 6);
+$stories1 = $story->batchChangePlanTest($storyIdList, 1366);
+$stories2 = $story->batchChangePlanTest($storyIdList, 1400, 1366);
+
+r(count($stories1)) && p() && e('6'); // 批量修改6个需求的计划,查看被修改计划的需求数量
+r(count($stories2)) && p() && e('6'); // 批量修改6个需求的计划,查看被修改计划的需求数量
+r($stories1) && p('1:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求1修改后的计划ID
+r($stories1) && p('2:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求2修改后的计划ID
+r($stories1) && p('3:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求3修改后的计划ID
+r($stories1) && p('4:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求4修改后的计划ID
+r($stories1) && p('5:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求5修改后的计划ID
+r($stories1) && p('6:plan') && e(',1366'); // 批量修改6个需求的计划,查看需求6修改后的计划ID
+r($stories2) && p('1:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求1修改后的计划ID
+r($stories2) && p('2:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求2修改后的计划ID
+r($stories2) && p('3:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求3修改后的计划ID
+r($stories2) && p('4:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求4修改后的计划ID
+r($stories2) && p('5:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求5修改后的计划ID
+r($stories2) && p('6:plan') && e(',1366,1400'); // 批量修改6个需求的计划,查看需求6修改后的计划ID
diff --git a/module/story/test/model/batchchangestage.php b/module/story/test/model/batchchangestage.php
new file mode 100755
index 0000000000..4cd746aace
--- /dev/null
+++ b/module/story/test/model/batchchangestage.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+batchChangeStage();
+cid=1
+pid=1
+
+批量修改6个需求的阶段,查看被修改阶段的需求数量 >> 5
+批量修改6个需求的阶段,查看需求101修改后的阶段 >> developing
+批量修改6个需求的阶段,查看需求102修改后的阶段 >> developing
+批量修改6个需求的阶段,查看需求104修改后的阶段 >> developing
+批量修改6个需求的阶段,查看需求110修改后的阶段 >> developing
+批量修改6个需求的阶段,查看需求114修改后的阶段 >> developing
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(100, 101, 102, 106, 110, 114);
+$result = $story->batchChangeStageTest($storyIdList, 'developing');
+
+r(count($result)) && p() && e('5'); // 批量修改6个需求的阶段,查看被修改阶段的需求数量
+r($result) && p('101:stage') && e('developing'); // 批量修改6个需求的阶段,查看需求101修改后的阶段
+r($result) && p('102:stage') && e('developing'); // 批量修改6个需求的阶段,查看需求102修改后的阶段
+r($result) && p('106:stage') && e('developing'); // 批量修改6个需求的阶段,查看需求104修改后的阶段
+r($result) && p('110:stage') && e('developing'); // 批量修改6个需求的阶段,查看需求110修改后的阶段
+r($result) && p('114:stage') && e('developing'); // 批量修改6个需求的阶段,查看需求114修改后的阶段
diff --git a/module/story/test/model/batchclose.php b/module/story/test/model/batchclose.php
new file mode 100755
index 0000000000..bcdbaf42d2
--- /dev/null
+++ b/module/story/test/model/batchclose.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+batchClose();
+cid=1
+pid=1
+
+批量关闭6个需求,查看被关闭的需求数量 >> 6
+批量关闭需求,查看需求1被关闭后的字段 >> closed,closed,done,0
+批量关闭需求,查看需求2被关闭后的字段 >> closed,closed,willnotdo,0
+批量关闭需求,查看需求3被关闭后的字段 >> closed,closed,putoff,0
+批量关闭需求,查看需求4被关闭后的字段 >> closed,closed,duplicate,8
+批量关闭需求,查看需求5被关闭后的字段 >> closed,closed,cancel,0
+批量关闭需求,查看需求6被关闭后的字段 >> closed,closed,bydesign,0
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(1, 2, 3, 4, 5, 6);
+$closedReasons = array(1 => 'done', 2 => 'willnotdo', 3 => 'putoff', 4 => 'duplicate', 5 => 'cancel', 6 => 'bydesign');
+$duplicateList = array(1 => '', 2 => '', 3 => '', 4 => 8, 5 => '', 6 => '');
+$childStoriesIDList = array(1 => '', 2 => '', 3 => '', 4 => '', 5 => '', 6 => '');
+
+$params['storyIdList'] = $storyIdList;
+$params['closedReasons'] = $closedReasons;
+$params['duplicateStoryIDList'] = $duplicateList;
+$params['childStoriesIDList'] = $childStoriesIDList;
+$stories = $story->batchCloseTest($params);
+
+r(count($stories)) && p() && e('6'); // 批量关闭6个需求,查看被关闭的需求数量
+r($stories) && p('1:status,stage,closedReason,duplicateStory') && e('closed,closed,done,0'); // 批量关闭需求,查看需求1被关闭后的字段
+r($stories) && p('2:status,stage,closedReason,duplicateStory') && e('closed,closed,willnotdo,0'); // 批量关闭需求,查看需求2被关闭后的字段
+r($stories) && p('3:status,stage,closedReason,duplicateStory') && e('closed,closed,putoff,0'); // 批量关闭需求,查看需求3被关闭后的字段
+r($stories) && p('4:status,stage,closedReason,duplicateStory') && e('closed,closed,duplicate,8'); // 批量关闭需求,查看需求4被关闭后的字段
+r($stories) && p('5:status,stage,closedReason,duplicateStory') && e('closed,closed,cancel,0'); // 批量关闭需求,查看需求5被关闭后的字段
+r($stories) && p('6:status,stage,closedReason,duplicateStory') && e('closed,closed,bydesign,0'); // 批量关闭需求,查看需求6被关闭后的字段
diff --git a/module/story/test/model/batchcreate.php b/module/story/test/model/batchcreate.php
new file mode 100755
index 0000000000..233fca6c36
--- /dev/null
+++ b/module/story/test/model/batchcreate.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+batchCreate();
+cid=1
+pid=1
+
+插入两条软件需求,判断返回的需求总量 >> 2
+插入两条用户需求,判断返回的需求总量 >> 2
+插入两条软件需求,判断返回的title、type等信息 >> 测试需求1,story,1,测试需求描述1,1,planned,2221
+插入两条用户需求,判断返回的title、type等信息 >> 测试需求2,requirement,2,测试需求描述2,2,planned,2222
+
+*/
+
+$story = new storyTest();
+$stories = array();
+$stories['title'] = array(1 => '测试需求1', 2 => '测试需求2', 3 => '');
+$stories['pri'] = array(1 => 1, 2 => 2, 3 => 3);
+$stories['spec'] = array(1 => '测试需求描述1', 2 => '测试需求描述2', 3 => '测试需求描述3');
+$stories['verify'] = array(1 => '测试需求验收标准1', 2 => '测试需求验收标准2', 3 => '测试需求验收标准3');
+$stories['estimate'] = array(1 => 1, 2 => 2, 3 => 3);
+$stories['module'] = array(1 => 2221, 2 => 2222, 3 => 2223);
+$stories['plan'] = array(1 => 1, 2 => 2, 3 => 3);
+
+$result1 = $story->batchCreateTest(1, 0, 'story', $stories);
+$result2 = $story->batchCreateTest(2, 0, 'requirement', $stories);
+
+r(count($result1)) && p() && e('2'); // 插入两条软件需求,判断返回的需求总量
+r(count($result2)) && p() && e('2'); // 插入两条用户需求,判断返回的需求总量
+r($result1) && p('401:title,type,pri,spec,estimate,stage,module') && e('测试需求1,story,1,测试需求描述1,1,planned,2221'); // 插入两条软件需求,判断返回的title、type等信息
+r($result2) && p('404:title,type,pri,spec,estimate,stage,module') && e('测试需求2,requirement,2,测试需求描述2,2,planned,2222'); // 插入两条用户需求,判断返回的title、type等信息
diff --git a/module/story/test/model/batchgetstorystage.php b/module/story/test/model/batchgetstorystage.php
new file mode 100755
index 0000000000..708199cfd4
--- /dev/null
+++ b/module/story/test/model/batchgetstorystage.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+batchGetStoryStage();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/batchreview.php b/module/story/test/model/batchreview.php
new file mode 100755
index 0000000000..387aeee432
--- /dev/null
+++ b/module/story/test/model/batchreview.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+batchReview();
+cid=1
+pid=1
+
+批量评审传入三个ID,查看被评审的需求数量 >> 2
+批量评审需求,查看被评审后的需求状态、阶段等信息 >> active,projected,done
+批量评审传入三个ID,查看被评审的需求数量 >> 2
+批量评审需求,查看被评审后的需求状态、阶段等信息 >> closed,closed,bydesign
+批量评审传入三个ID,查看被评审的需求数量 >> 2
+批量评审需求,查看被评审后的需求状态、阶段等信息 >> active,projected,cancel
+
+*/
+
+$story = new storyTest();
+
+$storyIdList1 = array(302, 304, '');
+$storyIdList2 = array(308, 310, 0);
+$storyIdList3 = array(314, 316, 2);
+
+$review1 = $story->batchReviewTest($storyIdList1, 'pass', '');
+$review2 = $story->batchReviewTest($storyIdList2, 'reject', 'done');
+$review3 = $story->batchReviewTest($storyIdList3, 'pass', '');
+
+r(count($review1)) && p() && e('2'); // 批量评审传入三个ID,查看被评审的需求数量
+r($review1) && p('302:status,stage,closedReason') && e('active,projected,done'); // 批量评审需求,查看被评审后的需求状态、阶段等信息
+r(count($review2)) && p() && e('2'); // 批量评审传入三个ID,查看被评审的需求数量
+r($review2) && p('308:status,stage,closedReason') && e('closed,closed,bydesign'); // 批量评审需求,查看被评审后的需求状态、阶段等信息
+r(count($review3)) && p() && e('2'); // 批量评审传入三个ID,查看被评审的需求数量
+r($review3) && p('314:status,stage,closedReason') && e('active,projected,cancel'); // 批量评审需求,查看被评审后的需求状态、阶段等信息
diff --git a/module/story/test/model/batchtotask.php b/module/story/test/model/batchtotask.php
new file mode 100755
index 0000000000..4bbf816472
--- /dev/null
+++ b/module/story/test/model/batchtotask.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+batchToTask();
+cid=1
+pid=1
+
+6个需求批量转任务,查看转化后的数量 >> 5
+查看从需求转化过来的任务的名称、状态、优先级等字段 >> 11,101,软件需求66,wait,0,test,
+查看从需求转化过来的任务的名称、状态、优先级等字段 >> 11,101,软件需求68,wait,0,test,
+查看从需求转化过来的任务的名称、状态、优先级等字段 >> 11,101,软件需求70,wait,0,test,
+查看从需求转化过来的任务的名称、状态、优先级等字段 >> 11,101,软件需求102,wait,0,test,
+查看从需求转化过来的任务的名称、状态、优先级等字段 >> 11,101,软件需求220,wait,0,test,
+
+*/
+
+$story = new storyTest();
+
+$params['storyIdList'] = array(66, 68, 70, 102, 220, 320);
+$params['type'] = 'test';
+$params['fields'] = array('assignedTo');
+
+$tasks = $story->batchToTaskTest(101, 11, $params);
+
+r(count($tasks)) && p() && e('5'); //6个需求批量转任务,查看转化后的数量
+r($tasks) && p('911:project,execution,name,status,pri,type,assignedTo') && e('11,101,软件需求66,wait,0,test,'); //查看从需求转化过来的任务的名称、状态、优先级等字段
+r($tasks) && p('912:project,execution,name,status,pri,type,assignedTo') && e('11,101,软件需求68,wait,0,test,'); //查看从需求转化过来的任务的名称、状态、优先级等字段
+r($tasks) && p('913:project,execution,name,status,pri,type,assignedTo') && e('11,101,软件需求70,wait,0,test,'); //查看从需求转化过来的任务的名称、状态、优先级等字段
+r($tasks) && p('914:project,execution,name,status,pri,type,assignedTo') && e('11,101,软件需求102,wait,0,test,'); //查看从需求转化过来的任务的名称、状态、优先级等字段
+r($tasks) && p('915:project,execution,name,status,pri,type,assignedTo') && e('11,101,软件需求220,wait,0,test,'); //查看从需求转化过来的任务的名称、状态、优先级等字段
diff --git a/module/story/test/model/batchupdate.php b/module/story/test/model/batchupdate.php
new file mode 100755
index 0000000000..9a6ca3dc14
--- /dev/null
+++ b/module/story/test/model/batchupdate.php
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+更新两条软件需求,判断返回的需求总量 >> 2
+更新两条用户需求,判断返回的需求总量 >> 2
+更新两条软件需求,判断返回的title、type等信息 >> 测试软件需求2,story,3,测试来源备注2,3,2223
+更新两条用户需求,判断返回的title、type等信息 >> 测试用户需求2,requirement,3,测试来源备注2,3,2221
+
+*/
+
+$story = new storyTest();
+$stories = array();
+$stories['titles'] = array(12 => '测试软件需求1', 14 => '测试软件需求2');
+$stories['colors'] = array(12 => '', 14 => '');
+$stories['pris'] = array(12 => 1, 14 => 3);
+$stories['estimates'] = array(12 => 1, 14 => 3);
+$stories['modules'] = array(12 => 2221, 14 => 2223);
+$stories['plans'] = array(12 => 1, 14 => 3);
+$stories['assignedTo'] = array(12 => 'admin', 14 => 'test10');
+$stories['sources'] = array(12 => 'customer', 14 => 'po');
+$stories['sourceNote'] = array(12 => '测试软件需求来源备注1', 14 => '测试软件需求来源备注2');
+$stories['category'] = array(12 => 'feature', 14 => 'improve');
+$stories['keywords'] = array(12 => '关键词111', 14 => '关键词333');
+$stories['storyIdList'] = array(12, 14);
+
+$requirements['titles'] = array(13 => '测试用户需求1', 15 => '测试用户需求2');
+$requirements['colors'] = array(13 => '', 15 => '');
+$requirements['pris'] = array(13 => 1, 15 => 3);
+$requirements['estimates'] = array(13 => 1, 15 => 3);
+$requirements['modules'] = array(13 => 2221, 15 => 2223);
+$requirements['plans'] = array(13 => 1, 15 => 3);
+$requirements['assignedTo'] = array(13 => 'admin', 15 => 'test10');
+$requirements['sources'] = array(13 => 'customer', 15 => 'po');
+$requirements['sourceNote'] = array(13 => '测试用户需求来源备注1', 15 => '测试用户需求来源备注2');
+$requirements['category'] = array(13 => 'feature', 15 => 'improve');
+$requirements['keywords'] = array(13 => '关键词111', 15 => '关键词333');
+$requirements['storyIdList'] = array(13, 15);
+
+$result1 = $story->batchUpdateTest($stories);
+$result2 = $story->batchUpdateTest($requirements);
+
+r(count($result1)) && p() && e('2'); // 更新两条软件需求,判断返回的需求总量
+r(count($result2)) && p() && e('2'); // 更新两条用户需求,判断返回的需求总量
+r($result1) && p('14:title,type,pri,sourceNote,estimate,module') && e('测试软件需求2,story,3,测试来源备注2,3,2223'); // 更新两条软件需求,判断返回的title、type等信息
+r($result2) && p('15:title,type,pri,sourceNote,estimate,module') && e('测试用户需求2,requirement,3,测试来源备注2,3,2221'); // 更新两条用户需求,判断返回的title、type等信息
diff --git a/module/story/test/model/change.php b/module/story/test/model/change.php
new file mode 100755
index 0000000000..5569812d81
--- /dev/null
+++ b/module/story/test/model/change.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+change();
+cid=1
+pid=1
+
+不勾选【不需要评审】,不传入由谁评审时的变更,给出提示 >> 『由谁评审』不能为空。
+变更时不填写需求名称,给出提示 >> 『研发需求名称』不能为空。
+正常变更需求,判断返回的status、title等信息 >> changed,测试需求1变更标题,测试需求1的变更描述,测试需求1的变更验收标准,1,admin,3
+
+*/
+
+$story = new storyTest();
+$story1['title'] = '测试需求1变更标题';
+$story1['spec'] = '测试需求1的变更描述';
+$story1['verify'] = '测试需求1的变更验收标准';
+$story1['estimate'] = 1;
+
+$story2 = $story1;
+$story2['reviewer'] = array('admin', 'test2');
+$story2['title'] = '';
+
+$story3 = $story1;
+$story3['needNotReview'] = true;
+
+$result1 = $story->changeTest(1, $story1);
+$result2 = $story->changeTest(2, $story2);
+$result3 = $story->changeTest(26, $story3);
+
+r($result1[0]) && p() && e('『由谁评审』不能为空。'); // 不勾选【不需要评审】,不传入由谁评审时的变更,给出提示
+r($result2) && p('title:0') && e('『研发需求名称』不能为空。'); // 变更时不填写需求名称,给出提示
+r($result3) && p('status,title,spec,verify,estimate,lastEditedBy,version') && e('changed,测试需求1变更标题,测试需求1的变更描述,测试需求1的变更验收标准,1,admin,3'); // 正常变更需求,判断返回的status、title等信息
diff --git a/module/story/test/model/checkneedconfirm.php b/module/story/test/model/checkneedconfirm.php
new file mode 100755
index 0000000000..aed008dde2
--- /dev/null
+++ b/module/story/test/model/checkneedconfirm.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+checkNeedConfirm();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/close.php b/module/story/test/model/close.php
new file mode 100755
index 0000000000..e2bf23c29e
--- /dev/null
+++ b/module/story/test/model/close.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+关闭一个用户需求,查看变更的字段1 >> assigedTo,,closed
+关闭一个用户需求,查看变更的字段2 >> status,active,closed
+关闭一个用户需求,查看变更的字段3 >> stage,wait,closed
+关闭一个软件需求,查看变更的字段1 >> closedReason,subdivided,willnotdo
+关闭一个软件需求,查看变更的字段2 >> assignedTo,,closed
+关闭一个软件需求,查看变更的字段3 >> status,active,closed
+
+*/
+
+$story = new storyTest();
+$changes1 = $story->closeTest(1, array('closedReason' => 'done'));
+$changes2 = $story->closeTest(2, array('closedReason' => 'willnotdo'));
+
+r($changes1) && p('0:field,old,new') && e('assigedTo,,closed'); // 关闭一个用户需求,查看变更的字段1
+r($changes1) && p('1:field,old,new') && e('status,active,closed'); // 关闭一个用户需求,查看变更的字段2
+r($changes1) && p('2:field,old,new') && e('stage,wait,closed'); // 关闭一个用户需求,查看变更的字段3
+r($changes2) && p('0:field,old,new') && e('closedReason,subdivided,willnotdo'); // 关闭一个软件需求,查看变更的字段1
+r($changes2) && p('1:field,old,new') && e('assignedTo,,closed'); // 关闭一个软件需求,查看变更的字段2
+r($changes2) && p('2:field,old,new') && e('status,active,closed'); // 关闭一个软件需求,查看变更的字段3
diff --git a/module/story/test/model/computeestimate.php b/module/story/test/model/computeestimate.php
new file mode 100755
index 0000000000..33855fc254
--- /dev/null
+++ b/module/story/test/model/computeestimate.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+computeEstimate();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/create.php b/module/story/test/model/create.php
new file mode 100755
index 0000000000..b5a94f1e6a
--- /dev/null
+++ b/module/story/test/model/create.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+不勾选由谁评审并且不传入评审人的情况,报错 >> 『由谁评审』不能为空。
+不勾选由谁评审传入评审人的情况,正常插入 >> 0,projected,1
+勾选由谁评审,不传入executionID的情况,阶段为wait >> 测试需求3,2,wait
+勾选由谁评审,传入executionID和fromBug的情况,阶段为projected >> 『研发需求名称』不能为空。
+
+*/
+
+$story = new storyTest();
+$story1['title'] = '测试需求1';
+$story1['pri'] = '3';
+$story1['product'] = 1;
+$story1['spec'] = '测试需求的描述111';
+$story1['verify'] = '测试需求的验收标准111';
+$story1['estimate'] = 3;
+$story1['mailto'] = array('user2', 'test2', 'admin');
+
+$story2 = $story1;
+$story2['reviewer'] = array('admin');
+$story2['title'] = '测试需求2';
+
+$story3 = $story1;
+$story3['needNotReview'] = true;
+$story3['product'] = 2;
+$story3['title'] = '测试需求3';
+
+$story4 = $story1;
+$story4['needNotReview'] = true;
+$story4['title'] = '';
+
+$result1 = $story->createTest(11, 0, '', '', $story1);
+$result2 = $story->createTest(11, 0, '', '', $story2);
+$result3 = $story->createTest(0, 2, '', '', $story3);
+$result4 = $story->createTest(12, 2, '', '', $story4);
+
+r($result1[0]) && p() && e('『由谁评审』不能为空。'); //不勾选由谁评审并且不传入评审人的情况,报错
+r($result2) && p('fromBug,stage,product') && e('0,projected,1'); //不勾选由谁评审传入评审人的情况,正常插入
+r($result3) && p('title,fromBug,stage') && e('测试需求3,2,wait'); //勾选由谁评审,不传入executionID的情况,阶段为wait
+r($result4) && p('title:0') && e('『研发需求名称』不能为空。'); //勾选由谁评审,传入executionID和fromBug的情况,阶段为projected
diff --git a/module/story/test/model/createstoryfromgitlabissue.php b/module/story/test/model/createstoryfromgitlabissue.php
new file mode 100755
index 0000000000..c35e41bcfa
--- /dev/null
+++ b/module/story/test/model/createstoryfromgitlabissue.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+createStoryFromGitlabIssue();
+cid=1
+pid=1
+
+创建正常的需求,获取创建后的id、title、stage、product >> 401,测试需求1,projected,1
+需求名称为空,给出提示 >> 『研发需求名称』不能为空。
+创建正常的需求,获取创建后的id、title、stage、product >> 402,测试需求3,projected,2
+
+*/
+
+$story = new storyTest();
+$story1->title = '测试需求1';
+$story1->pri = '3';
+$story1->product = 1;
+$story1->spec = '测试需求的描述111';
+$story1->verify = '测试需求的验收标准111';
+$story1->estimate = 3;
+$story1->mailto = array('user2', 'test2', 'admin');
+
+$story2 = clone $story1;
+$story2->title = '';
+
+$story3 = clone $story1;
+$story3->product = 2;
+$story3->title = '测试需求3';
+
+$result1 = $story->createStoryFromGitlabIssueTest($story1, 11);
+$result2 = $story->createStoryFromGitlabIssueTest($story2, 12);
+$result3 = $story->createStoryFromGitlabIssueTest($story3, 0);
+
+r($result1) && p('id,title,stage,product') && e('401,测试需求1,projected,1'); //创建正常的需求,获取创建后的id、title、stage、product
+r($result2) && p('title:0') && e('『研发需求名称』不能为空。'); //需求名称为空,给出提示
+r($result3) && p('id,title,stage,product') && e('402,测试需求3,projected,2'); //创建正常的需求,获取创建后的id、title、stage、product
diff --git a/module/story/test/model/extractaccountsfromlist.php b/module/story/test/model/extractaccountsfromlist.php
new file mode 100755
index 0000000000..6cec1349a6
--- /dev/null
+++ b/module/story/test/model/extractaccountsfromlist.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+extractAccountsFromList();
+cid=1
+pid=1
+
+根据产品1的需求列表获取的accounts数量 >> 2
+根据产品2的需求列表获取的accounts数量 >> 2
+根据产品1的需求列表获取的account详情 >> user2
+根据产品2的需求列表获取的account详情 >> user2
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getProductStories(1);
+$stories2 = $tester->story->getProductStories(2);
+
+$accounts1 = $tester->story->extractAccountsFromList($stories1);
+$accounts2 = $tester->story->extractAccountsFromList($stories2);
+
+r(count($accounts1)) && p() && e('2'); // 根据产品1的需求列表获取的accounts数量
+r(count($accounts2)) && p() && e('2'); // 根据产品2的需求列表获取的accounts数量
+r($accounts1) && p('2') && e('user2'); // 根据产品1的需求列表获取的account详情
+r($accounts2) && p('2') && e('user2'); // 根据产品2的需求列表获取的account详情
\ No newline at end of file
diff --git a/module/story/test/model/extractaccountsfromsingle.php b/module/story/test/model/extractaccountsfromsingle.php
new file mode 100755
index 0000000000..be32ee345f
--- /dev/null
+++ b/module/story/test/model/extractaccountsfromsingle.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+extractAccountsFromSingle();
+cid=1
+pid=1
+
+根据需求2获取的accounts数量 >> 1
+根据需求4获取的accounts数量 >> 1
+根据需求2获取的account详情 >> user2
+根据需求4获取的account详情 >> dev4
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$story1 = $tester->story->getById(2);
+$story2 = $tester->story->getById(4);
+
+$accounts1 = $tester->story->extractAccountsFromSingle($story1);
+$accounts2 = $tester->story->extractAccountsFromSingle($story2);
+
+r(count($accounts1)) && p() && e('1'); // 根据需求2获取的accounts数量
+r(count($accounts2)) && p() && e('1'); // 根据需求4获取的accounts数量
+r($accounts1[0]) && p('0') && e('user2'); // 根据需求2获取的account详情
+r($accounts2[0]) && p('0') && e('dev4'); // 根据需求4获取的account详情
\ No newline at end of file
diff --git a/module/story/test/model/formatstories.php b/module/story/test/model/formatstories.php
new file mode 100755
index 0000000000..d076dc9d6d
--- /dev/null
+++ b/module/story/test/model/formatstories.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+formatStories();
+cid=1
+pid=1
+
+获取处理title之前的需求列表数量 >> 2
+获取处理title之前的需求列表数量 >> 2
+获取处理title之前的需求title >> 软件需求2
+获取处理title之前的需求title >> 软件需求6
+获取处理title之后的需求列表数量 >> 3
+获取处理title之后的需求列表数量 >> 3
+获取处理title之后的需求title >> 2:软件需求2 (优先级:2,预计工时:20)
+获取处理title之后的需求title >> 6:软件需求6 (优先级:2,预计工时:17)
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getProductStories(1);
+$stories2 = $tester->story->getProductStories(2);
+
+$formatStories1 = $tester->story->formatStories($stories1);
+$formatStories2 = $tester->story->formatStories($stories2);
+
+r(count($stories1)) && p() && e('2'); // 获取处理title之前的需求列表数量
+r(count($stories2)) && p() && e('2'); // 获取处理title之前的需求列表数量
+r($stories1) && p('2:title') && e('软件需求2'); // 获取处理title之前的需求title
+r($stories2) && p('6:title') && e('软件需求6'); // 获取处理title之前的需求title
+r(count($formatStories1)) && p() && e('3'); // 获取处理title之后的需求列表数量
+r(count($formatStories2)) && p() && e('3'); // 获取处理title之后的需求列表数量
+r($formatStories1) && p('2') && e('2:软件需求2 (优先级:2,预计工时:20)'); // 获取处理title之后的需求title
+r($formatStories2) && p('6') && e('6:软件需求6 (优先级:2,预计工时:17)'); // 获取处理title之后的需求title
\ No newline at end of file
diff --git a/module/story/test/model/get2beclosed.php b/module/story/test/model/get2beclosed.php
new file mode 100755
index 0000000000..2aaddbdb55
--- /dev/null
+++ b/module/story/test/model/get2beclosed.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+get2BeClosed();
+cid=1
+pid=1
+
+获取产品3下需要关闭的软件需求数量 >> 1
+获取产品3下需要关闭的软件需求详情 >> 软件需求10,story,developed
+获取产品10下需要关闭的软件需求数量 >> 1
+获取产品10下需要关闭的软件需求详情 >> 软件需求38,story,released
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$toBeClosed1 = $tester->story->get2BeClosed(3, 0, array(), 'story', 'id_desc');
+$toBeClosed2 = $tester->story->get2BeClosed(10, 0, array(), 'story', 'id_asc');
+
+r(count($toBeClosed1)) && p() && e('1'); //获取产品3下需要关闭的软件需求数量
+r($toBeClosed1) && p('10:title,type,stage') && e('软件需求10,story,developed'); //获取产品3下需要关闭的软件需求详情
+r(count($toBeClosed2)) && p() && e('1'); //获取产品10下需要关闭的软件需求数量
+r($toBeClosed2) && p('38:title,type,stage') && e('软件需求38,story,released'); //获取产品10下需要关闭的软件需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getaffectedscope.php b/module/story/test/model/getaffectedscope.php
new file mode 100755
index 0000000000..a631e01551
--- /dev/null
+++ b/module/story/test/model/getaffectedscope.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getAffectedScope();
+cid=1
+pid=1
+
+获取需求1影响任务的数量 >> 6
+获取需求15影响任务的数量 >> 0
+查看返回的需求1的title >> 用户需求版本三41
+查看返回的需求15的title >> 软件需求版本三55
+查看需求100的影响的迭代的名字 >> 迭代25
+
+*/
+
+$story = new storyTest();
+$affectedScope1 = $story->getAffectedScopeTest(1);
+$affectedScope2 = $story->getAffectedScopeTest(15);
+$affectedScope3 = $story->getAffectedScopeTest(100);
+
+r(count($affectedScope1->tasks)) && p() && e('6'); //获取需求1影响任务的数量
+r(count($affectedScope2->tasks)) && p() && e('0'); //获取需求15影响任务的数量
+r($affectedScope1) && p('title') && e('用户需求版本三41'); //查看返回的需求1的title
+r($affectedScope2) && p('title') && e('软件需求版本三55'); //查看返回的需求15的title
+r($affectedScope3->executions) && p('125:name') && e('迭代25'); //查看需求100的影响的迭代的名字
\ No newline at end of file
diff --git a/module/story/test/model/getallstorysort.php b/module/story/test/model/getallstorysort.php
new file mode 100755
index 0000000000..72169d93b0
--- /dev/null
+++ b/module/story/test/model/getallstorysort.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getAllStorySort();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getbyassignedbyme.php b/module/story/test/model/getbyassignedbyme.php
new file mode 100755
index 0000000000..e23bf1598c
--- /dev/null
+++ b/module/story/test/model/getbyassignedbyme.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getByAssignedbyme();
+cid=1
+pid=1
+
+查看产品 1 由我指派的需求 >> 0
+查看产品 2 由我指派的需求 >> 0
+查看产品 3 由我指派的需求 >> 0
+查看产品 4 由我指派的需求 >> 0
+查看产品 5 由我指派的需求 >> 0
+
+*/
+
+$productIDList = array(1, 2, 3, 4 ,5);
+$branch = 'all';
+
+$story=new storyTest();
+
+r($story->getByAssignedByTest($productIDList[0], $branch)) && p() && e('0'); // 查看产品 1 由我指派的需求
+r($story->getByAssignedByTest($productIDList[1], $branch)) && p() && e('0'); // 查看产品 2 由我指派的需求
+r($story->getByAssignedByTest($productIDList[2], $branch)) && p() && e('0'); // 查看产品 3 由我指派的需求
+r($story->getByAssignedByTest($productIDList[3], $branch)) && p() && e('0'); // 查看产品 4 由我指派的需求
+r($story->getByAssignedByTest($productIDList[4], $branch)) && p() && e('0'); // 查看产品 5 由我指派的需求
\ No newline at end of file
diff --git a/module/story/test/model/getbyfield.php b/module/story/test/model/getbyfield.php
new file mode 100755
index 0000000000..626c59e3ea
--- /dev/null
+++ b/module/story/test/model/getbyfield.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getByField();
+cid=1
+pid=1
+
+根据指派给获取软件需求 >> 用户需求1,requirement,admin
+根据创建人获取软件需求 >> 软件需求6,user2
+根据由谁评审获取软件需求 >> 软件需求12,admin
+根据由谁评审获取软件需求数量 >> 2
+根据由谁评审获取软件需求 >> 软件需求306,story
+根据由谁关闭获取软件需求 >> 用户需求23,requirement,test3,关闭原因23
+根据状态获取软件需求 >> 软件需求22,active,story
+根据计划获取软件需求 >> 软件需求26,projected,7,19
+根据计划获取软件需求数量 >> 2
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$byAssignedTo = $tester->story->getByField(1, 0, array(), 'assignedTo', 'admin', 'requirement', 'id_desc');
+$byOpenedBy = $tester->story->getByField(2, 0, array(), 'openedBy', 'user2', 'story', 'id_asc');
+$byReviewedBy = $tester->story->getByField(3, 0, array(), 'reviewedBy', 'admin', 'story', 'id_desc');
+$byReviewBy = $tester->story->getByField(77, 0, array(), 'reviewBy', 'admin', 'story', 'id_desc');
+$byClosedBy = $tester->story->getByField(6, 0, array(), 'closedBy', 'test3', 'requirement', 'id_desc');
+$byStatus = $tester->story->getByField(6, 0, array(), 'status', 'active', 'story', 'id_desc');
+$byPlan = $tester->story->getByField(7, 0, array(), 'plan', '19', 'story', 'id_desc');
+
+r($byAssignedTo) && p('1:title,type,assignedTo') && e('用户需求1,requirement,admin'); // 根据指派给获取软件需求
+r($byOpenedBy) && p('6:title,openedBy') && e('软件需求6,user2'); // 根据创建人获取软件需求
+r($byReviewedBy) && p('12:title,reviewedBy') && e('软件需求12,admin'); // 根据由谁评审获取软件需求
+r(count($byReviewBy)) && p() && e('2'); // 根据由谁评审获取软件需求数量
+r($byReviewBy) && p('306:title,type') && e('软件需求306,story'); // 根据由谁评审获取软件需求
+r($byClosedBy) && p('23:title,type,closedBy,closedReason') && e('用户需求23,requirement,test3,关闭原因23'); // 根据由谁关闭获取软件需求
+r($byStatus) && p('22:title,status,type') && e('软件需求22,active,story'); // 根据状态获取软件需求
+r($byPlan) && p('26:title,stage,product,plan') && e('软件需求26,projected,7,19'); // 根据计划获取软件需求
+r(count($byPlan)) && p() && e('2'); // 根据计划获取软件需求数量
\ No newline at end of file
diff --git a/module/story/test/model/getbyid.php b/module/story/test/model/getbyid.php
new file mode 100755
index 0000000000..e528d44e9a
--- /dev/null
+++ b/module/story/test/model/getbyid.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+ >> 6
+获取ID为1、版本号为1的需求的名称 >> 用户需求版本一1
+获取ID为1、版本号为2的需求的名称 >> 用户需求版本二21
+获取ID为2、版本号为3的需求的名称 >> 用户需求版本三43
+获取ID为20、版本号为2的需求的名称 >> 这是一个软件需求描述40
+
+*/
+
+$story = new storyTest();
+$story1Version1 = $story->getByIdTest(1, 1);
+$story1Version2 = $story->getByIdTest(1, 2);
+$story2Version3 = $story->getByIdTest(3, 3);
+$story20Version2 = $story->getByIdTest(20, 2);
+
+r(count($story1Version1->tasks)) && p() && e('6');
+r($story1Version1) && p('title') && e('用户需求版本一1'); //获取ID为1、版本号为1的需求的名称
+r($story1Version2) && p('title') && e('用户需求版本二21'); //获取ID为1、版本号为2的需求的名称
+r($story2Version3) && p('title') && e('用户需求版本三43'); //获取ID为2、版本号为3的需求的名称
+r($story20Version2) && p('spec') && e('这是一个软件需求描述40'); //获取ID为20、版本号为2的需求的名称
\ No newline at end of file
diff --git a/module/story/test/model/getbylist.php b/module/story/test/model/getbylist.php
new file mode 100755
index 0000000000..1e9703520c
--- /dev/null
+++ b/module/story/test/model/getbylist.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+根据指定的ID列表,获取需求数量 >> 5
+获取软件需求数量 >> 10
+获取用户需求数量 >> 10
+根据指定的ID列表,获取第一个需求的名称 >> 用户需求1
+获取第一个软件需求的名称 >> 软件需求2
+获取第一个用户需求的名称 >> 用户需求1
+传入空类型,返回空列表 >> 0
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(1, 2, 3, 4, 5);
+
+$storyInIdList = $story->getByListTest($storyIdList);
+$stories = $story->getByListTest(0, 'story');
+$reqiurements = $story->getByListTest(0, 'requirement');
+$emptyStories = $story->getByListTest(0, '');
+
+r(count($storyInIdList)) && p() && e('5'); //根据指定的ID列表,获取需求数量
+r(count($stories)) && p() && e('10'); //获取软件需求数量
+r(count($reqiurements)) && p() && e('10'); //获取用户需求数量
+r($storyInIdList) && p('1:title') && e('用户需求1'); //根据指定的ID列表,获取第一个需求的名称
+r($stories) && p('2:title') && e('软件需求2'); //获取第一个软件需求的名称
+r($reqiurements) && p('1:title') && e('用户需求1'); //获取第一个用户需求的名称
+r($emptyStories) && p('') && e('0'); //传入空类型,返回空列表
\ No newline at end of file
diff --git a/module/story/test/model/getbysearch.php b/module/story/test/model/getbysearch.php
new file mode 100755
index 0000000000..179106dae3
--- /dev/null
+++ b/module/story/test/model/getbysearch.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getBySearch();
+cid=1
+pid=1
+
+根据第二个query获取需求数量 >> 1
+根据第二个query获取需求 >> 软件需求362,story,55,91
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getBySearch(91, '', 2);
+
+r(count($stories1)) && p() && e('1'); // 根据第二个query获取需求数量
+r($stories1) && p('362:title,type,plan,product') && e('软件需求362,story,55,91'); // 根据第二个query获取需求
\ No newline at end of file
diff --git a/module/story/test/model/getbysql.php b/module/story/test/model/getbysql.php
new file mode 100755
index 0000000000..9ad61f3ba6
--- /dev/null
+++ b/module/story/test/model/getbysql.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getBySQL();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getchangedstories.php b/module/story/test/model/getchangedstories.php
new file mode 100755
index 0000000000..9f8e7bc398
--- /dev/null
+++ b/module/story/test/model/getchangedstories.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getChangedStories();
+cid=1
+pid=1
+
+获取需求26关联的用户需求数量 >> 1
+获取需求26关联的用户需求详情 >> 用户需求25,draft,requirement
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$story = $tester->story->getById(26);
+$requirements = $tester->story->getChangedStories($story);
+
+r(count($requirements)) && p() && e('1'); // 获取需求26关联的用户需求数量
+r($requirements) && p('25:title,status,type') && e('用户需求25,draft,requirement'); // 获取需求26关联的用户需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperassignedto.php b/module/story/test/model/getdataofstorysperassignedto.php
new file mode 100755
index 0000000000..a3aa2a29de
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperassignedto.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getDataOfStorysPerAssignedTo();
+cid=1
+pid=1
+
+按照需求指派人分组,获取分组后的需求数量 >> 5
+按照需求指派人分组,获取各个指派人名下的需求数量,查看admin下的数据 >> admin,100
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerAssignedTo();
+
+r(count($data)) && p() && e('5'); // 按照需求指派人分组,获取分组后的需求数量
+r($data) && p('admin:name,value') && e('admin,100'); // 按照需求指派人分组,获取各个指派人名下的需求数量,查看admin下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperchange.php b/module/story/test/model/getdataofstorysperchange.php
new file mode 100755
index 0000000000..9153b3c38f
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperchange.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getDataOfStorysPerChange();
+cid=1
+pid=1
+
+按照需求版本号分组,获取分组后的需求数量 >> 3
+按照需求版本号分组,获取各个版本号下的需求数量,查看admin下的数据 >> 1,80
+按照需求版本号分组,获取各个版本号下的需求数量,查看admin下的数据 >> 0,350
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$data = $tester->story->getDataOfStorysPerChange();
+
+r(count($data)) && p() && e('3'); // 按照需求版本号分组,获取分组后的需求数量
+r($data) && p('1:name,value') && e('1,80'); // 按照需求版本号分组,获取各个版本号下的需求数量,查看admin下的数据
+r($data) && p('2:name,value') && e('0,350'); // 按照需求版本号分组,获取各个版本号下的需求数量,查看admin下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperclosedreason.php b/module/story/test/model/getdataofstorysperclosedreason.php
new file mode 100755
index 0000000000..96a957de13
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperclosedreason.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfStorysPerClosedReason();
+cid=1
+pid=1
+
+按照需求关闭原因分组,获取分组后的需求数量 >> 8
+按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看willnotdo的数据 >> 不做,12
+按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看bydesign的数据 >> 设计如此,12
+按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看cancel的数据 >> 已取消,11
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerClosedReason();
+
+r(count($data)) && p() && e('8'); // 按照需求关闭原因分组,获取分组后的需求数量
+r($data) && p('willnotdo:name,value') && e('不做,12'); // 按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看willnotdo的数据
+r($data) && p('bydesign:name,value') && e('设计如此,12'); // 按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看bydesign的数据
+r($data) && p('cancel:name,value') && e('已取消,11'); // 按照需求关闭原因分组,获取各个关闭原因下的需求数量,查看cancel的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperestimate.php b/module/story/test/model/getdataofstorysperestimate.php
new file mode 100755
index 0000000000..9f6c35c75e
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperestimate.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getDataOfStorysPerEstimate();
+cid=1
+pid=1
+
+按照需求预计工时分组,获取分组后的需求数量 >> 21
+按照需求预计工时分组,获取各个工时的需求数量,查看工时为19的数据 >> 17,28
+按照需求预计工时分组,获取各个工时的需求数量,查看工时为20的数据 >> 1,28
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$data = $tester->story->getDataOfStorysPerEstimate();
+
+r(count($data)) && p() && e('21'); // 按照需求预计工时分组,获取分组后的需求数量
+r($data) && p('19:name,value') && e('17,28'); // 按照需求预计工时分组,获取各个工时的需求数量,查看工时为19的数据
+r($data) && p('20:name,value') && e('1,28'); // 按照需求预计工时分组,获取各个工时的需求数量,查看工时为20的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstoryspermodule.php b/module/story/test/model/getdataofstoryspermodule.php
new file mode 100755
index 0000000000..e0b1c74aa1
--- /dev/null
+++ b/module/story/test/model/getdataofstoryspermodule.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getDataOfStorysPerModule();
+cid=1
+pid=1
+
+按照模块分组,获取分组后的需求数量 >> 100
+按照模块分组,获取各个模块下的需求数量,查看模块2150下的数据 >> /产品模块330,1,83
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerModule();
+
+r(count($data)) && p() && e('100'); // 按照模块分组,获取分组后的需求数量
+r($data) && p('2150:name,value,product') && e('/产品模块330,1,83'); // 按照模块分组,获取各个模块下的需求数量,查看模块2150下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperopenedby.php b/module/story/test/model/getdataofstorysperopenedby.php
new file mode 100755
index 0000000000..0d06a71291
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperopenedby.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getDataOfStorysPerOpenedBy();
+cid=1
+pid=1
+
+按照创建人分组,获取分组后的需求数量 >> 5
+按照创建人分组,获取各个创建人的需求数量,查看用户test3下的数据 >> 开发3,100
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerOpenedBy();
+
+r(count($data)) && p() && e('5'); // 按照创建人分组,获取分组后的需求数量
+r($data) && p('test3:name,value') && e('开发3,100'); // 按照创建人分组,获取各个创建人的需求数量,查看用户test3下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperplan.php b/module/story/test/model/getdataofstorysperplan.php
new file mode 100755
index 0000000000..d3a6a5794d
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperplan.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getDataOfStorysPerPlan();
+cid=1
+pid=1
+
+按照计划分组,获取分组后的需求数量 >> 25
+按照计划分组,获取各个计划的需求数量,查看1下的数据 >> 1.0,18
+按照计划分组,获取各个计划的需求数量,查看70下的数据 >> 1.0,15
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerPlan();
+
+r(count($data)) && p() && e('25'); // 按照计划分组,获取分组后的需求数量
+r($data) && p('1:name,value') && e('1.0,18'); // 按照计划分组,获取各个计划的需求数量,查看1下的数据
+r($data) && p('70:name,value') && e('1.0,15'); // 按照计划分组,获取各个计划的需求数量,查看70下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperpri.php b/module/story/test/model/getdataofstorysperpri.php
new file mode 100755
index 0000000000..c89caaa33c
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperpri.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getDataOfStorysPerPri();
+cid=1
+pid=1
+
+按照优先级分组,获取分组后的需求数量 >> 4
+按照优先级分组,获取各个优先级的需求数量,查看优先级1下的数据 >> 1,113
+按照优先级分组,获取各个优先级的需求数量,查看优先级4下的数据 >> 1,112
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerPri();
+
+r(count($data)) && p() && e('4'); // 按照优先级分组,获取分组后的需求数量
+r($data) && p('1:name,value') && e('1,113'); // 按照优先级分组,获取各个优先级的需求数量,查看优先级1下的数据
+r($data) && p('4:name,value') && e('1,112'); // 按照优先级分组,获取各个优先级的需求数量,查看优先级4下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperproduct.php b/module/story/test/model/getdataofstorysperproduct.php
new file mode 100755
index 0000000000..68880d20fa
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperproduct.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getDataOfStorysPerProduct();
+cid=1
+pid=1
+
+按照产品分组,获取分组后的需求数量 >> 100
+按照产品分组,获取各个产品下的需求数量,查看产品79下的数据 >> 已关闭的多分支产品79,4
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerProduct();
+
+r(count($data)) && p() && e('100'); // 按照产品分组,获取分组后的需求数量
+r($data) && p('79:name,value') && e('已关闭的多分支产品79,4'); // 按照产品分组,获取各个产品下的需求数量,查看产品79下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstoryspersource.php b/module/story/test/model/getdataofstoryspersource.php
new file mode 100755
index 0000000000..e5bf261ab1
--- /dev/null
+++ b/module/story/test/model/getdataofstoryspersource.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getDataOfStorysPerSource();
+cid=1
+pid=1
+
+按照需求来源分组,获取分组后的需求数量 >> 14
+按照需求来源分组,获取各个需求来源的需求数量,查看support下的数据 >> 技术支持,33
+按照需求来源分组,获取各个需求来源的需求数量,查看market下的数据 >> 市场,33
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerSource();
+
+r(count($data)) && p() && e('14'); // 按照需求来源分组,获取分组后的需求数量
+r($data) && p('support:name,value') && e('技术支持,33'); // 按照需求来源分组,获取各个需求来源的需求数量,查看support下的数据
+r($data) && p('market:name,value') && e('市场,33'); // 按照需求来源分组,获取各个需求来源的需求数量,查看market下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperstage.php b/module/story/test/model/getdataofstorysperstage.php
new file mode 100755
index 0000000000..456b8104ae
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperstage.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfStorysPerStage();
+cid=1
+pid=1
+
+按照需求阶段分组,获取分组后的需求数量 >> 11
+按照需求阶段分组,获取各个需求阶段的需求数量,查看wait下的数据 >> 未开始,25
+按照需求阶段分组,获取各个需求阶段的需求数量,查看planned下的数据 >> 已计划,25
+按照需求阶段分组,获取各个需求阶段的需求数量,查看released下的数据 >> 已发布,25
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerStage();
+
+r(count($data)) && p() && e('11'); // 按照需求阶段分组,获取分组后的需求数量
+r($data) && p('wait:name,value') && e('未开始,25'); // 按照需求阶段分组,获取各个需求阶段的需求数量,查看wait下的数据
+r($data) && p('planned:name,value') && e('已计划,25'); // 按照需求阶段分组,获取各个需求阶段的需求数量,查看planned下的数据
+r($data) && p('released:name,value') && e('已发布,25'); // 按照需求阶段分组,获取各个需求阶段的需求数量,查看released下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getdataofstorysperstatus.php b/module/story/test/model/getdataofstorysperstatus.php
new file mode 100755
index 0000000000..e97a7e6029
--- /dev/null
+++ b/module/story/test/model/getdataofstorysperstatus.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getDataOfStorysPerStatus();
+cid=1
+pid=1
+
+按照需求状态分组,获取分组后的需求数量 >> 4
+按照需求状态分组,获取各个需求状态的需求数量,查看draft下的数据 >> 草稿,184
+按照需求状态分组,获取各个需求状态的需求数量,查看active下的数据 >> 激活,103
+按照需求状态分组,获取各个需求状态的需求数量,查看closed下的数据 >> 已关闭,82
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->loadModel('report');
+
+$data = $tester->story->getDataOfStorysPerStatus();
+
+r(count($data)) && p() && e('4'); // 按照需求状态分组,获取分组后的需求数量
+r($data) && p('draft:name,value') && e('草稿,184'); // 按照需求状态分组,获取各个需求状态的需求数量,查看draft下的数据
+r($data) && p('active:name,value') && e('激活,103'); // 按照需求状态分组,获取各个需求状态的需求数量,查看active下的数据
+r($data) && p('closed:name,value') && e('已关闭,82'); // 按照需求状态分组,获取各个需求状态的需求数量,查看closed下的数据
\ No newline at end of file
diff --git a/module/story/test/model/getestimateinfo.php b/module/story/test/model/getestimateinfo.php
new file mode 100755
index 0000000000..b82212296f
--- /dev/null
+++ b/module/story/test/model/getestimateinfo.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getEstimateInfo();
+cid=1
+pid=1
+
+
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$storyInfo = $tester->story->getEstimateInfo(2);
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getestimaterounds.php b/module/story/test/model/getestimaterounds.php
new file mode 100755
index 0000000000..9cb38f0351
--- /dev/null
+++ b/module/story/test/model/getestimaterounds.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getEstimateRounds();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getexecutionstories.php b/module/story/test/model/getexecutionstories.php
new file mode 100755
index 0000000000..2ea8dd1972
--- /dev/null
+++ b/module/story/test/model/getexecutionstories.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getExecutionStories();
+cid=1
+pid=1
+
+获取执行11下的需求数量 >> 4
+获取执行11下的需求详情 >> 软件需求364,story,draft,developing
+获取执行11、产品91下的需求数量 >> 2
+获取执行11、产品91下的需求详情 >> 软件需求362,story,draft,planned
+获取执行11、产品1下的需求数量 >> 2
+获取执行11、产品1下的需求详情 >> 软件需求2,story,active,wait
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getExecutionStories(11);
+$stories2 = $tester->story->getExecutionStories(11, 91);
+$stories3 = $tester->story->getExecutionStories(11, 1);
+
+r(count($stories1)) && p() && e('4'); // 获取执行11下的需求数量
+r($stories1) && p('364:title,type,status,stage') && e('软件需求364,story,draft,developing'); // 获取执行11下的需求详情
+r(count($stories2)) && p() && e('2'); // 获取执行11、产品91下的需求数量
+r($stories2) && p('362:title,type,status,stage') && e('软件需求362,story,draft,planned'); // 获取执行11、产品91下的需求详情
+r(count($stories3)) && p() && e('2'); // 获取执行11、产品1下的需求数量
+r($stories3) && p('2:title,type,status,stage') && e('软件需求2,story,active,wait'); // 获取执行11、产品1下的需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getexecutionstorypairs.php b/module/story/test/model/getexecutionstorypairs.php
new file mode 100755
index 0000000000..047ec81fd6
--- /dev/null
+++ b/module/story/test/model/getexecutionstorypairs.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getExecutionStoryPairs();
+cid=1
+pid=1
+
+获取执行11下的需求数量 >> 5
+获取执行11下的需求详情 >> 364:软件需求364 (优先级:4,预计工时:7)
+获取执行11、产品91下的需求数量 >> 3
+获取执行11、产品91下的需求详情 >> 362:软件需求362 (优先级:2,预计工时:3)
+获取执行11、产品1下的需求数量 >> 3
+获取执行11、产品1下的需求详情 >> 2:软件需求2 (优先级:2,预计工时:19)
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getExecutionStoryPairs(11);
+$stories2 = $tester->story->getExecutionStoryPairs(11, 91);
+$stories3 = $tester->story->getExecutionStoryPairs(11, 1);
+
+r(count($stories1)) && p() && e('5'); // 获取执行11下的需求数量
+r($stories1) && p('364') && e('364:软件需求364 (优先级:4,预计工时:7)'); // 获取执行11下的需求详情
+r(count($stories2)) && p() && e('3'); // 获取执行11、产品91下的需求数量
+r($stories2) && p('362') && e('362:软件需求362 (优先级:2,预计工时:3)'); // 获取执行11、产品91下的需求详情
+r(count($stories3)) && p() && e('3'); // 获取执行11、产品1下的需求数量
+r($stories3) && p('2') && e('2:软件需求2 (优先级:2,预计工时:19)'); // 获取执行11、产品1下的需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getidlistwithtask.php b/module/story/test/model/getidlistwithtask.php
new file mode 100755
index 0000000000..52fe7bb97e
--- /dev/null
+++ b/module/story/test/model/getidlistwithtask.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getIdListWithTask();
+cid=1
+pid=1
+
+获取执行101下的有关联需求的任务ID列表数量 >> 1
+获取执行1下的有关联需求的任务ID列表数量 >> 0
+获取执行null下的有关联需求的任务ID列表数量 >> 0
+获取执行110下的有关联需求的任务ID列表数量 >> 1
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$taslIdList1 = $tester->story->getIdListWithTask(101);
+$taslIdList2 = $tester->story->getIdListWithTask(1);
+$taslIdList3 = $tester->story->getIdListWithTask(null);
+$taslIdList4 = $tester->story->getIdListWithTask(110);
+
+r(count($taslIdList1)) && p() && e('1'); // 获取执行101下的有关联需求的任务ID列表数量
+r(count($taslIdList2)) && p() && e('0'); // 获取执行1下的有关联需求的任务ID列表数量
+r(count($taslIdList3)) && p() && e('0'); // 获取执行null下的有关联需求的任务ID列表数量
+r(count($taslIdList4)) && p() && e('1'); // 获取执行110下的有关联需求的任务ID列表数量
\ No newline at end of file
diff --git a/module/story/test/model/getkanbangroupdata.php b/module/story/test/model/getkanbangroupdata.php
new file mode 100755
index 0000000000..60ea10088d
--- /dev/null
+++ b/module/story/test/model/getkanbangroupdata.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getKanbanGroupData();
+cid=1
+pid=1
+
+传入stories数据,获取按照stage分组后的结果数量 >> 2
+传入stories数据,获取按照stage分组后的结果数量 >> 2
+传入stories数据,获取按照stage分组后的结果详情 >> 软件需求2,story,wait
+传入stories数据,获取按照stage分组后的结果详情 >> 软件需求6,story,projected
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getProductStories(1);
+$stories2 = $tester->story->getProductStories(2);
+
+$storyGroup1 = $tester->story->getKanbanGroupData($stories1);
+$storyGroup2 = $tester->story->getKanbanGroupData($stories2);
+
+r(count($storyGroup1)) && p() && e('2'); //传入stories数据,获取按照stage分组后的结果数量
+r(count($storyGroup2)) && p() && e('2'); //传入stories数据,获取按照stage分组后的结果数量
+r($storyGroup1['wait']) && p('2:title,type,stage') && e('软件需求2,story,wait'); //传入stories数据,获取按照stage分组后的结果详情
+r($storyGroup2['projected']) && p('6:title,type,stage') && e('软件需求6,story,projected'); //传入stories数据,获取按照stage分组后的结果详情
\ No newline at end of file
diff --git a/module/story/test/model/getparentstorypairs.php b/module/story/test/model/getparentstorypairs.php
new file mode 100755
index 0000000000..07498d0329
--- /dev/null
+++ b/module/story/test/model/getparentstorypairs.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getParentStoryPairs();
+cid=1
+pid=1
+
+
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories = $tester->story->getParentStoryPairs(91);
+//a($stories);die;
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getplanstories.php b/module/story/test/model/getplanstories.php
new file mode 100755
index 0000000000..9115ab43f9
--- /dev/null
+++ b/module/story/test/model/getplanstories.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getPlanStories();
+cid=1
+pid=1
+
+获取计划1下的需求数量,每页10条 >> 10
+获取计划1下的需求数量,不分页 >> 20
+获取计划1下的需求列表,每页10条 >> 软件需求290,active,story
+获取计划1下的需求列表,不分页 >> 软件需求2,active,story
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->app->loadClass('pager', $static = true);
+$pager = new pager(0, 10, 1);
+
+$plan1Stories = $tester->story->getPlanStories(1, 'all', 'id_desc', $pager);
+$plan2Stories = $tester->story->getPlanStories(1, 'all', 'id_desc');
+
+r(count($plan1Stories)) && p() && e('10'); //获取计划1下的需求数量,每页10条
+r(count($plan2Stories)) && p() && e('20'); //获取计划1下的需求数量,不分页
+r($plan1Stories) && p('290:title,status,type') && e('软件需求290,active,story'); //获取计划1下的需求列表,每页10条
+r($plan2Stories) && p('2:title,status,type') && e('软件需求2,active,story'); //获取计划1下的需求列表,不分页
\ No newline at end of file
diff --git a/module/story/test/model/getproductstories.php b/module/story/test/model/getproductstories.php
new file mode 100755
index 0000000000..eafbac48e1
--- /dev/null
+++ b/module/story/test/model/getproductstories.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getProductStories();
+cid=1
+pid=1
+
+获取产品1下的所有软件需求数量 >> 2
+获取产品1下的所有用户需求数量 >> 2
+获取产品2可关联的需求数量 >> 1
+查看通过产品1获取的软件需求的type、product、module字段 >> story,1,1822
+查看通过产品1获取的用户需求的type、product、module字段 >> requirement,1,1821
+查看通过产品3获取的软件需求的type、product、module字段 >> story,3,1830
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getProductStories(1);
+$stories2 = $tester->story->getProductStories(1, 0, 0, 'all', 'requirement', 'id_asc', true);
+$stories3 = $tester->story->getProductStories(3, 0, 1830, 'all', 'story', 'id_asc', true);
+
+r(count($stories1)) && p() && e('2'); // 获取产品1下的所有软件需求数量
+r(count($stories2)) && p() && e('2'); // 获取产品1下的所有用户需求数量
+r(count($stories3)) && p() && e('1'); // 获取产品2可关联的需求数量
+r($stories1) && p('2:type,product,module') && e('story,1,1822'); // 查看通过产品1获取的软件需求的type、product、module字段
+r($stories2) && p('1:type,product,module') && e('requirement,1,1821'); // 查看通过产品1获取的用户需求的type、product、module字段
+r($stories3) && p('10:type,product,module') && e('story,3,1830'); // 查看通过产品3获取的软件需求的type、product、module字段
\ No newline at end of file
diff --git a/module/story/test/model/getproductstorypairs.php b/module/story/test/model/getproductstorypairs.php
new file mode 100755
index 0000000000..03ee7e836e
--- /dev/null
+++ b/module/story/test/model/getproductstorypairs.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getProductStoryPairs();
+cid=1
+pid=1
+
+获取产品1下的所有软件需求数量 >> 3
+获取产品1下的所有用户需求数量 >> 4
+获取产品2可关联的需求数量 >> 2
+查看通过产品1获取的软件需求的名称字段 >> 4:软件需求4 (优先级:4,预计工时:0),2:软件需求2 (优先级:2,预计工时:20)
+查看通过产品1获取的用户需求的键值对详情 >> 1:用户需求1,2:用户需求2,更多...
+查看通过产品3获取的软件需求的键值对详情 >> 10:软件需求10 (优先级:2,预计工时:9)
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$stories1 = $tester->story->getProductStoryPairs(1);
+$stories2 = $tester->story->getProductStoryPairs(1, 0, 0, 'all', 'id_asc', 1, '', 'requirement', true);
+$stories3 = $tester->story->getProductStoryPairs(3, 0, 1830, 'all', 'id_asc', 0, 'full', 'story', true);
+
+r(count($stories1)) && p() && e('3'); // 获取产品1下的所有软件需求数量
+r(count($stories2)) && p() && e('4'); // 获取产品1下的所有用户需求数量
+r(count($stories3)) && p() && e('2'); // 获取产品2可关联的需求数量
+r($stories1) && p('4,2') && e('4:软件需求4 (优先级:4,预计工时:0),2:软件需求2 (优先级:2,预计工时:20)'); // 查看通过产品1获取的软件需求的名称字段
+r($stories2) && p('1,3,showmore') && e('1:用户需求1,2:用户需求2,更多...'); // 查看通过产品1获取的用户需求的键值对详情
+r($stories3) && p('10') && e('10:软件需求10 (优先级:2,预计工时:9)'); // 查看通过产品3获取的软件需求的键值对详情
\ No newline at end of file
diff --git a/module/story/test/model/getrequierements.php b/module/story/test/model/getrequierements.php
new file mode 100755
index 0000000000..00d699f452
--- /dev/null
+++ b/module/story/test/model/getrequierements.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getRequierements();
+cid=1
+pid=1
+
+获取产品1下的第一个用户需求名称 >> 用户需求1
+获取产品1下的所有用户需求数量 >> 2
+获取产品5下的第一个用户需求名称 >> 用户需求17
+获取产品5下的所有用户需求数量 >> 2
+获取产品ID为Null的用户需求数量 >> 0
+
+*/
+
+$story = new storyTest();
+$requirements1 = $story->getRequierementsTest(1);
+$requirements2 = $story->getRequierementsTest(5);
+$requirements3 = $story->getRequierementsTest(null);
+
+r($requirements1) && p('1') && e('用户需求1'); //获取产品1下的第一个用户需求名称
+r(count($requirements1)) && p() && e('2'); //获取产品1下的所有用户需求数量
+r($requirements2) && p('17') && e('用户需求17'); //获取产品5下的第一个用户需求名称
+r(count($requirements2)) && p() && e('2'); //获取产品5下的所有用户需求数量
+r(count($requirements3)) && p() && e('0'); //获取产品ID为Null的用户需求数量
\ No newline at end of file
diff --git a/module/story/test/model/getreviewerpairs.php b/module/story/test/model/getreviewerpairs.php
new file mode 100755
index 0000000000..d3a8c7b3cd
--- /dev/null
+++ b/module/story/test/model/getreviewerpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getReviewerPairs();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getstories2link.php b/module/story/test/model/getstories2link.php
new file mode 100755
index 0000000000..39a128c291
--- /dev/null
+++ b/module/story/test/model/getstories2link.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getStories2Link();
+cid=1
+pid=1
+
+获取需求1可关联的需求数量 >> 2
+获取需求2可关联的需求数量 >> 2
+获取需求1可关联的需求id、product >> story,1
+获取需求2可关联的需求id、product >> requirement,1
+
+*/
+
+global $tester;
+$stories1 = $tester->loadModel('story')->getStories2Link(1, 'linkStories', 'bySearch', 0, 'requirement');
+$stories2 = $tester->loadModel('story')->getStories2Link(2);
+
+r(count($stories1)) && p() && e('2'); // 获取需求1可关联的需求数量
+r(count($stories2)) && p() && e('2'); // 获取需求2可关联的需求数量
+r($stories1) && p('2:type,product') && e('story,1'); // 获取需求1可关联的需求id、product
+r($stories2) && p('1:type,product') && e('requirement,1'); // 获取需求2可关联的需求id、product
\ No newline at end of file
diff --git a/module/story/test/model/getstoriesbyplanidlist.php b/module/story/test/model/getstoriesbyplanidlist.php
new file mode 100755
index 0000000000..32c9334758
--- /dev/null
+++ b/module/story/test/model/getstoriesbyplanidlist.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getStoriesByPlanIdList();
+cid=1
+pid=1
+
+传入计划ID列表,获取其下面的需求数量 >> 20
+传入计划ID列表,查看其下面的需求详情 >> 软件需求388,story,draft
+传入计划ID列表,获取其下面的需求数量 >> 20
+传入计划ID列表,查看其下面的需求详情 >> 软件需求392,story,draft
+传入空的计划ID列表,获取系统中所有需求数量 >> 424
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$planIdList1 = array(1, 2, 3);
+$planIdList2 = array(4, 5, 6);
+$planIdList3 = array();
+$stories1 = $tester->story->getStoriesByPlanIdList($planIdList1);
+$stories2 = $tester->story->getStoriesByPlanIdList($planIdList2);
+$stories3 = $tester->story->getStoriesByPlanIdList($planIdList3);
+
+r(count($stories1[1])) && p() && e('20'); //传入计划ID列表,获取其下面的需求数量
+r($stories1[1]) && p('388:title,type,status') && e('软件需求388,story,draft'); //传入计划ID列表,查看其下面的需求详情
+r(count($stories2[4])) && p() && e('20'); //传入计划ID列表,获取其下面的需求数量
+r($stories2[4]) && p('392:title,type,status') && e('软件需求392,story,draft'); //传入计划ID列表,查看其下面的需求详情
+r(count($stories3, true)) && p() && e('424'); //传入空的计划ID列表,获取系统中所有需求数量
\ No newline at end of file
diff --git a/module/story/test/model/getstoryrelation.php b/module/story/test/model/getstoryrelation.php
new file mode 100755
index 0000000000..1133da1c53
--- /dev/null
+++ b/module/story/test/model/getstoryrelation.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getStoryRelation();
+cid=1
+pid=1
+
+获取用户需求25关联的软件需求数量 >> 1
+获取软件需求26关联的用户需求数量 >> 1
+获取用户需求25关联的软件需求详情 >> 软件需求26,story,active
+获取软件需求26关联的用户需求详情 >> 用户需求25,requirement,draft
+
+*/
+
+global $tester;
+$relations1 = $tester->loadModel('story')->getStoryRelation(25, 'requirement');
+$relations2 = $tester->story->getStoryRelation(26, 'story');
+
+r(count($relations1)) && p() && e('1'); // 获取用户需求25关联的软件需求数量
+r(count($relations2)) && p() && e('1'); // 获取软件需求26关联的用户需求数量
+r($relations1[0]) && p('title,type,status') && e('软件需求26,story,active'); // 获取用户需求25关联的软件需求详情
+r($relations2[0]) && p('title,type,status') && e('用户需求25,requirement,draft'); // 获取软件需求26关联的用户需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getstoryrelationcounts.php b/module/story/test/model/getstoryrelationcounts.php
new file mode 100755
index 0000000000..ff379e06eb
--- /dev/null
+++ b/module/story/test/model/getstoryrelationcounts.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getStoryRelationCounts();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getstoryspecs.php b/module/story/test/model/getstoryspecs.php
new file mode 100755
index 0000000000..a78ba708cd
--- /dev/null
+++ b/module/story/test/model/getstoryspecs.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getStorySpecs();
+cid=1
+pid=1
+
+根据传入的需求ID列表,获取最新版本的需求描述信息 >> 这是一个软件需求描述41
+根据传入的需求ID列表,获取最新版本的验收标准信息 >> 这是一个需求验收55
+传入三个需求ID,判断获取到的需求描述信息数量 >> 2
+
+*/
+
+$story = new storyTest();
+$storyIdList = array(1, 15, 100);
+
+r($story->getStorySpecsTest($storyIdList)) && p('1:spec') && e('这是一个软件需求描述41'); //根据传入的需求ID列表,获取最新版本的需求描述信息
+r($story->getStorySpecsTest($storyIdList)) && p('15:verify') && e('这是一个需求验收55'); //根据传入的需求ID列表,获取最新版本的验收标准信息
+r(count($story->getStorySpecsTest($storyIdList))) && p() && e('2'); //传入三个需求ID,判断获取到的需求描述信息数量
\ No newline at end of file
diff --git a/module/story/test/model/getteammembers.php b/module/story/test/model/getteammembers.php
new file mode 100755
index 0000000000..3e3ee3d263
--- /dev/null
+++ b/module/story/test/model/getteammembers.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getTeamMembers();
+cid=1
+pid=1
+
+查找需求20的相关团队成员数量 >> 2
+查找需求21的变更时影响的团队成员数量 >> 3
+查找需求21的变更时影响的团队成员数量 >> po87,user97,test97
+查找需求0的相关团队成员数量 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$story20Members = $tester->story->getTeamMembers(20, '');
+$story21Members = $tester->story->getTeamMembers(21, 'changed');
+$story0Members = $tester->story->getTeamMembers(0, '');
+
+r(count($story20Members)) && p() && e('2'); // 查找需求20的相关团队成员数量
+r(count($story21Members)) && p() && e('3'); // 查找需求21的变更时影响的团队成员数量
+r($story21Members) && p('po87,user97,test97') && e('po87,user97,test97'); // 查找需求21的变更时影响的团队成员数量
+r(count($story0Members)) && p() && e('0'); // 查找需求0的相关团队成员数量
\ No newline at end of file
diff --git a/module/story/test/model/getteststories.php b/module/story/test/model/getteststories.php
new file mode 100755
index 0000000000..10e0b49fab
--- /dev/null
+++ b/module/story/test/model/getteststories.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getTestStories();
+cid=1
+pid=1
+
+获取和执行103关联的ID为9的测试类型的需求 >> 9
+获取和执行111关联的ID为41的测试类型的需求 >> 41
+获取和执行103关联的测试类型的需求,为空 >> 0
+
+*/
+
+$story = new storyTest();
+$storyIdList1 = array(9, 41, 73);
+$storyIdList2 = array(1, 2, 3);
+
+r($story->getTestStoriesTest($storyIdList1, 103)) && p('9') && e('9'); //获取和执行103关联的ID为9的测试类型的需求
+r($story->getTestStoriesTest($storyIdList1, 111)) && p('41') && e('41'); //获取和执行111关联的ID为41的测试类型的需求
+r($story->getTestStoriesTest($storyIdList2, 103)) && p() && e('0'); //获取和执行103关联的测试类型的需求,为空
\ No newline at end of file
diff --git a/module/story/test/model/gettoandcclist.php b/module/story/test/model/gettoandcclist.php
new file mode 100755
index 0000000000..e49acbddfd
--- /dev/null
+++ b/module/story/test/model/gettoandcclist.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getToAndCcList();
+cid=1
+pid=1
+
+获取创建需求1时的通知人数量 >> 2
+获取评审需求1时的通知人数量 >> 2
+获取变更需求1时的通知人数量 >> 2
+获取创建需求1时的通知人详情 >> admin
+获取评审需求1时的通知人详情 >> admin
+获取变更需求1时的通知人详情 >> po82,user92,
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$story1 = $tester->story->getByID(1);
+
+$dataList1 = $tester->story->getToAndCcList($story1, 'opened');
+$dataList2 = $tester->story->getToAndCcList($story1, 'reviewed');
+$dataList3 = $tester->story->getToAndCcList($story1, 'changed');
+
+r(count($dataList1)) && p() && e('2'); //获取创建需求1时的通知人数量
+r(count($dataList2)) && p() && e('2'); //获取评审需求1时的通知人数量
+r(count($dataList3)) && p() && e('2'); //获取变更需求1时的通知人数量
+r($dataList1[0]) && p() && e('admin'); //获取创建需求1时的通知人详情
+r($dataList2[0]) && p() && e('admin'); //获取评审需求1时的通知人详情
+r($dataList3[1]) && p() && e('po82,user92,'); //获取变更需求1时的通知人详情
\ No newline at end of file
diff --git a/module/story/test/model/gettrackbyid.php b/module/story/test/model/gettrackbyid.php
new file mode 100755
index 0000000000..f95ea0330a
--- /dev/null
+++ b/module/story/test/model/gettrackbyid.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getTrackByID();
+cid=1
+pid=1
+
+获取用户需求1下面的所有任务数量 >> 6
+获取用户需求1下面的任务601的名字 >> 开发任务511
+获取用户需求1下面的任务501的名字 >> 开发任务411
+获取用户需求的信息 >> 软件需求版本一551,requirement,active
+
+*/
+
+global $tester;
+$story1Tracks = $tester->loadModel('story')->getByID(1);
+
+r(count($story1Tracks->tasks)) && p() && e('6'); //获取用户需求1下面的所有任务数量
+r($story1Tracks->tasks[601]) && p('0:name') && e('开发任务511'); //获取用户需求1下面的任务601的名字
+r($story1Tracks->tasks[501]) && p('0:name') && e('开发任务411'); //获取用户需求1下面的任务501的名字
+r($story1Tracks) && p('title,type,status') && e('软件需求版本一551,requirement,active'); //获取用户需求的信息
\ No newline at end of file
diff --git a/module/story/test/model/gettracks.php b/module/story/test/model/gettracks.php
new file mode 100755
index 0000000000..a4046a95f6
--- /dev/null
+++ b/module/story/test/model/gettracks.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+getTracks();
+cid=1
+pid=1
+
+获取产品1的跟踪矩阵的数量 >> 2
+获取产品1的需求2的关联bug数量 >> 4
+获取产品1的需求2的关联用例数量 >> 4
+获取产品1的需求2的关联Bug名称 >> BUG1
+获取产品1的需求2的关联Bug名称 >> BUG101
+获取产品1的需求2的关联Case名称 >> 这个是测试用例1
+获取产品1的需求2的关联Case名称 >> 这个是测试用例2
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$tester->app->loadClass('pager', $static = true);
+$pager = new pager(0, 100, 1);
+
+$tracks = $tester->story->getTracks(1, 0, 0, $pager);
+
+r(count($tracks['noRequirement'])) && p() && e('2'); // 获取产品1的跟踪矩阵的数量
+r(count($tracks['noRequirement'][2]->bugs)) && p() && e('4'); // 获取产品1的需求2的关联bug数量
+r(count($tracks['noRequirement'][2]->cases)) && p() && e('4'); // 获取产品1的需求2的关联用例数量
+r($tracks['noRequirement'][2]->bugs) && p('1:title') && e('BUG1'); // 获取产品1的需求2的关联Bug名称
+r($tracks['noRequirement'][2]->bugs) && p('101:title') && e('BUG101'); // 获取产品1的需求2的关联Bug名称
+r($tracks['noRequirement'][2]->cases) && p('1:title') && e('这个是测试用例1'); // 获取产品1的需求2的关联Case名称
+r($tracks['noRequirement'][2]->cases) && p('2:title') && e('这个是测试用例2'); // 获取产品1的需求2的关联Case名称
\ No newline at end of file
diff --git a/module/story/test/model/getuserstories.php b/module/story/test/model/getuserstories.php
new file mode 100755
index 0000000000..194a8f04bf
--- /dev/null
+++ b/module/story/test/model/getuserstories.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+getUserStories();
+cid=1
+pid=1
+
+获取指派给User2的所有需求数量 >> 100
+获取指派给User2的ID为6的需求详情 >> 软件需求6,story,user2,projected
+获取由User2创建的需求数量,每页10条 >> 10
+获取由User2创建的ID为38的需求详情 >> 软件需求38,story,user2,released
+获取由Test3关闭的所有需求数量 >> 14
+获取由Test3关闭的ID为203的需求详情 >> 用户需求203,requirement,test3,
+获取无评审人的需求数量 >> 25
+获取无评审人的ID为402的需求详情 >> 软件子需求2,story,,planned
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->app->loadClass('pager', $static = true);
+$pager = new pager(0, 10, 1);
+
+$assignUser2Stories = $tester->story->getUserStories('user2', 'assignedTo');
+$openedByUser2Stories = $tester->story->getUserStories('user2', 'openedBy', 'id_asc', $pager, 'story', true);
+$closedByTest3Stories = $tester->story->getUserStories('test3', 'closedBy', 'id_asc', null, 'requirement', true);
+$emptyReviewedByStories = $tester->story->getUserStories('', 'reviewedBy');
+
+r(count($assignUser2Stories)) && p() && e('100'); //获取指派给User2的所有需求数量
+r($assignUser2Stories) && p('6:title,type,assignedTo,stage') && e('软件需求6,story,user2,projected'); //获取指派给User2的ID为6的需求详情
+r(count($openedByUser2Stories)) && p() && e('10'); //获取由User2创建的需求数量,每页10条
+r($openedByUser2Stories) && p('38:title,type,openedBy,stage') && e('软件需求38,story,user2,released'); //获取由User2创建的ID为38的需求详情
+r(count($closedByTest3Stories)) && p() && e('14'); //获取由Test3关闭的所有需求数量
+r($closedByTest3Stories) && p('203:title,type,closedBy,stage') && e('用户需求203,requirement,test3,'); //获取由Test3关闭的ID为203的需求详情
+r(count($emptyReviewedByStories)) && p() && e('25'); //获取无评审人的需求数量
+r($emptyReviewedByStories) && p('402:title,type,reviewedBy,stage') && e('软件子需求2,story,,planned'); //获取无评审人的ID为402的需求详情
\ No newline at end of file
diff --git a/module/story/test/model/getuserstorypairs.php b/module/story/test/model/getuserstorypairs.php
new file mode 100755
index 0000000000..d96de5c807
--- /dev/null
+++ b/module/story/test/model/getuserstorypairs.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getUserStoryPairs();
+cid=1
+pid=1
+
+获取指派给User2的需求数量,每页10条 >> 10
+获取指派给admin的用户需求,每页50条 >> 50
+获取指派给User2的所有需求总数 >> 100
+获取指派给admin的、不在产品91/92/93里的用户需求,每页50条 >> 97
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$skipProductIDList = array(91, 92, 93);
+$user2Stories = $tester->story->getUserStoryPairs('user2', '10');
+$adminRequirements = $tester->story->getUserStoryPairs('admin', '50', 'requirement');
+$allUser2Stories = $tester->story->getUserStoryPairs('user2', '0', 'story');
+$user2StoriesSkipProducts = $tester->story->getUserStoryPairs('user2', '0', 'story', $skipProductIDList);
+
+r(count($user2Stories)) && p() && e('10'); //获取指派给User2的需求数量,每页10条
+r(count($adminRequirements)) && p() && e('50'); //获取指派给admin的用户需求,每页50条
+r(count($allUser2Stories)) && p() && e('100'); //获取指派给User2的所有需求总数
+r(count($user2StoriesSkipProducts)) && p() && e('97'); //获取指派给admin的、不在产品91/92/93里的用户需求,每页50条
\ No newline at end of file
diff --git a/module/story/test/model/getversion.php b/module/story/test/model/getversion.php
new file mode 100755
index 0000000000..9b6520cdc5
--- /dev/null
+++ b/module/story/test/model/getversion.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getVersion();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getversions.php b/module/story/test/model/getversions.php
new file mode 100755
index 0000000000..b01ce5e524
--- /dev/null
+++ b/module/story/test/model/getversions.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getVersions();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/getzerocase.php b/module/story/test/model/getzerocase.php
new file mode 100755
index 0000000000..94846ce03c
--- /dev/null
+++ b/module/story/test/model/getzerocase.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getZeroCase();
+cid=1
+pid=1
+
+获取产品1下的零用例需求数量 >> 1
+获取产品2下的零用例需求数量 >> 1
+获取产品0下的零用例需求数量 >> 0
+获取产品1下的零用例需求详情 >> 软件需求4,active,story,planned
+获取产品2下的零用例需求详情 >> 软件需求8,active,story,developing
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$zeroCaseStory1 = $tester->story->getZeroCase(1);
+$zeroCaseStory2 = $tester->story->getZeroCase(2);
+$zeroCaseStory3 = $tester->story->getZeroCase(0);
+
+r(count($zeroCaseStory1)) && p() && e('1'); // 获取产品1下的零用例需求数量
+r(count($zeroCaseStory2)) && p() && e('1'); // 获取产品2下的零用例需求数量
+r(count($zeroCaseStory3)) && p() && e('0'); // 获取产品0下的零用例需求数量
+r($zeroCaseStory1) && p('4:title,status,type,stage') && e('软件需求4,active,story,planned'); // 获取产品1下的零用例需求详情
+r($zeroCaseStory2) && p('8:title,status,type,stage') && e('软件需求8,active,story,developing'); // 获取产品2下的零用例需求详情
\ No newline at end of file
diff --git a/module/story/test/model/isclickable.php b/module/story/test/model/isclickable.php
new file mode 100755
index 0000000000..26efb63ccc
--- /dev/null
+++ b/module/story/test/model/isclickable.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+recall();
+cid=1
+pid=1
+
+判断需求2是否有变更按钮操作权限 >> 1
+判断需求2是否有评审按钮操作权限 >> 0
+判断需求2是否有关闭按钮操作权限 >> 1
+判断需求2是否有激活按钮操作权限 >> 0
+判断需求2是否有指派按钮操作权限 >> 1
+判断需求2是否有创建用例按钮操作权限 >> 1
+判断需求2是否有批量创建按钮操作权限 >> 0
+
+*/
+
+global $tester;
+$storyModel = $tester->loadModel('story');
+$story = $storyModel->getById(2);
+
+r($storyModel::isClickable($story, 'change')) && p() && e('1'); // 判断需求2是否有变更按钮操作权限
+r($storyModel::isClickable($story, 'review')) && p() && e('0'); // 判断需求2是否有评审按钮操作权限
+r($storyModel::isClickable($story, 'close')) && p() && e('1'); // 判断需求2是否有关闭按钮操作权限
+r($storyModel::isClickable($story, 'activate')) && p() && e('0'); // 判断需求2是否有激活按钮操作权限
+r($storyModel::isClickable($story, 'assignto')) && p() && e('1'); // 判断需求2是否有指派按钮操作权限
+r($storyModel::isClickable($story, 'createcase')) && p() && e('1'); // 判断需求2是否有创建用例按钮操作权限
+r($storyModel::isClickable($story, 'batchcreate')) && p() && e('0'); // 判断需求2是否有批量创建按钮操作权限
\ No newline at end of file
diff --git a/module/story/test/model/linkstories.php b/module/story/test/model/linkstories.php
new file mode 100755
index 0000000000..5136c2abad
--- /dev/null
+++ b/module/story/test/model/linkstories.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+linkStories();
+cid=1
+pid=1
+
+查看关联前的关联关系数量 >> 0
+查看关联后的关联关系数量 >> 4
+查看关联后的需求详情 >> 软件需求300,软件需求302,软件需求304,软件需求306
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$beforeRelations = $tester->story->getRelation(1, 'requirement');
+
+$storyIdList = array(300, 302, 304, 306);
+$_POST['stories'] = $storyIdList;
+$tester->story->linkStories(1);
+
+$afterRelations = $tester->story->getRelation(1, 'requirement');
+
+r(count($beforeRelations)) && p() && e('0'); // 查看关联前的关联关系数量
+r(count($afterRelations)) && p() && e('4'); // 查看关联后的关联关系数量
+r($afterRelations) && p('300,302,304,306') && e('软件需求300,软件需求302,软件需求304,软件需求306'); // 查看关联后的需求详情
diff --git a/module/story/test/model/linkstory.php b/module/story/test/model/linkstory.php
new file mode 100755
index 0000000000..bcc61235ef
--- /dev/null
+++ b/module/story/test/model/linkstory.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+linkStory();
+cid=1
+pid=1
+
+获取关联需求后的执行下的需求数量 >> 5
+获取关联需求后的执行下的需求数量 >> 5
+获取关联需求后的执行下的需求数量 >> 5
+获取关联需求后的执行下的需求详情 >> 软件需求300,story,closed
+获取关联需求后的执行下的需求详情 >> 软件需求302,story,planned
+获取关联需求后的执行下的需求详情 >> 软件需求304,story,developing
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$tester->story->linkStory(11, 1, 300);
+$tester->story->linkStory(12, 1, 302);
+$tester->story->linkStory(13, 1, 304);
+
+$stories1 = $tester->story->getExecutionStories(11);
+$stories2 = $tester->story->getExecutionStories(12);
+$stories3 = $tester->story->getExecutionStories(13);
+
+r(count($stories1)) && p() && e('5'); // 获取关联需求后的执行下的需求数量
+r(count($stories2)) && p() && e('5'); // 获取关联需求后的执行下的需求数量
+r(count($stories3)) && p() && e('5'); // 获取关联需求后的执行下的需求数量
+r($stories1) && p('300:title,type,stage') && e('软件需求300,story,closed'); // 获取关联需求后的执行下的需求详情
+r($stories2) && p('302:title,type,stage') && e('软件需求302,story,planned'); // 获取关联需求后的执行下的需求详情
+r($stories3) && p('304:title,type,stage') && e('软件需求304,story,developing'); // 获取关联需求后的执行下的需求详情
diff --git a/module/story/test/model/mergechartoption.php b/module/story/test/model/mergechartoption.php
new file mode 100755
index 0000000000..7bad88c655
--- /dev/null
+++ b/module/story/test/model/mergechartoption.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+mergeChartOption();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/mergereviewer.php b/module/story/test/model/mergereviewer.php
new file mode 100755
index 0000000000..da571d7fb5
--- /dev/null
+++ b/module/story/test/model/mergereviewer.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+mergeReviewer();
+cid=1
+pid=1
+
+获取需求301的评审人 >> admin
+获取需求301的待评审人 >> admin
+获取产品76下的需求评审人 >> admin
+获取产品76下的需求待评审人 >> admin
+获取产品76下的需求评审人 >> admin
+获取产品76下的需求待评审人 >> admin
+
+*/
+
+global $tester;
+$story = $tester->loadModel('story')->getById(301);
+$story = $tester->story->mergeReviewer($story, true);
+
+$stories = $tester->story->getProductStories(76);
+$stories = $tester->story->mergeReviewer($stories);
+
+r($story) && p('reviewer:0') && e('admin'); // 获取需求301的评审人
+r($story) && p('notReview:0') && e('admin'); // 获取需求301的待评审人
+r($stories[302]->reviewer[0]) && p() && e('admin'); // 获取产品76下的需求评审人
+r($stories[302]->notReview[0]) && p() && e('admin'); // 获取产品76下的需求待评审人
+r($stories[304]->reviewer[0]) && p() && e('admin'); // 获取产品76下的需求评审人
+r($stories[304]->notReview[0]) && p() && e('admin'); // 获取产品76下的需求待评审人
\ No newline at end of file
diff --git a/module/story/test/model/printassignedhtml.php b/module/story/test/model/printassignedhtml.php
new file mode 100755
index 0000000000..8db15da298
--- /dev/null
+++ b/module/story/test/model/printassignedhtml.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+printAssignedHtml();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/recall.php b/module/story/test/model/recall.php
new file mode 100755
index 0000000000..7364b6005a
--- /dev/null
+++ b/module/story/test/model/recall.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+recall();
+cid=1
+pid=1
+
+撤回评审之前的状态信息 >> 2,用户需求版本一62,active
+撤回评审之后的状态信息 >> 2,用户需求版本一62,draft
+
+*/
+
+global $tester;
+
+$beforeRecall = $tester->loadModel('story')->getByID(2);
+$tester->loadModel('story')->recall(2);
+$afterRecall = $tester->story->getByID(2);
+
+r($beforeRecall) && p('id,title,status') && e('2,用户需求版本一62,active'); // 撤回评审之前的状态信息
+r($afterRecall) && p('id,title,status') && e('2,用户需求版本一62,draft'); // 撤回评审之后的状态信息
diff --git a/module/story/test/model/review.php b/module/story/test/model/review.php
new file mode 100755
index 0000000000..854166b2c0
--- /dev/null
+++ b/module/story/test/model/review.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+review();
+cid=1
+pid=1
+
+评审ID为2的需求,不传入评审意见,给出没有选择评审意见的提示 >> 必须选择评审意见
+评审一个草稿的需求,传入评审意见为通过,状态变为激活 >> active
+评审一个草稿的需求,传入评审意见为拒绝,状态变为关闭 >> closed
+
+*/
+
+$story = new storyTest();
+$pass['result'] = 'pass';
+$reject['result'] = 'reject';
+
+$review1 = $story->reviewTest(2, array());
+$review2 = $story->reviewTest(302, $pass);
+$review3 = $story->reviewTest(304, $reject);
+
+r($review1[0]) && p() && e('必须选择评审意见'); // 评审ID为2的需求,不传入评审意见,给出没有选择评审意见的提示
+r($review2) && p('status') && e('active'); // 评审一个草稿的需求,传入评审意见为通过,状态变为激活
+r($review3) && p('status') && e('closed'); // 评审一个草稿的需求,传入评审意见为拒绝,状态变为关闭
diff --git a/module/story/test/model/saveestimateinfo.php b/module/story/test/model/saveestimateinfo.php
new file mode 100755
index 0000000000..ef68d3a6fc
--- /dev/null
+++ b/module/story/test/model/saveestimateinfo.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+saveEstimateInfo();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/model/setstage.php b/module/story/test/model/setstage.php
new file mode 100755
index 0000000000..6addb24ea3
--- /dev/null
+++ b/module/story/test/model/setstage.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+setStage();
+cid=1
+pid=1
+
+为需求2拆分几个任务. >> execution
+把需求2下面的任务都完成. >> story
+查看设置之后的需求状态 >> projected
+查看设置之后的需求状态 >> testing
+查看设置之后的需求状态 >> tested
+
+*/
+
+$story = new storyTest();
+
+$before = $tester->story->getById(2);
+
+/* 为需求2拆分几个任务. */
+$tester->dao->update(TABLE_TASK)->set('story')->eq(2)->where('execution')->eq(101)->exec();
+$tester->story->setStage(2);
+
+$after1 = $tester->story->getById(2);
+
+/* 把需求2下面的任务都完成. */
+$tester->dao->update(TABLE_TASK)->set('status')->eq('done')->where('story')->eq(2)->exec();
+$tester->story->setStage(2);
+
+$after2 = $tester->story->getById(2);
+
+r($before) && p('stage') && e('projected'); //查看设置之后的需求状态
+r($after1) && p('stage') && e('testing'); //查看设置之后的需求状态
+r($after2) && p('stage') && e('tested'); //查看设置之后的需求状态
diff --git a/module/story/test/model/setstatusbyreviewrules.php b/module/story/test/model/setstatusbyreviewrules.php
new file mode 100755
index 0000000000..b2dfad1dec
--- /dev/null
+++ b/module/story/test/model/setstatusbyreviewrules.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+setStatusByReviewRules();
+cid=1
+pid=1
+
+传入两个通过一个拒绝,查看返回结果 >> 0
+传入全部通过,查看返回结果 >> active
+传入两个拒绝一个通过,查看返回结果 >> 0
+传入三个拒绝,查看返回结果 >> closed
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$reviewList1 = array('pass', 'pass', 'reject');
+$reviewList2 = array('pass', 'pass', 'pass');
+$reviewList3 = array('pass', 'reject', 'reject');
+$reviewList4 = array('reject', 'reject', 'reject');
+
+$result1 = $tester->story->setStatusByReviewRules($reviewList1);
+$result2 = $tester->story->setStatusByReviewRules($reviewList2);
+$result3 = $tester->story->setStatusByReviewRules($reviewList3);
+$result4 = $tester->story->setStatusByReviewRules($reviewList4);
+
+r($result1) && p() && e('0'); // 传入两个通过一个拒绝,查看返回结果
+r($result2) && p() && e('active'); // 传入全部通过,查看返回结果
+r($result3) && p() && e('0'); // 传入两个拒绝一个通过,查看返回结果
+r($result4) && p() && e('closed'); // 传入三个拒绝,查看返回结果
\ No newline at end of file
diff --git a/module/story/test/model/sortstoriesofplan.php b/module/story/test/model/sortstoriesofplan.php
new file mode 100755
index 0000000000..94f1f2d011
--- /dev/null
+++ b/module/story/test/model/sortstoriesofplan.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+sortStoriesOfPlan();
+cid=1
+pid=1
+
+获取更新排序之前的需求在计划下的排序 >> 5
+获取更新排序之前的需求在计划下的排序 >> 10
+获取更新排序之前的需求在计划下的排序 >> 15
+获取更新排序之前的需求在计划下的排序 >> 20
+获取更新排序之后的需求在计划下的排序 >> 2
+获取更新排序之后的需求在计划下的排序 >> 4
+获取更新排序之后的需求在计划下的排序 >> 1
+获取更新排序之后的需求在计划下的排序 >> 3
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+$beforeStories = $tester->story->getPlanStories(1);
+$tester->story->sortStoriesOfPlan(1, array(3, 1, 4, 2));
+$afterStories = $tester->story->getPlanStories(1);
+
+r($beforeStories) && p('1:order') && e('5'); //获取更新排序之前的需求在计划下的排序
+r($beforeStories) && p('2:order') && e('10'); //获取更新排序之前的需求在计划下的排序
+r($beforeStories) && p('3:order') && e('15'); //获取更新排序之前的需求在计划下的排序
+r($beforeStories) && p('4:order') && e('20'); //获取更新排序之前的需求在计划下的排序
+r($afterStories) && p('1:order') && e('2'); //获取更新排序之后的需求在计划下的排序
+r($afterStories) && p('2:order') && e('4'); //获取更新排序之后的需求在计划下的排序
+r($afterStories) && p('3:order') && e('1'); //获取更新排序之后的需求在计划下的排序
+r($afterStories) && p('4:order') && e('3'); //获取更新排序之后的需求在计划下的排序
diff --git a/module/story/test/model/subdivide.php b/module/story/test/model/subdivide.php
new file mode 100755
index 0000000000..6344212f0c
--- /dev/null
+++ b/module/story/test/model/subdivide.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+subdivide();
+cid=1
+pid=1
+
+将用户需求1拆分三个软件需求,查看relation表记录的数量 >> 3
+将用户需求1拆分三个软件需求,查看relation表记录的关系 >> 1,2,subdivideinto
+将用户需求1拆分三个软件需求,查看relation表记录的关系 >> 1,6,subdivideinto
+将软件需求2拆分三个子需求,查看子需求的数量 >> 3
+将软件需求2拆分三个子需求,查看子需求8的parent、title等字段 >> 2,这里是需求来源备注8,8
+将软件需求2拆分三个子需求,查看子需求12的parent、title等字段 >> 2,这里是需求来源备注12,12
+
+*/
+
+$story = new storyTest();
+$storyIdList1 = array(2, 4, 6);
+$storyIdList2 = array(8, 10, 12);
+
+$result1 = $story->subdivideTest(1, $storyIdList1, 'requirement');
+$result2 = $story->subdivideTest(2, $storyIdList2, 'story');
+
+r(count($result1)) && p() && e('3'); // 将用户需求1拆分三个软件需求,查看relation表记录的数量
+r($result1) && p('0:AID,BID,relation') && e('1,2,subdivideinto'); // 将用户需求1拆分三个软件需求,查看relation表记录的关系
+r($result1) && p('2:AID,BID,relation') && e('1,6,subdivideinto'); // 将用户需求1拆分三个软件需求,查看relation表记录的关系
+r(count($result2->children)) && p() && e('3'); // 将软件需求2拆分三个子需求,查看子需求的数量
+r($result2->children) && p('8:parent,title,id') && e('2,这里是需求来源备注8,8'); // 将软件需求2拆分三个子需求,查看子需求8的parent、title等字段
+r($result2->children) && p('12:parent,title,id') && e('2,这里是需求来源备注12,12'); // 将软件需求2拆分三个子需求,查看子需求12的parent、title等字段
diff --git a/module/story/test/model/unlinkstory.php b/module/story/test/model/unlinkstory.php
new file mode 100755
index 0000000000..5375d823b7
--- /dev/null
+++ b/module/story/test/model/unlinkstory.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+unlinkStory();
+cid=1
+pid=1
+
+删除用户需求25的关联关系之前,获取关联关系数量 >> 1
+删除用户需求25的关联关系之后,获取关联关系数量 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('story');
+
+$beforeRelation = $tester->story->getRelation(25, 'requirement');
+$tester->story->unlinkStory(25, 26);
+$afterRelation = $tester->story->getRelation(25, 'requirement');
+
+r(count($beforeRelation)) && p() && e('1'); //删除用户需求25的关联关系之前,获取关联关系数量
+r(count($afterRelation)) && p() && e('0'); //删除用户需求25的关联关系之后,获取关联关系数量
diff --git a/module/story/test/model/update.php b/module/story/test/model/update.php
new file mode 100755
index 0000000000..dce7e82678
--- /dev/null
+++ b/module/story/test/model/update.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+编辑用户需求,判断返回的信息,stage为空 >> 2,4,1,测试来源备注1,2
+编辑软件需求,判断返回的信息,stage为wait,parent为2 >> 2,4,1,测试来源备注1,2
+
+*/
+
+$story = new storyTest();
+$story1['parent'] = 2;
+$story1['pri'] = 4;
+$story1['estimate'] = 1;
+$story1['sourceNote'] = '测试来源备注1';
+$story1['product'] = 2;
+
+$result1 = $story->updateTest(1, $story1);
+$result2 = $story->updateTest(3, $story1);
+
+r($result1) && p('parent,pri,estimate,sourceNote,product') && e('2,4,1,测试来源备注1,2'); // 编辑用户需求,判断返回的信息,stage为空
+r($result2) && p('parent,pri,estimate,sourceNote,product') && e('2,4,1,测试来源备注1,2'); // 编辑软件需求,判断返回的信息,stage为wait,parent为2
diff --git a/module/story/test/model/updatestoryorderofplan.php b/module/story/test/model/updatestoryorderofplan.php
new file mode 100755
index 0000000000..09b6291208
--- /dev/null
+++ b/module/story/test/model/updatestoryorderofplan.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+updateStoryOrderOfPlan();
+cid=1
+pid=1
+
+把需求1迁移到计划1下,获取更新后的planstory >> 1,1,21
+把需求1迁移到计划1下,获取更新后的planstory数量 >> 4
+把需求1迁移到计划2下,获取更新后的planstory >> 2,1,1
+把需求1迁移到计划2下,获取更新后的planstory数量 >> 1
+
+*/
+
+$story = new storyTest();
+$planStories1 = $story->updateStoryOrderOfPlanTest(1, 1);
+$planStories2 = $story->updateStoryOrderOfPlanTest(1, 2, 1);
+
+r($planStories1) && p("0:plan,story,order") && e('1,1,21'); // 把需求1迁移到计划1下,获取更新后的planstory
+r(count($planStories1)) && p() && e('4'); // 把需求1迁移到计划1下,获取更新后的planstory数量
+r($planStories2) && p("0:plan,story,order") && e('2,1,1'); // 把需求1迁移到计划2下,获取更新后的planstory
+r(count($planStories2)) && p() && e('1'); // 把需求1迁移到计划2下,获取更新后的planstory数量
diff --git a/module/story/test/model/updatestoryproduct.php b/module/story/test/model/updatestoryproduct.php
new file mode 100755
index 0000000000..6e5340f369
--- /dev/null
+++ b/module/story/test/model/updatestoryproduct.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+updateStoryProduct();
+cid=1
+pid=1
+
+判断需求变更所属产品之前的产品ID >> 1
+判断需求变更所属产品之后的产品ID >> 2
+
+*/
+
+$story = new storyTest();
+global $tester;
+
+$oldStory = $tester->loadModel('story')->getByID(1);
+$tester->story->updateStoryProduct(1, 2);
+$newStory = $tester->story->getByID(1);
+
+r($oldStory) && p('product') && e('1'); // 判断需求变更所属产品之前的产品ID
+r($newStory) && p('product') && e('2'); // 判断需求变更所属产品之后的产品ID
diff --git a/module/story/test/model/updatestoryversion.php b/module/story/test/model/updatestoryversion.php
new file mode 100755
index 0000000000..61dfcef3db
--- /dev/null
+++ b/module/story/test/model/updatestoryversion.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+updateStoryVersion();
+cid=1
+pid=1
+
+
+
+*/
+
+$story = new storyTest();
+
+r() && p() && e();
\ No newline at end of file
diff --git a/module/story/test/story.class.php b/module/story/test/story.class.php
new file mode 100644
index 0000000000..18d111159c
--- /dev/null
+++ b/module/story/test/story.class.php
@@ -0,0 +1,530 @@
+objectModel = $tester->loadModel('story');
+ }
+
+ /**
+ * Test get by id.
+ *
+ * @param int $storyID
+ * @param int $version
+ * @access public
+ * @return void
+ */
+ public function getByIdTest($storyID, $version = 0)
+ {
+ $story = $this->objectModel->getById($storyID, $version);
+
+ if(dao::isError()) return dao::getError();
+
+ return $story;
+ }
+
+ /**
+ * Test get by list.
+ *
+ * @param int $storyIdList
+ * @param string $type
+ * @access public
+ * @return void
+ */
+ public function getByListTest($storyIdList = 0, $type = 'story')
+ {
+ $stories = $this->objectModel->getByList($storyIdList, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return $stories;
+ }
+
+ /**
+ * Test get test stories.
+ *
+ * @param array $storyIdList
+ * @param int $executionID
+ * @access public
+ * @return void
+ */
+ public function getTestStoriesTest($storyIdList, $executionID)
+ {
+ $objects = $this->objectModel->getTestStories($storyIdList, $executionID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get story specs.
+ *
+ * @param array $storyIdList
+ * @access public
+ * @return void
+ */
+ public function getStorySpecsTest($storyIdList)
+ {
+ $objects = $this->objectModel->getStorySpecs($storyIdList);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get affected scope.
+ *
+ * @param int $storyID
+ * @access public
+ * @return void
+ */
+ public function getAffectedScopeTest($storyID)
+ {
+ global $tester;
+ $story = $tester->loadModel('story')->getById($storyID);
+ $scope = $this->objectModel->getAffectedScope($story);
+
+ if(dao::isError()) return dao::getError();
+
+ return $scope;
+ }
+
+ /**
+ * Test get requierements.
+ *
+ * @param int $productID
+ * @access public
+ * @return void
+ */
+ public function getRequierementsTest($productID)
+ {
+ $requirements = $this->objectModel->getRequierements($productID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $requirements;
+ }
+
+ /**
+ * Test create story.
+ *
+ * @param int $executionID
+ * @param int $bugID
+ * @param string $from
+ * @param string $extra
+ * @param string $params
+ * @access public
+ * @return void
+ */
+ public function createTest($executionID = 0, $bugID = 0, $from = '', $extra = '', $params = '')
+ {
+ $_POST = $params;
+ $result = $this->objectModel->create($executionID, $bugID, $from, $extra);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $storyID = $result['id'];
+ return $tester->loadModel('story')->getById($storyID);
+ }
+
+ /**
+ * Test create story from gitlab issue.
+ *
+ * @param int $story
+ * @param int $executionID
+ * @access public
+ * @return void
+ */
+ public function createStoryFromGitlabIssueTest($story, $executionID)
+ {
+ $storyID = $this->objectModel->createStoryFromGitlabIssue($story, $executionID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ return $tester->loadModel('story')->getById($storyID);
+ }
+
+ /**
+ * Test batch create stories.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param string $type
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function batchCreateTest($productID = 0, $branch = 0, $type = 'story', $params = '')
+ {
+ $_POST = $params;
+ $results = $this->objectModel->batchCreate($productID, $branch, $type);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ foreach($results as $result) $storyIdList[] = $result->storyID;
+
+ global $tester;
+ $stories = $tester->loadModel('story')->getByList($storyIdList);
+ return $stories;
+ }
+
+ /**
+ * Test change story.
+ *
+ * @param int $storyID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function changeTest($storyID, $params)
+ {
+ $_POST = $params;
+ $this->objectModel->change($storyID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ return $tester->loadModel('story')->getById($storyID);
+ }
+
+ /**
+ * Test update story.
+ *
+ * @param int $storyID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function updateTest($storyID, $params)
+ {
+ $_POST = $params;
+ $this->objectModel->update($storyID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $this->objectModel->getById($storyID);
+ }
+
+ /**
+ * Test update story order of plan.
+ *
+ * @param int $storyID
+ * @param string $planIDList
+ * @param string $oldPlanIDList
+ * @access public
+ * @return void
+ */
+ public function updateStoryOrderOfPlanTest($storyID, $planIDList = '', $oldPlanIDList = '')
+ {
+ $this->objectModel->updateStoryOrderOfPlan($storyID, $planIDList, $oldPlanIDList);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ return $tester->dao->select('*')->from(TABLE_PLANSTORY)->where('plan')->in($planIDList)->fetchAll();
+ }
+
+ /**
+ * Test compute estimate.
+ *
+ * @param int $storyID
+ * @access public
+ * @return void
+ */
+ public function computeEstimateTest($storyID)
+ {
+ $this->objectModel->computeEstimate($storyID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $this->objectModel->getByID($storyID);
+ }
+
+ /**
+ * Test batch update stories.
+ *
+ * @access public
+ * @return void
+ */
+ public function batchUpdateTest($params)
+ {
+ $_POST = $params;
+ $allStories = $this->objectModel->batchUpdate();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($allStories);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test review story.
+ *
+ * @param int $storyID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function reviewTest($storyID, $params)
+ {
+ $_POST = $params;
+ $changes = $this->objectModel->review($storyID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $this->objectModel->getByID($storyID);
+ }
+
+ /**
+ * Test batch review.
+ *
+ * @param int $storyIdList
+ * @param int $result
+ * @param int $reason
+ * @access public
+ * @return void
+ */
+ public function batchReviewTest($storyIdList, $result, $reason)
+ {
+ $actions = $this->objectModel->batchReview($storyIdList, $result, $reason);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($actions);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test story subdivide.
+ *
+ * @param int $storyID
+ * @param array $stories
+ * @access public
+ * @return void
+ */
+ public function subdivideTest($storyID, $stories, $type)
+ {
+ $this->objectModel->subdivide($storyID, $stories);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ if($type == 'requirement')
+ {
+ return $tester->dao->select('*')->from(TABLE_RELATION)->where('AID')->eq($storyID)->andWhere('AType')->eq($type)->fetchAll();
+ }
+ else
+ {
+ return $this->objectModel->getById($storyID);
+ }
+ }
+
+ /**
+ * Test close a story.
+ *
+ * @param int $storyID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function closeTest($storyID, $params)
+ {
+ $_POST = $params;
+ $changes = $this->objectModel->close($storyID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $changes;
+ }
+
+ /**
+ * Test batch close story.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function batchCloseTest($params)
+ {
+ $_POST = $params;
+ $changes = $this->objectModel->batchClose();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test batch change story module.
+ *
+ * @param int $storyIdList
+ * @param int $moduleID
+ * @access public
+ * @return void
+ */
+ public function batchChangeModuleTest($storyIdList, $moduleID)
+ {
+ $changes = $this->objectModel->batchChangeModule($storyIdList, $moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test batch change story plan.
+ *
+ * @param arary $storyIdList
+ * @param int $planID
+ * @param int $oldPlanID
+ * @access public
+ * @return void
+ */
+ public function batchChangePlanTest($storyIdList, $planID, $oldPlanID = 0)
+ {
+ $changes = $this->objectModel->batchChangePlan($storyIdList, $planID, $oldPlanID);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test batch change story branch.
+ *
+ * @param arary $storyIdList
+ * @param int $branchID
+ * @param string $confirm
+ * @param array $plans
+ * @access public
+ * @return void
+ */
+ public function batchChangeBranchTest($storyIdList, $branchID, $confirm = '', $plans = array())
+ {
+ $changes = $this->objectModel->batchChangeBranch($storyIdList, $branchID, $confirm, $plans);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test batch change stage.
+ *
+ * @param arrau $storyIdList
+ * @param string $stage
+ * @access public
+ * @return void
+ */
+ public function batchChangeStageTest($storyIdList, $stage)
+ {
+ $changes = $this->objectModel->batchChangeStage($storyIdList, $stage);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test story batch to task.
+ *
+ * @param int $executionID
+ * @param int $projectID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function batchToTaskTest($executionID, $projectID = 0, $params = '')
+ {
+ $_POST = $params;
+ $taskIdList = $this->objectModel->batchToTask($executionID, $projectID);
+ unset($params);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ return $tester->loadModel('task')->getByList($taskIdList);
+ }
+
+ /**
+ * Test assign a story.
+ *
+ * @param int $storyID
+ * @param string $assignedTo
+ * @access public
+ * @return void
+ */
+ public function assignTest($storyID, $assignedTo)
+ {
+ $_POST['assignedTo'] = $assignedTo;
+ $this->objectModel->assign($storyID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $this->objectModel->getById($storyID);
+ }
+
+ /**
+ * Test batch assign story.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function batchAssignToTest($params)
+ {
+ $_POST = $params;
+ $changes = $this->objectModel->batchAssignTo();
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $storyIdList = array_keys($changes);
+ return $this->objectModel->getByList($storyIdList);
+ }
+
+ /**
+ * Test get stories by assignedBy.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @access public
+ * @return string
+ */
+ public function getByAssignedByTest($productID, $branch)
+ {
+ global $tester;
+ $stories = $this->objectModel->getByAssignedBy($productID, $branch, $modules = array(), $account = $tester->app->user->account, $type = 'story', $orderBy = '', $pager = null);
+
+ $title = '';
+ foreach($stories as $story)
+ {
+ $title .= ',' . $story->title;
+ }
+ $title = trim($title, ',');
+ $title = str_replace("'", '', $title);
+
+ if(dao::isError()) return dao::getError();
+
+ return $title;
+ }
+}
diff --git a/module/task/test/model/activate.php b/module/task/test/model/activate.php
new file mode 100755
index 0000000000..747e48bbc1
--- /dev/null
+++ b/module/task/test/model/activate.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+activate();
+cid=1
+pid=1
+
+wait状态任务激活 >> status,wait,doing
+done状态任务激活 >> status,done,doing
+pause状态任务激活 >> status,pause,doing
+cancel状态任务激活 >> status,cancel,doing
+closed状态任务激活 >> status,closed,doing
+
+*/
+
+$taskIDList = array('37','39','40','41','42');
+
+$task = new taskTest();
+r($task->activateTest($taskIDList[0])) && p('0:field,old,new') && e('status,wait,doing'); //wait状态任务激活
+r($task->activateTest($taskIDList[1])) && p('0:field,old,new') && e('status,done,doing'); //done状态任务激活
+r($task->activateTest($taskIDList[2])) && p('0:field,old,new') && e('status,pause,doing'); //pause状态任务激活
+r($task->activateTest($taskIDList[3])) && p('0:field,old,new') && e('status,cancel,doing'); //cancel状态任务激活
+r($task->activateTest($taskIDList[4])) && p('0:field,old,new') && e('status,closed,doing'); //closed状态任务激活
diff --git a/module/task/test/model/addtaskestimate.php b/module/task/test/model/addtaskestimate.php
new file mode 100755
index 0000000000..45f35c491c
--- /dev/null
+++ b/module/task/test/model/addtaskestimate.php
@@ -0,0 +1,56 @@
+#!/usr/bin/env php
+addTaskEstimate();
+cid=1
+pid=1
+
+插入task为1 left为0 consumed为3的任务 >> 601,1,0,3
+插入task为601 left为0 consumed为3的任务 >> 602,601,0,3
+插入task为601 left为1 consumed为4的任务 >> 603,602,1,4
+插入task为904 left为3 consumed为6的任务 >> 604,904,3,6
+插入task为907 left为6 consumed为9的任务 >> 605,907,6,9
+
+*/
+
+$record1 = new stdclass();
+$record1->account = 'po82';
+$record1->task = 1;
+$record1->left = 0;
+$record1->consumed = 3;
+
+$record2 = new stdclass();
+$record2->account = 'po82';
+$record2->task = 601;
+$record2->left = 0;
+$record2->consumed = 3;
+
+$record3 = new stdclass();
+$record3->account = 'po82';
+$record3->task = 602;
+$record3->left = 1;
+$record3->consumed = 4;
+
+$record4 = new stdclass();
+$record4->account = 'po82';
+$record4->task = 904;
+$record4->left = 3;
+$record4->consumed = 6;
+
+$record5 = new stdclass();
+$record5->account = 'po82';
+$record5->task = 907;
+$record5->left = 6;
+$record5->consumed = 9;
+
+$task = new taskTest();
+r($task->addTaskEstimateTest($record1)) && p('id,task,left,consumed') && e("601,1,0,3"); // 插入task为1 left为0 consumed为3的任务
+r($task->addTaskEstimateTest($record2)) && p('id,task,left,consumed') && e("602,601,0,3"); // 插入task为601 left为0 consumed为3的任务
+r($task->addTaskEstimateTest($record3)) && p('id,task,left,consumed') && e("603,602,1,4"); // 插入task为601 left为1 consumed为4的任务
+r($task->addTaskEstimateTest($record4)) && p('id,task,left,consumed') && e("604,904,3,6"); // 插入task为904 left为3 consumed为6的任务
+r($task->addTaskEstimateTest($record5)) && p('id,task,left,consumed') && e("605,907,6,9"); // 插入task为907 left为6 consumed为9的任务
diff --git a/module/task/test/model/assign.php b/module/task/test/model/assign.php
new file mode 100755
index 0000000000..1baa2507eb
--- /dev/null
+++ b/module/task/test/model/assign.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+assign();
+cid=1
+pid=1
+
+wait状态任务指派 >> assignedTo,po82,user92
+doing状态任务指派 >> assignedTo,,user93
+done状态任务指派 >> assignedTo,,user94
+pause状态任务指派 >> assignedTo,,user95
+cancel状态任务指派 >> assignedTo,,user96
+closed状态任务指派 >> assignedTo,,user97
+
+*/
+
+$taskIDlist = array('1','2','3','4','5','6');
+
+$waitTask = array('assignedTo' => 'user92','status' => 'wait', 'left' => '1');
+$doingTask = array('assignedTo' => 'user93','status' => 'doing');
+$doneTask = array('assignedTo' => 'user94','status' => 'done');
+$pauseTask = array('assignedTo' => 'user95','status' => 'pause');
+$cancelTask = array('assignedTo' => 'user96','status' => 'cancel');
+$closedTask = array('assignedTo' => 'user97','status' => 'closed');
+
+$task = new taskTest();
+r($task->assignTest($taskIDlist[0],$waitTask)) && p('0:field,old,new') && e('assignedTo,po82,user92'); // wait状态任务指派
+r($task->assignTest($taskIDlist[1],$doingTask)) && p('0:field,old,new') && e('assignedTo,,user93'); // doing状态任务指派
+r($task->assignTest($taskIDlist[2],$doneTask)) && p('0:field,old,new') && e('assignedTo,,user94'); // done状态任务指派
+r($task->assignTest($taskIDlist[3],$pauseTask)) && p('0:field,old,new') && e('assignedTo,,user95'); // pause状态任务指派
+r($task->assignTest($taskIDlist[4],$cancelTask)) && p('0:field,old,new') && e('assignedTo,,user96'); // cancel状态任务指派
+r($task->assignTest($taskIDlist[5],$closedTask)) && p('0:field,old,new') && e('assignedTo,,user97'); // closed状态任务指派
diff --git a/module/task/test/model/batchchangemodule.php b/module/task/test/model/batchchangemodule.php
new file mode 100755
index 0000000000..b056050ac7
--- /dev/null
+++ b/module/task/test/model/batchchangemodule.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+batchChangeModule();
+cid=1
+pid=1
+
+返回批量修改的第一个值 >> module,21,22
+
+*/
+
+$moduleID = '22';
+$taskIDList = array('1','2','3');
+
+$task = new taskTest();
+r($task->batchChangeModuleTest($taskIDList,$moduleID)) && p('0:field,old,new') && e('module,21,22'); // 返回批量修改的第一个值
diff --git a/module/task/test/model/batchcreate.php b/module/task/test/model/batchcreate.php
new file mode 100755
index 0000000000..345b0b263a
--- /dev/null
+++ b/module/task/test/model/batchcreate.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+batchCreate();
+cid=1
+pid=1
+
+测试正常的创建开发任务 >> 批量任务三
+测试正常的创建开发任务 >> 『任务类型』不能为空。
+
+*/
+
+$executionID = '101';
+
+$name = array('批量任务一','批量任务二','批量任务三');
+$type = array('devel','test','design');
+$normal_create = array('name' => $name, 'type' => $type);
+
+$name = array('异常一','异常二','异常三');
+$Exception_create = array('name' => $name);
+
+$task = new taskTest();
+r($task->batchCreateObject($normal_create, $executionID)) && p('name') && e('批量任务三'); // 测试正常的创建开发任务
+r($task->batchCreateObject($Exception_create, $executionID)) && p('message:0') && e('『任务类型』不能为空。'); // 测试正常的创建开发任务
+
diff --git a/module/task/test/model/batchupdate.php b/module/task/test/model/batchupdate.php
new file mode 100755
index 0000000000..7c5fc826ae
--- /dev/null
+++ b/module/task/test/model/batchupdate.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+测试批量修改任务 >> name,开发任务17,批量修改任务一
+
+*/
+
+$taskID = '7';
+
+$name = array( '7' => '批量修改任务一');
+$type = array( '7' => 'devel');
+$statuses = array('7' =>'doing');
+
+$normal = array('names' => $name, 'types' => $type,'statuses'=> $statuses);
+
+$task = new taskTest();
+r($task->batchUpdateObject($normal, $taskID)) && p('1:field,old,new') && e('name,开发任务17,批量修改任务一'); // 测试批量修改任务
diff --git a/module/task/test/model/cancel.php b/module/task/test/model/cancel.php
new file mode 100755
index 0000000000..907df66c36
--- /dev/null
+++ b/module/task/test/model/cancel.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+cancel();
+cid=1
+pid=1
+
+wait状态任务取消 >> status,wait,cancel
+doing状态任务取消 >> status,doing,cancel
+done状态任务取消 >> status,done,cancel
+pause状态任务取消 >> status,pause,cancel
+closed状态任务取消 >> status,closed,cancel
+
+*/
+
+$taskIDlist = array('31','32','33','34','36');
+
+$task = new taskTest();
+r($task->cancelTest($taskIDlist[0])) && p('0:field,old,new') && e('status,wait,cancel'); //wait状态任务取消
+r($task->cancelTest($taskIDlist[1])) && p('0:field,old,new') && e('status,doing,cancel'); //doing状态任务取消
+r($task->cancelTest($taskIDlist[2])) && p('0:field,old,new') && e('status,done,cancel'); //done状态任务取消
+r($task->cancelTest($taskIDlist[3])) && p('0:field,old,new') && e('status,pause,cancel'); //pause状态任务取消
+r($task->cancelTest($taskIDlist[4])) && p('0:field,old,new') && e('status,closed,cancel'); //closed状态任务取消
diff --git a/module/task/test/model/canoperateeffort.php b/module/task/test/model/canoperateeffort.php
new file mode 100644
index 0000000000..00057d1292
--- /dev/null
+++ b/module/task/test/model/canoperateeffort.php
@@ -0,0 +1,103 @@
+#!/usr/bin/env php
+canOperateEffort();
+cid=1
+pid=1
+
+判断非多人任务 >> 1
+判断已完成的串行多人任务并且不判断日志 >> 0
+判断已关闭的串行多人任务并且不判断日志 >> 0
+判断已取消的串行多人任务并且不判断日志 >> 0
+判断已暂停的串行多人任务并且不判断日志 >> 0
+判断当前用户不在多人任务团队成员列表中 >> 0
+判断串行多人任务的指派给不是当前用户 >> 0
+判断串行多人任务的指派给是当前用户 >> 1
+判断当前用户在并行多人任务团队成员列表中 >> 1
+判断已完成多人任务并且日志创建者和当前用户一致 >> 1
+判断已完成多人任务并且日志创建者和当前用户不一致 >> 0
+判断已关闭的串行多人任务并且判断日志 >> 0
+判断已取消的串行多人任务并且判断日志 >> 0
+判断已暂停的串行多人任务并且判断日志 >> 0
+判断进行中的串行多人任务并且当前日志创建者不是当前用户 >> 0
+判断进行中的串行多人任务并且当前日志创建者是当前用户 >> 1
+
+*/
+
+$user = new stdclass();
+$user->account = 'dev1';
+$user->status = 'wait';
+$user->order = '1';
+$users[] = $user;
+
+$user = new stdclass();
+$user->account = 'dev2';
+$user->status = 'wait';
+$user->order = '2';
+$users[] = $user;
+
+$task = new stdclass();
+$task->mode = '';
+$task->openedBy = 'dev1';
+$task->assignedTo = 'admin';
+
+$taskTest = new taskTest();
+r($taskTest->canOperateEffort($task)) && p() && e('1'); //判断非多人任务
+
+$task->mode = 'linear';
+$task->team = $users;
+$task->status = 'done';
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断已完成的串行多人任务并且不判断日志
+$task->status = 'closed';
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断已关闭的串行多人任务并且不判断日志
+$task->status = 'cancel';
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断已取消的串行多人任务并且不判断日志
+$task->status = 'pause';
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断已暂停的串行多人任务并且不判断日志
+
+$task->status = 'wait';
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断当前用户不在多人任务团队成员列表中
+
+$user = new stdclass();
+$user->account = 'admin';
+$user->status = 'wait';
+$user->order = '0';
+$users[] = $user;
+
+$task->mode = 'linear';
+$task->assignedTo = 'dev1';
+$task->team = $users;
+r($taskTest->canOperateEffort($task)) && p() && e('0'); //判断串行多人任务的指派给不是当前用户
+$task->assignedTo = 'admin';
+r($taskTest->canOperateEffort($task)) && p() && e('1'); //判断串行多人任务的指派给是当前用户
+
+$task->mode = 'multi';
+r($taskTest->canOperateEffort($task)) && p() && e('1'); //判断当前用户在并行多人任务团队成员列表中
+
+$effort = new stdclass();
+$effort->account = 'admin';
+
+$task->mode = 'linear';
+$task->status = 'done';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('1'); //判断已完成多人任务并且日志创建者和当前用户一致
+
+$effort->account = 'dev1';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('0'); //判断已完成多人任务并且日志创建者和当前用户不一致
+
+$task->mode = 'linear';
+$task->status = 'closed';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('0'); //判断已关闭的串行多人任务并且判断日志
+$task->status = 'cancel';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('0'); //判断已取消的串行多人任务并且判断日志
+$task->status = 'pause';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('0'); //判断已暂停的串行多人任务并且判断日志
+
+$task->status = 'doing';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('0'); //判断进行中的串行多人任务并且当前日志创建者不是当前用户
+$effort->account = 'admin';
+r($taskTest->canOperateEffort($task, $effort)) && p() && e('1'); //判断进行中的串行多人任务并且当前日志创建者是当前用户
diff --git a/module/task/test/model/checkeeststartedanddeadline.php b/module/task/test/model/checkeeststartedanddeadline.php
new file mode 100644
index 0000000000..e2b9ec2ca2
--- /dev/null
+++ b/module/task/test/model/checkeeststartedanddeadline.php
@@ -0,0 +1,62 @@
+#!/usr/bin/env php
+id->range('1-11');
+$execution->name->setFields(array(
+ array('field' => 'name1', 'range' => '项目{2},执行{3},迭代{2},阶段{2},看板{2}'),
+ array('field' => 'name2', 'range' => '1-3'),
+));
+$execution->code->setFields(array(
+ array('field' => 'name1', 'range' => '项目{2},执行{3},迭代{2},阶段{2},看板{2}'),
+ array('field' => 'name2', 'range' => '1-3'),
+));
+$execution->type->range('project{2},sprint{5},waterfall{2},kanban{2}');
+$execution->status->range('doing{11}');
+$execution->parent->range('0');
+$execution->begin->range('20230102 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->end->range('20230212 000000:0')->type('timestamp')->format('YY/MM/DD');
+$execution->gen(5);
+
+
+/**
+
+title=测试 taskModel->checkEstStartedAndDeadline();
+cid=1
+pid=1
+
+测试获取执行4 任务开始日期 2000-01-02 结束日期 2040-01-02 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,任务结束日期应小于等于迭代的结束日期:2023-02-12。
+测试获取执行4 任务开始日期 2000-01-02 结束日期 空 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,
+测试获取执行4 任务开始日期 2000-01-02 结束日期 2023-01-15 是否可以保存 >> 任务开始日期应大于等于迭代的开始日期:2023-01-02。,
+测试获取执行4 任务开始日期 空 结束日期 2040-01-02 是否可以保存 >> ,任务结束日期应小于等于迭代的结束日期:2023-02-12。
+测试获取执行4 任务开始日期 空 结束日期 空 是否可以保存 >> 0
+测试获取执行4 任务开始日期 空 结束日期 2023-01-15 是否可以保存 >> 0
+测试获取执行4 任务开始日期 2023-01-15 结束日期 2040-01-02 是否可以保存 >> ,任务结束日期应小于等于迭代的结束日期:2023-02-12。
+测试获取执行4 任务开始日期 2023-01-15 结束日期 空 是否可以保存 >> 0
+测试获取执行4 任务开始日期 2023-01-15 结束日期 2023-01-15 是否可以保存 >> 0
+
+*/
+
+$executionID = '4';
+$estStarted = array('2000-01-02', '', '2023-01-15');
+$deadline = array('2040-01-02', '', '2023-01-15');
+
+$task = new taskTest();
+
+global $tester;
+$tester->loadModel('setting')->setItem('system.common.limitTaskDate', 1);
+
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[0])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 2040-01-02 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[1])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 空 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[0], $deadline[2])) && p('estStarted,deadline') && e('任务开始日期应大于等于迭代的开始日期:2023-01-02。,'); // 测试获取执行4 任务开始日期 2000-01-02 结束日期 2023-01-15 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[0])) && p('estStarted,deadline') && e(',任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 空 结束日期 2040-01-02 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[1])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 空 结束日期 空 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[1], $deadline[2])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 空 结束日期 2023-01-15 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[0])) && p('estStarted,deadline') && e(',任务结束日期应小于等于迭代的结束日期:2023-02-12。'); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 2040-01-02 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[1])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 空 是否可以保存
+r($task->checkEstStartedAndDeadlineTest($executionID, $estStarted[2], $deadline[2])) && p('estStarted,deadline') && e(0); // 测试获取执行4 任务开始日期 2023-01-15 结束日期 2023-01-15 是否可以保存
+
+$tester->setting->setItem('system.common.limitTaskDate', 0);
diff --git a/module/task/test/model/closed.php b/module/task/test/model/closed.php
new file mode 100755
index 0000000000..1fbad89130
--- /dev/null
+++ b/module/task/test/model/closed.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+wait状态任务关闭 >> status,wait,closed
+doing状态任务关闭 >> status,doing,closed
+done状态任务关闭 >> status,done,closed
+pause状态任务关闭 >> status,pause,closed
+cancel状态任务关闭 >> status,cancel,closed
+
+*/
+
+$taskIDList = array('25','26','27','28','29');
+
+$task = new taskTest();
+r($task->closeTest($taskIDList[0])) && p('0:field,old,new') && e('status,wait,closed'); //wait状态任务关闭
+r($task->closeTest($taskIDList[1])) && p('0:field,old,new') && e('status,doing,closed'); //doing状态任务关闭
+r($task->closeTest($taskIDList[2])) && p('0:field,old,new') && e('status,done,closed'); //done状态任务关闭
+r($task->closeTest($taskIDList[3])) && p('0:field,old,new') && e('status,pause,closed'); //pause状态任务关闭
+r($task->closeTest($taskIDList[4])) && p('0:field,old,new') && e('status,cancel,closed'); //cancel状态任务关闭
diff --git a/module/task/test/model/computebeginandend.php b/module/task/test/model/computebeginandend.php
new file mode 100755
index 0000000000..b88da90a68
--- /dev/null
+++ b/module/task/test/model/computebeginandend.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+computeBeginAndEnd();
+cid=1
+pid=1
+
+根据taskID计算没有父计划的开始结束时间 >> 0,6
+根据taskID计算有父计划的父开始结束时间 >> 0,7
+根据不存在的taskID计算开始结束时间 >> 0
+
+*/
+
+$taskIDList = array('1', '901', '100001');
+
+$task = new taskTest();
+r($task->computeBeginAndEndTest($taskIDList[0])) && p('estStartedDiff,deadlineDiff') && e('0,6'); //根据taskID计算没有父计划的开始结束时间
+r($task->computeBeginAndEndTest($taskIDList[1])) && p('estStartedDiff,deadlineDiff') && e('0,7'); //根据taskID计算有父计划的父开始结束时间
+r($task->computeBeginAndEndTest($taskIDList[2])) && p('estStartedDiff,deadlineDiff') && e('0'); //根据不存在的taskID计算开始结束时间
diff --git a/module/task/test/model/computehours4multiple.php b/module/task/test/model/computehours4multiple.php
new file mode 100755
index 0000000000..b568c117f8
--- /dev/null
+++ b/module/task/test/model/computehours4multiple.php
@@ -0,0 +1,103 @@
+#!/usr/bin/env php
+computeHours4Multiple();
+cid=1
+pid=1
+
+task状态为wait只有老task计算多人工时 >> 1,po82,wait,3,3,3
+task状态为wait有新老task计算多人工时 >> 1,po82,wait,3,3,3
+task状态为wait有新老task和团队计算多人工时 >> 1,po82,doing,3,3,3
+task状态为done只有老task计算多人工时 >> 903,po82,done,3,3,3
+task状态为done有新老task计算多人工时 >> 903,po82,done,3,3,3
+task状态为done有新老task和团队计算多人工时 >> 903,po82,doing,3,3,3
+task状态为pause只有老task计算多人工时 >> 910,,pause,9,12,9
+task状态为pause有新老task计算多人工时 >> 910,,pause,9,12,9
+task状态为pause只有老task计算多人工时 >> 910,po82,doing,3,3,3
+老task不存在的情况有新老task和团队计算多人工时 >> 0
+老task不存在的情况有新老task计算多人工时 >> 0
+新task不存在的情况有新老task和团队计算多人工时 >> 10001,po82,doing,3,3,3
+
+*/
+$task1 = new stdclass();
+$task1->id = 1;
+$task1->status = 'wait';
+$task1->assignedTo = '';
+$task1->openedBy = '';
+
+$task2 = new stdclass();
+$task2->id = 1;
+$task2->status = 'wait';
+$task2->assignedTo = 'user92';
+$task2->openedBy = '';
+
+$task3 = new stdclass();
+$task3->id = 903;
+$task3->status = 'done';
+$task3->assignedTo = '';
+$task3->openedBy = '';
+
+$task4 = new stdclass();
+$task4->id = 903;
+$task4->status = 'done';
+$task4->assignedTo = 'po82';
+$task4->openedBy = '';
+
+$task5 = new stdclass();
+$task5->id = 910;
+$task5->status = 'pause';
+$task5->assignedTo = '';
+$task5->openedBy = '';
+
+$task6 = new stdclass();
+$task6->id = 910;
+$task6->status = 'pause';
+$task6->assignedTo = '';
+$task6->openedBy = '';
+
+$task7 = new stdclass();
+$task7->id = 100001;
+$task7->status = 'done';
+$task7->assignedTo = '';
+$task7->openedBy = '';
+
+$task8 = new stdclass();
+$task8->id = 10001;
+$task8->status = 'wait';
+$task8->assignedTo = '';
+$task8->openedBy = '';
+
+$user1 = new stdclass();
+$user1->account = 'po82';
+$user1->estimate = 1;
+$user1->consumed = 1;
+$user1->left = 1;
+
+$user2 = new stdclass();
+$user2->account = 'user92';
+$user2->estimate = 2;
+$user2->consumed = 2;
+$user2->left = 2;
+
+$team = array($user1, $user2);
+
+$autoStatusList = array(true, false);
+
+$task = new taskTest();
+r($task->computeHours4MultipleTest($task1)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,wait,3,3,3'); // task状态为wait只有老task计算多人工时
+r($task->computeHours4MultipleTest($task1, $task2)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,wait,3,3,3'); // task状态为wait有新老task计算多人工时
+r($task->computeHours4MultipleTest($task1, $task2, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('1,po82,doing,3,3,3'); // task状态为wait有新老task和团队计算多人工时
+r($task->computeHours4MultipleTest($task3)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,done,3,3,3'); // task状态为done只有老task计算多人工时
+r($task->computeHours4MultipleTest($task3, $task4)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,done,3,3,3'); // task状态为done有新老task计算多人工时
+r($task->computeHours4MultipleTest($task3, $task4, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('903,po82,doing,3,3,3'); // task状态为done有新老task和团队计算多人工时
+r($task->computeHours4MultipleTest($task5)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,,pause,9,12,9'); // task状态为pause只有老task计算多人工时
+r($task->computeHours4MultipleTest($task5, $task1, array(), false)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,,pause,9,12,9'); // task状态为pause有新老task计算多人工时
+r($task->computeHours4MultipleTest($task5, $task6, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('910,po82,doing,3,3,3'); // task状态为pause只有老task计算多人工时
+r($task->computeHours4MultipleTest($task7)) && p('id,assignedTo,status,estimate,consumed,left') && e('0'); // 老task不存在的情况有新老task和团队计算多人工时
+r($task->computeHours4MultipleTest($task7, $task8)) && p('id,assignedTo,status,estimate,consumed,left') && e('0'); // 老task不存在的情况有新老task计算多人工时
+r($task->computeHours4MultipleTest($task1, $task8, $team)) && p('id,assignedTo,status,estimate,consumed,left') && e('10001,po82,doing,3,3,3'); // 新task不存在的情况有新老task和团队计算多人工时
diff --git a/module/task/test/model/computeworkinghours.php b/module/task/test/model/computeworkinghours.php
new file mode 100755
index 0000000000..6f4a593797
--- /dev/null
+++ b/module/task/test/model/computeworkinghours.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+computeWorkingHours();
+cid=1
+pid=1
+
+根据taskID计算没有子任务的计划工时 >> 1,0,3,0
+根据taskID计算有父任务的子任务工时 >> 601,18,30,18
+根据不存在的taskID计算工时 >> 0
+
+*/
+
+$taskIDList = array('1', '601', '100001');
+
+$task = new taskTest();
+r($task->computeWorkingHoursTest($taskIDList[0])) && p('id,estimate,consumed,left') && e('1,0,3,0'); //根据taskID计算没有子任务的计划工时
+r($task->computeWorkingHoursTest($taskIDList[1])) && p('id,estimate,consumed,left') && e('601,18,30,18'); //根据taskID计算有父任务的子任务工时
+r($task->computeWorkingHoursTest($taskIDList[2])) && p('id,estimate,consumed,left') && e('0'); //根据不存在的taskID计算工时
diff --git a/module/task/test/model/create.php b/module/task/test/model/create.php
new file mode 100755
index 0000000000..d83e7e47df
--- /dev/null
+++ b/module/task/test/model/create.php
@@ -0,0 +1,60 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试正常的创建开发任务 >> 开发任务一
+测试正常的创建设计任务 >> 11
+测试正常的创建需求任务 >> 101
+测试正常的创建测试任务 >> test
+测试正常的创建研究任务 >> 3
+测试正常的创建讨论任务 >> wait
+测试正常的创建界面任务 >> admin
+测试正常的创建事务任务 >> 2021-01-10
+测试正常的创建其他任务 >> 2021-03-19
+测试不输入名称创建任务 >> 『任务名称』不能为空。
+测试不输入类型创建任务 >> 『任务类型』不能为空。
+测试开始时间大于结束时间 >> 『截止日期』应当不小于『2021-04-10』。
+测试指派人任务 >> user92
+
+*/
+
+$executionID = '101';
+
+$devel = array('name' => '开发任务一', 'type' => 'devel');
+$design = array('name' => '设计任务一', 'type' => 'design');
+$request = array('name' => '需求任务一', 'type' => 'request');
+$test = array('name' => '测试任务一', 'type' => 'test');
+$study = array('name' => '研究任务一', 'type' => 'study');
+$discuss = array('name' => '讨论任务一', 'type' => 'discuss');
+$ui = array('name' => '界面任务一', 'type' => 'ui');
+$affair = array('name' => '事务任务一', 'type' => 'affair');
+$misc = array('name' => '其他任务一', 'type' => 'misc');
+$noname = array('name' => '', 'type' => 'devel');
+$notype = array('name' => '特殊任务一', 'type' => '');
+$errortime = array('name' => '特殊任务二', 'type' => 'devel', 'estStarted' => '2021-04-10', 'deadline' => '2021-03-19');
+$assignedTo = array('user92');
+$assign = array('name' => '指派人user92任务', 'type' => 'devel', 'assignedTo' => $assignedTo);
+
+$task = new taskTest();
+r($task->createObject($devel, $executionID)) && p('name') && e('开发任务一'); // 测试正常的创建开发任务
+r($task->createObject($design, $executionID)) && p('project') && e('11'); // 测试正常的创建设计任务
+r($task->createObject($request, $executionID)) && p('execution') && e('101'); // 测试正常的创建需求任务
+r($task->createObject($test, $executionID)) && p('type') && e('test'); // 测试正常的创建测试任务
+r($task->createObject($study, $executionID)) && p('pri') && e('3'); // 测试正常的创建研究任务
+r($task->createObject($discuss, $executionID)) && p('status') && e('wait'); // 测试正常的创建讨论任务
+r($task->createObject($ui, $executionID)) && p('openedBy') && e('admin'); // 测试正常的创建界面任务
+r($task->createObject($affair, $executionID)) && p('estStarted') && e('2021-01-10'); // 测试正常的创建事务任务
+r($task->createObject($misc, $executionID)) && p('deadline') && e('2021-03-19'); // 测试正常的创建其他任务
+r($task->createObject($noname, $executionID)) && p('name:0') && e('『任务名称』不能为空。'); // 测试不输入名称创建任务
+r($task->createObject($notype, $executionID)) && p('type:0') && e('『任务类型』不能为空。'); // 测试不输入类型创建任务
+r($task->createObject($errortime, $executionID)) && p('deadline:0') && e('『截止日期』应当不小于『2021-04-10』。'); // 测试开始时间大于结束时间
+r($task->createObject($assign, $executionID)) && p('assignedTo') && e('user92'); // 测试指派人任务
+
diff --git a/module/task/test/model/createtaskfromgitlabissue.php b/module/task/test/model/createtaskfromgitlabissue.php
new file mode 100755
index 0000000000..99889814fd
--- /dev/null
+++ b/module/task/test/model/createtaskfromgitlabissue.php
@@ -0,0 +1,48 @@
+#!/usr/bin/env php
+createTaskFromGitlabIssue();
+cid=1
+pid=1
+
+测试正常的创建开发任务 >> gitlab中新建的问题01
+测试正常的创建开发任务 >> 101
+测试正常的创建开发任务 >> 11
+测试不输入执行创建任务 >> 『所属执行』不能为空。
+测试不输入名称创建任务 >> 『任务名称』不能为空。
+
+*/
+
+$executionID = 101;
+
+$task1 = new stdclass();
+$task1->name = 'gitlab中新建的问题01';
+$task1->execution = $executionID;
+
+$task2 = new stdclass();
+$task2->name = 'gitlab中新建的问题02';
+$task2->execution = $executionID;
+
+$task3 = new stdclass();
+$task3->name = 'gitlab中新建的问题03';
+$task3->execution = $executionID;
+
+$task4 = new stdclass();
+$task4->name = 'gitlab中新建的问题04';
+$task4->execution = '';
+
+$task5 = new stdclass();
+$task5->name = '';
+$task5->execution = $executionID;
+
+$task = new taskTest();
+r($task->createTaskFromGitlabIssueTest($task1, $executionID)) && p('name') && e('gitlab中新建的问题01'); // 测试正常的创建开发任务
+r($task->createTaskFromGitlabIssueTest($task2, $executionID)) && p('execution') && e('101'); // 测试正常的创建开发任务
+r($task->createTaskFromGitlabIssueTest($task3, $executionID)) && p('project') && e('11'); // 测试正常的创建开发任务
+r($task->createTaskFromGitlabIssueTest($task4, $executionID)) && p('execution:0') && e('『所属执行』不能为空。'); // 测试不输入执行创建任务
+r($task->createTaskFromGitlabIssueTest($task5, $executionID)) && p('name:0') && e('『任务名称』不能为空。'); // 测试不输入名称创建任务
diff --git a/module/task/test/model/deleteestimate.php b/module/task/test/model/deleteestimate.php
new file mode 100755
index 0000000000..291b2e1a0c
--- /dev/null
+++ b/module/task/test/model/deleteestimate.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+deleteEstimate();
+cid=1
+pid=1
+
+根据estimateID查看预计工时 >> consumed,3,2
+
+*/
+
+$estimateID = '1';
+
+$task = new taskTest();
+r($task->deleteEstimateTest($estimateID)) && p('0:field,old,new') && e('consumed,3,2'); // 根据estimateID查看预计工时
diff --git a/module/task/test/model/finish.php b/module/task/test/model/finish.php
new file mode 100755
index 0000000000..26c251beef
--- /dev/null
+++ b/module/task/test/model/finish.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+finish();
+cid=1
+pid=1
+
+wait状态任务完成 >> status,wait,done
+doing状态任务完成 >> status,doing,done
+done状态任务完成 >> finishedBy,,admin
+pause状态任务完成 >> status,pause,done
+cancel状态任务完成 >> status,cancel,done
+closed状态任务完成 >> status,closed,done
+总计消耗异常验证 >> "总计消耗"必须大于之前消耗
+本次消耗不为0 >> "本次消耗"不能为0
+
+*/
+
+$taskIDList = array('7','8','9','10','11','12','13','14');
+
+$currencyTask = array('consumed' => '17', 'currentConsumed' => '1');
+$consumedTask = array('consumed' => '0', 'currentConsumed' => '1');
+$currentConsumedTask = array('consumed' => '10', 'currentConsumed' => '0');
+
+$task = new taskTest();
+sleep(2);
+//var_dump($task->finishTest($taskIDList[2],$currencyTask));die;
+r($task->finishTest($taskIDList[0],$currencyTask)) && p('0:field,old,new') && e('status,wait,done'); //wait状态任务完成
+r($task->finishTest($taskIDList[1],$currencyTask)) && p('0:field,old,new') && e('status,doing,done'); //doing状态任务完成
+r($task->finishTest($taskIDList[2],$currencyTask)) && p('4:field,old,new') && e('finishedBy,,admin'); //done状态任务完成
+r($task->finishTest($taskIDList[3],$currencyTask)) && p('0:field,old,new') && e('status,pause,done'); //pause状态任务完成
+r($task->finishTest($taskIDList[4],$currencyTask)) && p('0:field,old,new') && e('status,cancel,done'); //cancel状态任务完成
+r($task->finishTest($taskIDList[5],$currencyTask)) && p('0:field,old,new') && e('status,closed,done'); //closed状态任务完成
+r($task->finishTest($taskIDList[6],$consumedTask)) && p() && e('"总计消耗"必须大于之前消耗'); //总计消耗异常验证
+r($task->finishTest($taskIDList[7],$currentConsumedTask)) && p() && e('"本次消耗"不能为0'); //本次消耗不为0
diff --git a/module/task/test/model/getassignedto4multi.php b/module/task/test/model/getassignedto4multi.php
new file mode 100644
index 0000000000..c2a90a6db7
--- /dev/null
+++ b/module/task/test/model/getassignedto4multi.php
@@ -0,0 +1,61 @@
+#!/usr/bin/env php
+getAssignedTo4Multi();
+cid=1
+pid=1
+
+获取非多人任务的指派给 >> admin
+获取非串行多人任务的指派给 >> null
+获取串行多人任务的指派给 >> admin
+获取排除已经完成的串行多人任务的指派给 >> dev1
+获取串行多人任务的下一个指派给 >> admin
+获取已经完成的串行多人任务的指派给 >> dev1
+
+*/
+
+$user = new stdclass();
+$user->account = 'admin';
+$user->status = 'wait';
+$user->order = '0';
+$users[] = $user;
+
+$user = new stdclass();
+$user->account = 'dev1';
+$user->status = 'wait';
+$user->order = '1';
+$users[] = $user;
+
+$user = new stdclass();
+$user->account = 'admin';
+$user->status = 'wait';
+$user->order = '2';
+$users[] = $user;
+
+$task = new stdclass();
+$task->mode = '';
+$task->openedBy = 'dev1';
+$task->assignedTo = 'admin';
+
+$taskTest = new taskTest();
+r($taskTest->getAssignedTo4Multi($users, $task)) && p() && e('admin'); //获取非多人任务的指派给
+
+$task->mode = 'multi';
+$task->team = $users;
+r($taskTest->getAssignedTo4Multi($users, $task)) && p() && e('admin'); //获取非串行多人任务的指派给
+
+$task->mode = 'linear';
+r($taskTest->getAssignedTo4Multi($users, $task)) && p() && e('admin'); //获取串行多人任务的指派给
+
+$users[0]->status = 'done';
+r($taskTest->getAssignedTo4Multi($users, $task)) && p() && e('dev1'); //获取排除已经完成的串行多人任务的指派给
+r($taskTest->getAssignedTo4Multi($users, $task, 'next')) && p() && e('admin'); //获取串行多人任务的下一个指派给
+
+$users[1]->status = 'done';
+$users[2]->status = 'done';
+r($taskTest->getAssignedTo4Multi($users, $task)) && p() && e('dev1'); //获取已经完成的串行多人任务的指派给
diff --git a/module/task/test/model/getbyid.php b/module/task/test/model/getbyid.php
new file mode 100755
index 0000000000..6dd45b250a
--- /dev/null
+++ b/module/task/test/model/getbyid.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+根据taskID查找任务详情 >> 开发任务60
+
+*/
+
+$taskID = '50';
+
+$task = new taskTest();
+r($task->getByIdTest($taskID)) && p('name') && e('开发任务60'); //根据taskID查找任务详情
diff --git a/module/task/test/model/getbylist.php b/module/task/test/model/getbylist.php
new file mode 100755
index 0000000000..0ab364af81
--- /dev/null
+++ b/module/task/test/model/getbylist.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+根据taskID查找任务详情 >> 开发任务61
+
+*/
+
+$taskID = '51';
+
+$task = new taskTest();
+r($task->getByListTest($taskID)) && p('51:name') && e('开发任务61'); //根据taskID查找任务详情
\ No newline at end of file
diff --git a/module/task/test/model/getdataoffinishedtasksperday.php b/module/task/test/model/getdataoffinishedtasksperday.php
new file mode 100755
index 0000000000..dbb208e263
--- /dev/null
+++ b/module/task/test/model/getdataoffinishedtasksperday.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getDataOffinishedTasksPerDay();
+cid=1
+pid=1
+
+统计没有每日完成的任务数量 >> 0
+
+*/
+
+$task = new taskTest();
+r($task->getDataOffinishedTasksPerDayTest()) && p() && e('0'); //统计没有每日完成的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperassignedto.php b/module/task/test/model/getdataoftasksperassignedto.php
new file mode 100755
index 0000000000..d8ade6b33e
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperassignedto.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getDataOfTasksPerAssignedTo();
+cid=1
+pid=1
+
+统计指派给为po82的任务数量 >> 研发主管82,1
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerAssignedToTest()) && p('po82:name,value') && e('研发主管82,1'); //统计指派给为po82的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperclosedreason.php b/module/task/test/model/getdataoftasksperclosedreason.php
new file mode 100755
index 0000000000..226654b81f
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperclosedreason.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getDataOfTasksPerClosedReason();
+cid=1
+pid=1
+
+统计没有完成原因的任务数量 >> 0
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerClosedReasonTest()) && p() && e('0'); //统计没有完成原因的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperconsumed.php b/module/task/test/model/getdataoftasksperconsumed.php
new file mode 100755
index 0000000000..40bc2e31e2
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperconsumed.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getDataOfTasksPerConsumed();
+cid=1
+pid=1
+
+统计消耗工时为3的任务数量 >> 3,90
+统计消耗工时为4的任务数量 >> 4,90
+统计消耗工时为5的任务数量 >> 5,90
+统计消耗工时为6的任务数量 >> 6,91
+统计消耗工时为7的任务数量 >> 7,91
+统计消耗工时为8的任务数量 >> 8,91
+统计消耗工时为9的任务数量 >> 9,91
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerConsumedTest()) && p('3:name,value') && e('3,90'); //统计消耗工时为3的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('4:name,value') && e('4,90'); //统计消耗工时为4的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('5:name,value') && e('5,90'); //统计消耗工时为5的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('6:name,value') && e('6,91'); //统计消耗工时为6的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('7:name,value') && e('7,91'); //统计消耗工时为7的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('8:name,value') && e('8,91'); //统计消耗工时为8的任务数量
+r($task->getDataOfTasksPerConsumedTest()) && p('9:name,value') && e('9,91'); //统计消耗工时为9的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperdeadline.php b/module/task/test/model/getdataoftasksperdeadline.php
new file mode 100755
index 0000000000..f124f2aef4
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperdeadline.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getDataOfTasksPerDeadline();
+cid=1
+pid=1
+
+统计日期为+1days的任务数量 >> 17
+统计日期为+2days的任务数量 >> 17
+统计日期为+3days的任务数量 >> 18
+统计日期为+4days的任务数量 >> 18
+统计日期为-1days的任务数量 >> 17
+统计日期为-2days的任务数量 >> 17
+统计日期为-3days的任务数量 >> 17
+统计日期为-4days的任务数量 >> 17
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerDeadlineTest(0)) && p("0:value") && e("17"); //统计日期为+1days的任务数量
+r($task->getDataOfTasksPerDeadlineTest(1)) && p("1:value") && e("17"); //统计日期为+2days的任务数量
+r($task->getDataOfTasksPerDeadlineTest(2)) && p("2:value") && e("18"); //统计日期为+3days的任务数量
+r($task->getDataOfTasksPerDeadlineTest(3)) && p("3:value") && e("18"); //统计日期为+4days的任务数量
+r($task->getDataOfTasksPerDeadlineTest(4)) && p("4:value") && e("17"); //统计日期为-1days的任务数量
+r($task->getDataOfTasksPerDeadlineTest(5)) && p("5:value") && e("17"); //统计日期为-2days的任务数量
+r($task->getdataoftasksperdeadlinetest(6)) && p("6:value") && e("17"); //统计日期为-3days的任务数量
+r($task->getdataoftasksperdeadlinetest(7)) && p("7:value") && e("17"); //统计日期为-4days的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperestimate.php b/module/task/test/model/getdataoftasksperestimate.php
new file mode 100755
index 0000000000..e53a291935
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperestimate.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getDataOfTasksPerEstimate();
+cid=1
+pid=1
+
+统计预计工时为0的任务数量 >> 0,83
+统计预计工时为1的任务数量 >> 1,83
+统计预计工时为2的任务数量 >> 2,83
+统计预计工时为3的任务数量 >> 3,83
+统计预计工时为4的任务数量 >> 4,83
+统计预计工时为5的任务数量 >> 5,83
+统计预计工时为6的任务数量 >> 6,82
+统计预计工时为7的任务数量 >> 7,82
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerEstimateTest()) && p('0:name,value') && e('0,83'); //统计预计工时为0的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('1:name,value') && e('1,83'); //统计预计工时为1的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('2:name,value') && e('2,83'); //统计预计工时为2的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('3:name,value') && e('3,83'); //统计预计工时为3的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('4:name,value') && e('4,83'); //统计预计工时为4的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('5:name,value') && e('5,83'); //统计预计工时为5的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('6:name,value') && e('6,82'); //统计预计工时为6的任务数量
+r($task->getDataOfTasksPerEstimateTest()) && p('7:name,value') && e('7,82'); //统计预计工时为7的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperexecution.php b/module/task/test/model/getdataoftasksperexecution.php
new file mode 100755
index 0000000000..43594617cd
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperexecution.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getDataOfTasksPerExecution();
+cid=1
+pid=1
+
+统计executionID为101的执行的任务数量 >> 迭代1,14
+统计executionID为102的执行的任务数量 >> 迭代2,4
+统计executionID为103的执行的任务数量 >> 迭代3,4
+统计executionID为104的执行的任务数量 >> 迭代4,4
+统计executionID为105的执行的任务数量 >> 迭代5,4
+统计executionID为106的执行的任务数量 >> 迭代6,4
+统计executionID为107的执行的任务数量 >> 迭代7,4
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerExecutionTest()) && p('101:name,value') && e('迭代1,14'); //统计executionID为101的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('102:name,value') && e('迭代2,4'); //统计executionID为102的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('103:name,value') && e('迭代3,4'); //统计executionID为103的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('104:name,value') && e('迭代4,4'); //统计executionID为104的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('105:name,value') && e('迭代5,4'); //统计executionID为105的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('106:name,value') && e('迭代6,4'); //统计executionID为106的执行的任务数量
+r($task->getDataOfTasksPerExecutionTest()) && p('107:name,value') && e('迭代7,4'); //统计executionID为107的执行的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperfinishedby.php b/module/task/test/model/getdataoftasksperfinishedby.php
new file mode 100755
index 0000000000..ed2ce36981
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperfinishedby.php
@@ -0,0 +1,18 @@
+#!/usr/bin/env php
+getDataOfTasksPerFinishedBy();
+cid=1
+pid=1
+
+统计没有完成者的任务数量 >> 0
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerFinishedByTest()) && p() && e('0'); //统计没有完成者的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperleft.php b/module/task/test/model/getdataoftasksperleft.php
new file mode 100755
index 0000000000..e59a383303
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperleft.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getDataOfTasksPerLeft();
+cid=1
+pid=1
+
+统计剩余工时为0的任务数量 >> 0,83
+统计剩余工时为1的任务数量 >> 1,83
+统计剩余工时为2的任务数量 >> 2,83
+统计剩余工时为3的任务数量 >> 3,83
+统计剩余工时为4的任务数量 >> 4,83
+统计剩余工时为5的任务数量 >> 5,83
+统计剩余工时为6的任务数量 >> 6,82
+统计剩余工时为7的任务数量 >> 7,82
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerLeftTest()) && p('0:name,value') && e('0,83'); //统计剩余工时为0的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('1:name,value') && e('1,83'); //统计剩余工时为1的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('2:name,value') && e('2,83'); //统计剩余工时为2的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('3:name,value') && e('3,83'); //统计剩余工时为3的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('4:name,value') && e('4,83'); //统计剩余工时为4的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('5:name,value') && e('5,83'); //统计剩余工时为5的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('6:name,value') && e('6,82'); //统计剩余工时为6的任务数量
+r($task->getDataOfTasksPerLeftTest()) && p('7:name,value') && e('7,82'); //统计剩余工时为7的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftaskspermodule.php b/module/task/test/model/getdataoftaskspermodule.php
new file mode 100755
index 0000000000..1fd41aff7f
--- /dev/null
+++ b/module/task/test/model/getdataoftaskspermodule.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getDataOfTasksPerModule();
+cid=1
+pid=1
+
+统计moduleID为21的模块的任务数量 >> /模块1,12
+统计moduleID为615的模块的任务数量 >> /模块595,2
+统计moduleID为504的模块的任务数量 >> /模块484,2
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerModuleTest()) && p('21:name,value') && e('/模块1,12'); //统计moduleID为21的模块的任务数量
+r($task->getDataOfTasksPerModuleTest()) && p('615:name,value') && e('/模块595,2'); //统计moduleID为615的模块的任务数量
+r($task->getDataOfTasksPerModuleTest()) && p('504:name,value') && e('/模块484,2'); //统计moduleID为504的模块的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperpri.php b/module/task/test/model/getdataoftasksperpri.php
new file mode 100755
index 0000000000..d17be4676a
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperpri.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getDataOfTasksPerPri();
+cid=1
+pid=1
+
+统计优先级为1的任务数量 >> 1,228
+统计优先级为2的任务数量 >> 2,228
+统计优先级为3的任务数量 >> 3,227
+统计优先级为4的任务数量 >> 4,227
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerPriTest()) && p('1:name,value') && e('1,228'); //统计优先级为1的任务数量
+r($task->getDataOfTasksPerPriTest()) && p('2:name,value') && e('2,228'); //统计优先级为2的任务数量
+r($task->getDataOfTasksPerPriTest()) && p('3:name,value') && e('3,227'); //统计优先级为3的任务数量
+r($task->getDataOfTasksPerPriTest()) && p('4:name,value') && e('4,227'); //统计优先级为4的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftasksperstatus.php b/module/task/test/model/getdataoftasksperstatus.php
new file mode 100755
index 0000000000..75cbc2f910
--- /dev/null
+++ b/module/task/test/model/getdataoftasksperstatus.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfTasksPerStatus();
+cid=1
+pid=1
+
+统计状态为已完成的任务数量 >> 已完成,152
+统计状态为未开始的任务数量 >> 未开始,152
+统计状态为进行中的任务数量 >> 进行中,152
+统计状态为已暂停的任务数量 >> 已暂停,152
+统计状态为已取消的任务数量 >> 已取消,151
+统计状态为已关闭的任务数量 >> 已关闭,151
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerStatusTest()) && p('done:name,value') && e('已完成,152'); //统计状态为已完成的任务数量
+r($task->getDataOfTasksPerStatusTest()) && p('wait:name,value') && e('未开始,152'); //统计状态为未开始的任务数量
+r($task->getDataOfTasksPerStatusTest()) && p('doing:name,value') && e('进行中,152'); //统计状态为进行中的任务数量
+r($task->getDataOfTasksPerStatusTest()) && p('pause:name,value') && e('已暂停,152'); //统计状态为已暂停的任务数量
+r($task->getDataOfTasksPerStatusTest()) && p('cancel:name,value') && e('已取消,151'); //统计状态为已取消的任务数量
+r($task->getDataOfTasksPerStatusTest()) && p('closed:name,value') && e('已关闭,151'); //统计状态为已关闭的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getdataoftaskspertype.php b/module/task/test/model/getdataoftaskspertype.php
new file mode 100755
index 0000000000..05d508cf32
--- /dev/null
+++ b/module/task/test/model/getdataoftaskspertype.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getDataOfTasksPerType();
+cid=1
+pid=1
+
+统计类型为devel的任务数量 >> 开发,115
+统计类型为study的任务数量 >> 研究,114
+统计类型为discuss的任务数量 >> 讨论,113
+统计类型为ui的任务数量 >> 界面,113
+
+*/
+
+$task = new taskTest();
+r($task->getDataOfTasksPerTypeTest()) && p('devel:name,value') && e('开发,115'); //统计类型为devel的任务数量
+r($task->getDataOfTasksPerTypeTest()) && p('study:name,value') && e('研究,114'); //统计类型为study的任务数量
+r($task->getDataOfTasksPerTypeTest()) && p('discuss:name,value') && e('讨论,113'); //统计类型为discuss的任务数量
+r($task->getDataOfTasksPerTypeTest()) && p('ui:name,value') && e('界面,113'); //统计类型为ui的任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getestimatebyid.php b/module/task/test/model/getestimatebyid.php
new file mode 100755
index 0000000000..873da3c815
--- /dev/null
+++ b/module/task/test/model/getestimatebyid.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getEstimateById();
+cid=1
+pid=1
+
+根据estimateID查看预计工时 >> 这里是工作内容1
+
+*/
+
+$estimateID = '1';
+
+$task = new taskTest();
+r($task->getEstimateByIdTest($estimateID)) && p('work') && e('这里是工作内容1'); // 根据estimateID查看预计工时
\ No newline at end of file
diff --git a/module/task/test/model/getexecutiontaskpairs.php b/module/task/test/model/getexecutiontaskpairs.php
new file mode 100755
index 0000000000..20faab3dc3
--- /dev/null
+++ b/module/task/test/model/getexecutiontaskpairs.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getExecutionTaskPairs();
+cid=1
+pid=1
+
+根据执行id查出任务id与name >> 2::开发任务12
+
+*/
+
+$executionID = '102';
+
+$task = new taskTest();
+r($task->getExecutionTaskPairsTest($executionID)) && p('2') && e('2::开发任务12'); //根据执行id查出任务id与name
\ No newline at end of file
diff --git a/module/task/test/model/getexecutiontasks.php b/module/task/test/model/getexecutiontasks.php
new file mode 100755
index 0000000000..a7026b7218
--- /dev/null
+++ b/module/task/test/model/getexecutiontasks.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getExecutionTasks();
+cid=1
+pid=1
+
+根据执行id获取任务列表 >> 开发任务11
+根据执行id获取任务数量 >> 4
+根据执行id,按pri升序获取第一个任务pri >> 3
+根据执行id,按pri降序获取第一个任务pri >> 1
+
+*/
+
+$executionID = '101';
+$productID = 0;
+$type = 'all';
+$modules = 0;
+$orderBy = array('status_asc, id_desc', 'pri_desc', 'pri_asc');
+$count = array('0','1');
+
+$task = new taskTest();
+$priDescTasks = $task->getExecutionTasksTest($executionID, $productID, $type, $modules, $orderBy[1]);
+$priAscTasks = $task->getExecutionTasksTest($executionID, $productID, $type, $modules, $orderBy[2]);
+
+r($task->getExecutionTasksTest($executionID)) && p('1:name') && e('开发任务11'); //根据执行id获取任务列表
+r($task->getExecutionTasksTest($executionID, $productID, $type, $modules, $orderBy[0], $count[1])) && p() && e('4'); //根据执行id获取任务数量
+r(array_shift($priDescTasks)) && p('pri') && e('3'); //根据执行id,按pri升序获取第一个任务pri
+r(array_shift($priAscTasks)) && p('pri') && e('1'); //根据执行id,按pri降序获取第一个任务pri
diff --git a/module/task/test/model/getfinishedusers.php b/module/task/test/model/getfinishedusers.php
new file mode 100755
index 0000000000..876fe67c58
--- /dev/null
+++ b/module/task/test/model/getfinishedusers.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getDataOfTasksPerEstimate();
+cid=1
+pid=1
+
+获取空数据 >> 0
+获取完成多人任务ID为1的人员 >> 0
+
+*/
+
+$task = new taskTest();
+
+$taskObject = $task->getByIDTest(1);
+
+r($task->getFinishedUsersTest()) && p() && e('0'); // 获取空数据
+r($task->getFinishedUsersTest($taskObject->id, $taskObject->team)) && p() && e('0'); // 获取完成多人任务ID为1的人员
\ No newline at end of file
diff --git a/module/task/test/model/getmemberpairs.php b/module/task/test/model/getmemberpairs.php
new file mode 100755
index 0000000000..e9a4ae4131
--- /dev/null
+++ b/module/task/test/model/getmemberpairs.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfTasksPerEstimate();
+cid=1
+pid=1
+
+获取taskid为1的团队人员 po82 >> P:研发主管82
+获取taskid为1的团队人员 user92 >> U:测试92
+获取taskid为1的团队人员数量 >> 3
+获取taskid为601的团队人员数量 >> 1
+获取taskid为不存在的100001的团队人员 >> 0
+
+*/
+
+$taskIDList = array('1', '601', '100001');
+
+$task = new taskTest();
+r($task->getMemberPairsTest($taskIDList[0])) && p('po82') && e('P:研发主管82'); //获取taskid为1的团队人员 po82
+r($task->getMemberPairsTest($taskIDList[0])) && p('user92') && e('U:测试92'); //获取taskid为1的团队人员 user92
+r($task->getMemberPairsTest($taskIDList[0])) && p('count') && e('3'); //获取taskid为1的团队人员数量
+r($task->getMemberPairsTest($taskIDList[1])) && p('count') && e('1'); //获取taskid为601的团队人员数量
+r($task->getMemberPairsTest($taskIDList[2])) && p() && e('0'); //获取taskid为不存在的100001的团队人员
\ No newline at end of file
diff --git a/module/task/test/model/getparenttaskpairs.php b/module/task/test/model/getparenttaskpairs.php
new file mode 100755
index 0000000000..b7df067b82
--- /dev/null
+++ b/module/task/test/model/getparenttaskpairs.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+getParentTaskPairs();
+cid=1
+pid=1
+
+查找有父任务的执行下的父任务 普通任务和特定任务601 >> 更多任务1
+查找有父任务的执行下的父任务 普通任务和特定任务602 >> 更多任务2
+查找有父任务的执行下的父任务 普通任务和特定任务603 >> 更多任务3
+查找有父任务的执行下的父任务 普通任务和特定任务11 >> 开发任务21
+查找有父任务的执行下的父任务 普通任务和特定任务22 >> 开发任务32
+查找有父任务的执行下的父任务 普通任务601 >> 更多任务1
+查找有父任务的执行下的父任务 普通任务602 >> 更多任务2
+查找有父任务的执行下的父任务 普通任务603 >> 更多任务3
+查找没有父任务的执行下的父任务 普通任务12 >> 开发任务12
+查找没有父任务的执行下的父任务 普通任务604 >> 更多任务4
+查找不是执行的父任务 >> 0
+查找不存在的执行下的父任务 >> 0
+
+*/
+
+$executionIDList = array('101','102','1','100001');
+$append = '11,22';
+
+$task = new taskTest();
+
+r($task->getParentTaskPairsTest($executionIDList[0], $append)) && p('601') && e('更多任务1'); // 查找有父任务的执行下的父任务 普通任务和特定任务601
+r($task->getParentTaskPairsTest($executionIDList[0], $append)) && p('602') && e('更多任务2'); // 查找有父任务的执行下的父任务 普通任务和特定任务602
+r($task->getParentTaskPairsTest($executionIDList[0], $append)) && p('603') && e('更多任务3'); // 查找有父任务的执行下的父任务 普通任务和特定任务603
+r($task->getParentTaskPairsTest($executionIDList[0], $append)) && p('11') && e('开发任务21');// 查找有父任务的执行下的父任务 普通任务和特定任务11
+r($task->getParentTaskPairsTest($executionIDList[0], $append)) && p('22') && e('开发任务32');// 查找有父任务的执行下的父任务 普通任务和特定任务22
+r($task->getParentTaskPairsTest($executionIDList[0])) && p('601') && e('更多任务1'); // 查找有父任务的执行下的父任务 普通任务601
+r($task->getParentTaskPairsTest($executionIDList[0])) && p('602') && e('更多任务2'); // 查找有父任务的执行下的父任务 普通任务602
+r($task->getParentTaskPairsTest($executionIDList[0])) && p('603') && e('更多任务3'); // 查找有父任务的执行下的父任务 普通任务603
+r($task->getParentTaskPairsTest($executionIDList[1])) && p('2') && e('开发任务12'); // 查找没有父任务的执行下的父任务 普通任务12
+r($task->getParentTaskPairsTest($executionIDList[1])) && p('604') && e('更多任务4'); // 查找没有父任务的执行下的父任务 普通任务604
+r($task->getParentTaskPairsTest($executionIDList[2])) && p('name') && e('0'); // 查找不是执行的父任务
+r($task->getParentTaskPairsTest($executionIDList[3])) && p('name') && e('0'); // 查找不存在的执行下的父任务
\ No newline at end of file
diff --git a/module/task/test/model/getprojectid.php b/module/task/test/model/getprojectid.php
new file mode 100755
index 0000000000..572a2b8c45
--- /dev/null
+++ b/module/task/test/model/getprojectid.php
@@ -0,0 +1,20 @@
+#!/usr/bin/env php
+getProjectID();
+cid=1
+pid=1
+
+根据executionID查找projectID >> 11
+
+*/
+
+$executionID = '101';
+
+$task = new taskTest();
+r($task->getProjectIDTest($executionID)) && p('project') && e('11'); //根据executionID查找projectID
\ No newline at end of file
diff --git a/module/task/test/model/getstorycomments.php b/module/task/test/model/getstorycomments.php
new file mode 100755
index 0000000000..4a931dc238
--- /dev/null
+++ b/module/task/test/model/getstorycomments.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getStoryComments();
+cid=1
+pid=1
+
+根据storyID查找comment >> 这是一个系统日志测试备注2
+根据不存在的storyID查找comment >> 0
+
+*/
+
+$storyIDList = array(2, 1000001);
+
+$task = new taskTest();
+r($task->getStoryCommentsTest($storyIDList[0])) && p('0:comment') && e('这是一个系统日志测试备注2'); //根据storyID查找comment
+r($task->getStoryCommentsTest($storyIDList[1])) && p('0:comment') && e('0'); //根据不存在的storyID查找comment
\ No newline at end of file
diff --git a/module/task/test/model/getstorytaskcounts.php b/module/task/test/model/getstorytaskcounts.php
new file mode 100755
index 0000000000..9cc332b82c
--- /dev/null
+++ b/module/task/test/model/getstorytaskcounts.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getStoryTaskCounts();
+cid=1
+pid=1
+
+根据需求1查看任务数量 >> 6
+根据需求5查看任务数量 >> 6
+根据需求9查看任务数量 >> 6
+
+*/
+
+$storyIDList = array('1','5','9');
+
+$task = new taskTest();
+r($task->getStoryTaskCountsTest($storyIDList)) && p('1') && e('6'); // 根据需求1查看任务数量
+r($task->getStoryTaskCountsTest($storyIDList)) && p('5') && e('6'); // 根据需求5查看任务数量
+r($task->getStoryTaskCountsTest($storyIDList)) && p('9') && e('6'); // 根据需求9查看任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getstorytasks.php b/module/task/test/model/getstorytasks.php
new file mode 100755
index 0000000000..2d8a852f07
--- /dev/null
+++ b/module/task/test/model/getstorytasks.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getStoryTasks();
+cid=1
+pid=1
+
+根据需求查看任务 >> 开发任务11
+根据需求查看任务数量统计 >> 6
+
+*/
+
+$storyID = '1';
+$count = array('0','1');
+
+$task = new taskTest();
+r($task->getStoryTasksTest($storyID,$count[0])) && p('1:name') && e('开发任务11'); // 根据需求查看任务
+r($task->getStoryTasksTest($storyID,$count[1])) && p() && e('6'); // 根据需求查看任务数量统计
\ No newline at end of file
diff --git a/module/task/test/model/gettaskestimate.php b/module/task/test/model/gettaskestimate.php
new file mode 100755
index 0000000000..f5546dbde0
--- /dev/null
+++ b/module/task/test/model/gettaskestimate.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getTaskEstimate();
+cid=1
+pid=1
+
+查看任务预计 >> 55
+
+*/
+
+$taskID = '55';
+$waitstart = array('assignedTo' => 'user92','consumed' => '10');
+
+$task = new taskTest();
+$task->startTest($taskID,$waitstart);
+r($task->getTaskEstimateTest($taskID)) && p('0:task') && e('55'); // 查看任务预计
\ No newline at end of file
diff --git a/module/task/test/model/gettasksbymodule.php b/module/task/test/model/gettasksbymodule.php
new file mode 100755
index 0000000000..bc1430630d
--- /dev/null
+++ b/module/task/test/model/gettasksbymodule.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getTasksByModule();
+cid=1
+pid=1
+
+根据模块获取任务列表 >> 子任务10
+根据模块获取任务数量 >> 1
+
+*/
+
+$executionID = '101';
+$moduleIdList = '21';
+
+$count = array('0','1');
+
+$task = new taskTest();
+r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[0])) && p('0:name') && e('子任务10'); //根据模块获取任务列表
+r($task->getTasksByModuleTest($executionID,$moduleIdList,$count[1])) && p() && e('1'); //根据模块获取任务数量
\ No newline at end of file
diff --git a/module/task/test/model/getteambyaccount.php b/module/task/test/model/getteambyaccount.php
new file mode 100644
index 0000000000..94949b5a72
--- /dev/null
+++ b/module/task/test/model/getteambyaccount.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+getTeamByAccount();
+cid=1
+pid=1
+
+获取未开始的指定账号的团队信息 >> admin_wait
+获取进行中的指定账号的团队信息 >> admin_doing
+过滤已完成的成员获取的指定账号的团队信息 >> admin_wait
+不过滤已完成的成员获取的指定账号的团队信息 >> admin_done
+获取的不存在账号 >> _
+
+*/
+
+$user = new stdclass();
+$user->account = 'admin';
+$user->status = 'wait';
+$user->order = '0';
+$users[] = $user;
+
+$user = new stdclass();
+$user->account = 'dev1';
+$user->status = 'wait';
+$user->order = '1';
+$users[] = $user;
+
+$user = new stdclass();
+$user->account = 'admin';
+$user->status = 'wait';
+$user->order = '2';
+$users[] = $user;
+
+$task = new taskTest();
+r($task->getTeamByAccount($users, 'admin')) && p() && e('admin_wait'); //获取未开始的指定账号的团队信息
+
+$users[0]->status = 'doing';
+r($task->getTeamByAccount($users, 'admin')) && p() && e('admin_doing'); //获取进行中的指定账号的团队信息
+
+$users[0]->status = 'done';
+r($task->getTeamByAccount($users, 'admin')) && p() && e('admin_wait'); //过滤已完成的成员获取的指定账号的团队信息
+r($task->getTeamByAccount($users, 'admin', array('filter' => ''))) && p() && e('admin_done'); //不过滤已完成的成员获取的指定账号的团队信息
+
+r($task->getTeamByAccount($users, 'dev')) && p() && e('_'); //获取的不存在账号
diff --git a/module/task/test/model/gettoandcclist.php b/module/task/test/model/gettoandcclist.php
new file mode 100755
index 0000000000..f82f53f786
--- /dev/null
+++ b/module/task/test/model/gettoandcclist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getToAndCcList();
+cid=1
+pid=1
+
+计算有assignedto 有mailto的发信列表2 >> po82
+计算有assignedto 有mailto的发信列表1 >> user1,user2,user3
+计算有assignedto 无mailto的发信列表2 >> po82
+计算有assignedto 无mailto的发信列表1 >> 0
+计算无assignedto 无mailto的发信列表 >> 0
+计算不存在的task的发信列表 >> 0
+
+*/
+$taskIDList = array('1', '601', '100001');
+
+$task = new taskTest();
+r($task->getToAndCcListTest($taskIDList[0])) && p('2') && e('po82'); //计算有assignedto 有mailto的发信列表2
+r($task->getToAndCcListTest($taskIDList[0])) && p('1') && e('user1,user2,user3'); //计算有assignedto 有mailto的发信列表1
+r($task->getToAndCcListTest($taskIDList[0], true)) && p('2') && e('po82'); //计算有assignedto 无mailto的发信列表2
+r($task->getToAndCcListTest($taskIDList[0], true)) && p('1') && e('0'); //计算有assignedto 无mailto的发信列表1
+r($task->getToAndCcListTest($taskIDList[1])) && p() && e('0'); //计算无assignedto 无mailto的发信列表
+r($task->getToAndCcListTest($taskIDList[2])) && p() && e('0'); //计算不存在的task的发信列表
\ No newline at end of file
diff --git a/module/task/test/model/getusersuspendedtasks.php b/module/task/test/model/getusersuspendedtasks.php
new file mode 100755
index 0000000000..788265d1f0
--- /dev/null
+++ b/module/task/test/model/getusersuspendedtasks.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getUserSuspendedTasks();
+cid=1
+pid=1
+
+根据指派人员查看执行和任务对应关系 >> 开发任务33
+
+*/
+
+$taskID = '23';
+$assignedTo = 'test14';
+
+$task = new taskTest();
+//var_dump($task->getUserSuspendedTasksTest($taskID,$assignedTo));die;
+r($task->getUserSuspendedTasksTest($taskID,$assignedTo)) && p(''.$taskID.':name') && e('开发任务33'); // 根据指派人员查看执行和任务对应关系
\ No newline at end of file
diff --git a/module/task/test/model/getusertaskpairs.php b/module/task/test/model/getusertaskpairs.php
new file mode 100755
index 0000000000..913385ec8f
--- /dev/null
+++ b/module/task/test/model/getusertaskpairs.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getUserTaskPairs();
+cid=1
+pid=1
+
+根据指派人员查看执行和任务对应关系 >> 迭代3 / 开发任务13
+
+*/
+
+$taskID = '3';
+$assignedTo = 'user95';
+
+$task = new taskTest();
+r($task->getUserTaskPairsTest($taskID,$assignedTo)) && p('3') && e('迭代3 / 开发任务13'); // 根据指派人员查看执行和任务对应关系
\ No newline at end of file
diff --git a/module/task/test/model/getusertasks.php b/module/task/test/model/getusertasks.php
new file mode 100755
index 0000000000..2400ba30ce
--- /dev/null
+++ b/module/task/test/model/getusertasks.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getUserTasks();
+cid=1
+pid=1
+
+根据指派人员查看任务 >> 开发任务12
+
+*/
+
+$taskID = '2';
+$assignedTo = 'user92';
+
+$task = new taskTest();
+r($task->getUserTasksTest($taskID,$assignedTo)) && p('2:name') && e('开发任务12'); // 根据指派人员查看任务
diff --git a/module/task/test/model/isclickable.php b/module/task/test/model/isclickable.php
new file mode 100755
index 0000000000..4b8c64580f
--- /dev/null
+++ b/module/task/test/model/isclickable.php
@@ -0,0 +1,124 @@
+#!/usr/bin/env php
+isClickable();
+cid=1
+pid=1
+
+计算任务为父任务 状态为wait 能否进行start操作 >> 1
+计算任务为父任务 状态为doing 能否进行finished操作 >> 1
+计算任务为父任务 状态为done 能否进行pause操作 >> 2
+计算任务为父任务 状态为pause 能否进行assignto操作 >> 1
+计算任务为父任务 状态为closed 能否进行close操作 >> 2
+计算任务为父任务 状态为cancel 能否进行batchcreate操作 >> 1
+计算任务为普通任务 状态为wait 能否进行recordestimate操作 >> 2
+计算任务为普通任务 状态为doing 能否进行delete操作 >> 2
+计算任务为普通任务 状态为done 能否进行start操作 >> 2
+计算任务为普通任务 状态为pause 能否进行finished操作 >> 1
+计算任务为普通任务 状态为closed 能否进行restart操作 >> 2
+计算任务为普通任务 状态为cancel 能否进行pause操作 >> 2
+计算任务为子任务 状态为wait 能否进行assignto操作 >> 1
+计算任务为子任务 状态为doing 能否进行close操作 >> 2
+计算任务为子任务 状态为done 能否进行batchcreate操作 >> 2
+计算任务为子任务 状态为pause 能否进行recordestimate操作 >> 1
+计算任务为子任务 状态为closed 能否进行delete操作 >> 1
+计算任务为子任务 状态为cancel 能否进行start操作 >> 2
+
+*/
+
+$task1 = new stdclass();
+$task1->parent = 0;
+$task1->status = 'wait';
+
+$task2 = new stdclass();
+$task2->parent = 0;
+$task2->status = 'doing';
+
+$task3 = new stdclass();
+$task3->parent = 0;
+$task3->status = 'done';
+
+$task4 = new stdclass();
+$task4->parent = 0;
+$task4->status = 'pause';
+
+$task5 = new stdclass();
+$task5->parent = 0;
+$task5->status = 'closed';
+
+$task6 = new stdclass();
+$task6->parent = 0;
+$task6->status = 'cancel';
+
+$task7 = new stdclass();
+$task7->parent = -1;
+$task7->status = 'wait';
+
+$task8 = new stdclass();
+$task8->parent = -1;
+$task8->status = 'doing';
+
+$task9 = new stdclass();
+$task9->parent = -1;
+$task9->status = 'done';
+
+$task10 = new stdclass();
+$task10->parent = -1;
+$task10->status = 'pause';
+
+$task11 = new stdclass();
+$task11->parent = -1;
+$task11->status = 'closed';
+
+$task12 = new stdclass();
+$task12->parent = -1;
+$task12->status = 'cancel';
+
+$task13 = new stdclass();
+$task13->parent = 1;
+$task13->status = 'wait';
+
+$task14 = new stdclass();
+$task14->parent = 1;
+$task14->status = 'doing';
+
+$task15 = new stdclass();
+$task15->parent = 1;
+$task15->status = 'done';
+
+$task16 = new stdclass();
+$task16->parent = 1;
+$task16->status = 'pause';
+
+$task17 = new stdclass();
+$task17->parent = 1;
+$task17->status = 'closed';
+
+$task18 = new stdclass();
+$task18->parent = 1;
+$task18->status = 'cancel';
+
+$task = new taskTest();
+r($task->isClickableTest($task1, 'start')) && p('1') && e("1"); //计算任务为父任务 状态为wait 能否进行start操作
+r($task->isClickableTest($task2, 'finished')) && p('1') && e("1"); //计算任务为父任务 状态为doing 能否进行finished操作
+r($task->isClickableTest($task3, 'pause')) && p('2') && e("2"); //计算任务为父任务 状态为done 能否进行pause操作
+r($task->isClickableTest($task4, 'assignto')) && p('1') && e("1"); //计算任务为父任务 状态为pause 能否进行assignto操作
+r($task->isClickableTest($task5, 'close')) && p('2') && e("2"); //计算任务为父任务 状态为closed 能否进行close操作
+r($task->isClickableTest($task6, 'batchcreate')) && p('1') && e("1"); //计算任务为父任务 状态为cancel 能否进行batchcreate操作
+r($task->isClickableTest($task7, 'recordestimate')) && p('2') && e("2"); //计算任务为普通任务 状态为wait 能否进行recordestimate操作
+r($task->isClickableTest($task8, 'delete')) && p('2') && e("2"); //计算任务为普通任务 状态为doing 能否进行delete操作
+r($task->isClickableTest($task9, 'start')) && p('2') && e("2"); //计算任务为普通任务 状态为done 能否进行start操作
+r($task->isClickableTest($task10, 'finished')) && p('1') && e("1"); //计算任务为普通任务 状态为pause 能否进行finished操作
+r($task->isClickableTest($task11, 'restart')) && p('2') && e("2"); //计算任务为普通任务 状态为closed 能否进行restart操作
+r($task->isClickableTest($task12, 'pause')) && p('2') && e("2"); //计算任务为普通任务 状态为cancel 能否进行pause操作
+r($task->isClickableTest($task13, 'assignto')) && p('1') && e("1"); //计算任务为子任务 状态为wait 能否进行assignto操作
+r($task->isClickableTest($task14, 'close')) && p('2') && e("2"); //计算任务为子任务 状态为doing 能否进行close操作
+r($task->isClickableTest($task15, 'batchcreate')) && p('2') && e("2"); //计算任务为子任务 状态为done 能否进行batchcreate操作
+r($task->isClickableTest($task16, 'recordestimate')) && p('1') && e("1"); //计算任务为子任务 状态为pause 能否进行recordestimate操作
+r($task->isClickableTest($task17, 'delete')) && p('1') && e("1"); //计算任务为子任务 状态为closed 能否进行delete操作
+r($task->isClickableTest($task18, 'start')) && p('2') && e("2"); //计算任务为子任务 状态为cancel 能否进行start操作
\ No newline at end of file
diff --git a/module/task/test/model/needupdatebugstatus.php b/module/task/test/model/needupdatebugstatus.php
new file mode 100755
index 0000000000..785a3204c9
--- /dev/null
+++ b/module/task/test/model/needupdatebugstatus.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+needUpdateBugStatus();
+cid=1
+pid=1
+
+计算不来源于bug的任务是否需要更新bug状态 >> 2
+计算来源于bug的任务是否需要更新bug状态 bug状态active >> 1
+计算来源于bug的任务是否需要更新bug状态 bug状态resolved >> 2
+
+*/
+
+$task1 = new stdclass();
+$task1->fromBug = 0;
+
+$task2 = new stdclass();
+$task2->fromBug = 1;
+
+$task3 = new stdclass();
+$task3->fromBug = 51;
+
+$task = new taskTest();
+r($task->needUpdateBugStatusTest($task1)) && p() && e('2'); //计算不来源于bug的任务是否需要更新bug状态
+r($task->needUpdateBugStatusTest($task2)) && p() && e('1'); //计算来源于bug的任务是否需要更新bug状态 bug状态active
+r($task->needUpdateBugStatusTest($task3)) && p() && e('2'); //计算来源于bug的任务是否需要更新bug状态 bug状态resolved
\ No newline at end of file
diff --git a/module/task/test/model/pause.php b/module/task/test/model/pause.php
new file mode 100755
index 0000000000..76886ea20b
--- /dev/null
+++ b/module/task/test/model/pause.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+pause();
+cid=1
+pid=1
+
+wait状态任务暂停 >> status,wait,pause
+doing状态任务暂停 >> status,doing,pause
+done状态任务暂停 >> status,done,pause
+cancel状态任务暂停 >> status,cancel,pause
+closed状态任务暂停 >> status,closed,pause
+
+*/
+
+$taskIDList = array('19','20','21','23','24');
+
+$task = new taskTest();
+r($task->pauseTest($taskIDList[0])) && p('0:field,old,new') && e('status,wait,pause'); //wait状态任务暂停
+r($task->pauseTest($taskIDList[1])) && p('0:field,old,new') && e('status,doing,pause'); //doing状态任务暂停
+r($task->pauseTest($taskIDList[2])) && p('0:field,old,new') && e('status,done,pause'); //done状态任务暂停
+r($task->pauseTest($taskIDList[3])) && p('0:field,old,new') && e('status,cancel,pause'); //cancel状态任务暂停
+r($task->pauseTest($taskIDList[4])) && p('0:field,old,new') && e('status,closed,pause'); //closed状态任务暂停
diff --git a/module/task/test/model/processdata4report.php b/module/task/test/model/processdata4report.php
new file mode 100755
index 0000000000..251826f765
--- /dev/null
+++ b/module/task/test/model/processdata4report.php
@@ -0,0 +1,58 @@
+#!/usr/bin/env php
+processData4Report();
+cid=1
+pid=1
+
+计算executionID为101的执行下按迭代任务数统计的图表数据 101 >> 101,14
+计算executionID为101的执行下按模块任务统计的图表数据 27 >> 27,1
+计算executionID为101的执行下按模块任务统计的图表数据 21 >> 21,12
+计算executionID为101的执行下按指派给统计的图表数据 >> po82,1
+计算executionID为101的执行下按任务类型统计的图表数据 ui >> ui,1
+计算executionID为101的执行下按任务类型统计的图表数据 test >> test,2
+计算executionID为101的执行下按优先级统计的图表数据 1 >> 1,5
+计算executionID为101的执行下按优先级统计的图表数据 2 >> 2,4
+计算executionID为101的执行下按任务状态统计的图表数据 -8day >> 2
+计算executionID为101的执行下按任务状态统计的图表数据 -15day >> 1
+计算executionID为101的执行下按截止时间统计的图表数据 0 >> 0,3
+计算executionID为101的执行下按截止时间统计的图表数据 5 >> 5,1
+计算executionID为101的执行下按预计时间统计的图表数据 0 >> 0,2
+计算executionID为101的执行下按预计时间统计的图表数据 6 >> 6,1
+计算executionID为101的执行下按剩余时间统计的图表数据 3 >> 3,2
+计算executionID为101的执行下按剩余时间统计的图表数据 7 >> 7,1
+计算executionID为101的执行下按消耗时间统计的图表数据 >> ,11
+计算executionID为101的执行下按由谁完成统计的图表数据 >> ,14
+计算executionID为101的执行下按关闭原因统计的图表数据 >> void
+计算executionID为101的执行下按每天完成统计的图表数据 wait >> wait,4
+计算executionID为101的执行下按每天完成统计的图表数据 done >> done,3
+
+*/
+
+$task = new taskTest();
+r($task->processData4ReportTest('', "execution")) && p('101:name,value') && e('101,14'); //计算executionID为101的执行下按迭代任务数统计的图表数据 101
+r($task->processData4ReportTest('', 'module')) && p('27:name,value') && e('27,1'); //计算executionID为101的执行下按模块任务统计的图表数据 27
+r($task->processData4ReportTest('', 'module')) && p('21:name,value') && e('21,12'); //计算executionID为101的执行下按模块任务统计的图表数据 21
+r($task->processData4ReportTest('', 'assignedTo')) && p('po82:name,value') && e('po82,1'); //计算executionID为101的执行下按指派给统计的图表数据
+r($task->processData4ReportTest('', 'type')) && p('ui:name,value') && e('ui,1'); //计算executionID为101的执行下按任务类型统计的图表数据 ui
+r($task->processData4ReportTest('', 'type')) && p('test:name,value') && e('test,2'); //计算executionID为101的执行下按任务类型统计的图表数据 test
+r($task->processData4ReportTest('', 'pri')) && p('1:name,value') && e('1,5'); //计算executionID为101的执行下按优先级统计的图表数据 1
+r($task->processData4ReportTest('', 'pri')) && p('2:name,value') && e('2,4'); //计算executionID为101的执行下按优先级统计的图表数据 2
+r($task->processData4ReportTest('', 'deadline')) && p('0:value') && e("2"); //计算executionID为101的执行下按任务状态统计的图表数据 -8day
+r($task->processData4ReportTest('', 'deadline')) && p('1:value') && e("1"); //计算executionID为101的执行下按任务状态统计的图表数据 -15day
+r($task->processData4ReportTest('', 'estimate')) && p('0:name,value') && e('0,3'); //计算executionID为101的执行下按截止时间统计的图表数据 0
+r($task->processData4ReportTest('', 'estimate')) && p('5:name,value') && e('5,1'); //计算executionID为101的执行下按截止时间统计的图表数据 5
+r($task->processData4ReportTest('1', 'left')) && p('0:name,value') && e('0,2'); //计算executionID为101的执行下按预计时间统计的图表数据 0
+r($task->processData4ReportTest('1', 'left')) && p('6:name,value') && e('6,1'); //计算executionID为101的执行下按预计时间统计的图表数据 6
+r($task->processData4ReportTest('1', 'consumed')) && p('3:name,value') && e('3,2'); //计算executionID为101的执行下按剩余时间统计的图表数据 3
+r($task->processData4ReportTest('1', 'consumed')) && p('7:name,value') && e('7,1'); //计算executionID为101的执行下按剩余时间统计的图表数据 7
+r($task->processData4ReportTest('1', 'finishedBy')) && p('void:name,value') && e(',11'); //计算executionID为101的执行下按消耗时间统计的图表数据
+r($task->processData4ReportTest('', 'closedReason')) && p('void:name,value') && e(',14'); //计算executionID为101的执行下按由谁完成统计的图表数据
+r($task->processData4ReportTest('', 'date')) && p('void') && e('void'); //计算executionID为101的执行下按关闭原因统计的图表数据
+r($task->processData4ReportTest('', 'status')) && p('wait:name,value') && e('wait,4'); //计算executionID为101的执行下按每天完成统计的图表数据 wait
+r($task->processData4ReportTest('', 'status')) && p('done:name,value') && e('done,3'); //计算executionID为101的执行下按每天完成统计的图表数据 done
\ No newline at end of file
diff --git a/module/task/test/model/processtask.php b/module/task/test/model/processtask.php
new file mode 100755
index 0000000000..58c71bc27d
--- /dev/null
+++ b/module/task/test/model/processtask.php
@@ -0,0 +1,94 @@
+#!/usr/bin/env php
+processTask();
+cid=1
+pid=1
+
+根据taskID计算wait 未延迟的任务进度 >> ,,normal,75
+根据taskID计算wait 延迟的任务进度 >> 1,,normal,75
+根据taskID计算doing 延迟的任务进度 >> 1,,normal,80
+根据taskID计算doing 未延迟的任务进度 >> ,,normal,80
+根据taskID计算done 延迟的任务进度 >> ,,normal,100
+根据taskID计算算done 未延迟的任务进度 >> ,,normal,100
+
+*/
+
+$task1 = new stdclass();
+$task1->status = 'wait';
+$task1->deadline = '+1day';
+$task1->storyStatus = 'draft';
+$task1->latestStoryVersion = '1';
+$task1->storyVersion = '1';
+$task1->product = '1';
+$task1->assignedTo = 'po82';
+$task1->consumed = '3';
+$task1->left = '1';
+
+$task2 = new stdclass();
+$task2->status = 'doing';
+$task2->deadline = '-1day';
+$task2->storyStatus = 'draft';
+$task2->latestStoryVersion = '1';
+$task2->storyVersion = '1';
+$task2->product = '9';
+$task2->assignedTo = '';
+$task2->consumed = '3';
+$task2->left = '1';
+
+$task3 = new stdclass();
+$task3->status = 'doing';
+$task3->deadline = '-1day';
+$task3->storyStatus = 'draft';
+$task3->latestStoryVersion = '1';
+$task3->storyVersion = '1';
+$task3->product = '2';
+$task3->assignedTo = '';
+$task3->consumed = '4';
+$task3->left = '1';
+
+$task4 = new stdclass();
+$task4->status = 'doing';
+$task4->deadline = '+1day';
+$task4->storyStatus = 'draft';
+$task4->latestStoryVersion = '1';
+$task4->storyVersion = '1';
+$task4->product = '2';
+$task4->assignedTo = '';
+$task4->consumed = '4';
+$task4->left = '1';
+
+$task5 = new stdclass();
+$task5->status = 'done';
+$task5->deadline = '-1day';
+$task5->storyStatus = 'draft';
+$task5->latestStoryVersion = '1';
+$task5->storyVersion = '1';
+$task5->product = '9';
+$task5->assignedTo = '';
+$task5->consumed = '11';
+$task5->left = '0';
+
+$task6 = new stdclass();
+$task6->status = 'done';
+$task6->deadline = '+1day';
+$task6->storyStatus = 'draft';
+$task6->latestStoryVersion = '1';
+$task6->storyVersion = '1';
+$task6->product = '9';
+$task6->assignedTo = '';
+$task6->consumed = '11';
+$task6->left = '0';
+
+$task = new taskTest();
+r($task->processTaskTest($task1)) && p('delay,needConfirm,productType,progress') && e(',,normal,75'); //根据taskID计算wait 未延迟的任务进度
+r($task->processTaskTest($task2)) && p('delay,needConfirm,productType,progress') && e('1,,normal,75'); //根据taskID计算wait 延迟的任务进度
+r($task->processTaskTest($task3)) && p('delay,needConfirm,productType,progress') && e('1,,normal,80'); //根据taskID计算doing 延迟的任务进度
+r($task->processTaskTest($task4)) && p('delay,needConfirm,productType,progress') && e(',,normal,80'); //根据taskID计算doing 未延迟的任务进度
+r($task->processTaskTest($task5)) && p('delay,needConfirm,productType,progress') && e(',,normal,100'); //根据taskID计算done 延迟的任务进度
+r($task->processTaskTest($task6)) && p('delay,needConfirm,productType,progress') && e(',,normal,100'); //根据taskID计算算done 未延迟的任务进度
\ No newline at end of file
diff --git a/module/task/test/model/processtasks.php b/module/task/test/model/processtasks.php
new file mode 100755
index 0000000000..a07dc93b6c
--- /dev/null
+++ b/module/task/test/model/processtasks.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+processTasks();
+cid=1
+pid=1
+
+根据tasks计算executionID为1的执行下所有任务的进度 任务1 >> ,100
+根据tasks计算executionID为1的执行下所有任务的进度 任务601 >> 7,100
+根据tasks计算executionID为1的执行下所有任务的进度 任务602 >> 8,80
+根据tasks计算executionID为1的执行下所有任务的进度 任务603 >> ,71
+根据tasks计算executionID为2的执行下所有任务的进度 任务2 >> ,80
+根据tasks计算executionID为2的执行下所有任务的进度 任务604 >> 10,67
+根据tasks计算executionID为2的执行下所有任务的进度 任务605 >> ,64
+根据tasks计算executionID为2的执行下所有任务的进度 任务606 >> ,62
+
+*/
+
+$executionID = array('101', '102');
+
+$task = new taskTest();
+r($task->processTasksTest($executionID['0'])) && p('1:delay,progress') && e(',100'); //根据tasks计算executionID为1的执行下所有任务的进度 任务1
+r($task->processTasksTest($executionID['0'])) && p('601:delay,progress') && e('7,100'); //根据tasks计算executionID为1的执行下所有任务的进度 任务601
+r($task->processTasksTest($executionID['0'])) && p('602:delay,progress') && e('8,80'); //根据tasks计算executionID为1的执行下所有任务的进度 任务602
+r($task->processTasksTest($executionID['0'])) && p('603:delay,progress') && e(',71'); //根据tasks计算executionID为1的执行下所有任务的进度 任务603
+r($task->processTasksTest($executionID['1'])) && p('2:delay,progress') && e(',80'); //根据tasks计算executionID为2的执行下所有任务的进度 任务2
+r($task->processTasksTest($executionID['1'])) && p('604:delay,progress') && e('10,67'); //根据tasks计算executionID为2的执行下所有任务的进度 任务604
+r($task->processTasksTest($executionID['1'])) && p('605:delay,progress') && e(',64'); //根据tasks计算executionID为2的执行下所有任务的进度 任务605
+r($task->processTasksTest($executionID['1'])) && p('606:delay,progress') && e(',62'); //根据tasks计算executionID为2的执行下所有任务的进度 任务606
\ No newline at end of file
diff --git a/module/task/test/model/recordestimate.php b/module/task/test/model/recordestimate.php
new file mode 100755
index 0000000000..7cfb00cf7a
--- /dev/null
+++ b/module/task/test/model/recordestimate.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+recordEstimate();
+cid=1
+pid=1
+
+正常记录工时 >> status,wait,doing
+pause任务记录工时 >> status,pause,doing
+
+*/
+$taskIDList = array('1','4');
+
+$consumed = array('2','','');
+$left = array('1','','');
+$work = array('测试','','');
+
+$create = array('consumed' => $consumed, 'left' => $left, 'work' => $work);
+
+$task = new taskTest('admin');
+r($task->recordEstimateTest($taskIDList[0],$create)) && p('2:field,old,new') && e('status,wait,doing'); // 正常记录工时
+r($task->recordEstimateTest($taskIDList[1],$create)) && p('2:field,old,new') && e('status,pause,doing'); // pause任务记录工时
diff --git a/module/task/test/model/start.php b/module/task/test/model/start.php
new file mode 100755
index 0000000000..3ac0ac5b46
--- /dev/null
+++ b/module/task/test/model/start.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+startTest();
+cid=1
+pid=1
+
+wait状态任务开始 >> status,wait,doing
+doing状态任务开始 >> 此任务已被启动,不能重复启动!
+pause状态任务开始 >> status,pause,doing
+closed状态任务开始 >> status,closed,doing
+
+*/
+
+$taskIDList = array('1','4','6');
+
+$waitstart = array('assignedTo' => 'user92','consumed' => '10');
+$pausestart = array('assignedTo' => 'user95','consumed' => '10');
+$closedstart = array('assignedTo' => 'user97','consumed' => '10');
+
+$task = new taskTest();
+r($task->startTest($taskIDList[0],$waitstart)) && p('0:field,old,new') && e('status,wait,doing'); // wait状态任务开始
+r($task->startTest($taskIDList[0],$waitstart)) && p() && e('此任务已被启动,不能重复启动!'); // doing状态任务开始
+r($task->startTest($taskIDList[1],$pausestart)) && p('0:field,old,new') && e('status,pause,doing'); // pause状态任务开始
+r($task->startTest($taskIDList[2],$closedstart)) && p('0:field,old,new') && e('status,closed,doing'); // closed状态任务开始
diff --git a/module/task/test/model/update.php b/module/task/test/model/update.php
new file mode 100755
index 0000000000..f4099b9491
--- /dev/null
+++ b/module/task/test/model/update.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试修改任务名称 >> name,开发任务11,任务名修改
+测试无修改 >> 没有数据更新
+测试修改任务模块 >> module,24,25
+测试修改任务指派人 >> assignedTo,,user94
+测试修改任务类型 >> type,study,devel
+测试修改任务状态 >> status,cancel,doing
+测试修改任务优先级 >> pri,2,1
+测试修改任务所属执行 >> execution,107,101
+测试修改任务截止时间 >> deadline,2022-03-29
+测试修改任务关闭原因 >> 『关闭原因』必须为空。
+
+*/
+
+$deadline = '2022-03-29';
+$taskIDList = array('1','2','3','4','5','6','7','8','9');
+
+$changename = array('name' => '任务名修改','deadline' => $deadline);
+$changemodule = array('module' => '25');
+$changeassign = array('assignedTo' => 'user94');
+$changetype = array('type' => 'devel');
+$changestatus = array('status' => 'doing');
+$changepri = array('pri' => '1');
+$changeexecution = array('execution' => '101');
+$changedeadline = array('deadline' => $deadline);
+$ckclosedReason = array('closedReason' => '关闭原因');
+
+$today = helper::today();
+$oldDeadline = $dao->select("date_sub('$today', interval 1 day) as date")->fetch()->date;
+
+$task = new taskTest();
+r($task->updateObject($taskIDList[0], $changename)) && p('1:field,old,new') && e('name,开发任务11,任务名修改'); // 测试修改任务名称
+r($task->updateObject($taskIDList[0], $changename)) && p() && e('没有数据更新'); // 测试无修改
+r($task->updateObject($taskIDList[1], $changemodule)) && p('0:field,old,new') && e('module,24,25'); // 测试修改任务模块
+r($task->updateObject($taskIDList[2], $changeassign)) && p('1:field,old,new') && e('assignedTo,,user94'); // 测试修改任务指派人
+r($task->updateObject($taskIDList[3], $changetype)) && p('0:field,old,new') && e('type,study,devel'); // 测试修改任务类型
+r($task->updateObject($taskIDList[4], $changestatus)) && p('0:field,old,new') && e('status,cancel,doing'); // 测试修改任务状态
+r($task->updateObject($taskIDList[5], $changepri)) && p('0:field,old,new') && e('pri,2,1'); // 测试修改任务优先级
+r($task->updateObject($taskIDList[6], $changeexecution)) && p('0:field,old,new') && e('execution,107,101'); // 测试修改任务所属执行
+r($task->updateObject($taskIDList[8], $changedeadline)) && p('0:field,new') && e("deadline,2022-03-29"); // 测试修改任务截止时间
+r($task->updateObject($taskIDList[0], $ckclosedReason)) && p('closedReason:0') && e(' 『关闭原因』必须为空。'); // 测试修改任务关闭原因
+
diff --git a/module/task/test/model/updateestimate.php b/module/task/test/model/updateestimate.php
new file mode 100755
index 0000000000..69d3bcdbfd
--- /dev/null
+++ b/module/task/test/model/updateestimate.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+updateEstimate();
+cid=1
+pid=1
+
+根据estimateID查看预计工时 >> consumed,4,1
+根据estimateID查看预计工时 >> consumed,1,5
+根据estimateID查看预计工时 >> consumed,5,1
+根据estimateID查看预计工时 >> status,doing,done
+
+*/
+
+$estimateID = '2';
+
+$updateDate = array('date' => '2022-02-22');
+$updateConsumed = array('consumed' => '5');
+$updateLeft = array('left' => '1');
+$noLeft = array('left' => '0');
+
+$task = new taskTest();
+r($task->updateEstimateTest($estimateID, $updateDate)) && p('0:field,old,new') && e('consumed,4,1'); // 根据estimateID查看预计工时
+r($task->updateEstimateTest($estimateID, $updateConsumed)) && p('0:field,old,new') && e('consumed,1,5'); // 根据estimateID查看预计工时
+r($task->updateEstimateTest($estimateID, $updateLeft)) && p('0:field,old,new') && e('consumed,5,1'); // 根据estimateID查看预计工时
+r($task->updateEstimateTest($estimateID, $noLeft)) && p('1:field,old,new') && e('status,doing,done'); // 根据estimateID查看预计工时
diff --git a/module/task/test/model/updateparentstatus.php b/module/task/test/model/updateparentstatus.php
new file mode 100755
index 0000000000..1b37c39b70
--- /dev/null
+++ b/module/task/test/model/updateparentstatus.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+updateParentStatus();
+cid=1
+pid=1
+
+更新任务ID为1 创建动态的任务的父任务 >> 1
+更新任务ID为601 创建动态的任务的父任务 >> 1
+更新任务ID为601 父ID为601 创建动态的任务的父任务 >> doing,更多任务1
+更新任务ID为901 创建动态的任务的父任务 >> wait,子任务1
+更新任务ID为901 父ID为601 创建动态的任务的父任务 >> wait,子任务1
+更新任务ID为901 父ID为601 不创建动态的任务的父任务 >> wait,子任务1
+更新任务ID为901 父ID为902 创建动态的任务的父任务 >> 1
+更新任务ID为不存在的100001 父ID为601 创建动态的任务的父任务 >> 0
+更新任务ID为不存在的100001 父ID为601 不创建动态的任务的父任务 >> 0
+更新任务ID为不存在的100001 父ID为902 创建动态的任务的父任务 >> 1
+
+*/
+
+$taskIDList = array('1', '601', '901', '100001');
+$parentIDList = array('601', '902');
+
+$task = new taskTest();
+r($task->updateParentStatusTest($taskIDList[0])) && p('status,name') && e('1'); //更新任务ID为1 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[1])) && p('status,name') && e('1'); //更新任务ID为601 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[1], $parentIDList[0])) && p('status,name') && e('doing,更多任务1'); //更新任务ID为601 父ID为601 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[2])) && p('status,name') && e('wait,子任务1'); //更新任务ID为901 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[2], $parentIDList[0])) && p('status,name') && e('wait,子任务1'); //更新任务ID为901 父ID为601 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[2], $parentIDList[0], false)) && p('status,name') && e('wait,子任务1'); //更新任务ID为901 父ID为601 不创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[2], $parentIDList[1])) && p('status,name') && e('1'); //更新任务ID为901 父ID为902 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[3], $parentIDList[0])) && p('status,name') && e('0'); //更新任务ID为不存在的100001 父ID为601 创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[3], $parentIDList[0], false)) && p('status,name') && e('0'); //更新任务ID为不存在的100001 父ID为601 不创建动态的任务的父任务
+r($task->updateParentStatusTest($taskIDList[3], $parentIDList[1])) && p('status,name') && e('1'); //更新任务ID为不存在的100001 父ID为902 创建动态的任务的父任务
diff --git a/module/task/test/task.class.php b/module/task/test/task.class.php
new file mode 100644
index 0000000000..0a6fb333f3
--- /dev/null
+++ b/module/task/test/task.class.php
@@ -0,0 +1,1511 @@
+objectModel = $tester->loadModel('task');
+ }
+
+ /**
+ * Test create a task.
+ *
+ * @param array $param
+ * @param int $executionID
+ * @access public
+ * @return object
+ */
+ public function createObject($param = array(), $executionID = '', $bugID = '')
+ {
+ $assignedTo = array('');
+ $createFields = array('module' => '', 'story' => '', 'name' => '', 'type' => '', 'assignedTo' => $assignedTo,
+ 'pri' => 3, 'estimate' => '', 'estStarted' => '2021-01-10', 'deadline' => '2021-03-19', 'desc' => '');
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $object = $this->objectModel->create($executionID, $bugID);
+ if (in_array('user92', $_POST['assignedTo'], true))
+ {
+ $objectID = $object['user92']['id'];
+ }
+ else
+ {
+ $objectID = $object['']['id'];
+ }
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getByID($objectID);
+ return $object;
+ }
+ }
+
+ /**
+ * Test update a task.
+ *
+ * @param int $objectID
+ * @param array $param
+ * @access public
+ * @return array|string
+ */
+ public function updateObject($objectID, $param = array())
+ {
+ global $tester;
+ $object = $tester->dbh->query("SELECT `parent`,`estStarted`,`deadline`,`execution`,`module`,`name`,`type`,`pri`,`estimate`,`consumed`,`left`,`status`,
+ `color`,`desc`,`assignedTo`,`realStarted`,`finishedBy`,`canceledBy`,`closedReason` FROM zt_task WHERE id = $objectID")->fetch();
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $this->objectModel->update($objectID);
+ if($change == array()) $change = '没有数据更新';
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $change;
+ }
+ }
+
+ /**
+ * Test batch create tasks.
+ *
+ * @param array $param
+ * @param int $executionID
+ * @access public
+ * @return object
+ */
+ public function batchCreateObject($param = array(), $executionID = '')
+ {
+ $modul = array('','','');
+ $parent = array('0','0','0');
+ $name = array('','','');
+ $type = array('','','');
+ $assignedTo = array('','','');
+ $story =array('','','');
+ $pri = array('3','3','3');
+ $color = array('','','');
+ $desc = array('','','');
+ $estimate = array('','','');
+ $createFields = array('parent' => $parent, 'module' => $modul, 'name' => $name, 'type' => $type, 'assignedTo' => $assignedTo,
+ 'pri' => $pri, 'story' => $story, 'color' => $color, 'desc' => $desc ,'estimate' => $estimate);
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $object = $this->objectModel->batchCreate($executionID);
+ if (in_array('批量任务三', $_POST['name'], true))
+ {
+ $objectID = $object[2]->taskID;
+ }
+ else
+ {
+ $objectID = $object[0];
+ }
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getByID($objectID);
+ return $object;
+ }
+ }
+
+ /**
+ * Test batch update tasks.
+ *
+ * @param array $param
+ * @param int $taskID
+ * @access public
+ * @return array
+ */
+ public function batchUpdateObject($param = array(), $taskID = '')
+ {
+ $taskIDList = array($taskID => $taskID);
+ $colors = array($taskID =>'#ff4e3e');
+ $name = array($taskID =>'');
+ $modules = array($taskID => '0');
+ $assignedTos = array($taskID =>'');
+ $types =array($taskID => '');
+ $statuses = array($taskID =>'wait');
+ $estStarteds = array($taskID => '');
+ $deadlines = array($taskID => '');
+ $pris = array($taskID => '3');
+ $finishedBys = array($taskID => '');
+ $canceledBys = array($taskID => '');
+ $closedBys = array($taskID => '');
+ $closedReasons = array($taskID => '');
+ $consumeds = array($taskID => '');
+ $lefts = array($taskID => '');
+ $createFields = array('taskIDList' => $taskIDList, 'modules' => $modules, 'names' => $name, 'types' => $types, 'assignedTos' => $assignedTos,
+ 'pris' => $pris, 'estStarteds' => $estStarteds, 'colors' => $colors, 'deadlines' => $deadlines, 'statuses' => $statuses, 'finishedBys'=>$finishedBys,
+ 'canceledBys' => $canceledBys, 'closedBys' => $closedBys, 'closedReasons' => $closedReasons, 'consumeds' => $consumeds, 'lefts'=> $lefts);
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $object = $this->objectModel->batchUpdate();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $object[$taskID];
+ return $object;
+ }
+ }
+
+ /**
+ * Test batch change module.
+ *
+ * @param array $taskIDList
+ * @param int $moduleID
+ * @access public
+ * @return array
+ */
+ public function batchChangeModuleTest($taskIDList, $moduleID)
+ {
+ $object = $this->objectModel->batchChangeModule($taskIDList, $moduleID);
+ return $object[1];
+ }
+
+ public function startTest($taskID, $param = array())
+ {
+ $createFields = array( 'status' => 'doing', 'consumed' => '9', 'assignedTo' => '', 'comment' => '9', 'realStarted' => '', 'left' => '3');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $obj = $this->objectModel->start($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ if ($error[0] = "此任务已被启动,不能重复启动!")
+ {
+ return $error[0];
+ }
+ else
+ {
+ return $error;
+ }
+ }
+ else
+ {
+ return $obj;
+ }
+ }
+
+ /**
+ * Test record estimate and left of task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function recordEstimateTest($taskID, $param = array())
+ {
+ $todate = date("Y-m-d");
+ $id = array('1','2','3');
+ $dates = array($todate, $todate, $todate);
+ $consumed = array('','','');
+ $left = array('','','');
+ $work = array('','','');
+ $createFields = array('id' => $id, 'dates' => $dates, 'consumed' => $consumed, 'left' => $left, 'work' => $work);
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->recordEstimate($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test activate a task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function activateTest($taskID, $param = array())
+ {
+ $createFields = array('status' => 'doing', 'comment' => '单元测试','assignedTo' => '', 'left' => '3');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->activate($taskID, $extra = '');
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test assign a task to a user again.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function assignTest($taskID, $param = array())
+ {
+ $createFields = array('assignedTo' => '', 'status' => '', 'comment' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->assign($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test cancel a task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function cancelTest($taskID, $param = array())
+ {
+ $createFields = array('status' => 'cancel', 'comment' => '单元测试');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->cancel($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test close a task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function closeTest($taskID, $param = array())
+ {
+ $createFields = array('status' => 'closed', 'comment' => '单元测试');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->close($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test finish a task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function finishTest($taskID, $param = array())
+ {
+ $todate = date("Y-m-d h:i:s");
+ $labels = array('');
+ $createFields = array('status' => 'done', 'currentConsumed' => '', 'realStarted' => '2020-01-17 17:07:07', 'consumed' => '',
+ 'assignedTo' => '', 'finishedDate' => $todate, 'labels' => $labels, 'comment' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->finish($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get task info by Id.
+ *
+ * @param int $taskID
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($taskID)
+ {
+ $object = $this->objectModel->getById($taskID);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get task info by Id List.
+ *
+ * @param int|array|string $taskID
+ * @access public
+ * @return array
+ */
+ public function getByListTest($taskID)
+ {
+ $object = $this->objectModel->getByList($taskID);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get execution tasks pairs..
+ *
+ * @param int $executionID
+ * @access public
+ * @return array
+ */
+ public function getExecutionTaskPairsTest($executionID)
+ {
+ $object = $this->objectModel->getExecutionTaskPairs($executionID);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get tasks of a execution.
+ *
+ * @param int $executionID
+ * @param int $productID
+ * @param string $type
+ * @param string $modules
+ * @param string $orderBy
+ * @param string $count
+ * @access public
+ * @return array
+ */
+ public function getExecutionTasksTest($executionID, $productID = 0, $type = 'all', $modules = 0, $orderBy = 'status_asc, id_desc', $count = '0')
+ {
+ $object = $this->objectModel->getExecutionTasks($executionID, $productID, $type, $modules, $orderBy);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ elseif($count == "1")
+ {
+ return count($object);
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get tasks list of a execution.
+ *
+ * @param int $executionID
+ * @param array $moduleIdList
+ * @param int $count
+ * @access public
+ * @return array
+ */
+ public function getTasksByModuleTest($executionID, $moduleIdList, $count)
+ {
+ $object = $this->objectModel->getTasksByModule($executionID, $moduleIdList);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ elseif($count == "1")
+ {
+ return count($object);
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get tasks of a user.
+ *
+ * @param int $taskID
+ * @param string $assignedTo
+ * @access public
+ * @return array
+ */
+ public function getUserTasksTest($taskID, $assignedTo)
+ {
+ $createFields = array('assignedTo' => $assignedTo, 'status' => 'doing', 'comment' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ $this->objectModel->assign($taskID);
+ $object = $this->objectModel->getUserTasks($assignedTo);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test pause a task.
+ *
+ * @param int $taskID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function pauseTest($taskID, $param = array())
+ {
+ $createFields = array('status' => 'pause', 'comment' => '单元测试');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->pause($taskID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get tasks pairs of a user.
+ *
+ * @param int $taskID
+ * @param string $assignedTo
+ * @access public
+ * @return array
+ */
+ public function getUserTaskPairsTest($taskID, $assignedTo)
+ {
+ $createFields = array('assignedTo' => $assignedTo, 'status' => 'doing', 'comment' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ $this->objectModel->assign($taskID);
+ $object = $this->objectModel->getUserTaskPairs($assignedTo);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get suspended tasks of a user.
+ *
+ * @param int $taskID
+ * @param string $assignedTo
+ * @access public
+ * @return array
+ */
+ public function getUserSuspendedTasksTest($taskID, $assignedTo)
+ {
+ $createFields = array('assignedTo' => $assignedTo, 'status' => 'doing', 'comment' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ $this->objectModel->assign($taskID);
+ $object = $this->objectModel->getUserSuspendedTasks($assignedTo);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get task pairs of a story.
+ *
+ * @param int $storyID
+ * @param int $count
+ * @access public
+ * @return array
+ */
+ public function getStoryTasksTest($storyID, $count)
+ {
+ $object = $this->objectModel->getStoryTasks($storyID);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ elseif($count == "1")
+ {
+ return count($object);
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get counts of some stories' tasks.
+ *
+ * @param array $storyIDList
+ * @access public
+ * @return int
+ */
+ public function getStoryTaskCountsTest($storyIDList)
+ {
+ $object = $this->objectModel->getStoryTaskCounts($storyIDList);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get task estimate.
+ *
+ * @param int $taskID
+ * @param string $account
+ * @param string $append
+ * @access public
+ * @return object
+ */
+ public function getTaskEstimateTest($taskID, $account = '', $append = '')
+ {
+ $object = $this->objectModel->getTaskEstimate($taskID, $account, $append);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get estimate by id.
+ *
+ * @param int $estimateID
+ * @access public
+ * @return object
+ */
+ public function getEstimateByIdTest($estimateID)
+ {
+ $object = $this->objectModel->getEstimateById($estimateID);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error;
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test update estimate.
+ *
+ * @param int $estimateID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateEstimateTest($estimateID, $param = array())
+ {
+ $createFields = array('date' => '0000-00-00', 'consumed' => '1', 'left' => '1', 'work' => '这里是工作内容1');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->updateEstimate($estimateID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test delete estimate.
+ *
+ * @param int $estimateID
+ * @access public
+ * @return array
+ */
+ public function deleteEstimateTest($estimateID)
+ {
+ $object = $this->objectModel->deleteEstimate($estimateID);
+ unset($_POST);
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test create task from gitlab issue.
+ *
+ * @param array $task
+ * @param int $executionID
+ * @access public
+ * @return int
+ */
+ public function createTaskFromGitlabIssueTest($task, $executionID)
+ {
+ $objectID = $this->objectModel->createTaskFromGitlabIssue($task, $executionID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getById($objectID);
+ return $object;
+ }
+ }
+
+ /**
+ * Test get project id by execution id.
+ *
+ * @param int $executionID
+ * @access public
+ * @return array
+ */
+ public function getProjectIDTest($executionID)
+ {
+ $object = $this->objectModel->getProjectID($executionID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get story comments.
+ *
+ * @param int $storyID
+ * @access public
+ * @return array
+ */
+ public function getStoryCommentsTest($storyID)
+ {
+ $object = $this->objectModel->getStoryComments($storyID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test compute parent task working hours.
+ *
+ * @param int $taskID
+ * @access public
+ * @return object
+ */
+ public function computeWorkingHoursTest($taskID)
+ {
+ $result = $this->objectModel->computeWorkingHours($taskID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getById($taskID);
+ if(!empty($object) and $object->parent > 0) $parentObject = $this->objectModel->getById($object->parent);
+ return isset($parentObject) ? $parentObject : $object;
+ }
+ }
+
+ /**
+ * Test compute begin and end for parent task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return array
+ */
+ public function computeBeginAndEndTest($taskID)
+ {
+ $result = $this->objectModel->computeBeginAndEnd($taskID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getById($taskID);
+
+ if(empty($object)) return 0;
+
+ if($object->parent > 0) $object = $this->objectModel->getById($object->parent);
+
+
+ $estStartedDiff = date_diff(date_create($object->estStarted), date_create(helper::now()));
+ $deadlineDiff = date_diff(date_create($object->deadline), date_create(helper::now()));
+ return array('estStartedDiff' => $estStartedDiff->d, 'deadlineDiff' => $deadlineDiff->d);
+ }
+ }
+
+ /**
+ * Test compute hours for multiple task.
+ *
+ * @param object $oldTask
+ * @param object $task
+ * @param array $team
+ * @param bool $autoStatus
+ * @access public
+ * @return array
+ */
+ public function computeHours4MultipleTest($oldTask, $task = null, $team = array(), $autoStatus = true)
+ {
+ $result = $this->objectModel->computeHours4Multiple($oldTask, $task, $team, $autoStatus);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $object = $this->objectModel->getById($oldTask->id);
+ return !empty($team) ? $result : $object;
+ }
+ }
+
+ public function getParentTaskPairsTest($executionID, $append = '')
+ {
+ $objectList = $this->objectModel->getParentTaskPairs($executionID, $append);
+ $objectList = count($objectList) == 1 ? array('name' => 0): $objectList;
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $objectList;
+ }
+ }
+
+ /**
+ * Test process a task, judge it's status.
+ *
+ * @param object $task
+ * @access public
+ * @return object
+ */
+ public function processTaskTest($task)
+ {
+ $task->deadline = $task->deadline == '-1day' ? date('Y-m-d',strtotime('-1 day')) : date('Y-m-d',strtotime('+1 day'));
+ $object = $this->objectModel->processTask($task);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test batch process tasks.
+ *
+ * @param int $executionID
+ * @access public
+ * @return array
+ */
+ public function processTasksTest($executionID)
+ {
+ global $tester;
+ $tasks = $tester->dao->select('*')->from(TABLE_TASK)->where('execution')->eq($executionID)->andWhere('deleted')->eq('0')->fetchAll('id');
+ $parents = '0';
+ foreach($tasks as $task)
+ {
+ if($task->parent > 0) $parents .= ",$task->parent";
+ }
+ $parents = $tester->dao->select('*')->from(TABLE_TASK)->where('`id`')->in($parents)->andWhere('deleted')->eq('0')->fetchAll('id');
+ foreach($tasks as $task)
+ {
+ if($task->parent > 0)
+ {
+ if(isset($tasks[$task->parent]))
+ {
+ $tasks[$task->parent]->children[$task->id] = $task;
+ unset($tasks[$task->id]);
+ }
+ else
+ {
+ $parent = $parents[$task->parent];
+ $task->parentName = $parent->name;
+ }
+ }
+ }
+
+ $object = $this->objectModel->processTasks($tasks);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test process data for report.
+ *
+ * @param bool $children
+ * @param array $field
+ * @access public
+ * @return array
+ */
+ public function processData4ReportTest($children, $field)
+ {
+ global $tester;
+ $tasks = $tester->dao->select('*')->from(TABLE_TASK)->where('`execution`')->eq('101')->andWhere('deleted')->eq(0)->fetchAll('id');
+ $parents = array();
+ foreach($tasks as $task)
+ {
+ if($task->parent > 0) $parents[$task->parent] = $task->parent;
+ }
+ $parents = $tester->dao->select('*')->from(TABLE_TASK)->where('id')->in($parents)->fetchAll('id');
+ foreach($tasks as $task)
+ {
+ if($task->parent > 0)
+ {
+ if(isset($tasks[$task->parent]))
+ {
+ $tasks[$task->parent]->children[$task->id] = $task;
+ }
+ else
+ {
+ $parent = $parents[$task->parent];
+ $task->parentName = $parent->name;
+ }
+ }
+ $task->date = '0000-00-00';
+ }
+
+ $children = $children ? $tasks[601]->children + $tasks[602]->children + $tasks[603]->children : array();
+
+ $object = $this->objectModel->processData4Report($tasks, $children, $field);
+
+ $object['void'] = isset($object['']) ? $object[''] : 'void';
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ if($field == 'deadline')
+ {
+ $dateList = array(date('Y-m-d',strtotime('-8 day')), date('Y-m-d',strtotime('-15 day')));
+ return array($object[$dateList[0]], $object[$dateList[1]]);
+ }
+ return count($object) == 0 ? array('void' => 'void') : $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per execution.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerExecutionTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerExecution();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per module.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerModuleTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerModule();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per assignedto.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerAssignedToTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerAssignedTo();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per type.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerTypeTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerType();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per priority.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerPriTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerPri();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per deadline.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerDeadlineTest($dateID)
+ {
+ $dateList = array(date('Y-m-d',strtotime('+1 day')), date('Y-m-d',strtotime('+2 day')), date('Y-m-d',strtotime('+3 day')), date('Y-m-d',strtotime('+4 day')), date('Y-m-d',strtotime('-1 day')), date('Y-m-d',strtotime('-2 day')), date('Y-m-d',strtotime('-3 day')), date('Y-m-d',strtotime('-4 day')));
+ $object = $this->objectModel->getDataOfTasksPerDeadline();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return array($dateID => $object[$dateList[$dateID]]);
+ }
+ }
+
+ /**
+ * Test get report data of tasks per estimate.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerEstimateTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerEstimate();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per left.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerLeftTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerLeft();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per consumed.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerConsumedTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerConsumed();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per finishedBy.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerFinishedByTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerFinishedBy();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per closed reason.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerClosedReasonTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerClosedReason();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of finished tasks per day.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOffinishedTasksPerDayTest()
+ {
+ $object = $this->objectModel->getDataOffinishedTasksPerDay();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get report data of tasks per status.
+ *
+ * @access public
+ * @return array
+ */
+ public function getDataOfTasksPerStatusTest()
+ {
+ $object = $this->objectModel->getDataOfTasksPerStatus();
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test update parent status by taskID.
+ *
+ * @param int $taskID
+ * @param int $parentID
+ * @param bool $createAction
+ * @access public
+ * @return object
+ */
+ public function updateParentStatusTest($taskID, $parentID = 0, $createAction = true)
+ {
+ $object = $this->objectModel->updateParentStatus($taskID, $parentID, $createAction);
+ if(!$object) $object = $this->objectModel->getByID($taskID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test judge an action is clickable or not.
+ *
+ * @param object $task
+ * @param string $action
+ * @access public
+ * @return int
+ */
+ public function isClickableTest($task, $action)
+ {
+ $object = $this->objectModel->isClickable($task, $action);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object ? 1 : 2;
+ }
+ }
+
+ /**
+ * Test add task estimate.
+ *
+ * @param object $data
+ * @access public
+ * @return object
+ */
+ public function addTaskEstimateTest($data)
+ {
+ $data->date = date("Y-m-d");
+ $this->objectModel->addTaskEstimate($data);
+
+ global $tester;
+ $objectID = $tester->dao->lastInsertID();
+ $object = $this->objectModel->getEstimateById($objectID);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test get toList and ccList.
+ *
+ * @param int $taskID
+ * @param bool $skipMailto
+ * @access public
+ * @return array
+ */
+ public function getToAndCcListTest($taskID, $skipMailto = false)
+ {
+ $task = $this->objectModel->getByID($taskID);
+ if(empty($task)) return 0;
+ if($skipMailto) $task->mailto = '';
+
+ $object = $this->objectModel->getToAndCcList($task);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ if(isset($object[0])) $object[2] = $object[0];
+ if(isset($object[1]) and $object[1] == '') $object[1] = 0;
+ return $object;
+ }
+ }
+
+ /**
+ * Test for get team by account.
+ *
+ * @param array $users
+ * @param string $account
+ * @param string $filter
+ * @access public
+ * @return string
+ */
+ public function getTeamByAccount($users, $account, $filter = array('filter' => 'done'))
+ {
+ $object = $this->objectModel->getTeamByAccount($users, $account, $filter);
+ if(empty($object)) return '_';
+ return $object->account . '_' . $object->status;
+ }
+
+ /**
+ * Test get assignedTo for multi task.
+ *
+ * @param array $users
+ * @param string $current
+ * @access public
+ * @return string
+ */
+ public function getAssignedTo4Multi($users, $task, $type = 'current')
+ {
+ $assignedTo = $this->objectModel->getAssignedTo4Multi($users, $task, $type);
+ return empty($assignedTo) ? 'null' : $assignedTo;
+ }
+
+ /**
+ * Test for can operate effort;
+ *
+ * @param object $task
+ * @param object $effort
+ * @access public
+ * @return bool
+ */
+ public function canOperateEffort($task, $effort = null)
+ {
+ $result = $this->objectModel->canOperateEffort($task, $effort);
+ return $result ? 1 : 0;
+ }
+
+ /**
+ * Test get task's team member pairs.
+ *
+ * @param int $taskID
+ * @access public
+ * @return array
+ */
+ public function getMemberPairsTest($taskID)
+ {
+ $task = $this->objectModel->getByID($taskID);
+ if(empty($task)) return 0;
+
+ $object = $this->objectModel->getMemberPairs($task);
+ $object['count'] = count($object);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object;
+ }
+ }
+
+ /**
+ * Test check whether need update status of bug.
+ *
+ * @param object $task
+ * @access public
+ * @return int
+ */
+ public function needUpdateBugStatusTest($task)
+ {
+ $object = $this->objectModel->needUpdateBugStatus($task);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $object ? 1 : 2;
+ }
+ }
+
+ /**
+ * Get the users who finished the multiple task.
+ *
+ * @param int $taskID
+ * @param string|array $team
+ * @access public
+ * @return array
+ */
+ public function getFinishedUsersTest($taskID = 0, $team = array())
+ {
+ $object = $this->objectModel->getFinishedUsers($taskID, $team);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Get the users who finished the multiple task.
+ * @param int $executionID
+ * @param string $estStarted
+ * @param string $deadline
+ *
+ * @access public
+ * @return array
+ */
+ public function checkEstStartedAndDeadlineTest($executionID, $estStarted, $deadline)
+ {
+ $object = $this->objectModel->checkEstStartedAndDeadline($executionID, $estStarted, $deadline);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+}
diff --git a/module/testcase/test/model/appenddata.php b/module/testcase/test/model/appenddata.php
new file mode 100755
index 0000000000..8a7da1ac61
--- /dev/null
+++ b/module/testcase/test/model/appenddata.php
@@ -0,0 +1,70 @@
+#!/usr/bin/env php
+appendData();
+cid=1
+pid=1
+
+获取case 1 2 可以加入的数据 >> 0,1,0,1;2,1,1,1
+获取case 1 2 可以加入的数据 >> 0,1,0,1;0,1,1,1
+获取case 1 2 可以加入的数据 >> 0,1,0,1;2,1,1,1
+获取case 1 2 可以加入的数据 >> 0,1,0,1;0,1,1,1
+获取case 1 2 可以加入的数据 >> 0,1,0,1;2,1,1,1
+
+*/
+$case1 = new stdclass();
+$case1->id = 1;
+$case1->case = 1;
+
+$case2 = new stdclass();
+$case2->id = 2;
+$case2->case = 2;
+
+$case3 = new stdclass();
+$case3->id = 3;
+$case3->case = 3;
+
+$case4 = new stdclass();
+$case4->id = 4;
+$case4->case = 4;
+
+$case5 = new stdclass();
+$case5->id = 5;
+$case5->case = 5;
+
+$case6 = new stdclass();
+$case6->id = 6;
+$case6->case = 6;
+
+$case7 = new stdclass();
+$case7->id = 7;
+$case7->case = 7;
+
+$case8 = new stdclass();
+$case8->id = 8;
+$case8->case = 8;
+
+$case9 = new stdclass();
+$case9->id = 9;
+$case9->case = 9;
+
+$case10 = new stdclass();
+$case10->id = 10;
+$case10->case = 10;
+
+$cases = array(array(1 => $case1, 2 => $case2), array(3 => $case3, 4 => $case4), array(5 => $case5, 6 => $case6), array(7 => $case7, 8 => $case8), array(9 => $case9, 10 => $case10));
+
+$type = 'run';
+
+$testcase = new testcaseTest();
+
+r($testcase->appendDataTest($cases[0])) && p('1:bugs,results,caseFails,stepNumber;2:bugs,results,caseFails,stepNumber') && e('0,1,0,1;2,1,1,1'); // 获取case 1 2 可以加入的数据
+r($testcase->appendDataTest($cases[1])) && p('3:bugs,results,caseFails,stepNumber;4:bugs,results,caseFails,stepNumber') && e('0,1,0,1;0,1,1,1'); // 获取case 1 2 可以加入的数据
+r($testcase->appendDataTest($cases[2])) && p('5:bugs,results,caseFails,stepNumber;6:bugs,results,caseFails,stepNumber') && e('0,1,0,1;2,1,1,1'); // 获取case 1 2 可以加入的数据
+r($testcase->appendDataTest($cases[3])) && p('7:bugs,results,caseFails,stepNumber;8:bugs,results,caseFails,stepNumber') && e('0,1,0,1;0,1,1,1'); // 获取case 1 2 可以加入的数据
+r($testcase->appendDataTest($cases[4])) && p('9:bugs,results,caseFails,stepNumber;10:bugs,results,caseFails,stepNumber') && e('0,1,0,1;2,1,1,1'); // 获取case 1 2 可以加入的数据
\ No newline at end of file
diff --git a/module/testcase/test/model/batchcasetypechange.php b/module/testcase/test/model/batchcasetypechange.php
new file mode 100755
index 0000000000..4bc70d9e0e
--- /dev/null
+++ b/module/testcase/test/model/batchcasetypechange.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+batchCaseTypeChange();
+cid=1
+pid=1
+
+测试批量修改case 1 2 type为 feature >> feature;feature
+测试批量修改case 3 4 type为 performance >> performance;performance
+测试批量修改case 5 6 type为 config >> config;config
+测试批量修改case 7 8 type为 install >> install;install
+测试批量修改case 9 10 type为 security >> security;security
+测试批量修改case 11 12 type为 interface >> interface;interface
+测试批量修改case 13 14 15 type为 other >> other;other;other
+
+*/
+$caseIDList = array(array(1, 2), array(3, 4), array(5, 6), array(7, 8), array(9, 10), array(11, 12), array(13, 14, 15));
+$typeList = array('feature', 'performance', 'config', 'install', 'security', 'interface', 'other');
+
+$testcase = new testcaseTest();
+
+r($testcase->batchCaseTypeChangeTest($caseIDList[0], $typeList[0])) && p('1:type;2:type') && e('feature;feature'); // 测试批量修改case 1 2 type为 feature
+r($testcase->batchCaseTypeChangeTest($caseIDList[1], $typeList[1])) && p('3:type;4:type') && e('performance;performance '); // 测试批量修改case 3 4 type为 performance
+r($testcase->batchCaseTypeChangeTest($caseIDList[2], $typeList[2])) && p('5:type;6:type') && e('config;config'); // 测试批量修改case 5 6 type为 config
+r($testcase->batchCaseTypeChangeTest($caseIDList[3], $typeList[3])) && p('7:type;8:type') && e('install;install'); // 测试批量修改case 7 8 type为 install
+r($testcase->batchCaseTypeChangeTest($caseIDList[4], $typeList[4])) && p('9:type;10:type') && e('security;security'); // 测试批量修改case 9 10 type为 security
+r($testcase->batchCaseTypeChangeTest($caseIDList[5], $typeList[5])) && p('11:type;12:type') && e('interface;interface'); // 测试批量修改case 11 12 type为 interface
+r($testcase->batchCaseTypeChangeTest($caseIDList[6], $typeList[6])) && p('13:type;14:type;15:type') && e('other;other;other'); // 测试批量修改case 13 14 15 type为 other
diff --git a/module/testcase/test/model/batchchangebranch.php b/module/testcase/test/model/batchchangebranch.php
new file mode 100755
index 0000000000..49b352f733
--- /dev/null
+++ b/module/testcase/test/model/batchchangebranch.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+batchChangeBranch();
+cid=1
+pid=1
+
+测试批量修改case 161 162 的branch为1 >> 1;1
+测试批量修改case 163 164 的branch为2 >> 2;2
+测试批量修改case 165 166 的branch为3 >> 3;3
+测试批量修改case 167 168 的branch为4 >> 4;4
+测试批量修改case 169 170 的branch为5 >> 5;5
+测试批量修改case 171 172 的branch为6 >> 6;6
+测试批量修改case 173 174 的branch为7 >> 7;7
+
+*/
+
+$caseIDList = array(array(161, 162), array(163, 164), array(165, 166), array(167, 168), array(169, 170), array(171, 172), array(173, 174));
+$branchList = array(1, 2, 3, 4, 5, 6, 7);
+
+$testcase = new testcaseTest();
+
+r($testcase->batchChangeBranchTest($caseIDList[0], $branchList[0])) && p('161:branch;162:branch') && e('1;1'); // 测试批量修改case 161 162 的branch为1
+r($testcase->batchChangeBranchTest($caseIDList[1], $branchList[1])) && p('163:branch;164:branch') && e('2;2'); // 测试批量修改case 163 164 的branch为2
+r($testcase->batchChangeBranchTest($caseIDList[2], $branchList[2])) && p('165:branch;166:branch') && e('3;3'); // 测试批量修改case 165 166 的branch为3
+r($testcase->batchChangeBranchTest($caseIDList[3], $branchList[3])) && p('167:branch;168:branch') && e('4;4'); // 测试批量修改case 167 168 的branch为4
+r($testcase->batchChangeBranchTest($caseIDList[4], $branchList[4])) && p('169:branch;170:branch') && e('5;5'); // 测试批量修改case 169 170 的branch为5
+r($testcase->batchChangeBranchTest($caseIDList[5], $branchList[5])) && p('171:branch;172:branch') && e('6;6'); // 测试批量修改case 171 172 的branch为6
+r($testcase->batchChangeBranchTest($caseIDList[6], $branchList[6])) && p('173:branch;174:branch') && e('7;7'); // 测试批量修改case 173 174 的branch为7
diff --git a/module/testcase/test/model/batchchangemodule.php b/module/testcase/test/model/batchchangemodule.php
new file mode 100755
index 0000000000..6da35fb4df
--- /dev/null
+++ b/module/testcase/test/model/batchchangemodule.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+batchChangeModule();
+cid=1
+pid=1
+
+测试批量修改case 161 162 的module为161 >> 161;161
+测试批量修改case 163 164 的module为163 >> 163;163
+测试批量修改case 165 166 的module为165 >> 165;165
+测试批量修改case 167 168 的module为167 >> 167;167
+测试批量修改case 169 170 的module为169 >> 169;169
+测试批量修改case 171 172 的module为171 >> 171;171
+测试批量修改case 173 174 的module为173 >> 173;173
+
+*/
+$caseIDList = array(array(161, 162), array(163, 164), array(165, 166), array(167, 168), array(169, 170), array(171, 172), array(173, 174));
+$moduleList = array(161, 163, 165, 167, 169, 171, 173);
+
+$testcase = new testcaseTest();
+
+r($testcase->batchChangeModuleTest($caseIDList[0], $moduleList[0])) && p('161:module;162:module') && e('161;161'); // 测试批量修改case 161 162 的module为161
+r($testcase->batchChangeModuleTest($caseIDList[1], $moduleList[1])) && p('163:module;164:module') && e('163;163'); // 测试批量修改case 163 164 的module为163
+r($testcase->batchChangeModuleTest($caseIDList[2], $moduleList[2])) && p('165:module;166:module') && e('165;165'); // 测试批量修改case 165 166 的module为165
+r($testcase->batchChangeModuleTest($caseIDList[3], $moduleList[3])) && p('167:module;168:module') && e('167;167'); // 测试批量修改case 167 168 的module为167
+r($testcase->batchChangeModuleTest($caseIDList[4], $moduleList[4])) && p('169:module;170:module') && e('169;169'); // 测试批量修改case 169 170 的module为169
+r($testcase->batchChangeModuleTest($caseIDList[5], $moduleList[5])) && p('171:module;172:module') && e('171;171'); // 测试批量修改case 171 172 的module为171
+r($testcase->batchChangeModuleTest($caseIDList[6], $moduleList[6])) && p('173:module;174:module') && e('173;173'); // 测试批量修改case 173 174 的module为173
diff --git a/module/testcase/test/model/batchcreate.php b/module/testcase/test/model/batchcreate.php
new file mode 100755
index 0000000000..245a44e30f
--- /dev/null
+++ b/module/testcase/test/model/batchcreate.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+batchCreate();
+cid=1
+pid=1
+
+测试批量创建用例1 >> 2
+测试批量创建用例2 >> 3
+测试批量创建用例3 >> 3
+测试批量创建用例4 >> 3
+测试批量创建用例5 >> 3
+测试重复批量创建用例1 >> 0
+
+*/
+
+$title1 = array('测试批量创建4', '', '测试批量创建6');
+$title2 = array('测试批量创建7', '测试批量创建8', '测试批量创建9');
+$title3 = array('测试批量创建10', '测试批量创建11', '测试批量创建12');
+$title4 = array('测试批量创建13', '测试批量创建14', '测试批量创建15');
+$title5 = array('测试批量创建16', '测试批量创建17', '测试批量创建18');
+$type = array('feature', 'ditto', 'config');
+$pri = array('2', 'ditto', '1');
+$stage = array(array('system', 'smoke'), array('bvt'), array('unittest'));
+$needReview = array(0, 1, 0);
+
+$testcase = new testcaseTest();
+
+r($testcase->batchCreateTest(array('title' => $title1))) && p() && e('2'); // 测试批量创建用例1
+r($testcase->batchCreateTest(array('type' => $type, 'title' => $title2))) && p() && e('3'); // 测试批量创建用例2
+r($testcase->batchCreateTest(array('pri' => $pri, 'title' => $title3))) && p() && e('3'); // 测试批量创建用例3
+r($testcase->batchCreateTest(array('stage' => $stage, 'title' => $title4))) && p() && e('3'); // 测试批量创建用例4
+r($testcase->batchCreateTest(array('needReview' => $needReview, 'title' => $title5))) && p() && e('3'); // 测试批量创建用例5
+r($testcase->batchCreateTest(array('title' => $title1))) && p() && e('0'); // 测试重复批量创建用例1
diff --git a/module/testcase/test/model/batchreview.php b/module/testcase/test/model/batchreview.php
new file mode 100755
index 0000000000..c2016d428d
--- /dev/null
+++ b/module/testcase/test/model/batchreview.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+batchReview();
+cid=1
+pid=1
+
+测试评审case 401 402 为clarify >> 102
+测试评审case 403 404 为clarify >> 0
+测试评审case 405 406 为clarify >> 103
+测试评审case 407 408 为clarify >> 0
+测试评审case 409 410 为clarify >> 104
+测试评审case 401 402 为pass >> 105
+测试评审case 403 404 为pass >> 0
+测试评审case 405 406 为pass >> 106
+测试评审case 407 408 为pass >> 0
+测试评审case 409 410 为pass >> 107
+
+*/
+$caseIDList = array(array(401, 402), array(403, 404), array(405, 406), array(407, 408), array(409, 410));
+$resultList = array('clarify', 'pass');
+
+$testcase = new testcaseTest();
+
+r($testcase->batchReviewTest($caseIDList[0], $resultList[0])) && p('401') && e('102'); // 测试评审case 401 402 为clarify
+r($testcase->batchReviewTest($caseIDList[1], $resultList[0])) && p() && e('0'); // 测试评审case 403 404 为clarify
+r($testcase->batchReviewTest($caseIDList[2], $resultList[0])) && p('405') && e('103'); // 测试评审case 405 406 为clarify
+r($testcase->batchReviewTest($caseIDList[3], $resultList[0])) && p() && e('0'); // 测试评审case 407 408 为clarify
+r($testcase->batchReviewTest($caseIDList[4], $resultList[0])) && p('409') && e('104'); // 测试评审case 409 410 为clarify
+r($testcase->batchReviewTest($caseIDList[0], $resultList[1])) && p('401') && e('105'); // 测试评审case 401 402 为pass
+r($testcase->batchReviewTest($caseIDList[1], $resultList[1])) && p() && e('0'); // 测试评审case 403 404 为pass
+r($testcase->batchReviewTest($caseIDList[2], $resultList[1])) && p('405') && e('106'); // 测试评审case 405 406 为pass
+r($testcase->batchReviewTest($caseIDList[3], $resultList[1])) && p() && e('0'); // 测试评审case 407 408 为pass
+r($testcase->batchReviewTest($caseIDList[4], $resultList[1])) && p('409') && e('107'); // 测试评审case 409 410 为pass
diff --git a/module/testcase/test/model/batchupdate.php b/module/testcase/test/model/batchupdate.php
new file mode 100755
index 0000000000..ec75f34704
--- /dev/null
+++ b/module/testcase/test/model/batchupdate.php
@@ -0,0 +1,55 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+测试批量修改用例标题 >> title,这个是测试用例1,修改后的测试用例1
+测试批量修改用例优先级 >> pri,2,1
+测试批量修改用例状态 >> status,blocked,nomal
+测试批量修改用例模块 >> module,0,1822
+测试批量修改用例颜色 >> color,#3da7f5,#2dbdb2
+测试批量修改用例类型 >> type,performance,other
+测试批量修改用例前置条件 >> precondition,这是前置条件3,修改后的前置条件3
+测试批量修改用例关键词 >> keywords,这是关键词4,修改后的关键词4
+测试批量修改用例阶段 >> stage,unittest,unittest,feature
+
+*/
+
+$changeTitle = array('1' => '修改后的测试用例1', '2' => '这个是测试用例2', '3' => '这个是测试用例3', '4' => '这个是测试用例4');;
+$changePris = array('1' => 1, '2' => 1, '3' => 3, '4' => 4);
+$changeStatuses = array('1' => 'wait', '2' => 'normal', '3' => 'nomal', '4' => 'investigate');
+$changeModules = array('1' => 0, '2' => 0, '3' => 0, '4' => 1822);
+$changeColor = array('1' => '#2dbdb2', '2' => '#75c941', '3' => '#2dbdb2', '4' => '#797ec9');
+$changeTypes = array('1' => 'feature', '2' => 'other', '3' => 'config', '4' => 'install');
+$changePrecondition = array('1' => '这是前置条件1', '2' => '这是前置条件2', '3' => '修改后的前置条件3', '4' => '这是前置条件4');
+$changeKeywords = array('1' => '这是关键词1', '2' => '这是关键词2', '3' => '这是关键词3', '4' => '修改后的关键词4');
+$changeStages = array('1' => array('unittest', 'feature'), '2' => array('feature'), '3' => array('intergrate'), '4' => array('system'));
+
+$changeTitle = array('title' => $changeTitle);
+$changePris = array('pris' => $changePris);
+$changeStatuses = array('statuses' => $changeStatuses);
+$changeModules = array('modules' => $changeModules);
+$changeColor = array('color' => $changeColor);
+$changeTypes = array('types' => $changeTypes);
+$changePrecondition = array('precondition' => $changePrecondition);
+$changeKeywords = array('keywords' => $changeKeywords);
+$changeStages = array('stages' => $changeStages);
+
+$testcase = new testcaseTest();
+
+r($testcase->batchUpdateTest(1, $changeTitle)) && p('field,old,new') && e('title,这个是测试用例1,修改后的测试用例1'); // 测试批量修改用例标题
+r($testcase->batchUpdateTest(2, $changePris)) && p('field,old,new') && e('pri,2,1'); // 测试批量修改用例优先级
+r($testcase->batchUpdateTest(3, $changeStatuses)) && p('field,old,new') && e('status,blocked,nomal'); // 测试批量修改用例状态
+r($testcase->batchUpdateTest(4, $changeModules)) && p('field,old,new') && e('module,0,1822'); // 测试批量修改用例模块
+r($testcase->batchUpdateTest(1, $changeColor)) && p('field,old,new') && e('color,#3da7f5,#2dbdb2'); // 测试批量修改用例颜色
+r($testcase->batchUpdateTest(2, $changeTypes)) && p('field,old,new') && e('type,performance,other'); // 测试批量修改用例类型
+r($testcase->batchUpdateTest(3, $changePrecondition)) && p('field,old,new') && e('precondition,这是前置条件3,修改后的前置条件3'); // 测试批量修改用例前置条件
+r($testcase->batchUpdateTest(4, $changeKeywords)) && p('field,old,new') && e('keywords,这是关键词4,修改后的关键词4'); // 测试批量修改用例关键词
+r($testcase->batchUpdateTest(1, $changeStages)) && p('field,old,new') && e('stage,unittest,unittest,feature'); // 测试批量修改用例阶段
diff --git a/module/testcase/test/model/create.php b/module/testcase/test/model/create.php
new file mode 100755
index 0000000000..aea44d6755
--- /dev/null
+++ b/module/testcase/test/model/create.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试创建用例1 >> created
+测试创建用例2 >> created
+测试创建用例3 >> created
+测试创建重名用例1 >> exists
+测试创建没有填写名字的用例 >> 『用例标题』不能为空。
+测试创建没有填写类型的用例 >> 『用例类型』不能为空。
+
+*/
+
+$testcase1 = array('title' => '测试创建测试用例1');
+$testcase2 = array('title' => '测试创建测试用例2', 'pri' => '1', 'type' => 'performance');
+$testcase3 = array('title' => '测试创建测试用例3', 'keywords' => '测试关键词3', 'stage' => array('unittest', 'smoke'));
+
+$no_title = array('title' => '');
+$no_type = array('type' => '', 'title' => '测试创建没有填写类型的用例');
+
+$testcase = new testcaseTest();
+
+r($testcase->createTest($testcase1)) && p('status') && e('created'); // 测试创建用例1
+r($testcase->createTest($testcase2)) && p('status') && e('created'); // 测试创建用例2
+r($testcase->createTest($testcase3)) && p('status') && e('created'); // 测试创建用例3
+r($testcase->createTest($testcase1)) && p('status') && e('exists'); // 测试创建重名用例1
+r($testcase->createTest($no_title)) && p() && e('『用例标题』不能为空。'); // 测试创建没有填写名字的用例
+r($testcase->createTest($no_type)) && p() && e('『用例类型』不能为空。'); // 测试创建没有填写类型的用例
diff --git a/module/testcase/test/model/createfromimport.php b/module/testcase/test/model/createfromimport.php
new file mode 100755
index 0000000000..f9e8877f1a
--- /dev/null
+++ b/module/testcase/test/model/createfromimport.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+createFromImport();
+cid=1
+pid=1
+
+测试直接导入数据 >> 这个是测试用例1,这个是测试用例2,导入测试用例1,导入测试用例2
+测试导入数据覆盖原有数据 >> 导入覆盖的用例1,导入覆盖的用例2,导入测试用例1,导入测试用例2
+测试导入数据不覆盖原有数据 >> 导入覆盖的用例1,导入覆盖的用例2,导入测试用例1,导入测试用例2,导入插入的用例1,导入插入的用例2
+
+*/
+
+$productID = 1;
+
+$param1 = array('id' => array('1' => 1, '2' => 2), 'title' => array('1' => '导入覆盖的用例1', '2' => '导入覆盖的用例2'), 'insert' => '0');
+$param2 = array('id' => array('1' => 1, '2' => 2), 'title' => array('1' => '导入插入的用例1', '2' => '导入插入的用例2'), 'insert' => '1');
+
+$testcase = new testcaseTest();
+
+r($testcase->createFromImportTest($productID)) && p() && e('这个是测试用例1,这个是测试用例2,导入测试用例1,导入测试用例2'); // 测试直接导入数据
+r($testcase->createFromImportTest($productID, $param1)) && p() && e('导入覆盖的用例1,导入覆盖的用例2,导入测试用例1,导入测试用例2'); // 测试导入数据覆盖原有数据
+r($testcase->createFromImportTest($productID, $param2)) && p() && e('导入覆盖的用例1,导入覆盖的用例2,导入测试用例1,导入测试用例2,导入插入的用例1,导入插入的用例2'); // 测试导入数据不覆盖原有数据
diff --git a/module/testcase/test/model/forcenotreview.php b/module/testcase/test/model/forcenotreview.php
new file mode 100755
index 0000000000..bfc72b3672
--- /dev/null
+++ b/module/testcase/test/model/forcenotreview.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+forceNotReview();
+cid=1
+pid=1
+
+测试检查是否强制审核 >> 1
+
+*/
+
+$testcase = new testcaseTest();
+
+r($testcase->forceNotReviewTest()) && p() && e('1'); // 测试检查是否强制审核
\ No newline at end of file
diff --git a/module/testcase/test/model/getbyassignedto.php b/module/testcase/test/model/getbyassignedto.php
new file mode 100755
index 0000000000..2a9b1e7794
--- /dev/null
+++ b/module/testcase/test/model/getbyassignedto.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getByAssignedTo();
+cid=1
+pid=1
+
+测试获取指派给 admin 的用例执行 >> 37,33,29,21,17,13,5,1
+测试获取指派给 user2 的用例执行 >> 38,34,30,22,18,14,6,2
+测试获取指派给 test3 的用例执行 >> 39,35,31,23,19,15,7,3
+测试获取指派给 dev4 的用例执行 >> 40,36,32,24,20,16,8,4
+
+*/
+
+$accountList = array('admin', 'user2', 'test3', 'dev4');
+
+$testcase = new testcaseTest();
+
+r($testcase->getByAssignedToTest($accountList[0])) && p() && e('37,33,29,21,17,13,5,1'); // 测试获取指派给 admin 的用例执行
+r($testcase->getByAssignedToTest($accountList[1])) && p() && e('38,34,30,22,18,14,6,2'); // 测试获取指派给 user2 的用例执行
+r($testcase->getByAssignedToTest($accountList[2])) && p() && e('39,35,31,23,19,15,7,3'); // 测试获取指派给 test3 的用例执行
+r($testcase->getByAssignedToTest($accountList[3])) && p() && e('40,36,32,24,20,16,8,4'); // 测试获取指派给 dev4 的用例执行
\ No newline at end of file
diff --git a/module/testcase/test/model/getbyid.php b/module/testcase/test/model/getbyid.php
new file mode 100755
index 0000000000..32f9369157
--- /dev/null
+++ b/module/testcase/test/model/getbyid.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+测试获取case 1 的信息 >> 这个是测试用例1,feature,wait
+测试获取case 2 的信息 >> 这个是测试用例2,performance,normal
+测试获取case 3 的信息 >> 这个是测试用例3,config,blocked
+测试获取case 4 的信息 >> 这个是测试用例4,install,investigate
+测试获取case 5 的信息 >> 这个是测试用例5,security,wait
+
+*/
+
+$caseIDList = array(1, 2, 3, 4, 5);
+
+$testcase = new testcaseTest();
+
+r($testcase->getByIdTest($caseIDList[0])) && p('title,type,status') && e('这个是测试用例1,feature,wait'); // 测试获取case 1 的信息
+r($testcase->getByIdTest($caseIDList[1])) && p('title,type,status') && e('这个是测试用例2,performance,normal'); // 测试获取case 2 的信息
+r($testcase->getByIdTest($caseIDList[2])) && p('title,type,status') && e('这个是测试用例3,config,blocked'); // 测试获取case 3 的信息
+r($testcase->getByIdTest($caseIDList[3])) && p('title,type,status') && e('这个是测试用例4,install,investigate'); // 测试获取case 4 的信息
+r($testcase->getByIdTest($caseIDList[4])) && p('title,type,status') && e('这个是测试用例5,security,wait'); // 测试获取case 5 的信息
\ No newline at end of file
diff --git a/module/testcase/test/model/getbylist.php b/module/testcase/test/model/getbylist.php
new file mode 100755
index 0000000000..b08f0c23a0
--- /dev/null
+++ b/module/testcase/test/model/getbylist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+测试获取case 1 2 3 的信息 >> 这个是测试用例1;这个是测试用例2;这个是测试用例3
+测试获取case 4 5 6 的信息 >> 这个是测试用例4;这个是测试用例5;这个是测试用例6
+测试获取case 7 8 9 的信息 >> 这个是测试用例7;这个是测试用例8;这个是测试用例9
+测试获取case 10 11 12 的信息 >> 这个是测试用例10;这个是测试用例11;这个是测试用例12
+测试获取case 13 14 15 的信息 >> 这个是测试用例13;这个是测试用例14;这个是测试用例15
+
+*/
+
+$caseIDList = array('1,2,3', '4,5,6', '7,8,9', '10,11,12', '13,14,15');
+
+$testcase = new testcaseTest();
+
+r($testcase->getByListTest($caseIDList[0])) && p('1:title;2:title;3:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3'); // 测试获取case 1 2 3 的信息
+r($testcase->getByListTest($caseIDList[0])) && p('4:title;5:title;6:title') && e('这个是测试用例4;这个是测试用例5;这个是测试用例6'); // 测试获取case 4 5 6 的信息
+r($testcase->getByListTest($caseIDList[0])) && p('7:title;8:title;9:title') && e('这个是测试用例7;这个是测试用例8;这个是测试用例9'); // 测试获取case 7 8 9 的信息
+r($testcase->getByListTest($caseIDList[0])) && p('10:title;11:title;12:title') && e('这个是测试用例10;这个是测试用例11;这个是测试用例12'); // 测试获取case 10 11 12 的信息
+r($testcase->getByListTest($caseIDList[0])) && p('13:title;14:title;15:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15'); // 测试获取case 13 14 15 的信息
\ No newline at end of file
diff --git a/module/testcase/test/model/getbyopenedby.php b/module/testcase/test/model/getbyopenedby.php
new file mode 100755
index 0000000000..75ebbda052
--- /dev/null
+++ b/module/testcase/test/model/getbyopenedby.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getByOpenedBy();
+cid=1
+pid=1
+
+测试查询由 test1 创建的case信息 >> 这个是测试用例1;这个是测试用例101;这个是测试用例201;这个是测试用例301
+测试查询由 test2 创建的case信息 >> 这个是测试用例2;这个是测试用例102;这个是测试用例202;这个是测试用例302
+测试查询由 test3 创建的case信息 >> 这个是测试用例3;这个是测试用例103;这个是测试用例203;这个是测试用例303
+测试查询由 test4 创建的case信息 >> 这个是测试用例4;这个是测试用例104;这个是测试用例204;这个是测试用例304
+测试查询由 test5 创建的case信息 >> 这个是测试用例5;这个是测试用例105;这个是测试用例205;这个是测试用例305
+
+*/
+$accountList = array('test1', 'test2', 'test3', 'test4', 'test5');
+
+$testcase = new testcaseTest();
+
+r($testcase->getByOpenedByTest($accountList[0])) && p('1:title;101:title;201:title;301:title') && e('这个是测试用例1;这个是测试用例101;这个是测试用例201;这个是测试用例301'); // 测试查询由 test1 创建的case信息
+r($testcase->getByOpenedByTest($accountList[1])) && p('2:title;102:title;202:title;302:title') && e('这个是测试用例2;这个是测试用例102;这个是测试用例202;这个是测试用例302'); // 测试查询由 test2 创建的case信息
+r($testcase->getByOpenedByTest($accountList[2])) && p('3:title;103:title;203:title;303:title') && e('这个是测试用例3;这个是测试用例103;这个是测试用例203;这个是测试用例303'); // 测试查询由 test3 创建的case信息
+r($testcase->getByOpenedByTest($accountList[3])) && p('4:title;104:title;204:title;304:title') && e('这个是测试用例4;这个是测试用例104;这个是测试用例204;这个是测试用例304'); // 测试查询由 test4 创建的case信息
+r($testcase->getByOpenedByTest($accountList[4])) && p('5:title;105:title;205:title;305:title') && e('这个是测试用例5;这个是测试用例105;这个是测试用例205;这个是测试用例305'); // 测试查询由 test5 创建的case信息
\ No newline at end of file
diff --git a/module/testcase/test/model/getbystatus.php b/module/testcase/test/model/getbystatus.php
new file mode 100755
index 0000000000..c2005cf343
--- /dev/null
+++ b/module/testcase/test/model/getbystatus.php
@@ -0,0 +1,53 @@
+#!/usr/bin/env php
+getByStatus();
+cid=1
+pid=1
+
+测试查询所有产品 所有状态的case >> 400
+测试查询产品1 所有状态的case >> 4
+测试查询产品2 所有状态的case >> 4
+测试查询所有产品 type needconfirm 的case >> 100
+测试查询所有产品 状态 wait 的case >> 100
+测试查询所有产品 状态 normal 的case >> 100
+测试查询所有产品 状态 blocked 的case >> 100
+测试查询所有产品 状态 investigate 的case >> 100
+测试查询产品1 状态 wait 的case >> 1
+测试查询产品1 状态 normal 的case >> 1
+测试查询产品1 状态 blocked 的case >> 1
+测试查询产品1 状态 investigate 的case >> 1
+测试查询产品2 状态 wait 的case >> 1
+测试查询产品2 状态 normal 的case >> 1
+测试查询产品2 状态 blocked 的case >> 1
+测试查询产品2 状态 investigate 的case >> 1
+
+*/
+$productIDList = array('0', '1', '2');
+$branch = 0;
+$typeList = array('all', 'needConfirm');
+$statusList = array('wait', 'normal', 'blocked', 'investigate');
+
+$testcase = new testcaseTest();
+
+r($testcase->getByStatusTest()) && p() && e('400'); // 测试查询所有产品 所有状态的case
+r($testcase->getByStatusTest($productIDList[1])) && p() && e('4'); // 测试查询产品1 所有状态的case
+r($testcase->getByStatusTest($productIDList[2])) && p() && e('4'); // 测试查询产品2 所有状态的case
+r($testcase->getByStatusTest($productIDList[0], $branch, $typeList[1], $statusList[0])) && p() && e('100'); // 测试查询所有产品 type needconfirm 的case
+r($testcase->getByStatusTest($productIDList[0], $branch, $typeList[0], $statusList[0])) && p() && e('100'); // 测试查询所有产品 状态 wait 的case
+r($testcase->getByStatusTest($productIDList[0], $branch, $typeList[0], $statusList[1])) && p() && e('100'); // 测试查询所有产品 状态 normal 的case
+r($testcase->getByStatusTest($productIDList[0], $branch, $typeList[0], $statusList[2])) && p() && e('100'); // 测试查询所有产品 状态 blocked 的case
+r($testcase->getByStatusTest($productIDList[0], $branch, $typeList[0], $statusList[3])) && p() && e('100'); // 测试查询所有产品 状态 investigate 的case
+r($testcase->getByStatusTest($productIDList[1], $branch, $typeList[0], $statusList[0])) && p() && e('1'); // 测试查询产品1 状态 wait 的case
+r($testcase->getByStatusTest($productIDList[1], $branch, $typeList[0], $statusList[1])) && p() && e('1'); // 测试查询产品1 状态 normal 的case
+r($testcase->getByStatusTest($productIDList[1], $branch, $typeList[0], $statusList[2])) && p() && e('1'); // 测试查询产品1 状态 blocked 的case
+r($testcase->getByStatusTest($productIDList[1], $branch, $typeList[0], $statusList[3])) && p() && e('1'); // 测试查询产品1 状态 investigate 的case
+r($testcase->getByStatusTest($productIDList[2], $branch, $typeList[0], $statusList[0])) && p() && e('1'); // 测试查询产品2 状态 wait 的case
+r($testcase->getByStatusTest($productIDList[2], $branch, $typeList[0], $statusList[1])) && p() && e('1'); // 测试查询产品2 状态 normal 的case
+r($testcase->getByStatusTest($productIDList[2], $branch, $typeList[0], $statusList[2])) && p() && e('1'); // 测试查询产品2 状态 blocked 的case
+r($testcase->getByStatusTest($productIDList[2], $branch, $typeList[0], $statusList[3])) && p() && e('1'); // 测试查询产品2 状态 investigate 的case
\ No newline at end of file
diff --git a/module/testcase/test/model/getbysuite.php b/module/testcase/test/model/getbysuite.php
new file mode 100755
index 0000000000..47c39b2974
--- /dev/null
+++ b/module/testcase/test/model/getbysuite.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getBySuite();
+cid=1
+pid=1
+
+测试获取产品 1 套件 1 的case >> 这个是测试用例1;这个是测试用例2
+测试获取产品 2 套件 3 的case >> 这个是测试用例5;这个是测试用例6
+测试获取产品 3 套件 5 的case >> 这个是测试用例9;这个是测试用例10
+测试获取产品 4 套件 7 的case >> 这个是测试用例13;这个是测试用例14
+测试获取产品 5 套件 9 的case >> 这个是测试用例17;这个是测试用例18
+
+*/
+$productIDList = array(1, 2, 3, 4, 5);
+$branch = 0;
+$suiteIDList = array('1', '3', '5', '7', '9');
+
+$testcase = new testcaseTest();
+
+r($testcase->getBySuiteTest($productIDList[0], $branch, $suiteIDList[0])) && p('1:title;2:title') && e('这个是测试用例1;这个是测试用例2'); // 测试获取产品 1 套件 1 的case
+r($testcase->getBySuiteTest($productIDList[1], $branch, $suiteIDList[1])) && p('5:title;6:title') && e('这个是测试用例5;这个是测试用例6'); // 测试获取产品 2 套件 3 的case
+r($testcase->getBySuiteTest($productIDList[2], $branch, $suiteIDList[2])) && p('9:title;10:title') && e('这个是测试用例9;这个是测试用例10'); // 测试获取产品 3 套件 5 的case
+r($testcase->getBySuiteTest($productIDList[3], $branch, $suiteIDList[3])) && p('13:title;14:title') && e('这个是测试用例13;这个是测试用例14'); // 测试获取产品 4 套件 7 的case
+r($testcase->getBySuiteTest($productIDList[4], $branch, $suiteIDList[4])) && p('17:title;18:title') && e('这个是测试用例17;这个是测试用例18'); // 测试获取产品 5 套件 9 的case
\ No newline at end of file
diff --git a/module/testcase/test/model/getexecutioncases.php b/module/testcase/test/model/getexecutioncases.php
new file mode 100755
index 0000000000..9f3f39df4f
--- /dev/null
+++ b/module/testcase/test/model/getexecutioncases.php
@@ -0,0 +1,82 @@
+#!/usr/bin/env php
+getExecutionCases();
+cid=1
+pid=1
+
+测试获取执行 101 的用例 >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4
+测试获取执行 101 状态 wait 的用例 >> 1
+测试获取执行 101 状态 normal 的用例 >> 1
+测试获取执行 101 状态 blocked 的用例 >> 1
+测试获取执行 101 状态 investigate 的用例 >> 1
+测试获取执行 101 状态 needconfirm 的用例 >> 4
+测试获取执行 102 的用例 >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8
+测试获取执行 102 状态 wait 的用例 >> 1
+测试获取执行 102 状态 normal 的用例 >> 1
+测试获取执行 102 状态 blocked 的用例 >> 1
+测试获取执行 102 状态 investigate 的用例 >> 1
+测试获取执行 102 状态 needconfirm 的用例 >> 4
+测试获取执行 103 的用例 >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12
+测试获取执行 103 状态 wait 的用例 >> 1
+测试获取执行 103 状态 normal 的用例 >> 1
+测试获取执行 103 状态 blocked 的用例 >> 1
+测试获取执行 103 状态 investigate 的用例 >> 1
+测试获取执行 103 状态 needconfirm 的用例 >> 4
+测试获取执行 104 的用例 >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16
+测试获取执行 104 状态 wait 的用例 >> 1
+测试获取执行 104 状态 normal 的用例 >> 1
+测试获取执行 104 状态 blocked 的用例 >> 1
+测试获取执行 104 状态 investigate 的用例 >> 1
+测试获取执行 104 状态 needconfirm 的用例 >> 4
+测试获取执行 105 的用例 >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20
+测试获取执行 105 状态 wait 的用例 >> 1
+测试获取执行 105 状态 normal 的用例 >> 1
+测试获取执行 105 状态 blocked 的用例 >> 1
+测试获取执行 105 状态 investigate 的用例 >> 1
+测试获取执行 105 状态 needconfirm 的用例 >> 4
+
+*/
+
+$executionIDList = array(101, 102, 103, 104, 105);
+$orderBy = 'id_desc';
+$pager = null;
+$browseTypeList = array('all', 'wait', 'normal', 'blocked', 'investigate', 'needconfirm');
+
+$testcase = new testcaseTest();
+
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[0])) && p('1:title;2:title;3:title;4:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4'); // 测试获取执行 101 的用例
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[1])) && p() && e('1'); // 测试获取执行 101 状态 wait 的用例
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[2])) && p() && e('1'); // 测试获取执行 101 状态 normal 的用例
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[3])) && p() && e('1'); // 测试获取执行 101 状态 blocked 的用例
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[4])) && p() && e('1'); // 测试获取执行 101 状态 investigate 的用例
+r($testcase->getExecutionCasesTest($executionIDList[0], $orderBy, $pager, $browseTypeList[5])) && p() && e('4'); // 测试获取执行 101 状态 needconfirm 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[0])) && p('5:title;6:title;7:title;8:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8'); // 测试获取执行 102 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[1])) && p() && e('1'); // 测试获取执行 102 状态 wait 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[2])) && p() && e('1'); // 测试获取执行 102 状态 normal 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[3])) && p() && e('1'); // 测试获取执行 102 状态 blocked 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[4])) && p() && e('1'); // 测试获取执行 102 状态 investigate 的用例
+r($testcase->getExecutionCasesTest($executionIDList[1], $orderBy, $pager, $browseTypeList[5])) && p() && e('4'); // 测试获取执行 102 状态 needconfirm 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[0])) && p('9:title;10:title;11:title;12:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12'); // 测试获取执行 103 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[1])) && p() && e('1'); // 测试获取执行 103 状态 wait 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[2])) && p() && e('1'); // 测试获取执行 103 状态 normal 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[3])) && p() && e('1'); // 测试获取执行 103 状态 blocked 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[4])) && p() && e('1'); // 测试获取执行 103 状态 investigate 的用例
+r($testcase->getExecutionCasesTest($executionIDList[2], $orderBy, $pager, $browseTypeList[5])) && p() && e('4'); // 测试获取执行 103 状态 needconfirm 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[0])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16'); // 测试获取执行 104 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[1])) && p() && e('1'); // 测试获取执行 104 状态 wait 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[2])) && p() && e('1'); // 测试获取执行 104 状态 normal 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[3])) && p() && e('1'); // 测试获取执行 104 状态 blocked 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[4])) && p() && e('1'); // 测试获取执行 104 状态 investigate 的用例
+r($testcase->getExecutionCasesTest($executionIDList[3], $orderBy, $pager, $browseTypeList[5])) && p() && e('4'); // 测试获取执行 104 状态 needconfirm 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[0])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20'); // 测试获取执行 105 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[1])) && p() && e('1'); // 测试获取执行 105 状态 wait 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[2])) && p() && e('1'); // 测试获取执行 105 状态 normal 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[3])) && p() && e('1'); // 测试获取执行 105 状态 blocked 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[4])) && p() && e('1'); // 测试获取执行 105 状态 investigate 的用例
+r($testcase->getExecutionCasesTest($executionIDList[4], $orderBy, $pager, $browseTypeList[5])) && p() && e('4'); // 测试获取执行 105 状态 needconfirm 的用例
\ No newline at end of file
diff --git a/module/testcase/test/model/getimportfields.php b/module/testcase/test/model/getimportfields.php
new file mode 100755
index 0000000000..5acd4b0b1b
--- /dev/null
+++ b/module/testcase/test/model/getimportfields.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getImportFields();
+cid=1
+pid=1
+
+测试获取product 1 可以导出的字段的名称 >> 用例编号,所属产品,分支/平台,所属模块,B,R,S
+测试获取product 2 可以导出的字段的名称 >> 用例编号,所属产品,分支/平台,所属模块,B,R,S
+测试获取product 3 可以导出的字段的名称 >> 用例编号,所属产品,分支/平台,所属模块,B,R,S
+测试获取product 4 可以导出的字段的名称 >> 用例编号,所属产品,分支/平台,所属模块,B,R,S
+测试获取product 5 可以导出的字段的名称 >> 用例编号,所属产品,分支/平台,所属模块,B,R,S
+
+*/
+
+$productIDList = array(1, 2, 3, 4, 5);
+
+$testcase = new testcaseTest();
+
+r($testcase->getImportFieldsTest($productIDList[0])) && p('id,product,branch,module,bugsAB,resultsAB,stepNumberAB') && e('用例编号,所属产品,分支/平台,所属模块,B,R,S'); // 测试获取product 1 可以导出的字段的名称
+r($testcase->getImportFieldsTest($productIDList[1])) && p('id,product,branch,module,bugsAB,resultsAB,stepNumberAB') && e('用例编号,所属产品,分支/平台,所属模块,B,R,S'); // 测试获取product 2 可以导出的字段的名称
+r($testcase->getImportFieldsTest($productIDList[2])) && p('id,product,branch,module,bugsAB,resultsAB,stepNumberAB') && e('用例编号,所属产品,分支/平台,所属模块,B,R,S'); // 测试获取product 3 可以导出的字段的名称
+r($testcase->getImportFieldsTest($productIDList[3])) && p('id,product,branch,module,bugsAB,resultsAB,stepNumberAB') && e('用例编号,所属产品,分支/平台,所属模块,B,R,S'); // 测试获取product 4 可以导出的字段的名称
+r($testcase->getImportFieldsTest($productIDList[4])) && p('id,product,branch,module,bugsAB,resultsAB,stepNumberAB') && e('用例编号,所属产品,分支/平台,所属模块,B,R,S'); // 测试获取product 5 可以导出的字段的名称
\ No newline at end of file
diff --git a/module/testcase/test/model/getmodulecases.php b/module/testcase/test/model/getmodulecases.php
new file mode 100755
index 0000000000..98882df37e
--- /dev/null
+++ b/module/testcase/test/model/getmodulecases.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+getModuleCases();
+cid=1
+pid=1
+
+测试获取产品1的case >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4
+测试获取产品1 module 1821 1822 的case >> 0
+测试获取产品2的case >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8
+测试获取产品2 module 1825 2827 的case >> 0
+测试获取产品3的case >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例
+测试获取产品3 module 1829 2832 的case >> 0
+测试获取产品4的case >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例
+测试获取产品4 module 1834 2835 的case >> 0
+测试获取产品5的case >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例
+测试获取产品5 module 1838 2840 的case >> 0
+
+*/
+
+$productIDList = array(1, 2, 3, 4, 5);
+$branch = 0;
+$moduleIDList = array('1821,1822', '1825,1827', '1829,1832', '1834,2835', '1838,1840');
+
+$testcase = new testcaseTest();
+
+r($testcase->getModuleCasesTest($productIDList[0])) && p('1:title;2:title;3:title;4:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4'); // 测试获取产品1的case
+r($testcase->getModuleCasesTest($productIDList[0], $branch, $moduleIDList[0])) && p() && e('0'); // 测试获取产品1 module 1821 1822 的case
+r($testcase->getModuleCasesTest($productIDList[1])) && p('5:title;6:title;7:title;8:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8'); // 测试获取产品2的case
+r($testcase->getModuleCasesTest($productIDList[1], $branch, $moduleIDList[1])) && p() && e('0'); // 测试获取产品2 module 1825 2827 的case
+r($testcase->getModuleCasesTest($productIDList[2])) && p('9:title;10:title;11:title;12:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例'); // 测试获取产品3的case
+r($testcase->getModuleCasesTest($productIDList[2], $branch, $moduleIDList[2])) && p() && e('0'); // 测试获取产品3 module 1829 2832 的case
+r($testcase->getModuleCasesTest($productIDList[3])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例'); // 测试获取产品4的case
+r($testcase->getModuleCasesTest($productIDList[3], $branch, $moduleIDList[3])) && p() && e('0'); // 测试获取产品4 module 1834 2835 的case
+r($testcase->getModuleCasesTest($productIDList[4])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例'); // 测试获取产品5的case
+r($testcase->getModuleCasesTest($productIDList[4], $branch, $moduleIDList[4])) && p() && e('0'); // 测试获取产品5 module 1838 2840 的case
\ No newline at end of file
diff --git a/module/testcase/test/model/getmoduleprojectcases.php b/module/testcase/test/model/getmoduleprojectcases.php
new file mode 100755
index 0000000000..6f4cc24459
--- /dev/null
+++ b/module/testcase/test/model/getmoduleprojectcases.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+getModuleProjectCases();
+cid=1
+pid=1
+
+测试获取产品1的case >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4
+测试获取产品1 module 1821 1822 的case >> 0
+测试获取产品2的case >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8
+测试获取产品2 module 1825 2827 的case >> 0
+测试获取产品3的case >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12
+测试获取产品3 module 1829 2832 的case >> 0
+测试获取产品4的case >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16
+测试获取产品4 module 1834 2835 的case >> 0
+测试获取产品5的case >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20
+测试获取产品5 module 1838 2840 的case >> 0
+
+*/
+$productIDList = array(1, 2, 3, 4, 5);
+$branch = 0;
+$moduleIDList = array('1821,1822', '1825,1827', '1829,1832', '1834,2835', '1838,1840');
+
+$testcase = new testcaseTest();
+
+r($testcase->getModuleProjectCasesTest($productIDList[0])) && p('1:title;2:title;3:title;4:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4'); // 测试获取产品1的case
+r($testcase->getModuleProjectCasesTest($productIDList[0], $branch, $moduleIDList[0])) && p() && e('0'); // 测试获取产品1 module 1821 1822 的case
+r($testcase->getModuleProjectCasesTest($productIDList[1])) && p('5:title;6:title;7:title;8:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8'); // 测试获取产品2的case
+r($testcase->getModuleProjectCasesTest($productIDList[1], $branch, $moduleIDList[1])) && p() && e('0'); // 测试获取产品2 module 1825 2827 的case
+r($testcase->getModuleProjectCasesTest($productIDList[2])) && p('9:title;10:title;11:title;12:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12'); // 测试获取产品3的case
+r($testcase->getModuleProjectCasesTest($productIDList[2], $branch, $moduleIDList[2])) && p() && e('0'); // 测试获取产品3 module 1829 2832 的case
+r($testcase->getModuleProjectCasesTest($productIDList[3])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16'); // 测试获取产品4的case
+r($testcase->getModuleProjectCasesTest($productIDList[3], $branch, $moduleIDList[3])) && p() && e('0'); // 测试获取产品4 module 1834 2835 的case
+r($testcase->getModuleProjectCasesTest($productIDList[4])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20'); // 测试获取产品5的case
+r($testcase->getModuleProjectCasesTest($productIDList[4], $branch, $moduleIDList[4])) && p() && e('0'); // 测试获取产品5 module 1838 2840 的case
\ No newline at end of file
diff --git a/module/testcase/test/model/getpairsbyproduct.php b/module/testcase/test/model/getpairsbyproduct.php
new file mode 100644
index 0000000000..6c91aba44f
--- /dev/null
+++ b/module/testcase/test/model/getpairsbyproduct.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getPairsByProduct();
+cid=1
+pid=1
+
+获取产品1的case >> 1:这个是测试用例1
+获取产品41分支1的case >> empty
+
+*/
+$productIDList = array(1, 41);
+$branch = 1;
+
+$testcase = new testcaseTest();
+r($testcase->getPairsByProductTest($productIDList[0])) && p('1') && e('1:这个是测试用例1'); // 获取产品1的case
+r($testcase->getPairsByProductTest($productIDList[1], $branch)) && p() && e('empty'); // 获取产品41分支1的case
diff --git a/module/testcase/test/model/getstatus.php b/module/testcase/test/model/getstatus.php
new file mode 100755
index 0000000000..0cd8a0b411
--- /dev/null
+++ b/module/testcase/test/model/getstatus.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+getStatus();
+cid=1
+pid=1
+
+测试获取create的状态 >> normal
+测试获取review pass 的状态 >> pass
+测试获取review clarify 的状态 >> clarify
+测试获取update的状态 >> wait
+测试获取update 别人变更 的状态 >> 该记录可能已经被改动。请刷新页面重新编辑!
+
+*/
+
+$typeList = array('create', 'review', 'update');
+
+$case1 = new stdclass();
+$case1->status = 'pass';
+
+$case2 = new stdclass();
+$case2->status = 'clarify';
+
+$case = null;
+$param1 = array('lastEditedDate' => '2022-03-04 00:00:00');
+
+$testcase = new testcaseTest();
+
+r($testcase->getStatusTest($typeList[0])) && p() && e('normal'); // 测试获取create的状态
+r($testcase->getStatusTest($typeList[1], $case1)) && p() && e('pass'); // 测试获取review pass 的状态
+r($testcase->getStatusTest($typeList[1], $case2)) && p() && e('clarify'); // 测试获取review clarify 的状态
+r($testcase->getStatusTest($typeList[2], $case)) && p('1') && e('wait'); // 测试获取update的状态
+r($testcase->getStatusTest($typeList[2], $case, $param1)) && p() && e('该记录可能已经被改动。请刷新页面重新编辑!'); // 测试获取update 别人变更 的状态
\ No newline at end of file
diff --git a/module/testcase/test/model/getstorycasecounts.php b/module/testcase/test/model/getstorycasecounts.php
new file mode 100755
index 0000000000..6357650981
--- /dev/null
+++ b/module/testcase/test/model/getstorycasecounts.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getStoryCaseCounts();
+cid=1
+pid=1
+
+测试获取需求 1 2 的测试用例个数 >> 0;8
+测试获取需求 3 4 的测试用例个数 >> 0;0
+测试获取需求 5 6 的测试用例个数 >> 0;8
+测试获取需求 7 8 的测试用例个数 >> 0;0
+测试获取需求 9 10 的测试用例个数 >> 0;6
+
+*/
+
+$stories = array(array('1' => 1, '2' => 2 ), array('3' => 3, '4' => 4 ), array('5' => 5, '6' => 6 ), array('7' => 7, '8' => 8 ), array('9' => 9, '10' => 10 ));
+
+$testcase = new testcaseTest();
+
+r($testcase->getStoryCaseCountsTest($stories[0])) && p('1;2') && e('0;8'); // 测试获取需求 1 2 的测试用例个数
+r($testcase->getStoryCaseCountsTest($stories[1])) && p('3;4') && e('0;0'); // 测试获取需求 3 4 的测试用例个数
+r($testcase->getStoryCaseCountsTest($stories[2])) && p('5;6') && e('0;8'); // 测试获取需求 5 6 的测试用例个数
+r($testcase->getStoryCaseCountsTest($stories[3])) && p('7;8') && e('0;0'); // 测试获取需求 7 8 的测试用例个数
+r($testcase->getStoryCaseCountsTest($stories[4])) && p('9;10') && e('0;6'); // 测试获取需求 9 10 的测试用例个数
\ No newline at end of file
diff --git a/module/testcase/test/model/getstorycases.php b/module/testcase/test/model/getstorycases.php
new file mode 100755
index 0000000000..1259fbd552
--- /dev/null
+++ b/module/testcase/test/model/getstorycases.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getStoryCases();
+cid=1
+pid=1
+
+测试获取需求 2 的关联用例 >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4;用例库用例1;用例库用例2;用例库用例3;用例库用例4
+测试获取需求 6 的关联用例 >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8;用例库用例5;用例库用例6;用例库用例7;用例库用例8
+测试获取需求 10 的关联用例 >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12;用例库用例9;用例库用例10
+测试获取需求 14 的关联用例 >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16
+测试获取需求 18 的关联用例 >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20
+测试获取需求 1 的关联用例 >> 0
+
+*/
+
+$storyIDList = array(2, 6, 10, 14, 18, 1);
+
+$testcase = new testcaseTest();
+
+r($testcase->getStoryCasesTest($storyIDList[0])) && p('1:title;2:title;3:title;4:title;401:title;402:title;403:title;404:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4;用例库用例1;用例库用例2;用例库用例3;用例库用例4'); // 测试获取需求 2 的关联用例
+r($testcase->getStoryCasesTest($storyIDList[1])) && p('5:title;6:title;7:title;8:title;405:title;406:title;407:title;408:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8;用例库用例5;用例库用例6;用例库用例7;用例库用例8'); // 测试获取需求 6 的关联用例
+r($testcase->getStoryCasesTest($storyIDList[2])) && p('9:title;10:title;11:title;12:title;409:title;410:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12;用例库用例9;用例库用例10'); // 测试获取需求 10 的关联用例
+r($testcase->getStoryCasesTest($storyIDList[3])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16'); // 测试获取需求 14 的关联用例
+r($testcase->getStoryCasesTest($storyIDList[4])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20'); // 测试获取需求 18 的关联用例
+r($testcase->getStoryCasesTest($storyIDList[5])) && p() && e('0'); // 测试获取需求 1 的关联用例
\ No newline at end of file
diff --git a/module/testcase/test/model/gettestcases.php b/module/testcase/test/model/gettestcases.php
new file mode 100755
index 0000000000..1fd4a66ae8
--- /dev/null
+++ b/module/testcase/test/model/gettestcases.php
@@ -0,0 +1,71 @@
+#!/usr/bin/env php
+getTestCases();
+cid=1
+pid=1
+
+测试查询产品1 suiteID 1 browseType all 的测试用例 >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4
+测试查询产品1 suiteID 1 browseType wait 的测试用例 >> 这个是测试用例1
+测试查询产品1 suiteID 1 browseType bymodule 的测试用例 >> 这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4
+测试查询产品1 suiteID 1 browseType needconfirm 的测试用例 >> 这个是测试用例4;这个是测试用例3;这个是测试用例2;这个是测试用例1
+测试查询产品1 suiteID 1 browseType bysuite 的测试用例 >> 这个是测试用例1;这个是测试用例2
+测试查询产品2 suiteID 3 browseType all 的测试用例 >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8
+测试查询产品2 suiteID 3 browseType wait 的测试用例 >> 这个是测试用例5
+测试查询产品2 suiteID 3 browseType bymodule 的测试用例 >> 这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8
+测试查询产品2 suiteID 3 browseType needconfirm 的测试用例 >> 这个是测试用例8;这个是测试用例7;这个是测试用例6;这个是测试用例5
+测试查询产品2 suiteID 3 browseType bysuite 的测试用例 >> 这个是测试用例5;这个是测试用例6
+测试查询产品3 suiteID 5 browseType all 的测试用例 >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12
+测试查询产品3 suiteID 5 browseType wait 的测试用例 >> 这个是测试用例9
+测试查询产品3 suiteID 5 browseType bymodule 的测试用例 >> 这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12
+测试查询产品3 suiteID 5 browseType needconfirm 的测试用例 >> 这个是测试用例12;这个是测试用例11;这个是测试用例10;这个是测试用例9
+测试查询产品3 suiteID 5 browseType bysuite 的测试用例 >> 这个是测试用例9;这个是测试用例10
+测试查询产品4 suiteID 7 browseType all 的测试用例 >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16
+测试查询产品4 suiteID 7 browseType wait 的测试用例 >> 这个是测试用例13
+测试查询产品4 suiteID 7 browseType bymodule 的测试用例 >> 这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16
+测试查询产品4 suiteID 7 browseType needconfirm 的测试用例 >> 这个是测试用例16;这个是测试用例15;这个是测试用例14;这个是测试用例13
+测试查询产品4 suiteID 7 browseType bysuite 的测试用例 >> 这个是测试用例13;这个是测试用例14
+测试查询产品5 suiteID 9 browseType all 的测试用例 >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20
+测试查询产品5 suiteID 9 browseType wait 的测试用例 >> 这个是测试用例17
+测试查询产品5 suiteID 9 browseType bymodule 的测试用例 >> 这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20
+测试查询产品5 suiteID 9 browseType needconfirm 的测试用例 >> 这个是测试用例20;这个是测试用例19;这个是测试用例18;这个是测试用例17
+测试查询产品5 suiteID 9 browseType bysuite 的测试用例 >> 这个是测试用例17;这个是测试用例18
+
+*/
+
+$productID = array('1', '2', '3', '4', '5');
+$browseType = array('all', 'wait', 'bymodule', 'needconfirm', 'bysuite');
+$suiteID = array('1', '3', '5', '7', '9');
+
+$testcase = new testcaseTest();
+
+r($testcase->getTestCasesTest($productID[0], $browseType[0], $suiteID[0])) && p('1:title;2:title;3:title;4:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4'); // 测试查询产品1 suiteID 1 browseType all 的测试用例
+r($testcase->getTestCasesTest($productID[0], $browseType[1], $suiteID[0])) && p('1:title') && e('这个是测试用例1'); // 测试查询产品1 suiteID 1 browseType wait 的测试用例
+r($testcase->getTestCasesTest($productID[0], $browseType[2], $suiteID[0])) && p('1:title;2:title;3:title;4:title') && e('这个是测试用例1;这个是测试用例2;这个是测试用例3;这个是测试用例4'); // 测试查询产品1 suiteID 1 browseType bymodule 的测试用例
+r($testcase->getTestCasesTest($productID[0], $browseType[3], $suiteID[0])) && p('0:title;1:title;2:title;3:title') && e('这个是测试用例4;这个是测试用例3;这个是测试用例2;这个是测试用例1'); // 测试查询产品1 suiteID 1 browseType needconfirm 的测试用例
+r($testcase->getTestCasesTest($productID[0], $browseType[4], $suiteID[0])) && p('1:title;2:title') && e('这个是测试用例1;这个是测试用例2'); // 测试查询产品1 suiteID 1 browseType bysuite 的测试用例
+r($testcase->getTestCasesTest($productID[1], $browseType[0], $suiteID[1])) && p('5:title;6:title;7:title;8:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8'); // 测试查询产品2 suiteID 3 browseType all 的测试用例
+r($testcase->getTestCasesTest($productID[1], $browseType[1], $suiteID[1])) && p('5:title') && e('这个是测试用例5'); // 测试查询产品2 suiteID 3 browseType wait 的测试用例
+r($testcase->getTestCasesTest($productID[1], $browseType[2], $suiteID[1])) && p('5:title;6:title;7:title;8:title') && e('这个是测试用例5;这个是测试用例6;这个是测试用例7;这个是测试用例8'); // 测试查询产品2 suiteID 3 browseType bymodule 的测试用例
+r($testcase->getTestCasesTest($productID[1], $browseType[3], $suiteID[1])) && p('0:title;1:title;2:title;3:title') && e('这个是测试用例8;这个是测试用例7;这个是测试用例6;这个是测试用例5'); // 测试查询产品2 suiteID 3 browseType needconfirm 的测试用例
+r($testcase->getTestCasesTest($productID[1], $browseType[4], $suiteID[1])) && p('5:title;6:title') && e('这个是测试用例5;这个是测试用例6'); // 测试查询产品2 suiteID 3 browseType bysuite 的测试用例
+r($testcase->getTestCasesTest($productID[2], $browseType[0], $suiteID[2])) && p('9:title;10:title;11:title;12:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12'); // 测试查询产品3 suiteID 5 browseType all 的测试用例
+r($testcase->getTestCasesTest($productID[2], $browseType[1], $suiteID[2])) && p('9:title') && e('这个是测试用例9'); // 测试查询产品3 suiteID 5 browseType wait 的测试用例
+r($testcase->getTestCasesTest($productID[2], $browseType[2], $suiteID[2])) && p('9:title;10:title;11:title;12:title') && e('这个是测试用例9;这个是测试用例10;这个是测试用例11;这个是测试用例12'); // 测试查询产品3 suiteID 5 browseType bymodule 的测试用例
+r($testcase->getTestCasesTest($productID[2], $browseType[3], $suiteID[2])) && p('0:title;1:title;2:title;3:title') && e('这个是测试用例12;这个是测试用例11;这个是测试用例10;这个是测试用例9'); // 测试查询产品3 suiteID 5 browseType needconfirm 的测试用例
+r($testcase->getTestCasesTest($productID[2], $browseType[4], $suiteID[2])) && p('9:title;10:title') && e('这个是测试用例9;这个是测试用例10'); // 测试查询产品3 suiteID 5 browseType bysuite 的测试用例
+r($testcase->getTestCasesTest($productID[3], $browseType[0], $suiteID[3])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16'); // 测试查询产品4 suiteID 7 browseType all 的测试用例
+r($testcase->getTestCasesTest($productID[3], $browseType[1], $suiteID[3])) && p('13:title') && e('这个是测试用例13'); // 测试查询产品4 suiteID 7 browseType wait 的测试用例
+r($testcase->getTestCasesTest($productID[3], $browseType[2], $suiteID[3])) && p('13:title;14:title;15:title;16:title') && e('这个是测试用例13;这个是测试用例14;这个是测试用例15;这个是测试用例16'); // 测试查询产品4 suiteID 7 browseType bymodule 的测试用例
+r($testcase->getTestCasesTest($productID[3], $browseType[3], $suiteID[3])) && p('0:title;1:title;2:title;3:title') && e('这个是测试用例16;这个是测试用例15;这个是测试用例14;这个是测试用例13'); // 测试查询产品4 suiteID 7 browseType needconfirm 的测试用例
+r($testcase->getTestCasesTest($productID[3], $browseType[4], $suiteID[3])) && p('13:title;14:title') && e('这个是测试用例13;这个是测试用例14'); // 测试查询产品4 suiteID 7 browseType bysuite 的测试用例
+r($testcase->getTestCasesTest($productID[4], $browseType[0], $suiteID[4])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20'); // 测试查询产品5 suiteID 9 browseType all 的测试用例
+r($testcase->getTestCasesTest($productID[4], $browseType[1], $suiteID[4])) && p('17:title') && e('这个是测试用例17'); // 测试查询产品5 suiteID 9 browseType wait 的测试用例
+r($testcase->getTestCasesTest($productID[4], $browseType[2], $suiteID[4])) && p('17:title;18:title;19:title;20:title') && e('这个是测试用例17;这个是测试用例18;这个是测试用例19;这个是测试用例20'); // 测试查询产品5 suiteID 9 browseType bymodule 的测试用例
+r($testcase->getTestCasesTest($productID[4], $browseType[3], $suiteID[4])) && p('0:title;1:title;2:title;3:title') && e('这个是测试用例20;这个是测试用例19;这个是测试用例18;这个是测试用例17'); // 测试查询产品5 suiteID 9 browseType needconfirm 的测试用例
+r($testcase->getTestCasesTest($productID[4], $browseType[4], $suiteID[4])) && p('17:title;18:title') && e('这个是测试用例17;这个是测试用例18'); // 测试查询产品5 suiteID 9 browseType bysuite 的测试用例
\ No newline at end of file
diff --git a/module/testcase/test/model/importfromlib.php b/module/testcase/test/model/importfromlib.php
new file mode 100755
index 0000000000..5d2acc1fa2
--- /dev/null
+++ b/module/testcase/test/model/importfromlib.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+importFromLib();
+cid=1
+pid=1
+
+测试导入用例库用例 401 402 >> 用例库用例1;用例库用例2
+测试导入用例库用例 403 404 >> 用例库用例3;用例库用例4
+测试导入用例库用例 405 406 >> 用例库用例5;用例库用例6
+测试导入用例库用例 407 408 >> 用例库用例7;用例库用例8
+测试导入用例库用例 409 410 >> 用例库用例9;用例库用例10
+
+*/
+
+$productID = 1;
+$caseIdList = array(array('401' => '401', '402' => '402'), array('403' => '403', '404' => '404'), array('405' => '405', '406' => '406'), array('407' => '407', '408' => '408'), array('409' => '409', '410' => '410'));
+
+$testcase = new testcaseTest();
+
+r($testcase->importFromLibTest($productID, $caseIdList[0])) && p('0:title;1:title') && e('用例库用例1;用例库用例2'); // 测试导入用例库用例 401 402
+r($testcase->importFromLibTest($productID, $caseIdList[1])) && p('0:title;1:title') && e('用例库用例3;用例库用例4'); // 测试导入用例库用例 403 404
+r($testcase->importFromLibTest($productID, $caseIdList[2])) && p('0:title;1:title') && e('用例库用例5;用例库用例6'); // 测试导入用例库用例 405 406
+r($testcase->importFromLibTest($productID, $caseIdList[3])) && p('0:title;1:title') && e('用例库用例7;用例库用例8'); // 测试导入用例库用例 407 408
+r($testcase->importFromLibTest($productID, $caseIdList[4])) && p('0:title;1:title') && e('用例库用例9;用例库用例10'); // 测试导入用例库用例 409 410
diff --git a/module/testcase/test/model/joinstep.php b/module/testcase/test/model/joinstep.php
new file mode 100755
index 0000000000..8809c2910c
--- /dev/null
+++ b/module/testcase/test/model/joinstep.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+joinStep();
+cid=1
+pid=1
+
+测试获取步骤 1 2 的字符串 >> 用例步骤描述1 EXPECT:这是用例预期结果1 用例步骤描述2 EXPECT:这是用例预期结果2
+测试获取步骤 3 4 的字符串 >> 用例步骤描述3 EXPECT:这是用例预期结果3 用例步骤描述4 EXPECT:这是用例预期结果4
+测试获取步骤 5 6 的字符串 >> 用例步骤描述5 EXPECT:这是用例预期结果5 用例步骤描述6 EXPECT:这是用例预期结果6
+测试获取步骤 7 8 的字符串 >> 用例步骤描述7 EXPECT:这是用例预期结果7 用例步骤描述8 EXPECT:这是用例预期结果8
+测试获取步骤 9 10 的字符串 >> 用例步骤描述9 EXPECT:这是用例预期结果9 用例步骤描述10 EXPECT:这是用例预期结果10
+
+*/
+
+$stepIDList = array('1,2', '3,4', '5,6', '7,8', '9,10');
+
+$testcase = new testcaseTest();
+
+r($testcase->joinStepTest($stepIDList[0])) && p() && e('用例步骤描述1 EXPECT:这是用例预期结果1 用例步骤描述2 EXPECT:这是用例预期结果2'); // 测试获取步骤 1 2 的字符串
+r($testcase->joinStepTest($stepIDList[1])) && p() && e('用例步骤描述3 EXPECT:这是用例预期结果3 用例步骤描述4 EXPECT:这是用例预期结果4'); // 测试获取步骤 3 4 的字符串
+r($testcase->joinStepTest($stepIDList[2])) && p() && e('用例步骤描述5 EXPECT:这是用例预期结果5 用例步骤描述6 EXPECT:这是用例预期结果6'); // 测试获取步骤 5 6 的字符串
+r($testcase->joinStepTest($stepIDList[3])) && p() && e('用例步骤描述7 EXPECT:这是用例预期结果7 用例步骤描述8 EXPECT:这是用例预期结果8'); // 测试获取步骤 7 8 的字符串
+r($testcase->joinStepTest($stepIDList[4])) && p() && e('用例步骤描述9 EXPECT:这是用例预期结果9 用例步骤描述10 EXPECT:这是用例预期结果10'); // 测试获取步骤 9 10 的字符串
\ No newline at end of file
diff --git a/module/testcase/test/model/review.php b/module/testcase/test/model/review.php
new file mode 100755
index 0000000000..145f4206d1
--- /dev/null
+++ b/module/testcase/test/model/review.php
@@ -0,0 +1,54 @@
+#!/usr/bin/env php
+review();
+cid=1
+pid=1
+
+测试评审用例 1 >> status,wait,normal
+测试评审用例 2 >> reviewedBy,admin,test2
+测试评审用例 3 >> status,wait,normal
+测试评审用例 4 >> reviewedBy,admin,test4
+测试评审用例 5 >> status,wait,normal
+
+*/
+
+$caseIDList = array(1, 5, 9, 13, 17);
+
+$case1 = new stdclass();
+$case1->result = 'pass';
+$case1->status = 'normal';
+$case1->reviewedBy = array('test1');
+
+$case2 = new stdclass();
+$case2->result = 'clarify';
+$case2->status = 'wait';
+$case2->reviewedBy = array('test2');
+
+$case3 = new stdclass();
+$case3->result = 'pass';
+$case3->status = 'normal';
+$case3->reviewedBy = array('test3');
+
+$case4 = new stdclass();
+$case4->result = 'clarify';
+$case4->status = 'wait';
+$case4->reviewedBy = array('test4');
+
+$case5 = new stdclass();
+$case5->result = 'pass';
+$case5->status = 'normal';
+$case5->reviewedBy = array('test5');
+
+$testcase = new testcaseTest();
+
+r($testcase->reviewTest($caseIDList[0], $case1)) && p('0:field,old,new') && e('status,wait,normal'); // 测试评审用例 1
+r($testcase->reviewTest($caseIDList[1], $case2)) && p('0:field,old,new') && e('reviewedBy,admin,test2'); // 测试评审用例 2
+r($testcase->reviewTest($caseIDList[2], $case3)) && p('0:field,old,new') && e('status,wait,normal'); // 测试评审用例 3
+r($testcase->reviewTest($caseIDList[3], $case4)) && p('0:field,old,new') && e('reviewedBy,admin,test4'); // 测试评审用例 4
+r($testcase->reviewTest($caseIDList[4], $case5)) && p('0:field,old,new') && e('status,wait,normal'); // 测试评审用例 5
diff --git a/module/testcase/test/model/synccase2project.php b/module/testcase/test/model/synccase2project.php
new file mode 100755
index 0000000000..8bfab57e20
--- /dev/null
+++ b/module/testcase/test/model/synccase2project.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+syncCase2Project();
+cid=1
+pid=1
+
+测试同步用例 1 到关联项目中 >> 2
+测试同步用例 2 到关联项目中 >> 2
+测试同步用例 3 到关联项目中 >> 2
+测试同步用例 4 到关联项目中 >> 2
+测试同步用例 5 到关联项目中 >> 2
+
+*/
+
+$caseIDList = array(1, 5, 9, 13, 17, 2);
+
+$testcase = new testcaseTest();
+
+r($testcase->syncCase2ProjectTest($caseIDList[0])) && p() && e('2'); // 测试同步用例 1 到关联项目中
+r($testcase->syncCase2ProjectTest($caseIDList[1])) && p() && e('2'); // 测试同步用例 2 到关联项目中
+r($testcase->syncCase2ProjectTest($caseIDList[2])) && p() && e('2'); // 测试同步用例 3 到关联项目中
+r($testcase->syncCase2ProjectTest($caseIDList[3])) && p() && e('2'); // 测试同步用例 4 到关联项目中
+r($testcase->syncCase2ProjectTest($caseIDList[4])) && p() && e('2'); // 测试同步用例 5 到关联项目中
diff --git a/module/testcase/test/model/update.php b/module/testcase/test/model/update.php
new file mode 100755
index 0000000000..9d8bc9bad2
--- /dev/null
+++ b/module/testcase/test/model/update.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试修改标题 >> title,这个是测试用例1,修改后的名称
+测试重复修改标题 >> 没有数据更新
+测试修改前置条件 >> precondition,这是前置条件1,修改后的前置条件
+测试修改状态 >> status,wait,normal
+测试修改优先级 >> pri,1,3
+
+*/
+
+$changeTitle = array('title' => '修改后的名称');
+$changePrecondition = array('precondition' => '修改后的前置条件');
+$changeStatus = array('status' => 'normal');
+$changePri = array('pri' => '3');
+
+$testcase = new testcaseTest();
+
+r($testcase->updateTest($changeTitle)) && p('0:field,old,new') && e('title,这个是测试用例1,修改后的名称'); // 测试修改标题
+r($testcase->updateTest($changeTitle)) && p('0:field,old,new') && e('没有数据更新'); // 测试重复修改标题
+r($testcase->updateTest($changePrecondition)) && p('0:field,old,new') && e('precondition,这是前置条件1,修改后的前置条件'); // 测试修改前置条件
+r($testcase->updateTest($changeStatus)) && p('0:field,old,new') && e('status,wait,normal'); // 测试修改状态
+r($testcase->updateTest($changePri)) && p('0:field,old,new') && e('pri,1,3'); // 测试修改优先级
diff --git a/module/testcase/test/model/updatecase2project.php b/module/testcase/test/model/updatecase2project.php
new file mode 100755
index 0000000000..e886cf9120
--- /dev/null
+++ b/module/testcase/test/model/updatecase2project.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+updateCase2Project();
+cid=1
+pid=1
+
+测试修改用例 1 产品 >> 101,2,1
+测试修改用例 1 需求 >> 101,2,1;12,1,1;102,1,1
+测试修改用例 3 产品 >> 101,2,3
+测试修改用例 3 需求 >> 101,2,3;12,1,3;102,1,3
+测试修改用例 5 产品 >> 102,1,5
+测试修改用例 5 需求 >> 102,1,5;11,2,5;101,2,5
+测试修改用例 7 产品 >> 102,1,7
+测试修改用例 7 需求 >> 102,1,7;11,2,7;101,2,7
+测试修改用例 9 产品 >> 103,1,9
+测试修改用例 9 需求 >> 103,1,9;11,3,9;101,3,9
+
+*/
+
+$caseIDList = array('1', '3', '5', '7', '9');
+$objectTypeList = array('product', 'story');
+$objectIDList = array('2', '1', '6', '2');
+
+$testcase = new testcaseTest();
+
+r($testcase->updateCase2ProjectTest($caseIDList[0], $objectTypeList[0], $objectIDList[0])) && p('0:project,product,case') && e('101,2,1'); // 测试修改用例 1 产品
+r($testcase->updateCase2ProjectTest($caseIDList[0], $objectTypeList[1], $objectIDList[2])) && p('0:project,product,case;1:project,product,case;2:project,product,case') && e('101,2,1;12,1,1;102,1,1'); // 测试修改用例 1 需求
+r($testcase->updateCase2ProjectTest($caseIDList[1], $objectTypeList[0], $objectIDList[0])) && p('0:project,product,case') && e('101,2,3'); // 测试修改用例 3 产品
+r($testcase->updateCase2ProjectTest($caseIDList[1], $objectTypeList[1], $objectIDList[2])) && p('0:project,product,case;1:project,product,case;2:project,product,case') && e('101,2,3;12,1,3;102,1,3'); // 测试修改用例 3 需求
+r($testcase->updateCase2ProjectTest($caseIDList[2], $objectTypeList[0], $objectIDList[1])) && p('0:project,product,case') && e('102,1,5'); // 测试修改用例 5 产品
+r($testcase->updateCase2ProjectTest($caseIDList[2], $objectTypeList[1], $objectIDList[3])) && p('0:project,product,case;1:project,product,case;2:project,product,case') && e('102,1,5;11,2,5;101,2,5'); // 测试修改用例 5 需求
+r($testcase->updateCase2ProjectTest($caseIDList[3], $objectTypeList[0], $objectIDList[1])) && p('0:project,product,case') && e('102,1,7'); // 测试修改用例 7 产品
+r($testcase->updateCase2ProjectTest($caseIDList[3], $objectTypeList[1], $objectIDList[3])) && p('0:project,product,case;1:project,product,case;2:project,product,case') && e('102,1,7;11,2,7;101,2,7'); // 测试修改用例 7 需求
+r($testcase->updateCase2ProjectTest($caseIDList[4], $objectTypeList[0], $objectIDList[1])) && p('0:project,product,case') && e('103,1,9'); // 测试修改用例 9 产品
+r($testcase->updateCase2ProjectTest($caseIDList[4], $objectTypeList[1], $objectIDList[3])) && p('0:project,product,case;1:project,product,case;2:project,product,case') && e('103,1,9;11,3,9;101,3,9'); // 测试修改用例 9 需求
diff --git a/module/testcase/test/testcase.class.php b/module/testcase/test/testcase.class.php
new file mode 100644
index 0000000000..73723830a0
--- /dev/null
+++ b/module/testcase/test/testcase.class.php
@@ -0,0 +1,755 @@
+objectModel = $tester->loadModel('testcase');
+ }
+
+ /**
+ * Test create a case.
+ *
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function createTest($param)
+ {
+ $bugID = 0;
+
+ $_POST['product'] = '1';
+ $_POST['module'] = '1821';
+ $_POST['type'] = 'feature';
+ $_POST['stage'] = array('', 'unittest');
+ $_POST['story'] = '4';
+ $_POST['color'] = '';
+ $_POST['pri'] = '3';
+ $_POST['precondition'] = '前置条件';
+ $_POST['steps'] = array('1' => '1','1.1' => '1.1', '1.2' => '1.2', '2' => '2', '3' => '3', '4' => '');
+ $_POST['stepType'] = array('1' => 'group','1.1' => 'item', '1.2' => 'item', '2' => 'step', '3' => 'item', '4' => 'step');
+ $_POST['expects'] = array('1' => '','1.1' => '', '1.2' => '', '2' => '', '3' => '', '4' => '');
+ $_POST['keywords'] = '关键词1,关键词2';
+ $_POST['status'] = 'normal';
+ $_POST['labels'] = array('');
+ $_POST['files'] = array('');
+
+ foreach($param as $field => $value) $_POST[$field] = $value;
+
+ $objects = $this->objectModel->create($bugID);
+
+ unset($_POST);
+
+ if(dao::isError()) return isset($param['type']) ? dao::getError()['type'][0] : dao::getError()['title'][0];
+
+ return $objects;
+ }
+
+ /**
+ * Test batch create cases.
+ *
+ * @param array $param
+ * @access public
+ * @return int
+ */
+ function batchCreateTest($param)
+ {
+ $productID = 1;
+ $branch = 0;
+ $storyID = 0;
+
+ $module = array(0, 0, 0);
+ $story = array(0, 0, 0);
+ $title = array('测试批量创建1', '测试批量创建2', '测试批量创建3');
+ $color = array('#3da7f5', '', '#ffaf38');
+ $type = array('performance', 'config', 'install');
+ $pri = array('1', '2', '3');
+ $precondition = array('测试批量创建前置1', '测试批量创建前置2', '测试批量创建前置3');
+ $keywords = array('测试批量创建关键词1', '测试批量创建关键词2', '测试批量创建关键词3');
+ $stage = array(array('smoke'), array('bvt'), array('intergrate'));
+ $needReview = array(0, 0, 0);
+
+ $_POST['module'] = $module;
+ $_POST['story'] = $story;
+ $_POST['title'] = $title;
+ $_POST['color'] = $color;
+ $_POST['type'] = $type;
+ $_POST['pri'] = $pri;
+ $_POST['precondition'] = $precondition;
+ $_POST['keywords'] = $keywords;
+ $_POST['stage'] = $stage;
+ $_POST['needReview'] = $needReview;
+
+ foreach($param as $field => $value) $_POST[$field] = $value;
+
+ $objects = $this->objectModel->batchCreate($productID, $branch, $storyID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get cases of a module.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param int $moduleIdList
+ * @param string $browseType
+ * @param string $auto
+ * @param string $caseType
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getModuleCasesTest($productID, $branch = 0, $moduleIdList = 0, $browseType = '', $auto = 'no', $caseType = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getModuleCases($productID, $branch, $moduleIdList, $browseType, $auto, $caseType, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get project cases of a module.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param int $moduleIdList
+ * @param string $browseType
+ * @param string $auto
+ * @param string $caseType
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getModuleProjectCasesTest($productID, $branch = 0, $moduleIdList = 0, $browseType = '', $auto = 'no', $caseType = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getModuleProjectCases($productID, $branch, $moduleIdList, $browseType, $auto, $caseType, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get execution cases.
+ *
+ * @param int $executionID
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $browseType
+ * @access public
+ * @return string
+ */
+ public function getExecutionCasesTest($executionID, $orderBy = 'id_desc', $pager = null, $browseType = '')
+ {
+ $objects = $this->objectModel->getExecutionCases($executionID, $orderBy, $pager, $browseType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $browseType == 'all' ? $objects : count($objects);
+ }
+
+ /**
+ * Test get cases by suite.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param int $suiteID
+ * @param int $moduleIdList
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $auto
+ * @access public
+ * @return array
+ */
+ public function getBySuiteTest($productID, $branch = 0, $suiteID = 0, $moduleIdList = 0, $orderBy = 'id_desc', $pager = null, $auto = 'no')
+ {
+ $objects = $this->objectModel->getBySuite($productID, $branch, $suiteID, $moduleIdList, $orderBy, $pager, $auto);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get case info by ID.
+ *
+ * @param int $caseID
+ * @param int $version
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($caseID, $version = 0)
+ {
+ $object = $this->objectModel->getById($caseID, $version = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get case list.
+ *
+ * @param string $caseIDList
+ * @access public
+ * @return array
+ */
+ public function getByListTest($caseIDList = 0)
+ {
+ $objects = $this->objectModel->getByList($caseIDList = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get test cases.
+ *
+ * @param int $productID
+ * @param string $browseType
+ * @param int $queryID
+ * @param string $auto
+ * @access public
+ * @return array
+ */
+ public function getTestCasesTest($productID, $browseType, $queryID, $auto = 'no')
+ {
+ $objects = $this->objectModel->getTestCases($productID, 0, $browseType, $queryID, $moduleID, '', 'id_desc', null, $auto);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get cases by assignedTo.
+ *
+ * @param string $account
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $auto
+ * @access public
+ * @return string
+ */
+ public function getByAssignedToTest($account, $orderBy = 'id_desc', $pager = null, $auto = 'no')
+ {
+ $objects = $this->objectModel->getByAssignedTo($account, $orderBy = 'id_desc', $pager = null, $auto = 'no');
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = implode(array_keys($objects), ',');
+ return $ids;
+ }
+
+ /**
+ * Test get cases by openedBy
+ *
+ * @param string $account
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $auto
+ * @access public
+ * @return array
+ */
+ public function getByOpenedByTest($account, $orderBy = 'id_desc', $pager = null, $auto = 'no')
+ {
+ $objects = $this->objectModel->getByOpenedBy($account, $orderBy = 'id_desc', $pager = null, $auto = 'no');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get cases by type.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @param string $type
+ * @param string $status
+ * @param int $moduleID
+ * @param string $orderBy
+ * @param object $pager
+ * @param string $auto
+ * @access public
+ * @return int
+ */
+ public function getByStatusTest($productID = 0, $branch = 0, $type = 'all', $status = 'all', $moduleID = 0, $orderBy = 'id_desc', $pager = null, $auto = 'no')
+ {
+ $objects = $this->objectModel->getByStatus($productID, $branch, $type, $status, $moduleID, $orderBy, $pager, $auto);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get stories' cases.
+ *
+ * @param int $storyID
+ * @access public
+ * @return array
+ */
+ public function getStoryCasesTest($storyID)
+ {
+ $objects = $this->objectModel->getStoryCases($storyID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get case pairs by product id and branch.
+ *
+ * @param int $productID
+ * @param int $branch
+ * @access public
+ * @return array
+ */
+ public function getPairsByProductTest($productID = 0, $branch = 0)
+ {
+ $objects = $this->objectModel->getPairsByProduct($productID, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ if(empty($objects)) return 'empty';
+ return $objects;
+ }
+
+ /**
+ * Test get counts of some stories' cases.
+ *
+ * @param array $stories
+ * @access public
+ * @return void
+ */
+ public function getStoryCaseCountsTest($stories)
+ {
+ $counts = $this->objectModel->getStoryCaseCounts($stories);
+
+ if(dao::isError()) return dao::getError();
+
+ return $counts;
+ }
+
+ /**
+ * Test update a case.
+ *
+ * @param array $param
+ * @access public
+ * @return int
+ */
+ public function updateTest($param = array())
+ {
+ $caseId = 1;
+ $case = $this->objectModel->getById($caseId);
+
+ $_POST['title'] = $case->title;
+ $_POST['color'] = $case->color;
+ $_POST['precondition'] = $case->precondition;
+ $_POST['steps'] = array('用例步骤描述1');
+ $_POST['stepType'] = array('step');
+ $_POST['expects'] = array('这是用例预期结果1');
+ $_POST['comment'] = '';
+ $_POST['labels'] = '';
+ $_POST['lastEditedDate'] = $case->lastEditedDate;
+ $_POST['product'] = $case->product;
+ $_POST['module'] = $case->module;
+ $_POST['story'] = $case->story;
+ $_POST['type'] = $case->type;
+ $_POST['stage'] = $case->stage;
+ $_POST['pri'] = $case->pri;
+ $_POST['status'] = $case->status;
+ $_POST['keywords'] = $case->keywords;
+
+ foreach($param as $field => $value) $_POST[$field] = $value;
+
+ $change = $this->objectModel->update('1');
+ if($change == array()) $change = '没有数据更新';
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test review case.
+ *
+ * @param int $caseID
+ * @param object $case
+ * @access public
+ * @return array
+ */
+ public function reviewTest($caseID, $case)
+ {
+ foreach($case as $field => $value) $_POST[$field] = $value;
+
+ $objects = $this->objectModel->review($caseID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test batch review cases.
+ *
+ * @param array $caseIdList
+ * @param string $result
+ * @access public
+ * @return array
+ */
+ public function batchReviewTest($caseIdList, $result)
+ {
+ $objects = $this->objectModel->batchReview($caseIdList, $result);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test batch update cases.
+ *
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function batchUpdateTest($index, $param = array())
+ {
+ $batchUpdateField['caseIDList'] = array('1' => 1, '2' => 2, '3' => 3, '4' => 4);
+ $batchUpdateField['pris'] = array('1' => 1, '2' => 2, '3' => 3, '4' => 4);
+ $batchUpdateField['statuses'] = array('1' => 'wait', '2' => 'normal', '3' => 'blocked', '4' => 'investigate');
+ $batchUpdateField['modules'] = array('1' => 0, '2' => 0, '3' => 0, '4' => 0);
+ $batchUpdateField['branches'] = array('1' => 0, '2' => 0, '3' => 0, '4' => 0);
+ $batchUpdateField['story'] = array('1' => 2, '2' => 2, '3' => 2, '4' => 2);
+ $batchUpdateField['product'] = array('1' => 1, '2' => 1, '3' => 1, '4' => 1);
+ $batchUpdateField['title'] = array('1' => '这个是测试用例1', '2' => '这个是测试用例2', '3' => '这个是测试用例3', '4' => '这个是测试用例4');
+ $batchUpdateField['color'] = array('1' => '#3da7f5', '2' => '#75c941', '3' => '#2dbdb2', '4' => '#797ec9');
+ $batchUpdateField['types'] = array('1' => 'feature', '2' => 'performance', '3' => 'config', '4' => 'install');
+ $batchUpdateField['precondition'] = array('1' => '这是前置条件1', '2' => '这是前置条件2', '3' => '这是前置条件3', '4' => '这是前置条件4');
+ $batchUpdateField['keywords'] = array('1' => '这是关键词1', '2' => '这是关键词2', '3' => '这是关键词3', '4' => '这是关键词4');
+ $batchUpdateField['stages'] = array('1' => array('unittest'), '2' => array('feature'), '3' => array('intergrate'), '4' => array('system'));
+
+ foreach($batchUpdateField as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->batchUpdate();
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects[$index][0];
+ }
+
+ /**
+ * Test batch change branch.
+ *
+ * @param array $caseIDList
+ * @param int $branchID
+ * @access public
+ * @return array
+ */
+ public function batchChangeBranchTest($caseIDList, $branchID)
+ {
+ $this->objectModel->batchChangeBranch($caseIDList, $branchID);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByList($caseIDList);
+ return $objects;
+ }
+
+ /**
+ * Test batch change module.
+ *
+ * @param array $caseIDList
+ * @param int $moduleID
+ * @access public
+ * @return array
+ */
+ public function batchChangeModuleTest($caseIDList, $moduleID)
+ {
+ $this->objectModel->batchChangeModule($caseIDList, $moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByList($caseIDList);
+ return $objects;
+ }
+
+ /**
+ * Test batch case type change.
+ *
+ * @param array $caseIdList
+ * @param string $result
+ * @access public
+ * @return array
+ */
+ public function batchCaseTypeChangeTest($caseIdList, $result)
+ {
+ $this->objectModel->batchCaseTypeChange($caseIdList, $result);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByList($caseIdList);
+ return $objects;
+ }
+
+ /**
+ * Test join steps to a string, thus can diff them.
+ *
+ * @param array $stepIDList
+ * @access public
+ * @return string
+ */
+ public function joinStepTest($stepIDList)
+ {
+ global $tester;
+ $steps = $tester->dao->select('*')->from(TABLE_CASESTEP)->where('id')->in($stepIDList)->fetchAll();
+
+ $string = $this->objectModel->joinStep($steps);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = str_replace("\n", ' ', $string);
+ return $string;
+ }
+
+ /**
+ * Test create from import.
+ *
+ * @param int $productID
+ * @param array $param
+ * @access public
+ * @return string
+ */
+ public function createFromImportTest($productID, $param = array())
+ {
+ global $tester;
+
+ $_POST['product'] = array('1' => '1', '2' => '1');
+ $_POST['keywords'] = array('1' => '这是关键词1', '2' => '这是关键词2');
+ $_POST['title'] = array('1' => '导入测试用例1', '2' => '导入测试用例2');
+ $_POST['module'] = array('1' => '0', '2' => '0');
+ $_POST['story'] = array('1' => '2', '2' => '2');
+ $_POST['pri'] = array('1' => '1', '2' => '2');
+ $_POST['type'] = array('1' => 'performance', '2' => 'feature');
+ $_POST['stage'] = array('1' => array('0' => 'feature'), '2' => array('0' => 'unittest'));
+ $_POST['precondition'] = array('1' => '这是前置条件1', '2' => '这是前置条件2');
+ $_POST['stepType'] = array('1' => array('1' => 'step'), '2' => array('1' => 'step'));
+ $_POST['desc'] = array('1' => array('1' => '用例步骤描述1'), '2' => array('1' => '用例步骤描述2'));
+ $_POST['expect'] = array('1' => array('1' => '这是用例预期结果1'), '2' => array('1' => '这是用例预期结果2'));
+ $_POST['isEndPage'] = '1';
+ $_POST['pagerID'] = '1';
+
+ foreach($param as $field => $value) $_POST[$field] = $value;
+
+ $fileName = __DIR__ . DS . 'a.txt';
+ fopen($fileName, 'a');
+ $tester->session->fileImport = $fileName;
+
+ $this->objectModel->createFromImport($productID, 0);
+
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $tester->dao->select('*')->from(TABLE_CASE)->where('product')->eq(1)->andWhere('lib')->eq(0)->markLeft()->andWhere('id')->gt(560)->orWhere('id')->in('1,2')->markRight()->fetchAll('title');
+ $titles = implode(',', array_keys($objects));
+ return $titles;
+ }
+
+ /**
+ * Test get fields for import.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getImportFieldsTest($productID = 0)
+ {
+ $object = $this->objectModel->getImportFields($productID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test import case from Lib.
+ *
+ * @param int $productID
+ * @param array $caseIdList
+ * @access public
+ * @return array
+ */
+ public function importFromLibTest($productID, $caseIdList = array())
+ {
+ $_POST['module'] = array('410' => 0, '409' => 'ditto', '408' => 'ditto', '407' => 'ditto', '406' => 'ditto', '405' => 'ditto', '404' => 'ditto', '403' => 'ditto', '402' => 'ditto', '401' => 'ditto');
+ $_POST['caseIdList'] = $caseIdList;
+
+ $this->objectModel->importFromLib($productID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_CASE)->where('fromCaseID')->in($caseIdList)->orderBy('id_asc')->fetchAll();
+ return $objects;
+ }
+
+ /**
+ * Test append bugs and results.
+ *
+ * @param array $cases
+ * @param string $type
+ * @access public
+ * @return array
+ */
+ public function appendDataTest($cases, $type = 'case')
+ {
+ $objects = $this->objectModel->appendData($cases, $type = 'case');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test check whether force not review.
+ *
+ * @access public
+ * @return int
+ */
+ public function forceNotReviewTest()
+ {
+ $object = $this->objectModel->forceNotReview();
+
+ if(dao::isError()) return dao::getError();
+
+ return $object ? 1 : 2;
+ }
+
+ /**
+ * Test sync case to project.
+ *
+ * @param int $caseID
+ * @access public
+ * @return int
+ */
+ public function syncCase2ProjectTest($caseID)
+ {
+ global $tester;
+ $tester->dao->delete()->from(TABLE_PROJECTCASE)->where('`case`')->eq($caseID)->exec();
+ $case = $this->objectModel->getByID($caseID);
+ $this->objectModel->syncCase2Project($case, $caseID);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $tester->dao->select('*')->from(TABLE_PROJECTCASE)->where('`case`')->eq($caseID)->fetchAll();
+ return count($objects);
+ }
+
+ /**
+ * Test deal with the relationship between the case and project when edit the case.
+ *
+ * @param int $caseID
+ * @param string $objectType
+ * @param int $objectID
+ * @access public
+ * @return array
+ */
+ public function updateCase2ProjectTest($caseID, $objectType, $objectID)
+ {
+ $oldCase = $this->objectModel->getByID($caseID);
+
+ $case = new stdclass();
+ $case->title = $oldCase->title;
+ $case->color = $oldCase->color;
+ $case->precondition = $oldCase->precondition;
+ $case->lastEditedDate = $oldCase->lastEditedDate;
+ $case->product = $objectType == 'product' ? $objectID : $oldCase->product;
+ $case->module = $oldCase->module;
+ $case->story = $objectType == 'story' ? $objectID : $oldCase->story;
+ $case->type = $oldCase->type;
+ $case->stage = $oldCase->stage;
+ $case->pri = $oldCase->pri;
+ $case->status = $oldCase->status;
+ $case->keywords = $oldCase->keywords;
+ $case->version = $oldCase->version + 1;
+ $case->linkCase = $oldCase->linkCase;
+ $case->lastEditedBy = $oldCase->lastEditedBy;
+ $case->branch = $oldCase->branch;
+
+ $this->objectModel->updateCase2Project($oldCase, $case, $caseID);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_PROJECTCASE)->where('`case`')->eq($caseID)->fetchAll();
+ return $objects;
+ }
+
+ /**
+ * Test get status for different method.
+ *
+ * @param string $methodName
+ * @param object $case
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function getStatusTest($methodName, $case = null, $param = array())
+ {
+ if($methodName == 'update')
+ {
+ $case = $this->objectModel->getByID(1);
+ $_POST['title'] = $case->title;
+ $_POST['color'] = $case->color;
+ $_POST['precondition'] = $case->precondition;
+ $_POST['steps'] = array('用例步骤描述1');
+ $_POST['stepType'] = array('step');
+ $_POST['expects'] = array('这是用例预期结果1');
+ $_POST['comment'] = '';
+ $_POST['labels'] = '';
+ $_POST['lastEditedDate'] = $case->lastEditedDate;
+ $_POST['product'] = $case->product;
+ $_POST['module'] = $case->module;
+ $_POST['story'] = $case->story;
+ $_POST['type'] = $case->type;
+ $_POST['stage'] = $case->stage;
+ $_POST['pri'] = $case->pri;
+ $_POST['status'] = $case->status;
+ $_POST['keywords'] = $case->keywords;
+
+ foreach($param as $field => $value) $_POST[$field] = $value;
+ }
+
+ $objects = $this->objectModel->getStatus($methodName, $case);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError()[0];
+
+ return $objects;
+ }
+}
diff --git a/module/testreport/test/model/create.php b/module/testreport/test/model/create.php
new file mode 100755
index 0000000000..7138917be9
--- /dev/null
+++ b/module/testreport/test/model/create.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+正常新增 >> 11,正常新增
+负责人为空测试 >> 『负责人』不能为空。
+标题为空测试 >> 『标题』不能为空。
+参与人员测试 >> 12
+
+*/
+$members = array('dev1','dev11');
+$cases = array(1,2,3,4);
+$title = array('正常新增', '负责人为空测试', '参与人员为空测试', '');
+
+$testreport = new testreportTest();
+
+$normalReport = array('owner' => 'user3', 'members' => $members, 'title' => $title[0], 'report' => '', 'cases' => $cases) ;
+$noOwner = array('owner' => '', 'members' => $members, 'title' => $title[1], 'report' => '', 'cases' => $cases) ;
+$noTitle = array('owner' => 'user3', 'members' => $members, 'title' => $title[3], 'report' => '', 'cases' => $cases) ;
+$noMembers = array('owner' => 'user3', 'members' => '', 'title' => $title[2], 'report' => '', 'cases' => $cases) ;
+
+r($testreport->createTest($normalReport)) && p('id,title') && e('11,正常新增'); //正常新增
+r($testreport->createTest($noOwner)) && p('owner:0') && e('『负责人』不能为空。'); //负责人为空测试
+r($testreport->createTest($noTitle)) && p('title:0') && e('『标题』不能为空。'); //标题为空测试
+r($testreport->createTest($noMembers)) && p('id') && e('12'); //参与人员测试
+
diff --git a/module/testreport/test/model/getbug4report.php b/module/testreport/test/model/getbug4report.php
new file mode 100755
index 0000000000..90f0da74b6
--- /dev/null
+++ b/module/testreport/test/model/getbug4report.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getBug4Report();
+cid=1
+pid=1
+
+正常查询 >> 0;0
+taskIDs为空查询 >> 0;0
+productIdList为空查询 >> 0;0
+buildIDs为空查询 >> 0;0
+
+*/
+$taskIDs = array('1');
+$productIdList = array('1');
+$reportID = '1';
+$buildIDs = array('11');
+
+$testreport = new testreportTest();
+r($testreport->getBug4ReportTest($taskIDs, $productIdList, $reportID, $buildIDs)) && p('1:foundBugs;1:countBugByTask') && e('0;0');//正常查询
+r($testreport->getBug4ReportTest(array(), $productIdList, $reportID, $buildIDs)) && p('1:foundBugs;1:countBugByTask') && e('0;0');//taskIDs为空查询
+r($testreport->getBug4ReportTest($taskIDs, array(), $reportID, $buildIDs)) && p('1:foundBugs;1:countBugByTask') && e('0;0');//productIdList为空查询
+r($testreport->getBug4ReportTest($taskIDs, $productIdList, $reportID, array())) && p('1:foundBugs;1:countBugByTask') && e('0;0');//buildIDs为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getbugs4test.php b/module/testreport/test/model/getbugs4test.php
new file mode 100755
index 0000000000..916585431d
--- /dev/null
+++ b/module/testreport/test/model/getbugs4test.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+getBugs4Test();
+cid=1
+pid=1
+
+正常查询 >> 0
+buildIdList为空查询 >> 0
+product为空查询 >> 0
+type为project查询 >> 0
+type为execution查询 >> 0
+type为空查询 >> 1;301
+
+*/
+$buildIdList = array('11' ,'');
+$product = array('1', '');
+$taskID = '1';
+$type = array('build', 'project', 'execution', '');
+
+$testreport = new testreportTest();
+r($testreport->getBugs4TestTest($buildIdList[0], $product[0], $taskID, $type[0])) && p() && e('0'); //正常查询
+r($testreport->getBugs4TestTest($buildIdList[1], $product[0], $taskID, $type[0])) && p() && e('0'); //buildIdList为空查询
+r($testreport->getBugs4TestTest($buildIdList[0], $product[1], $taskID, $type[0])) && p() && e('0'); //product为空查询
+r($testreport->getBugs4TestTest($buildIdList[0], $product[0], $taskID, $type[1])) && p() && e('0'); //type为project查询
+r($testreport->getBugs4TestTest($buildIdList[0], $product[0], $taskID, $type[2])) && p() && e('0'); //type为execution查询
+r($testreport->getBugs4TestTest($buildIdList[0], $product[0], $taskID, $type[3])) && p('1:id;301:id') && e('1;301'); //type为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getbyid.php b/module/testreport/test/model/getbyid.php
new file mode 100755
index 0000000000..bf72f76fba
--- /dev/null
+++ b/module/testreport/test/model/getbyid.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+正常查询 >> 1,user3,1,2,3,4
+reportID为空查询 >> 0
+reportID不存在查询 >> 0
+
+*/
+$reportID = array('1', '', '16');
+
+$testreport = new testreportTest();
+
+r($testreport->getByIdTest($reportID[0])) && p('id,owner,cases') && e('1,user3,1,2,3,4');//正常查询
+r($testreport->getByIdTest($reportID[1])) && p() && e('0'); //reportID为空查询
+r($testreport->getByIdTest($reportID[2])) && p() && e('0'); //reportID不存在查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getcaseidlist.php b/module/testreport/test/model/getcaseidlist.php
new file mode 100755
index 0000000000..1bc60762fa
--- /dev/null
+++ b/module/testreport/test/model/getcaseidlist.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+getCaseIdList();
+cid=1
+pid=1
+
+正常查询 >> 1,4
+查询创建者不为自己的数据 >> 5,8
+查询reportID为空的数据 >> 0
+
+*/
+$reportID = array('1', '2', '');
+
+$testreport = new testreportTest();
+
+r($testreport->getCaseIdListTest($reportID[0])) && p('1,4') && e('1,4'); //正常查询
+r($testreport->getCaseIdListTest($reportID[1])) && p('5,8') && e('5,8'); //查询创建者不为自己的数据
+r($testreport->getCaseIdListTest($reportID[2])) && p() && e('0'); //查询reportID为空的数据
\ No newline at end of file
diff --git a/module/testreport/test/model/getlist.php b/module/testreport/test/model/getlist.php
new file mode 100755
index 0000000000..f362c5b7df
--- /dev/null
+++ b/module/testreport/test/model/getlist.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+正常查询 >> 1;user3;1,2,3,4
+objectID为空查询 >> 0
+objectID不存在查询 >> 0
+objectType为空查询 >> 10;9
+
+*/
+$objectID = array('1', '', '1000');
+$objectType = array('product', '');
+
+$testreport = new testreportTest();
+r($testreport->getListTest($objectID[0], $objectType[0])) && p('1:id;1:owner;1:cases') && e('1;user3;1,2,3,4'); //正常查询
+r($testreport->getListTest($objectID[1], $objectType[0])) && p() && e('0'); //objectID为空查询
+r($testreport->getListTest($objectID[2], $objectType[0])) && p() && e('0'); //objectID不存在查询
+r($testreport->getListTest($objectID[0], $objectType[1])) && p('10:id;9:id') && e('10;9'); //objectType为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getpairs.php b/module/testreport/test/model/getpairs.php
new file mode 100755
index 0000000000..a69f79a88e
--- /dev/null
+++ b/module/testreport/test/model/getpairs.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+正常查询 >> 1
+productID为空测试 >> 10,9
+productID不存在测试 >> 0
+
+*/
+$productID = array('1', '', '1000');
+
+$testreport = new testreportTest();
+r($testreport->getPairsTest($productID[0])[0]) && p() && e('1'); //正常查询
+r($testreport->getPairsTest($productID[1])) && p('0,1') && e('10,9'); //productID为空测试
+r($testreport->getPairsTest($productID[2])) && p() && e('0'); //productID不存在测试
\ No newline at end of file
diff --git a/module/testreport/test/model/getpercaseresult4report.php b/module/testreport/test/model/getpercaseresult4report.php
new file mode 100755
index 0000000000..06cff3d4c7
--- /dev/null
+++ b/module/testreport/test/model/getpercaseresult4report.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getPerCaseResult4Report();
+cid=1
+pid=1
+
+正常查询 >> 通过,1
+taskID为空查询 >> 0
+
+*/
+$taskID = array('1', '');
+$reportID = '1';
+
+$testreport = new testreportTest();
+
+r($testreport->getPerCaseResult4ReportTest($taskID[0], $reportID)) && p('pass:name,value') && e('通过,1'); //正常查询
+r($testreport->getPerCaseResult4ReportTest($taskID[1], $reportID)) && p() && e('0'); //taskID为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getpercaserunner4report.php b/module/testreport/test/model/getpercaserunner4report.php
new file mode 100755
index 0000000000..bec17212c3
--- /dev/null
+++ b/module/testreport/test/model/getpercaserunner4report.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getPerCaseRunner4Report();
+cid=1
+pid=1
+
+正常查询 >> admin,1
+taskID为空查询 >> 0
+
+*/
+$taskID = array('1', '');
+$reportID = '1';
+
+$testreport = new testreportTest();
+r($testreport->getPerCaseRunner4ReportTest($taskID[0], $reportID)) && p('admin:name,value') && e('admin,1'); //正常查询
+r($testreport->getPerCaseRunner4ReportTest($taskID[1], $reportID)) && p() && e('0'); //taskID为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getresultsummary.php b/module/testreport/test/model/getresultsummary.php
new file mode 100755
index 0000000000..60382f147d
--- /dev/null
+++ b/module/testreport/test/model/getresultsummary.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getResultSummary();
+cid=1
+pid=1
+
+正常查询 >> 共有
4个用例,共执行
4个用例,产生了
4个结果,失败的用例有
2个。
+taskID为空查询 >> 共有
0个用例,共执行
0个用例,产生了
0个结果,失败的用例有
0个。
+
+*/
+$taskID = array('1', '');
+$reportID = '1';
+
+$testreport = new testreportTest();
+r($testreport->getResultSummaryTest($taskID[0], $reportID)) && p() && e('共有
4个用例,共执行
4个用例,产生了
4个结果,失败的用例有
2个。'); //正常查询
+r($testreport->getResultSummaryTest($taskID[1], $reportID)) && p() && e('共有
0个用例,共执行
0个用例,产生了
0个结果,失败的用例有
0个。'); //taskID为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/getstories4test.php b/module/testreport/test/model/getstories4test.php
new file mode 100755
index 0000000000..468986202b
--- /dev/null
+++ b/module/testreport/test/model/getstories4test.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+getStories4Test();
+cid=1
+pid=1
+
+buildIdList不为空查询 >> 0
+buildIdList为空查询 >> 0
+
+*/
+$buildIdList = array('11', '');
+
+$testreport = new testreportTest();
+
+r($testreport->getStories4TestTest($buildIdList[0])) && p() && e('0'); //buildIdList不为空查询
+r($testreport->getStories4TestTest($buildIdList[1])) && p() && e('0'); //buildIdList为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/gettaskcases.php b/module/testreport/test/model/gettaskcases.php
new file mode 100755
index 0000000000..1d1c197534
--- /dev/null
+++ b/module/testreport/test/model/gettaskcases.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getTaskCases();
+cid=1
+pid=1
+
+正常查询 >> 1;2
+tasksID为空查询 >> 0
+idList为空查询 >> 1;3
+
+*/
+$tasksID = array('1', '');
+$reportID = '1';
+$idList = array('1,2', '');
+
+$testreport = new testreportTest();
+
+r($testreport->getTaskCasesTest($tasksID[0], $reportID, $idList[0])[1]) && p('1:id;2:id') && e('1;2'); //正常查询
+r($testreport->getTaskCasesTest($tasksID[1], $reportID, $idList[0])) && p() && e('0'); //tasksID为空查询
+r($testreport->getTaskCasesTest($tasksID[0], $reportID, $idList[1])[1]) && p('1:id;3:id') && e('1;3'); //idList为空查询
\ No newline at end of file
diff --git a/module/testreport/test/model/update.php b/module/testreport/test/model/update.php
new file mode 100755
index 0000000000..e1d5de8659
--- /dev/null
+++ b/module/testreport/test/model/update.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+正常修改 >> 1,正常修改
+负责人为空测试 >> 『负责人』不能为空。
+参与人员为空测试 >> 1,参与人员为空测试,
+标题为空测试 >> 『标题』不能为空。
+
+*/
+$reportID = '1';
+$members = array('dev1','dev11');
+$cases = array(1,2,3,4);
+$title = array('正常修改', '负责人为空测试', '参与人员为空测试', '');
+
+$testreport = new testreportTest();
+
+$normalReport = array('owner' => 'user3', 'members' => $members, 'title' => $title[0], 'report' => '', 'cases' => $cases);
+$noOwner = array('owner' => '', 'members' => $members, 'title' => $title[1], 'report' => '', 'cases' => $cases);
+$noMembers = array('owner' => 'user3', 'members' => '', 'title' => $title[2], 'report' => '', 'cases' => $cases);
+$noTitle = array('owner' => 'user3', 'members' => $members, 'title' => $title[3], 'report' => '', 'cases' => $cases);
+
+r($testreport->updateTest($reportID, $normalReport)) && p('id,title') && e('1,正常修改'); //正常修改
+r($testreport->updateTest($reportID, $noOwner)) && p('owner:0') && e('『负责人』不能为空。'); //负责人为空测试
+r($testreport->updateTest($reportID, $noMembers)) && p('id,title,members') && e('1,参与人员为空测试,'); //参与人员为空测试
+r($testreport->updateTest($reportID, $noTitle)) && p('title:0') && e('『标题』不能为空。'); //标题为空测试
+
diff --git a/module/testreport/test/testreport.class.php b/module/testreport/test/testreport.class.php
new file mode 100644
index 0000000000..bcf94153c6
--- /dev/null
+++ b/module/testreport/test/testreport.class.php
@@ -0,0 +1,266 @@
+objectModel = $tester->loadModel('testreport');
+ $this->testtask = $tester->loadModel('testtask');
+ $this->build = $tester->loadModel('build');
+ $app->loadLang('bug');
+ }
+
+ /**
+ * Create report.
+ *
+ * @access public
+ * @return int
+ */
+ public function createTest($param)
+ {
+ $begin_date = date('Y-m-d');
+ $end_date = date('Y-m-d',strtotime("+7 day"));
+ $builds = array('11');
+ $labels = array();
+
+ $createFields = array('begin' => $begin_date, 'end' => $end_date, 'product' => '1', 'execution' => '101', 'tasks' => '1', 'objectID' => '1', 'objectType' => 'testtask', 'owner' => '', 'title' => '', 'report' => '', 'labels' => $labels, 'builds' => $builds, 'cases' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $reportID = $this->objectModel->create();
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+ $objects = $this->objectModel->getByID($reportID);
+ return $objects;
+ }
+
+ public function updateTest($reportID, $param)
+ {
+ $report = $this->objectModel->getByID($reportID);
+
+ $begin_date = $report->begin;
+ $end_date = $report->end;
+ $builds = $report->builds;
+ $labels = array();
+
+ $createFields = array('begin' => $begin_date, 'end' => $end_date, 'product' => $report->product, 'execution' => $report->execution, 'tasks' => $report->tasks, 'objectID' => $report->objectID, 'objectType' => $report->objectType, 'owner' => '', 'title' => '', 'report' => '', 'labels' => $labels, 'builds' => $builds, 'cases' => '');
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->update($reportID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = $this->objectModel->getByID($reportID);
+ return $objects;
+ }
+
+ /**
+ * Get report by id.
+ *
+ * @param int $reportID
+ * @access public
+ * @return object
+ */
+
+ public function getByIdTest($reportID)
+ {
+ $objects = $this->objectModel->getById($reportID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get report list.
+ *
+ * @param int $objectID
+ * @param string $objectType
+ * @access public
+ * @return array
+ */
+ public function getListTest($objectID, $objectType, $extra = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getList($objectID, $objectType, $extra, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get bug info and summary.
+ *
+ * @param array $tasksIDs
+ * @param array $productIdList
+ * @param int $reportID
+ * @param array $buildIDs
+ * @access public
+ * @return array
+ */
+ public function getBug4ReportTest($taskIDs, $productIdList, $reportID, $buildIDs)
+ {
+ $tasks = $taskIDs ? $this->testtask->getByList($taskIDs) : array();
+ $builds = $buildIDs ? $this->build->getByList($buildIDs) : array();
+ $report = $this->objectModel->getByID($reportID);
+
+ $objects = $this->objectModel->getBug4Report($tasks, $productIdList, $report->begin, $report->end, $builds);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get task cases.
+ *
+ * @param array $taskID
+ * @param int $reportID
+ * @access public
+ * @return array
+ */
+
+ public function getTaskCasesTest($taskID, $reportID, $idList = '', $pager = null)
+ {
+ $task = $taskID ? $this->testtask->getByList($taskID) : array();
+ $report = $this->objectModel->getByID($reportID);
+
+ $objects = $this->objectModel->getTaskCases($task, $report->begin, $report->end, $idList, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get caseID list.
+ *
+ * @param int $reportID
+ * @access public
+ * @return array
+ */
+
+ public function getCaseIdListTest($reportID)
+ {
+ $objects = $this->objectModel->getCaseIdList($reportID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get result summary.
+ *
+ * @param int $taskID
+ * @param int $reportID
+ * @access public
+ * @return string
+ */
+
+ public function getResultSummaryTest($taskID, $reportID)
+ {
+ $tasks = $taskID ? $this->testtask->getByList($taskID) : array();
+ $report = $this->objectModel->getByID($reportID);
+ $cases = $this->objectModel->getTaskCases($tasks, $report->begin, $report->end);
+
+ $objects = $this->objectModel->getResultSummary($tasks, $cases, $report->begin, $report->end);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get per run result for testreport.
+ *
+ * @param int $taskID
+ * @param int $reportID
+ * @access public
+ * @return string
+ */
+
+ public function getPerCaseResult4ReportTest($taskID, $reportID)
+ {
+ $tasks = $taskID ? $this->testtask->getByList($taskID) : array();
+ $report = $this->objectModel->getByID($reportID);
+
+ $objects = $this->objectModel->getPerCaseResult4Report($tasks, $report->cases, $report->begin, $report->end);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get per case runner for testreport.
+ *
+ * @param int $taskID
+ * @param int $reportID
+ * @access public
+ * @return string
+ */
+
+ public function getPerCaseRunner4ReportTest($taskID, $reportID)
+ {
+ $tasks = $taskID ? $this->testtask->getByList($taskID) : array();
+ $report = $this->objectModel->getByID($reportID);
+ $objects = $this->objectModel->getPerCaseRunner4Report($tasks, $report->cases, $report->begin, $report->end);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get bugs for test
+ *
+ * @param array $builds
+ * @param array $product
+ * @param string $begin
+ * @param string $end
+ * @param string $type
+ * @access public
+ * @return void
+ */
+
+ public function getBugs4TestTest($buildIdList, $product, $taskID, $type = 'build')
+ {
+ $task = $this->testtask->getByID($taskID);
+ $builds = $this->build->getByList($buildIdList);
+ $begin = !empty($begin) ? date("Y-m-d", strtotime($begin)) : $task->begin;
+ $end = !empty($end) ? date("Y-m-d", strtotime($end)) : $task->end;
+ $objects = $this->objectModel->getBugs4Test($builds, $product, $begin, $end, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get stories for test
+ *
+ * @param array $builds
+ * @return void
+ */
+ public function getStories4TestTest($buildIdList)
+ {
+ $builds = $this->build->getByList($buildIdList);
+ $objects = $this->objectModel->getStories4Test($builds);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+ /**
+ * Get pairs.
+ *
+ * @param int $productID
+ * @access public
+ * @return array
+ */
+ public function getPairsTest($productID = 0)
+ {
+ $objects = $this->objectModel->getPairs($productID);
+ if(dao::isError()) return dao::getError();
+ if($objects) $objects = array_keys($objects);
+ return $objects;
+ }
+}
diff --git a/module/testsuite/test/model/create.php b/module/testsuite/test/model/create.php
new file mode 100755
index 0000000000..3785c95a0f
--- /dev/null
+++ b/module/testsuite/test/model/create.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+测试productID为1,name正常存在,type为private >> 202
+测试productID为1,name为空,type为private >> 『名称』不能为空。
+测试productID为1,name正常存在,type为public >> 203
+测试productID为1,name为空,type为public >> 『名称』不能为空。
+测试productID为1,name正常存在,type为空 >> 204
+测试productID为1,name为空,type为空 >> 『名称』不能为空。
+测试productID为0,name正常存在,type为private >> 205
+测试productID为0,name为空,type为private >> 『名称』不能为空。
+测试productID为0,name正常存在,type为public >> 206
+测试productID为0,name为空,type为public >> 『名称』不能为空。
+测试productID为0,name正常存在,type为空 >> 207
+测试productID为0,name为空,type为空 >> 『名称』不能为空。
+
+*/
+$productID = array(1, 0);
+$name = array('这是测试套件名称1000', '');
+$type = array('private', 'public', '');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->createTest($productID[0], $name[0], $type[0])) && p() && e('202'); //测试productID为1,name正常存在,type为private
+r($testsuite->createTest($productID[0], $name[1], $type[0])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为private
+r($testsuite->createTest($productID[0], $name[0], $type[1])) && p() && e('203'); //测试productID为1,name正常存在,type为public
+r($testsuite->createTest($productID[0], $name[1], $type[1])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为public
+r($testsuite->createTest($productID[0], $name[0], $type[2])) && p() && e('204'); //测试productID为1,name正常存在,type为空
+r($testsuite->createTest($productID[0], $name[1], $type[2])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为空
+r($testsuite->createTest($productID[1], $name[0], $type[0])) && p() && e('205'); //测试productID为0,name正常存在,type为private
+r($testsuite->createTest($productID[1], $name[1], $type[0])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为private
+r($testsuite->createTest($productID[1], $name[0], $type[1])) && p() && e('206'); //测试productID为0,name正常存在,type为public
+r($testsuite->createTest($productID[1], $name[1], $type[1])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为public
+r($testsuite->createTest($productID[1], $name[0], $type[2])) && p() && e('207'); //测试productID为0,name正常存在,type为空
+r($testsuite->createTest($productID[1], $name[1], $type[2])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为空
diff --git a/module/testsuite/test/model/delete.php b/module/testsuite/test/model/delete.php
new file mode 100755
index 0000000000..c340486cb2
--- /dev/null
+++ b/module/testsuite/test/model/delete.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+delete();
+cid=1
+pid=1
+
+测试suiteID值为1 >> 1
+测试suiteID值为1000 >> 1
+测试suiteID值为0 >> 1
+
+*/
+$suiteID = array(1, 1000, 0);
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->deleteTest($suiteID[0])) && p() && e('1'); //测试suiteID值为1
+r($testsuite->deleteTest($suiteID[1])) && p() && e('1'); //测试suiteID值为1000
+r($testsuite->deleteTest($suiteID[2])) && p() && e('1'); //测试suiteID值为0
diff --git a/module/testsuite/test/model/getbyid.php b/module/testsuite/test/model/getbyid.php
new file mode 100755
index 0000000000..d6538414b0
--- /dev/null
+++ b/module/testsuite/test/model/getbyid.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+测试suiteID值为0,setImgSize值为false >> 0
+测试suiteID值为1000,setImgSize值为false >> 0
+测试suiteID值为1,setImgSize值为true >> 1,这是测试套件的描述1
+测试suiteID值为1,setImgSize值为false >> 1,这是测试套件的描述1
+
+*/
+$suiteID = array(0, 1, 1000);
+$setImgSize = array(true, false);
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getByIdTest($suiteID[0], $setImgSize[1])) && p() && e('0'); //测试suiteID值为0,setImgSize值为false
+r($testsuite->getByIdTest($suiteID[2], $setImgSize[1])) && p() && e('0'); //测试suiteID值为1000,setImgSize值为false
+r($testsuite->getByIdTest($suiteID[1], $setImgSize[0])) && p('id,desc') && e('1,这是测试套件的描述1'); //测试suiteID值为1,setImgSize值为true
+r($testsuite->getByIdTest($suiteID[1], $setImgSize[1])) && p('id,desc') && e('1,这是测试套件的描述1'); //测试suiteID值为1,setImgSize值为false
\ No newline at end of file
diff --git a/module/testsuite/test/model/getlinkedcases.php b/module/testsuite/test/model/getlinkedcases.php
new file mode 100755
index 0000000000..19add8a1a8
--- /dev/null
+++ b/module/testsuite/test/model/getlinkedcases.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+getLinkedCases();
+cid=1
+pid=1
+
+测试suiteID值正常存在,orderBy值为id_desc,append值为true >> 2,这个是测试用例2;1,这个是测试用例1
+测试suiteID值正常存在,orderBy值为id_desc,append值为false >> 2,这个是测试用例2;1,这个是测试用例1
+测试suiteID值正常存在,orderBy值为id_asc,append值为true >> 1,这个是测试用例1;2,这个是测试用例2
+测试suiteID值正常存在,orderBy值为id_asc,append值为false >> 1,这个是测试用例1;2,这个是测试用例2
+测试suiteID值正常存在,orderBy值为title_desc,id_desc,append值为true >> 2,这个是测试用例2;1,这个是测试用例1
+测试suiteID值正常存在,orderBy值为title_desc,id_desc,append值为false >> 2,这个是测试用例2;1,这个是测试用例1
+测试suiteID值正常存在,orderBy值为title_asc,id_desc,append值为true >> 1,这个是测试用例1;2,这个是测试用例2
+测试suiteID值正常存在,orderBy值为title_asc,id_desc,append值为false >> 1,这个是测试用例1;2,这个是测试用例2
+
+*/
+$suiteID = 1;
+$orderBy = array('id_desc', 'id_asc', 'title_desc,id_desc', 'title_asc,id_desc');
+$append = array(true, false);
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[0], '', $append[0])) && p('2:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值正常存在,orderBy值为id_desc,append值为true
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[0], '', $append[1])) && p('2:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值正常存在,orderBy值为id_desc,append值为false
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[1], '', $append[0])) && p('1:id,title;2:id,title') && e('1,这个是测试用例1;2,这个是测试用例2'); //测试suiteID值正常存在,orderBy值为id_asc,append值为true
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[1], '', $append[1])) && p('1:id,title;2:id,title') && e('1,这个是测试用例1;2,这个是测试用例2'); //测试suiteID值正常存在,orderBy值为id_asc,append值为false
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[2], '', $append[0])) && p('2:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值正常存在,orderBy值为title_desc,id_desc,append值为true
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[2], '', $append[1])) && p('2:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值正常存在,orderBy值为title_desc,id_desc,append值为false
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[3], '', $append[0])) && p('1:id,title;2:id,title') && e('1,这个是测试用例1;2,这个是测试用例2'); //测试suiteID值正常存在,orderBy值为title_asc,id_desc,append值为true
+r($testsuite->getLinkedCasesTest($suiteID, $orderBy[3], '', $append[1])) && p('1:id,title;2:id,title') && e('1,这个是测试用例1;2,这个是测试用例2'); //测试suiteID值正常存在,orderBy值为title_asc,id_desc,append值为false
\ No newline at end of file
diff --git a/module/testsuite/test/model/getnotimportedcases.php b/module/testsuite/test/model/getnotimportedcases.php
new file mode 100755
index 0000000000..457b482a31
--- /dev/null
+++ b/module/testsuite/test/model/getnotimportedcases.php
@@ -0,0 +1,52 @@
+#!/usr/bin/env php
+getNotImportedCases();
+cid=1
+pid=1
+
+测试productID值为1,libID值为0,orderBy值为id_desc >> 0
+测试productID值为1,libID值为0,orderBy值为id_asc >> 0
+测试productID值为1,libID值为0,orderBy值为title_desc,id_desc >> 0
+测试productID值为1,libID值为0,orderBy值为title_asc,id_desc >> 0
+测试productID值为0,libID值为0,orderBy值为id_desc >> 0
+测试productID值为0,libID值为0,orderBy值为id_asc >> 0
+测试productID值为0,libID值为0,orderBy值为title_desc,id_desc >> 0
+测试productID值为0,libID值为0,orderBy值为title_asc,id_desc >> 0
+测试productID值为1,libID值为201,orderBy值为id_desc >> 410,用例库用例10;409,用例库用例9
+测试productID值为1,libID值为201,orderBy值为id_asc >> 401,用例库用例1;402,用例库用例2
+测试productID值为1,libID值为201,orderBy值为title_desc,id_desc >> 409,用例库用例9;408,用例库用例8
+测试productID值为1,libID值为201,orderBy值为title_asc,id_desc >> 401,用例库用例1;410,用例库用例10
+测试productID值为0,libID值为201,orderBy值为id_desc >> 410,用例库用例10;409,用例库用例9
+测试productID值为0,libID值为201,orderBy值为id_asc >> 401,用例库用例1;402,用例库用例2
+测试productID值为0,libID值为201,orderBy值为title_desc,id_desc >> 409,用例库用例9;408,用例库用例8
+测试productID值为0,libID值为201,orderBy值为title_asc,id_desc >> 401,用例库用例1;410,用例库用例10
+
+*/
+$productID = array(1, 0);
+$libID = array(201, 0);
+$orderBy = array('id_desc', 'id_asc', 'title_desc,id_desc', 'title_asc,id_desc');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[1], $orderBy[0])) && p() && e('0'); //测试productID值为1,libID值为0,orderBy值为id_desc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[1], $orderBy[1])) && p() && e('0'); //测试productID值为1,libID值为0,orderBy值为id_asc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[1], $orderBy[2])) && p() && e('0'); //测试productID值为1,libID值为0,orderBy值为title_desc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[1], $orderBy[3])) && p() && e('0'); //测试productID值为1,libID值为0,orderBy值为title_asc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[1], $orderBy[0])) && p() && e('0'); //测试productID值为0,libID值为0,orderBy值为id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[1], $orderBy[1])) && p() && e('0'); //测试productID值为0,libID值为0,orderBy值为id_asc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[1], $orderBy[2])) && p() && e('0'); //测试productID值为0,libID值为0,orderBy值为title_desc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[1], $orderBy[3])) && p() && e('0'); //测试productID值为0,libID值为0,orderBy值为title_asc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[0], $orderBy[0])) && p('410:id,title;409:id,title') && e('410,用例库用例10;409,用例库用例9'); //测试productID值为1,libID值为201,orderBy值为id_desc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[0], $orderBy[1])) && p('401:id,title;402:id,title') && e('401,用例库用例1;402,用例库用例2'); //测试productID值为1,libID值为201,orderBy值为id_asc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[0], $orderBy[2])) && p('409:id,title;408:id,title') && e('409,用例库用例9;408,用例库用例8'); //测试productID值为1,libID值为201,orderBy值为title_desc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[0], $libID[0], $orderBy[3])) && p('401:id,title;410:id,title') && e('401,用例库用例1;410,用例库用例10'); //测试productID值为1,libID值为201,orderBy值为title_asc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[0], $orderBy[0])) && p('410:id,title;409:id,title') && e('410,用例库用例10;409,用例库用例9'); //测试productID值为0,libID值为201,orderBy值为id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[0], $orderBy[1])) && p('401:id,title;402:id,title') && e('401,用例库用例1;402,用例库用例2'); //测试productID值为0,libID值为201,orderBy值为id_asc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[0], $orderBy[2])) && p('409:id,title;408:id,title') && e('409,用例库用例9;408,用例库用例8'); //测试productID值为0,libID值为201,orderBy值为title_desc,id_desc
+r($testsuite->getNotImportedCasesTest($productID[1], $libID[0], $orderBy[3])) && p('401:id,title;410:id,title') && e('401,用例库用例1;410,用例库用例10'); //测试productID值为0,libID值为201,orderBy值为title_asc,id_desc
\ No newline at end of file
diff --git a/module/testsuite/test/model/getsuites.php b/module/testsuite/test/model/getsuites.php
new file mode 100755
index 0000000000..53aa0a360b
--- /dev/null
+++ b/module/testsuite/test/model/getsuites.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getSuites();
+cid=1
+pid=1
+
+测试productID值为1,orderBy为id_desc >> 这是测试套件名称2;这是测试套件名称1
+测试productID值为1,orderBy为id_asc >> 这是测试套件名称1;这是测试套件名称2
+测试productID值为1,orderBy为name_desc,id_desc >> 这是测试套件名称2;这是测试套件名称1
+测试productID值为1,orderBy为name_asc,id_desc >> 这是测试套件名称1;这是测试套件名称2
+测试productID值为1,orderBy为id_desc >> 0
+测试productID值为1,orderBy为id_asc >> 0
+测试productID值为1,orderBy为name_desc,id_desc >> 0
+测试productID值为1,orderBy为name_asc,id_desc >> 0
+
+*/
+$productID = array(1, 0);
+$orderBy = array('id_desc', 'id_asc', 'name_desc,id_desc', 'name_asc,id_desc');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getSuitesTest($productID[0], $orderBy[0])) && p('2:name;1:name') && e('这是测试套件名称2;这是测试套件名称1'); //测试productID值为1,orderBy为id_desc
+r($testsuite->getSuitesTest($productID[0], $orderBy[1])) && p('1:name;2:name') && e('这是测试套件名称1;这是测试套件名称2'); //测试productID值为1,orderBy为id_asc
+r($testsuite->getSuitesTest($productID[0], $orderBy[2])) && p('2:name;1:name') && e('这是测试套件名称2;这是测试套件名称1'); //测试productID值为1,orderBy为name_desc,id_desc
+r($testsuite->getSuitesTest($productID[0], $orderBy[3])) && p('1:name;2:name') && e('这是测试套件名称1;这是测试套件名称2'); //测试productID值为1,orderBy为name_asc,id_desc
+r($testsuite->getSuitesTest($productID[1], $orderBy[0])) && p() && e('0'); //测试productID值为1,orderBy为id_desc
+r($testsuite->getSuitesTest($productID[1], $orderBy[1])) && p() && e('0'); //测试productID值为1,orderBy为id_asc
+r($testsuite->getSuitesTest($productID[1], $orderBy[2])) && p() && e('0'); //测试productID值为1,orderBy为name_desc,id_desc
+r($testsuite->getSuitesTest($productID[1], $orderBy[3])) && p() && e('0'); //测试productID值为1,orderBy为name_asc,id_desc
\ No newline at end of file
diff --git a/module/testsuite/test/model/getunitsuites.php b/module/testsuite/test/model/getunitsuites.php
new file mode 100755
index 0000000000..9359d9501c
--- /dev/null
+++ b/module/testsuite/test/model/getunitsuites.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getUnitSuites();
+cid=1
+pid=1
+
+测试productID值为1,orderBy为id_desc >> 0
+测试productID值为1,orderBy为id_asc >> 0
+测试productID值为1,orderBy为name_desc,id_desc >> 0
+测试productID值为1,orderBy为name_asc,id_desc >> 0
+测试productID值为1,orderBy为id_desc >> 0
+测试productID值为1,orderBy为id_asc >> 0
+测试productID值为1,orderBy为name_desc,id_desc >> 0
+测试productID值为1,orderBy为name_asc,id_desc >> 0
+
+*/
+$productID = array(1, 0);
+$orderBy = array('id_desc', 'id_asc', 'name_desc,id_desc', 'name_asc,id_desc');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getUnitSuitesTest($productID[0], $orderBy[0])) && p() && e('0'); //测试productID值为1,orderBy为id_desc
+r($testsuite->getUnitSuitesTest($productID[0], $orderBy[1])) && p() && e('0'); //测试productID值为1,orderBy为id_asc
+r($testsuite->getUnitSuitesTest($productID[0], $orderBy[2])) && p() && e('0'); //测试productID值为1,orderBy为name_desc,id_desc
+r($testsuite->getUnitSuitesTest($productID[0], $orderBy[3])) && p() && e('0'); //测试productID值为1,orderBy为name_asc,id_desc
+r($testsuite->getUnitSuitesTest($productID[1], $orderBy[0])) && p() && e('0'); //测试productID值为1,orderBy为id_desc
+r($testsuite->getUnitSuitesTest($productID[1], $orderBy[1])) && p() && e('0'); //测试productID值为1,orderBy为id_asc
+r($testsuite->getUnitSuitesTest($productID[1], $orderBy[2])) && p() && e('0'); //测试productID值为1,orderBy为name_desc,id_desc
+r($testsuite->getUnitSuitesTest($productID[1], $orderBy[3])) && p() && e('0'); //测试productID值为1,orderBy为name_asc,id_desc
\ No newline at end of file
diff --git a/module/testsuite/test/model/getunlinkedcases.php b/module/testsuite/test/model/getunlinkedcases.php
new file mode 100755
index 0000000000..bf38025aae
--- /dev/null
+++ b/module/testsuite/test/model/getunlinkedcases.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getUnlinkedCases();
+cid=1
+pid=1
+
+测试suiteID值为1,param值为0 >> 4,这个是测试用例4;3,这个是测试用例3
+测试suiteID值为1,param值为myQueryID >> 4,这个是测试用例4;3,这个是测试用例3
+测试suiteID值为2,param值为0 >> 2,这个是测试用例2;1,这个是测试用例1
+测试suiteID值为2,param值为myQueryID >> 2,这个是测试用例2;1,这个是测试用例1
+
+*/
+$suiteID = array(1, 2);
+$param = array(0, 'myQueryID');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->getUnlinkedCasesTest($suiteID[0], $param[0])) && p('0:id,title;1:id,title') && e('4,这个是测试用例4;3,这个是测试用例3'); //测试suiteID值为1,param值为0
+r($testsuite->getUnlinkedCasesTest($suiteID[0], $param[1])) && p('0:id,title;1:id,title') && e('4,这个是测试用例4;3,这个是测试用例3'); //测试suiteID值为1,param值为myQueryID
+r($testsuite->getUnlinkedCasesTest($suiteID[1], $param[0])) && p('0:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值为2,param值为0
+r($testsuite->getUnlinkedCasesTest($suiteID[1], $param[1])) && p('0:id,title;1:id,title') && e('2,这个是测试用例2;1,这个是测试用例1'); //测试suiteID值为2,param值为myQueryID
\ No newline at end of file
diff --git a/module/testsuite/test/model/linkcase.php b/module/testsuite/test/model/linkcase.php
new file mode 100755
index 0000000000..a18528382d
--- /dev/null
+++ b/module/testsuite/test/model/linkcase.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+linkCase();
+cid=1
+pid=1
+
+测试存在的suiteID值为1,cases值为空 >> 0
+测试存在的suiteID值为1,cases值为一个 >> 1,1
+测试存在的suiteID值为1,cases值为多个 >> 1,2;1,3
+测试不存在的suiteID值为1000,cases值为空 >> 0
+测试不存在的suiteID值为1000,cases值为一个 >> 1000,1
+测试不存在的suiteID值为1000,cases值为多个 >> 1000,2;1000,3
+测试不存在的suiteID值为0,cases值为空 >> 0
+测试不存在的suiteID值为0,cases值为一个 >> 0,1
+测试不存在的suiteID值为0,cases值为多个 >> 0,2;0,3
+
+*/
+$suiteID = array(1, 1000, 0);
+$cases = array(array(), array(1), array(2, 3));
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->linkCaseTest($suiteID[0], $cases[0])) && p() && e('0'); //测试存在的suiteID值为1,cases值为空
+r($testsuite->linkCaseTest($suiteID[0], $cases[1])) && p('0:suite,case') && e('1,1'); //测试存在的suiteID值为1,cases值为一个
+r($testsuite->linkCaseTest($suiteID[0], $cases[2])) && p('0:suite,case;1:suite,case') && e('1,2;1,3'); //测试存在的suiteID值为1,cases值为多个
+r($testsuite->linkCaseTest($suiteID[1], $cases[0])) && p() && e('0'); //测试不存在的suiteID值为1000,cases值为空
+r($testsuite->linkCaseTest($suiteID[1], $cases[1])) && p('0:suite,case') && e('1000,1'); //测试不存在的suiteID值为1000,cases值为一个
+r($testsuite->linkCaseTest($suiteID[1], $cases[2])) && p('0:suite,case;1:suite,case') && e('1000,2;1000,3'); //测试不存在的suiteID值为1000,cases值为多个
+r($testsuite->linkCaseTest($suiteID[2], $cases[0])) && p() && e('0'); //测试不存在的suiteID值为0,cases值为空
+r($testsuite->linkCaseTest($suiteID[2], $cases[1])) && p('0:suite,case') && e('0,1'); //测试不存在的suiteID值为0,cases值为一个
+r($testsuite->linkCaseTest($suiteID[2], $cases[2])) && p('0:suite,case;1:suite,case') && e('0,2;0,3'); //测试不存在的suiteID值为0,cases值为多个
diff --git a/module/testsuite/test/model/select.php b/module/testsuite/test/model/select.php
new file mode 100755
index 0000000000..bb96174173
--- /dev/null
+++ b/module/testsuite/test/model/select.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+select();
+cid=1
+pid=1
+
+
+
+*/
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->selectTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testsuite/test/model/update.php b/module/testsuite/test/model/update.php
new file mode 100755
index 0000000000..f4d8a45bb6
--- /dev/null
+++ b/module/testsuite/test/model/update.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试productID为1,name正常存在,type为private >> type,public,private
+测试productID为1,name为空,type为private >> 『名称』不能为空。
+测试productID为1,name正常存在,type为public >> type,private,public
+测试productID为1,name为空,type为public >> 『名称』不能为空。
+测试productID为1,name正常存在,type为空 >> type,public,
+测试productID为1,name为空,type为空 >> 『名称』不能为空。
+测试productID为0,name正常存在,type为private >> 0
+测试productID为0,name为空,type为private >> 『名称』不能为空。
+测试productID为0,name正常存在,type为public >> 0
+测试productID为0,name为空,type为public >> 『名称』不能为空。
+测试productID为0,name正常存在,type为空 >> 0
+测试productID为0,name为空,type为空 >> 『名称』不能为空。
+
+*/
+$productID = array(1, 0);
+$name = array('这是测试套件名称1000', '');
+$type = array('private', 'public', '');
+
+$testsuite = new testsuiteTest();
+
+r($testsuite->updateTest($productID[0], $name[0], $type[0])) && p('2:field,old,new') && e('type,public,private'); //测试productID为1,name正常存在,type为private
+r($testsuite->updateTest($productID[0], $name[1], $type[0])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为private
+r($testsuite->updateTest($productID[0], $name[0], $type[1])) && p('0:field,old,new') && e('type,private,public'); //测试productID为1,name正常存在,type为public
+r($testsuite->updateTest($productID[0], $name[1], $type[1])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为public
+r($testsuite->updateTest($productID[0], $name[0], $type[2])) && p('0:field,old,new') && e('type,public,'); //测试productID为1,name正常存在,type为空
+r($testsuite->updateTest($productID[0], $name[1], $type[2])) && p('name:0') && e('『名称』不能为空。'); //测试productID为1,name为空,type为空
+r($testsuite->updateTest($productID[1], $name[0], $type[0])) && p() && e('0'); //测试productID为0,name正常存在,type为private
+r($testsuite->updateTest($productID[1], $name[1], $type[0])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为private
+r($testsuite->updateTest($productID[1], $name[0], $type[1])) && p() && e('0'); //测试productID为0,name正常存在,type为public
+r($testsuite->updateTest($productID[1], $name[1], $type[1])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为public
+r($testsuite->updateTest($productID[1], $name[0], $type[2])) && p() && e('0'); //测试productID为0,name正常存在,type为空
+r($testsuite->updateTest($productID[1], $name[1], $type[2])) && p('name:0') && e('『名称』不能为空。'); //测试productID为0,name为空,type为空
diff --git a/module/testsuite/test/testsuite.class.php b/module/testsuite/test/testsuite.class.php
new file mode 100644
index 0000000000..9c92031e1a
--- /dev/null
+++ b/module/testsuite/test/testsuite.class.php
@@ -0,0 +1,218 @@
+objectModel = $tester->loadModel('testsuite');
+ }
+
+ public function selectTest($products, $productID, $currentModule, $currentMethod, $extra = '')
+ {
+ $objects = $this->objectModel->select($products, $productID, $currentModule, $currentMethod, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test create a test suite.
+ *
+ * @param int $productID
+ * @param string $name
+ * @param string $type
+ * @access public
+ * @return array|int
+ */
+ public function createTest($productID, $name, $type)
+ {
+ $_POST['name'] = $name;
+ $_POST['desc'] = '';
+ $_POST['type'] = $type;
+ $_POST['uid'] = '62538b850bb9d';
+
+ $objects = $this->objectModel->create($productID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get test suites of a product.
+ *
+ * @param int $productID
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getSuitesTest($productID, $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getSuites($productID, $orderBy, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get unit suite.
+ *
+ * @param int $productID
+ * @param string $orderBy
+ * @access public
+ * @return array
+ */
+ public function getUnitSuitesTest($productID, $orderBy = 'id_desc')
+ {
+ $objects = $this->objectModel->getUnitSuites($productID, $orderBy);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get test suite info by id.
+ *
+ * @param int $suiteID
+ * @param bool $setImgSize
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($suiteID, $setImgSize = false)
+ {
+ $objects = $this->objectModel->getById($suiteID, $setImgSize);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test update a test suite.
+ *
+ * @param int $suiteID
+ * @access public
+ * @return bool|array
+ */
+ public function updateTest($suiteID, $name, $type)
+ {
+ $_POST['name'] = $name;
+ $_POST['desc'] = '';
+ $_POST['type'] = $type;
+ $_POST['uid'] = '62538b850bb9d';
+
+ $objects = $this->objectModel->update($suiteID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test link cases.
+ *
+ * @param int $suiteID
+ * @param array $cases
+ * @access public
+ * @return void
+ */
+ public function linkCaseTest($suiteID, $cases)
+ {
+ $_POST['cases'] = $cases;
+ foreach($cases as $case)
+ {
+ $_POST['versions'][$case] = 1;
+ }
+
+ $this->objectModel->linkCase($suiteID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_SUITECASE)->where('suite')->eq($suiteID)->andWhere('`case`')->in($cases)->fetchAll();
+
+ return $objects;
+ }
+
+ /**
+ * Test get linked cases for suite.
+ *
+ * @param int $suiteID
+ * @param string $orderBy
+ * @param object $pager
+ * @param bool $append
+ * @access public
+ * @return array
+ */
+ public function getLinkedCasesTest($suiteID, $orderBy = 'id_desc', $pager = null, $append = true)
+ {
+ $objects = $this->objectModel->getLinkedCases($suiteID, $orderBy, $pager, $append);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get unlinked cases for suite.
+ *
+ * @param int $suiteID
+ * @param int $param
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getUnlinkedCasesTest($suiteID, $param = 0, $pager = null)
+ {
+
+ $suite = $this->objectModel->getById($suiteID);
+ $objects = $this->objectModel->getUnlinkedCases($suite, $param, $pager);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test delete suite and library.
+ *
+ * @param int $suiteID
+ * @param string $table
+ * @access public
+ * @return int
+ */
+ public function deleteTest($suiteID, $table = '')
+ {
+ $objects = $this->objectModel->delete($suiteID, $table);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test get not imported cases.
+ *
+ * @param int $productID
+ * @param int $libID
+ * @param string $orderBy
+ * @param object $pager
+ * @access public
+ * @return array
+ */
+ public function getNotImportedCasesTest($productID, $libID, $orderBy = 'id_desc', $pager = null, $browseType = '', $queryID = 0)
+ {
+ $objects = $this->objectModel->getNotImportedCases($productID, $libID, $orderBy, $pager, $browseType, $queryID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/testtask/test/model/activate.php b/module/testtask/test/model/activate.php
new file mode 100755
index 0000000000..a61843bcf2
--- /dev/null
+++ b/module/testtask/test/model/activate.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+activate();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->activateTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/batchrun.php b/module/testtask/test/model/batchrun.php
new file mode 100755
index 0000000000..e7776a6d2f
--- /dev/null
+++ b/module/testtask/test/model/batchrun.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+batchRun();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->batchRunTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/block.php b/module/testtask/test/model/block.php
new file mode 100755
index 0000000000..9300e98224
--- /dev/null
+++ b/module/testtask/test/model/block.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+block();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->blockTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/close.php b/module/testtask/test/model/close.php
new file mode 100755
index 0000000000..2e3a439981
--- /dev/null
+++ b/module/testtask/test/model/close.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->closeTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/create.php b/module/testtask/test/model/create.php
new file mode 100755
index 0000000000..ab6fde4638
--- /dev/null
+++ b/module/testtask/test/model/create.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+新增一个正常的测试单 >> 11,新增测试报告,200,1,system
+新增一个名称为空的测试单 >> 『名称』不能为空。
+新增一个结束日期小于开始日期的测试单 >> 『结束日期』应当不小于『2022-10-05』。
+
+*/
+
+$testtask = new testtaskTest();
+
+$normalTask['product'] = 1;
+$normalTask['execution'] = 200;
+$normalTask['build'] = 11;
+$normalTask['type'] = 'system';
+$normalTask['owner'] = 'test10';
+$normalTask['pri'] = 3;
+$normalTask['begin'] = '2022-03-05';
+$normalTask['end'] = '2022-09-05';
+$normalTask['status'] = 'wait';
+$normalTask['name'] = '新增测试单';
+$normalTask['desc'] = '新增测试单的描述详情';
+
+$emptyNameTask = $normalTask;
+$emptyNameTask['name'] = '';
+
+$beginGtEndTask = $normalTask;
+$beginGtEndTask['begin'] = '2022-10-05';
+
+r($testtask->create(11, $normalTask)) && p('id,name,execution,product,type') && e('11,新增测试报告,200,1,system'); // 新增一个正常的测试单
+r($testtask->create(12, $emptyNameTask)) && p('name:0') && e('『名称』不能为空。'); // 新增一个名称为空的测试单
+r($testtask->create(13, $beginGtEndTask)) && p('end:0') && e('『结束日期』应当不小于『2022-10-05』。'); // 新增一个结束日期小于开始日期的测试单
+
diff --git a/module/testtask/test/model/createresult.php b/module/testtask/test/model/createresult.php
new file mode 100755
index 0000000000..855ccdb5c2
--- /dev/null
+++ b/module/testtask/test/model/createresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+createResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->createResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getalllinkablecases.php b/module/testtask/test/model/getalllinkablecases.php
new file mode 100755
index 0000000000..af127fcaa5
--- /dev/null
+++ b/module/testtask/test/model/getalllinkablecases.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getAllLinkableCases();
+cid=1
+pid=1
+
+获取可关联到测试单1的用例列表,每页10条,查看数量 >> 10
+获取可关联到测试单2的用例列表,查看数量 >> 307
+获取可关联到测试单2的用例列表,传入已关联的用例ID,查看数量 >> 305
+获取可关联到测试单2的用例列表,传入sql语句,查看数量 >> 74
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+$tester->app->loadClass('pager', $static = true);
+
+$task1 = $tester->testtask->getById(1);
+$task2 = $tester->testtask->getById(2);
+$pager = new pager(0, 10, 1);
+
+$cases1 = $tester->testtask->getAllLinkableCases($task1, '1 = 1', '', $pager);
+$cases2 = $tester->testtask->getAllLinkableCases($task2, '1 = 1', '', null);
+$cases3 = $tester->testtask->getAllLinkableCases($task2, '1 = 1', '410,408', null);
+$cases4 = $tester->testtask->getAllLinkableCases($task2, 'id < 100', '410,408', null);
+
+r(count($cases1)) && p() && e('10'); // 获取可关联到测试单1的用例列表,每页10条,查看数量
+r(count($cases2)) && p() && e('307'); // 获取可关联到测试单2的用例列表,查看数量
+r(count($cases3)) && p() && e('305'); // 获取可关联到测试单2的用例列表,传入已关联的用例ID,查看数量
+r(count($cases4)) && p() && e('74'); // 获取可关联到测试单2的用例列表,传入sql语句,查看数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getbuginfo.php b/module/testtask/test/model/getbuginfo.php
new file mode 100755
index 0000000000..92d13b2941
--- /dev/null
+++ b/module/testtask/test/model/getbuginfo.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getBugInfo();
+cid=1
+pid=1
+
+查看根据测试单的ID获取到的数据数量 >> 8
+查看根据测试单的ID获取到的数据数量 >> 1,1
+查看根据测试单的ID获取到的数据数量 >> 激活,1
+查看根据测试单的ID获取到的数据数量 >> 8
+查看根据测试单的ID获取到的数据数量 >> 2,1
+查看根据测试单的ID获取到的数据数量 >> admin,1
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$task1 = $tester->testtask->getBugInfo(1, 1);
+$task2 = $tester->testtask->getBugInfo(2, 2);
+
+r(count($task1)) && p() && e('8'); // 查看根据测试单的ID获取到的数据数量
+r($task1['bugSeverityGroups']) && p('1:name,value') && e('1,1'); // 查看根据测试单的ID获取到的数据数量
+r($task1['bugStatusGroups']) && p('active:name,value') && e('激活,1'); // 查看根据测试单的ID获取到的数据数量
+
+r(count($task2)) && p() && e('8'); // 查看根据测试单的ID获取到的数据数量
+r($task2['bugSeverityGroups']) && p('2:name,value') && e('2,1'); // 查看根据测试单的ID获取到的数据数量
+r($task2['bugOpenedByGroups']) && p('admin:name,value') && e('admin,1'); // 查看根据测试单的ID获取到的数据数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getbyid.php b/module/testtask/test/model/getbyid.php
new file mode 100755
index 0000000000..0400b6f9a6
--- /dev/null
+++ b/module/testtask/test/model/getbyid.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+获取ID为0的测试单,返回空 >> 0
+获取ID为1的测试单的详细信息 >> 测试单1,执行版本版本11,这是测试单描述1,2022-04-08,2022-04-15
+获取ID为2的测试单的详细信息 >> 测试单2,执行版本版本12,这是测试单描述2,2022-04-08,2022-04-15
+获取ID为3的测试单的详细信息 >> 测试单3,执行版本版本13,这是测试单描述3,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+r($tester->testtask->getById(0)) && p('') && e('0'); // 获取ID为0的测试单,返回空
+r($tester->testtask->getById(1)) && p('name,buildName,desc,begin,end') && e('测试单1,执行版本版本11,这是测试单描述1,2022-04-08,2022-04-15'); // 获取ID为1的测试单的详细信息
+r($tester->testtask->getById(2)) && p('name,buildName,desc,begin,end') && e('测试单2,执行版本版本12,这是测试单描述2,2022-04-08,2022-04-15'); // 获取ID为2的测试单的详细信息
+r($tester->testtask->getById(3)) && p('name,buildName,desc,begin,end') && e('测试单3,执行版本版本13,这是测试单描述3,2022-04-08,2022-04-15'); // 获取ID为3的测试单的详细信息
\ No newline at end of file
diff --git a/module/testtask/test/model/getbylist.php b/module/testtask/test/model/getbylist.php
new file mode 100755
index 0000000000..0449ab74f9
--- /dev/null
+++ b/module/testtask/test/model/getbylist.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+查看按照ID列表获取的测试单的数量 >> 5
+查看按照ID列表获取的测试单的详情 >> 测试单1,,wait,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$taskIdList = array(1, 2, 3, 4, 5);
+
+r(count($tester->testtask->getByList($taskIdList))) && p() && e('5'); // 查看按照ID列表获取的测试单的数量
+r($tester->testtask->getByList($taskIdList)) && p('1:name,type,status,begin,end') && e('测试单1,,wait,2022-04-08,2022-04-15'); // 查看按照ID列表获取的测试单的详情
\ No newline at end of file
diff --git a/module/testtask/test/model/getbyuser.php b/module/testtask/test/model/getbyuser.php
new file mode 100755
index 0000000000..60f6f68437
--- /dev/null
+++ b/module/testtask/test/model/getbyuser.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+getByUser();
+cid=1
+pid=1
+
+获取用户user3的测试单数量 >> 1
+获取用户user4的测试单数量 >> 1
+获取用户user5的测试单数量 >> 1
+获取用户user6的测试单数量 >> 1
+获取用户user3的测试单详细信息 >> 测试单1,,wait,2022-04-08,2022-04-15
+获取用户user4的测试单详细信息 >> 测试单2,,doing,2022-04-08,2022-04-15
+获取用户user5的测试单详细信息 >> 测试单3,,done,2022-04-08,2022-04-15
+获取用户user6的测试单详细信息 >> 测试单4,,blocked,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+r(count($tester->testtask->getByUser('user3'))) && p() && e('1'); // 获取用户user3的测试单数量
+r(count($tester->testtask->getByUser('user4'))) && p() && e('1'); // 获取用户user4的测试单数量
+r(count($tester->testtask->getByUser('user5'))) && p() && e('1'); // 获取用户user5的测试单数量
+r(count($tester->testtask->getByUser('user6'))) && p() && e('1'); // 获取用户user6的测试单数量
+r($tester->testtask->getByUser('user3')) && p('0:name,type,status,begin,end') && e('测试单1,,wait,2022-04-08,2022-04-15'); // 获取用户user3的测试单详细信息
+r($tester->testtask->getByUser('user4')) && p('0:name,type,status,begin,end') && e('测试单2,,doing,2022-04-08,2022-04-15'); // 获取用户user4的测试单详细信息
+r($tester->testtask->getByUser('user5')) && p('0:name,type,status,begin,end') && e('测试单3,,done,2022-04-08,2022-04-15'); // 获取用户user5的测试单详细信息
+r($tester->testtask->getByUser('user6')) && p('0:name,type,status,begin,end') && e('测试单4,,blocked,2022-04-08,2022-04-15'); // 获取用户user6的测试单详细信息
\ No newline at end of file
diff --git a/module/testtask/test/model/getdataoftesttaskpermodule.php b/module/testtask/test/model/getdataoftesttaskpermodule.php
new file mode 100755
index 0000000000..c128187416
--- /dev/null
+++ b/module/testtask/test/model/getdataoftesttaskpermodule.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfTestTaskPerModule();
+cid=1
+pid=1
+
+获取测试单0的模块分组 >> 0
+获取测试单1模块分组,查看各个模块的数量 >> /,4
+获取测试单2模块分组,查看各个模块的数量 >> /,4
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$result0 = $tester->testtask->getDataOfTestTaskPerModule(0);
+$result1 = $tester->testtask->getDataOfTestTaskPerModule(1);
+$result2 = $tester->testtask->getDataOfTestTaskPerModule(2);
+
+r($result0) && p() && e('0'); // 获取测试单0的模块分组
+r($result1[0]) && p('name,value') && e('/,4'); // 获取测试单1模块分组,查看各个模块的数量
+r($result2[0]) && p('name,value') && e('/,4'); // 获取测试单2模块分组,查看各个模块的数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getdataoftesttaskperrunner.php b/module/testtask/test/model/getdataoftesttaskperrunner.php
new file mode 100755
index 0000000000..b168fe685b
--- /dev/null
+++ b/module/testtask/test/model/getdataoftesttaskperrunner.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+getDataOfTestTaskPerRunner();
+cid=1
+pid=1
+
+获取测试单0的执行人分组 >> 0
+获取测试单1执行人分组,查看各个执行人的执行数量 >> 未执行,4
+获取测试单2执行人分组,查看各个执行人的执行数量 >> 未执行,4
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$result0 = $tester->testtask->getDataOfTestTaskPerRunner(0);
+$result1 = $tester->testtask->getDataOfTestTaskPerRunner(1);
+$result2 = $tester->testtask->getDataOfTestTaskPerRunner(2);
+
+r($result0) && p() && e('0'); // 获取测试单0的执行人分组
+r(current($result1)) && p('name,value') && e('未执行,4'); // 获取测试单1执行人分组,查看各个执行人的执行数量
+r(current($result2)) && p('name,value') && e('未执行,4'); // 获取测试单2执行人分组,查看各个执行人的执行数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getdataoftesttaskperrunresult.php b/module/testtask/test/model/getdataoftesttaskperrunresult.php
new file mode 100755
index 0000000000..0c6aebbbcf
--- /dev/null
+++ b/module/testtask/test/model/getdataoftesttaskperrunresult.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getDataOfTestTaskPerRunResult();
+cid=1
+pid=1
+
+获取测试单0的执行结果 >> 0
+获取测试单1的成功执行结果 >> 2
+获取测试单1的失败执行结果 >> 2
+获取测试单2的成功执行结果 >> 2
+获取测试单2的失败执行结果 >> 2
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$result0 = $tester->testtask->getDataOfTestTaskPerRunResult(0);
+$result1 = $tester->testtask->getDataOfTestTaskPerRunResult(1);
+$result2 = $tester->testtask->getDataOfTestTaskPerRunResult(2);
+
+r($result0) && p() && e('0'); // 获取测试单0的执行结果
+r($result1) && p('pass:value') && e('2'); // 获取测试单1的成功执行结果
+r($result1) && p('fail:value') && e('2'); // 获取测试单1的失败执行结果
+r($result2) && p('pass:value') && e('2'); // 获取测试单2的成功执行结果
+r($result2) && p('fail:value') && e('2'); // 获取测试单2的失败执行结果
\ No newline at end of file
diff --git a/module/testtask/test/model/getdataoftesttaskpertype.php b/module/testtask/test/model/getdataoftesttaskpertype.php
new file mode 100755
index 0000000000..0756c5bad1
--- /dev/null
+++ b/module/testtask/test/model/getdataoftesttaskpertype.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+getDataOfTestTaskPerType();
+cid=1
+pid=1
+
+获取测试单0的类型分组 >> 0
+获取测试单1的config类型数量 >> 1
+获取测试单1的feature类型数量 >> 1
+获取测试单1的install类型数量 >> 1
+获取测试单1的performance类型数量 >> 1
+获取测试单2的other类型数量 >> 1
+获取测试单2的security类型数量 >> 1
+获取测试单2的feature类型数量 >> 1
+获取测试单2的interface类型数量 >> 1
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$result0 = $tester->testtask->getDataOfTestTaskPerType(0);
+$result1 = $tester->testtask->getDataOfTestTaskPerType(1);
+$result2 = $tester->testtask->getDataOfTestTaskPerType(2);
+
+r($result0) && p() && e('0'); // 获取测试单0的类型分组
+r($result1) && p('config:value') && e('1'); // 获取测试单1的config类型数量
+r($result1) && p('feature:value') && e('1'); // 获取测试单1的feature类型数量
+r($result1) && p('install:value') && e('1'); // 获取测试单1的install类型数量
+r($result1) && p('performance:value') && e('1'); // 获取测试单1的performance类型数量
+r($result2) && p('other:value') && e('1'); // 获取测试单2的other类型数量
+r($result2) && p('security:value') && e('1'); // 获取测试单2的security类型数量
+r($result2) && p('feature:value') && e('1'); // 获取测试单2的feature类型数量
+r($result2) && p('interface:value') && e('1'); // 获取测试单2的interface类型数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getexecutiontasks.php b/module/testtask/test/model/getexecutiontasks.php
new file mode 100755
index 0000000000..7eb5307cbd
--- /dev/null
+++ b/module/testtask/test/model/getexecutiontasks.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getExecutionTasks();
+cid=1
+pid=1
+
+查看迭代101下的所有测试单数量 >> 1
+查看迭代110下的所有测试单数量 >> 1
+查看迭代120下的所有测试单数量 >> 0
+查看迭代101下的测试单1的详细信息 >> 测试单1,,wait,2022-04-08,2022-04-15
+查看迭代110下的所有测试单10的详细信息 >> 测试单10,,doing,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$execution101Tasks = $tester->testtask->getExecutionTasks(101);
+$execution110Tasks = $tester->testtask->getExecutionTasks(110);
+$execution120Tasks = $tester->testtask->getExecutionTasks(120);
+
+r(count($execution101Tasks)) && p() && e('1'); // 查看迭代101下的所有测试单数量
+r(count($execution110Tasks)) && p() && e('1'); // 查看迭代110下的所有测试单数量
+r(count($execution120Tasks)) && p() && e('0'); // 查看迭代120下的所有测试单数量
+r($execution101Tasks) && p('1:name,type,status,begin,end') && e('测试单1,,wait,2022-04-08,2022-04-15'); // 查看迭代101下的测试单1的详细信息
+r($execution110Tasks) && p('10:name,type,status,begin,end') && e('测试单10,,doing,2022-04-08,2022-04-15'); // 查看迭代110下的所有测试单10的详细信息
\ No newline at end of file
diff --git a/module/testtask/test/model/getlinkablecasesbybug.php b/module/testtask/test/model/getlinkablecasesbybug.php
new file mode 100755
index 0000000000..d470d1c9d7
--- /dev/null
+++ b/module/testtask/test/model/getlinkablecasesbybug.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getLinkableCasesByBug();
+cid=1
+pid=1
+
+通过测试单1关联的版本下的Bug,获取可关联到测试单1的用例数量 >> 0
+通过测试单2关联的版本下的Bug,获取可关联到测试单2的用例数量 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+$tester->app->loadClass('pager', $static = true);
+
+$task1 = $tester->testtask->getById(1);
+$task2 = $tester->testtask->getById(2);
+$pager = new pager(0, 10, 1);
+
+$cases1 = $tester->testtask->getLinkableCasesByBug(1, $task1, '1 = 1', '', $pager);
+$cases2 = $tester->testtask->getLinkableCasesByBug(2, $task2, '1 = 1', '', $pager);
+
+r(count($cases1)) && p() && e('0'); // 通过测试单1关联的版本下的Bug,获取可关联到测试单1的用例数量
+r(count($cases2)) && p() && e('0'); // 通过测试单2关联的版本下的Bug,获取可关联到测试单2的用例数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getlinkablecasesbystory.php b/module/testtask/test/model/getlinkablecasesbystory.php
new file mode 100755
index 0000000000..dcda920165
--- /dev/null
+++ b/module/testtask/test/model/getlinkablecasesbystory.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getLinkableCasesByStory();
+cid=1
+pid=1
+
+通过测试单1关联的版本下的需求,获取可关联到测试单1的用例数量 >> 0
+通过测试单2关联的版本下的需求,获取可关联到测试单2的用例数量 >> 0
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+$tester->app->loadClass('pager', $static = true);
+
+$task1 = $tester->testtask->getById(1);
+$task2 = $tester->testtask->getById(2);
+$pager = new pager(0, 10, 1);
+
+$cases1 = $tester->testtask->getLinkableCasesByStory(1, $task1, '1 = 1', '', $pager);
+$cases2 = $tester->testtask->getLinkableCasesByStory(2, $task2, '1 = 1', '', $pager);
+
+r(count($cases1)) && p() && e('0'); // 通过测试单1关联的版本下的需求,获取可关联到测试单1的用例数量
+r(count($cases2)) && p() && e('0'); // 通过测试单2关联的版本下的需求,获取可关联到测试单2的用例数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getlinkablecasesbysuite.php b/module/testtask/test/model/getlinkablecasesbysuite.php
new file mode 100755
index 0000000000..47edfe0b39
--- /dev/null
+++ b/module/testtask/test/model/getlinkablecasesbysuite.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getLinkableCasesBySuite();
+cid=1
+pid=1
+
+根据测试套件1获取测试单1可关联的用例数量 >> 1
+根据测试套件2获取测试单2可关联的用例数量 >> 1
+根据测试套件1获取测试单1可关联的用例详情 >> 2,这个是测试用例2,normal,performance
+根据测试套件2获取测试单2可关联的用例详情 >> 6,这个是测试用例6,normal,interface
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+$tester->app->loadClass('pager', $static = true);
+
+$task1 = $tester->testtask->getById(1);
+$task2 = $tester->testtask->getById(2);
+$pager = new pager(0, 10, 1);
+
+$cases1 = $tester->testtask->getLinkableCasesBySuite(1, $task1, '1 = 1', 1, '', $pager);
+$cases2 = $tester->testtask->getLinkableCasesBySuite(2, $task2, '1 = 1', 3, '', $pager);
+
+r(count($cases1)) && p() && e('1'); // 根据测试套件1获取测试单1可关联的用例数量
+r(count($cases2)) && p() && e('1'); // 根据测试套件2获取测试单2可关联的用例数量
+r($cases1) && p('0:id,title,status,type') && e('2,这个是测试用例2,normal,performance'); // 根据测试套件1获取测试单1可关联的用例详情
+r($cases2) && p('0:id,title,status,type') && e('6,这个是测试用例6,normal,interface'); // 根据测试套件2获取测试单2可关联的用例详情
\ No newline at end of file
diff --git a/module/testtask/test/model/getlinkablecasesbytesttask.php b/module/testtask/test/model/getlinkablecasesbytesttask.php
new file mode 100755
index 0000000000..81301b6543
--- /dev/null
+++ b/module/testtask/test/model/getlinkablecasesbytesttask.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+getLinkableCasesByTestTask();
+cid=1
+pid=1
+
+直接获取测试单1可关联的用例数量,排除掉ID为2的用例,查看数量 >> 2
+直接获取测试单2可关联的用例数量,查看数量 >> 3
+直接获取测试单3可关联的用例数量,查看数量 >> 3
+直接获取测试单1可关联的用例数量,排除掉ID为2的用例,查看获取到的第一个用例的详情 >> 3,这个是测试用例3,config,intergrate
+直接获取测试单2可关联的用例数量,查看获取到的第一个用例的详情 >> 6,这个是测试用例6,interface,bvt
+直接获取测试单3可关联的用例数量,查看获取到的第一个用例的详情 >> 10,这个是测试用例10,config,system
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+$tester->app->loadClass('pager', $static = true);
+
+$task1 = $tester->testtask->getById(1);
+$task2 = $tester->testtask->getById(2);
+$pager = new pager(0, 10, 1);
+
+$cases1 = $tester->testtask->getLinkableCasesByTestTask(1, array(2), '1 = 1', $pager);
+$cases2 = $tester->testtask->getLinkableCasesByTestTask(2, '', '1 = 1', $pager);
+$cases3 = $tester->testtask->getLinkableCasesByTestTask(3, '', '1 = 1', $pager);
+
+r(count($cases1)) && p() && e('2'); // 直接获取测试单1可关联的用例数量,排除掉ID为2的用例,查看数量
+r(count($cases2)) && p() && e('3'); // 直接获取测试单2可关联的用例数量,查看数量
+r(count($cases3)) && p() && e('3'); // 直接获取测试单3可关联的用例数量,查看数量
+r($cases1) && p('0:id,title,type,stage') && e('3,这个是测试用例3,config,intergrate'); // 直接获取测试单1可关联的用例数量,排除掉ID为2的用例,查看获取到的第一个用例的详情
+r($cases2) && p('0:id,title,type,stage') && e('6,这个是测试用例6,interface,bvt'); // 直接获取测试单2可关联的用例数量,查看获取到的第一个用例的详情
+r($cases3) && p('0:id,title,type,stage') && e('10,这个是测试用例10,config,system'); // 直接获取测试单3可关联的用例数量,查看获取到的第一个用例的详情
\ No newline at end of file
diff --git a/module/testtask/test/model/getpairs.php b/module/testtask/test/model/getpairs.php
new file mode 100755
index 0000000000..d7c3c812a9
--- /dev/null
+++ b/module/testtask/test/model/getpairs.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getPairs();
+cid=1
+pid=1
+
+
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$appendIdList = array(40, 45, 50);
+
+$taskPairs1 = $tester->testtask->getPairs(1);
+$taskPairs2 = $tester->testtask->getPairs(1, 101);
+$taskPairs3 = $tester->testtask->getPairs(1, 101, $appendIdList);
+
+r(count($taskPairs1)) && p() && e(''); // 获取产品1下的测试单的数量
+r(count($taskPairs2)) && p() && e(''); // 获取产品1下的测试单的数量
+r(count($taskPairs3)) && p() && e(''); // 获取产品1下的测试单的数量
+r($taskPairs1) && p() && e(''); // 获取产品1下的测试单的数量
+r($taskPairs2) && p() && e(''); // 获取产品1下的测试单的数量
+r($taskPairs3) && p() && e(''); // 获取产品1下的测试单的数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getproducttasks.php b/module/testtask/test/model/getproducttasks.php
new file mode 100755
index 0000000000..12e5171850
--- /dev/null
+++ b/module/testtask/test/model/getproducttasks.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getProductTasks();
+cid=1
+pid=1
+
+查看产品1下的测试单的数量 >> 2
+查看系统中所有测试单的数量 >> 11
+查看系统中所有截止日期大于2023-01-01的测试单的数量 >> 0
+查看ID为11的测试单的详细信息 >> 新增测试报告,system,2022-03-05,2022-09-05
+查看ID为3的测试单的详细信息 >> 测试单3,,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$localScope = array('local', 'totalstatus');
+$allScope = array('all', 'totalstatus');
+
+$tasks1 = $tester->testtask->getProductTasks(1, 'all', 'id_desc', null, $localScope);
+$tasks2 = $tester->testtask->getProductTasks(2, 'all', 'id_asc', null, $allScope);
+$tasks3 = $tester->testtask->getProductTasks(2, 'all', 'id_asc', null, $allScope, '2023-01-01');
+
+r(count($tasks1)) && p() && e('2'); // 查看产品1下的测试单的数量
+r(count($tasks2)) && p() && e('11'); // 查看系统中所有测试单的数量
+r(count($tasks3)) && p() && e('0'); // 查看系统中所有截止日期大于2023-01-01的测试单的数量
+r($tasks1) && p('11:name,type,begin,end') && e('新增测试报告,system,2022-03-05,2022-09-05'); // 查看ID为11的测试单的详细信息
+r($tasks2) && p('3:name,type,begin,end') && e('测试单3,,2022-04-08,2022-04-15'); // 查看ID为3的测试单的详细信息
\ No newline at end of file
diff --git a/module/testtask/test/model/getproductunittasks.php b/module/testtask/test/model/getproductunittasks.php
new file mode 100755
index 0000000000..b9c7a47289
--- /dev/null
+++ b/module/testtask/test/model/getproductunittasks.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getProductUnitTasks();
+cid=1
+pid=1
+
+
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$tasks = $tester->testtask->getProductUnitTasks(1, 'all');
+
+r($testtask->getProductUnitTasksTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getprojecttasks.php b/module/testtask/test/model/getprojecttasks.php
new file mode 100755
index 0000000000..48cc14130f
--- /dev/null
+++ b/module/testtask/test/model/getprojecttasks.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getProjectTasks();
+cid=1
+pid=1
+
+查看项目11下的所有测试单数量 >> 1
+查看项目20下的所有测试单数量 >> 1
+查看项目100下的所有测试单数量 >> 0
+查看项目11下的测试单1的详细信息 >> 测试单1,,wait,2022-04-08,2022-04-15
+查看项目20下的所有测试单10的详细信息 >> 测试单10,,doing,2022-04-08,2022-04-15
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$project11Tasks = $tester->testtask->getProjectTasks(11);
+$project20Tasks = $tester->testtask->getProjectTasks(20);
+$project100Tasks = $tester->testtask->getProjectTasks(100);
+
+r(count($project11Tasks)) && p() && e('1'); // 查看项目11下的所有测试单数量
+r(count($project20Tasks)) && p() && e('1'); // 查看项目20下的所有测试单数量
+r(count($project100Tasks)) && p() && e('0'); // 查看项目100下的所有测试单数量
+r($project11Tasks) && p('1:name,type,status,begin,end') && e('测试单1,,wait,2022-04-08,2022-04-15'); // 查看项目11下的测试单1的详细信息
+r($project20Tasks) && p('10:name,type,status,begin,end') && e('测试单10,,doing,2022-04-08,2022-04-15'); // 查看项目20下的所有测试单10的详细信息
\ No newline at end of file
diff --git a/module/testtask/test/model/getrelatedtesttasks.php b/module/testtask/test/model/getrelatedtesttasks.php
new file mode 100755
index 0000000000..0c429174c5
--- /dev/null
+++ b/module/testtask/test/model/getrelatedtesttasks.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getRelatedTestTasks();
+cid=1
+pid=1
+
+查看产品1下相关的测试单,排除掉测试单1,查看数量 >> 0
+查看产品1下相关的测试单,不排除任何测试单,查看数量 >> 1
+查看产品2下相关的测试单,不排除任何测试单,查看数量 >> 1
+查看产品2下相关的测试单,不排除任何测试单,查看数量 >> 测试单1
+查看产品2下相关的测试单,不排除任何测试单,查看数量 >> 测试单2
+
+*/
+
+global $tester;
+$tester->loadModel('testtask');
+
+$tasks1 = $tester->testtask->getRelatedTestTasks(1, 1);
+$tasks2 = $tester->testtask->getRelatedTestTasks(1, 0);
+$tasks3 = $tester->testtask->getRelatedTestTasks(2, 0);
+
+r(count($tasks1)) && p() && e('0'); //查看产品1下相关的测试单,排除掉测试单1,查看数量
+r(count($tasks2)) && p() && e('1'); //查看产品1下相关的测试单,不排除任何测试单,查看数量
+r(count($tasks3)) && p() && e('1'); //查看产品2下相关的测试单,不排除任何测试单,查看数量
+r($tasks2) && p('1') && e('测试单1'); //查看产品2下相关的测试单,不排除任何测试单,查看数量
+r($tasks3) && p('2') && e('测试单2'); //查看产品2下相关的测试单,不排除任何测试单,查看数量
\ No newline at end of file
diff --git a/module/testtask/test/model/getresults.php b/module/testtask/test/model/getresults.php
new file mode 100755
index 0000000000..bd7918f18b
--- /dev/null
+++ b/module/testtask/test/model/getresults.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getResults();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getResultsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getrunbyid.php b/module/testtask/test/model/getrunbyid.php
new file mode 100755
index 0000000000..88aeb323d9
--- /dev/null
+++ b/module/testtask/test/model/getrunbyid.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getRunById();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getRunByIdTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getruns.php b/module/testtask/test/model/getruns.php
new file mode 100755
index 0000000000..dfc0b5ac61
--- /dev/null
+++ b/module/testtask/test/model/getruns.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getRuns();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getRunsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/gettaskcases.php b/module/testtask/test/model/gettaskcases.php
new file mode 100755
index 0000000000..3fdff12748
--- /dev/null
+++ b/module/testtask/test/model/gettaskcases.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getTaskCases();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getTaskCasesTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/gettoandcclist.php b/module/testtask/test/model/gettoandcclist.php
new file mode 100755
index 0000000000..d6cc36fea4
--- /dev/null
+++ b/module/testtask/test/model/gettoandcclist.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getToAndCcList();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getToAndCcListTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getuserruns.php b/module/testtask/test/model/getuserruns.php
new file mode 100755
index 0000000000..082e47b81e
--- /dev/null
+++ b/module/testtask/test/model/getuserruns.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserRuns();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getUserRunsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/getusertesttaskpairs.php b/module/testtask/test/model/getusertesttaskpairs.php
new file mode 100755
index 0000000000..b3fc635a6c
--- /dev/null
+++ b/module/testtask/test/model/getusertesttaskpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserTestTaskPairs();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->getUserTestTaskPairsTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/importunitresult.php b/module/testtask/test/model/importunitresult.php
new file mode 100755
index 0000000000..b75c47cad7
--- /dev/null
+++ b/module/testtask/test/model/importunitresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+importUnitResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->importUnitResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/linkcase.php b/module/testtask/test/model/linkcase.php
new file mode 100755
index 0000000000..39987ee5ca
--- /dev/null
+++ b/module/testtask/test/model/linkcase.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+linkCase();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->linkCaseTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/mergechartoption.php b/module/testtask/test/model/mergechartoption.php
new file mode 100755
index 0000000000..2b20cdbf22
--- /dev/null
+++ b/module/testtask/test/model/mergechartoption.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+mergeChartOption();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->mergeChartOptionTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/parsecppxmlresult.php b/module/testtask/test/model/parsecppxmlresult.php
new file mode 100755
index 0000000000..1d56ec63b3
--- /dev/null
+++ b/module/testtask/test/model/parsecppxmlresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+parseCppXMLResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->parseCppXMLResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/parsexmlresult.php b/module/testtask/test/model/parsexmlresult.php
new file mode 100755
index 0000000000..1aadd8088f
--- /dev/null
+++ b/module/testtask/test/model/parsexmlresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+parseXMLResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->parseXMLResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/parseztffuncresult.php b/module/testtask/test/model/parseztffuncresult.php
new file mode 100755
index 0000000000..1b4c5f24cd
--- /dev/null
+++ b/module/testtask/test/model/parseztffuncresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+parseZTFFuncResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->parseZTFFuncResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/parseztfunitresult.php b/module/testtask/test/model/parseztfunitresult.php
new file mode 100755
index 0000000000..d83c4e8a19
--- /dev/null
+++ b/module/testtask/test/model/parseztfunitresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+parseZTFUnitResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->parseZTFUnitResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/printcell.php b/module/testtask/test/model/printcell.php
new file mode 100755
index 0000000000..5be9d59867
--- /dev/null
+++ b/module/testtask/test/model/printcell.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+printCell();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->printCellTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/processautoresult.php b/module/testtask/test/model/processautoresult.php
new file mode 100755
index 0000000000..7258f84eb2
--- /dev/null
+++ b/module/testtask/test/model/processautoresult.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+processAutoResult();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->processAutoResultTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/start.php b/module/testtask/test/model/start.php
new file mode 100755
index 0000000000..df904e9df4
--- /dev/null
+++ b/module/testtask/test/model/start.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+start();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->startTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/model/update.php b/module/testtask/test/model/update.php
new file mode 100755
index 0000000000..56db94b7fc
--- /dev/null
+++ b/module/testtask/test/model/update.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+
+
+*/
+
+$testtask = new testtaskTest();
+
+r($testtask->updateTest()) && p() && e();
\ No newline at end of file
diff --git a/module/testtask/test/testtask.class.php b/module/testtask/test/testtask.class.php
new file mode 100644
index 0000000000..df515abc6b
--- /dev/null
+++ b/module/testtask/test/testtask.class.php
@@ -0,0 +1,226 @@
+objectModel = $tester->loadModel('testtask');
+ }
+
+ /**
+ * Test create testtask.
+ *
+ * @param int $projectID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function create($projectID, $params)
+ {
+ $_POST = $params;
+ $taskID = $this->objectModel->create($projectID);
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $this->objectModel->getById($taskID);
+ }
+
+ public function update($taskID)
+ {
+ $objects = $this->objectModel->update($taskID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function startTest($taskID)
+ {
+ $objects = $this->objectModel->start($taskID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function closeTest($taskID)
+ {
+ $objects = $this->objectModel->close($taskID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function blockTest($taskID)
+ {
+ $objects = $this->objectModel->block($taskID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function activateTest($taskID)
+ {
+ $objects = $this->objectModel->activate($taskID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function linkCaseTest($taskID, $type)
+ {
+ $objects = $this->objectModel->linkCase($taskID, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRunsTest($taskID, $moduleID, $orderBy, $pager = null)
+ {
+ $objects = $this->objectModel->getRuns($taskID, $moduleID, $orderBy, $pager = null);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getUserRunsTest($taskID, $user, $modules = '', $orderBy = 'id_desc', $pager = null)
+ {
+ $objects = $this->objectModel->getUserRuns($taskID, $user, $modules = '', $orderBy = 'id_desc', $pager = null);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getTaskCasesTest($productID, $browseType, $queryID, $moduleID, $sort, $pager, $task)
+ {
+ $objects = $this->objectModel->getTaskCases($productID, $browseType, $queryID, $moduleID, $sort, $pager, $task);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getUserTestTaskPairsTest($account, $limit = 0, $status = 'all', $skipProductIDList = array(), $skipExecutionIDList = array())
+ {
+ $objects = $this->objectModel->getUserTestTaskPairs($account, $limit = 0, $status = 'all', $skipProductIDList = array(), $skipExecutionIDList = array());
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getRunByIdTest($runID)
+ {
+ $objects = $this->objectModel->getRunById($runID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function createResultTest($runID = 0)
+ {
+ $objects = $this->objectModel->createResult($runID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function batchRunTest($runCaseType = 'testcase', $taskID = 0)
+ {
+ $objects = $this->objectModel->batchRun($runCaseType = 'testcase', $taskID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getResultsTest($runID, $caseID = 0)
+ {
+ $objects = $this->objectModel->getResults($runID, $caseID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function printCellTest($col, $run, $users, $task, $branches, $mode = 'datatable')
+ {
+ $objects = $this->objectModel->printCell($col, $run, $users, $task, $branches, $mode = 'datatable');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function getToAndCcListTest($testtask)
+ {
+ $objects = $this->objectModel->getToAndCcList($testtask);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function importUnitResultTest($productID)
+ {
+ $objects = $this->objectModel->importUnitResult($productID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function processAutoResultTest($testtaskID, $productID, $suites, $cases, $results, $suiteNames = array(), $caseTitles = array(), $auto = 'unit')
+ {
+ $objects = $this->objectModel->processAutoResult($testtaskID, $productID, $suites, $cases, $results, $suiteNames = array(), $caseTitles = array(), $auto = 'unit');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function parseCppXMLResultTest($fileName, $productID, $frame)
+ {
+ $objects = $this->objectModel->parseCppXMLResult($fileName, $productID, $frame);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function parseXMLResultTest($fileName, $productID, $frame)
+ {
+ $objects = $this->objectModel->parseXMLResult($fileName, $productID, $frame);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function parseZTFUnitResultTest($caseResults, $frame, $productID, $jobID, $compileID)
+ {
+ $objects = $this->objectModel->parseZTFUnitResult($caseResults, $frame, $productID, $jobID, $compileID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ public function parseZTFFuncResultTest($caseResults, $frame, $productID, $jobID, $compileID)
+ {
+ $objects = $this->objectModel->parseZTFFuncResult($caseResults, $frame, $productID, $jobID, $compileID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/todo/test/model/activate.php b/module/todo/test/model/activate.php
new file mode 100755
index 0000000000..15580b5f0c
--- /dev/null
+++ b/module/todo/test/model/activate.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+activate();
+cid=1
+pid=1
+
+激活一个状态为wait的todo >> wait
+激活一个状态为doing的todo >> wait
+激活一个状态为done的todo >> wait
+
+*/
+
+$todoIDList = array('1', '2', '3');
+
+$todo = new todoTest();
+
+r($todo->activateTest($todoIDList[0])) && p('status') && e('wait'); // 激活一个状态为wait的todo
+r($todo->activateTest($todoIDList[1])) && p('status') && e('wait'); // 激活一个状态为doing的todo
+r($todo->activateTest($todoIDList[2])) && p('status') && e('wait'); // 激活一个状态为done的todo
diff --git a/module/todo/test/model/assignto.php b/module/todo/test/model/assignto.php
new file mode 100755
index 0000000000..e6138f7319
--- /dev/null
+++ b/module/todo/test/model/assignto.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+assignTo();
+cid=1
+pid=1
+
+指派todo 1给test1 >> test1,20300101,1000,1400
+指派todo 2给test1 >> test1,2400,2400
+指派todo 3给test1 >> test1,1002,1402
+
+*/
+
+$todoIDList = array('1', '2', '3');
+
+$todo1 = new stdclass();
+$todo1->assignedTo = 'test1';
+$todo1->future = 'on';
+$todo1->begin = 1000;
+$todo1->end = 1400;
+
+$todo2 = new stdclass();
+$todo2->assignedTo = 'test1';
+$todo2->lblDisableDate = 'on';
+
+$todo3 = new stdclass();
+$todo3->assignedTo = 'test1';
+$todo3->begin = 1002;
+$todo3->end = 1402;
+
+$todo = new todoTest();
+
+r($todo->assignToTest($todoIDList[0], $todo1)) && p('assignedTo,date,begin,end') && e('test1,20300101,1000,1400'); // 指派todo 1给test1
+r($todo->assignToTest($todoIDList[1], $todo2)) && p('assignedTo,begin,end') && e('test1,2400,2400'); // 指派todo 2给test1
+r($todo->assignToTest($todoIDList[2], $todo3)) && p('assignedTo,begin,end') && e('test1,1002,1402'); // 指派todo 3给test1
diff --git a/module/todo/test/model/batchcreate.php b/module/todo/test/model/batchcreate.php
new file mode 100755
index 0000000000..a37465d8a3
--- /dev/null
+++ b/module/todo/test/model/batchcreate.php
@@ -0,0 +1,40 @@
+#!/usr/bin/env php
+batchCreate();
+cid=1
+pid=1
+
+批量创建有个没有名字的待办 >> 批量创建待办1,desc1,1,custom,0;批量创建待办2,desc2,2,custom,0;批量创建待办3,desc4,4,custom,0
+批量创建的待办 >> 测试单转Bug13,desc1,1,bug,313;用户需求版本一61,desc2,2,story,1;开发任务11,desc3,3,task,1;测试单1,desc4,4,testtask,1
+
+*/
+
+$names = array('批量创建待办1','批量创建待办2','', '批量创建待办3', '', '', '', '');
+$types = array('custom', 'custom', 'custom', 'custom', 'custom', 'custom', 'custom', 'custom');
+$pris = array('1', '2', '3', '4', '1', '2', '3', '4');
+$descs = array('desc1', 'desc2', 'desc3', 'desc4', '' , '', '', '');
+$begins = array('0830', '0900', '0930', '1000', '1030', '1100', '1130', '1200');
+$ends = array('0900', '0930', '1000','1030', '1100', '1130', '1200', '1230');
+$bugs = array('2' => '313');
+$assignedTos = array('user1', 'ditto', 'ditto', 'ditto', 'ditto', 'ditto', 'ditto', 'ditto',);
+$noname_create = array('types' => $types, 'pris' => $pris, 'names' => $names, 'descs' => $descs, 'begins' => $begins, 'ends' => $ends, 'assignedTos' => $assignedTos);
+
+$names = array('批量创建待办4','批量创建待办5','批量创建待办6', '批量创建待办7', '', '', '', '');
+$types = array('bug', 'story', 'task', 'testtask', 'custom', 'custom', 'custom', 'custom');
+$bugs = array('1' => '313');
+$stories = array('2' => '1');
+$tasks = array('3' => '1');
+$testtasks = array('4' => '1');
+
+$except_create = array('types' => $types, 'pris' => $pris, 'names' => $names, 'descs' => $descs, 'begins' => $begins, 'ends' => $ends, 'bugs' => $bugs, 'stories' => $stories, 'tasks' => $tasks, 'testtasks' => $testtasks, 'assignedTos' => $assignedTos);
+
+$todo = new todoTest();
+
+r($todo->batchCreateTest($noname_create)) && p('2006:name,desc,pri,type,idvalue;2007:name,desc,pri,type,idvalue;2008:name,desc,pri,type,idvalue') && e('批量创建待办1,desc1,1,custom,0;批量创建待办2,desc2,2,custom,0;批量创建待办3,desc4,4,custom,0'); // 批量创建有个没有名字的待办
+r($todo->batchCreateTest($except_create)) && p('2009:name,desc,pri,type,idvalue;2010:name,desc,pri,type,idvalue;2011:name,desc,pri,type,idvalue;2012:name,desc,pri,type,idvalue') && e('测试单转Bug13,desc1,1,bug,313;软件需求版本一551,desc2,2,story,1;开发任务11,desc3,3,task,1;测试单1,desc4,4,testtask,1'); // 批量创建的待办
diff --git a/module/todo/test/model/batchupdate.php b/module/todo/test/model/batchupdate.php
new file mode 100755
index 0000000000..08c4909ee9
--- /dev/null
+++ b/module/todo/test/model/batchupdate.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+batchUpdate();
+cid=1
+pid=1
+
+批量修改todo类型 >> type,task,custom
+批量修改todo优先级 >> pri,2,1
+批量修改todo状态 >> status,wait,doing
+
+*/
+
+$types = array('1' => 'custom', '2' => 'bug', '3' => 'custom');
+$pris = array('1' => '1', '2' => '1', '3' => '3');
+$status = array('1' => 'doing', '2' => 'doing', '3' => 'done');
+$bugs = array('2' => '1');
+$tasks = array('3' => '2');
+
+$changeType = array('types' => $types, 'bugs' => $bugs);
+$changePri = array('pris' => $pris, 'bugs' => $bugs, 'tasks' => $tasks);
+$changeStatus = array('status' => $status, 'bugs' => $bugs, 'tasks' => $tasks);
+
+$todo = new todoTest();
+
+r($todo->batchUpdateTest($changeType, '3')) && p('0:field,old,new') && e('type,task,custom'); // 批量修改todo类型
+r($todo->batchUpdateTest($changePri, '2')) && p('0:field,old,new') && e('pri,2,1'); // 批量修改todo优先级
+r($todo->batchUpdateTest($changeStatus, '1')) && p('0:field,old,new') && e('status,wait,doing'); // 批量修改todo状态
diff --git a/module/todo/test/model/close.php b/module/todo/test/model/close.php
new file mode 100755
index 0000000000..d02cee8333
--- /dev/null
+++ b/module/todo/test/model/close.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+close();
+cid=1
+pid=1
+
+关闭一个状态为wait的todo >> closed
+关闭一个状态为doing的todo >> closed
+关闭一个状态为done的todo >> closed
+
+*/
+
+$todoIDList = array('1', '2', '3');
+
+$todo = new todoTest();
+
+r($todo->closeTest($todoIDList[0])) && p('status') && e('closed'); // 关闭一个状态为wait的todo
+r($todo->closeTest($todoIDList[1])) && p('status') && e('closed'); // 关闭一个状态为doing的todo
+r($todo->closeTest($todoIDList[2])) && p('status') && e('closed'); // 关闭一个状态为done的todo
diff --git a/module/todo/test/model/create.php b/module/todo/test/model/create.php
new file mode 100755
index 0000000000..339618c8c0
--- /dev/null
+++ b/module/todo/test/model/create.php
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+create();
+cid=1
+pid=1
+
+创建没有名字的待办 >> 『待办名称』不能为空。
+创建自定义待办 >> 时间待定的月周期待办,custom,wait
+创建bug待办 >> 测试单转Bug13,bug,doing
+创建task待办 >> 开发任务11,task,done
+创建story待办 >> 用户需求1,story,closed
+
+*/
+
+$accountList = array('admin', 'dev1', 'test1');
+
+$b_noname = new stdclass();
+$b_noname->name = '';
+$b_noname->date = 'today';
+$b_noname->type = 'custom';
+
+$todo1 = new stdclass();
+$todo1->name = '时间待定的月周期待办';
+$todo1->type = 'custom';
+$todo1->date = '+3 days';
+$todo1->config = array('day' => '', 'specify' => array('month' => 0, 'day' => 1), 'month' => array(1,3,5), 'type' => 'month', 'beforeDays' => 2, 'end' => '2025-01-01');
+
+$todo2 = new stdclass();
+$todo2->name = 'bug待办';
+$todo2->type = 'bug';
+$todo2->date = 'today';
+$todo2->bug = '313';
+$todo2->status = 'doing';
+$todo2->uid = '313';
+
+$todo3 = new stdclass();
+$todo3->name = 'task待办';
+$todo3->type = 'task';
+$todo3->date = 'today';
+$todo3->task = '1';
+$todo3->status = 'done';
+$todo3->uid = '1';
+
+$todo4 = new stdclass();
+$todo4->name = 'story待办';
+$todo4->type = 'story';
+$todo4->date = 'today';
+$todo4->story = '1';
+$todo4->status = 'closed';
+$todo4->uid = '1';
+
+$todo = new todoTest();
+
+r($todo->createTest($accountList[0], $b_noname)) && p() && e('『待办名称』不能为空。'); //创建没有名字的待办
+r($todo->createTest($accountList[1], $todo1)) && p('name,type,status') && e('时间待定的月周期待办,custom,wait'); //创建自定义待办
+r($todo->createTest($accountList[2], $todo2)) && p('name,type,status') && e('测试单转Bug13,bug,doing'); //创建bug待办
+r($todo->createTest($accountList[0], $todo3)) && p('name,type,status') && e('开发任务11,task,done'); //创建task待办
+r($todo->createTest($accountList[0], $todo4)) && p('name,type,status') && e('用户需求1,story,closed'); //创建story待办
diff --git a/module/todo/test/model/createbycycle.php b/module/todo/test/model/createbycycle.php
new file mode 100755
index 0000000000..e8087bd0c9
--- /dev/null
+++ b/module/todo/test/model/createbycycle.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+createByCycle();
+cid=1
+pid=1
+
+ >> + days
+测试创建周期日待办 >> 11
+测试创建周期周待办 >> 9
+测试创建周期月待办 >> `%d`
+
+*/
+
+$days = 31;
+$begin = call_user_func_array('date', array('Y-m-d'));
+$end = call_user_func_array('date', array('Y-m-d', strtotime("+$days days")));
+$todo1 = new stdclass();
+$todo1->name = 'cycle生成的待办1';
+$todo1->config = '{"specify":{"month":"0","day":"1"},"day":"1","type":"day","beforeDays":11,"end":"' . $end . '","begin":"' . $begin . '"}';
+
+$todo2 = new stdclass();
+$todo2->name = 'cycle生成的待办2';
+$todo2->config = '{"specify":{"month":"0","day":"1"},"week":"2,4,7","type":"week","beforeDays":31,"end":"' . $end . '","begin":"' . $begin . '"}';
+
+$todo3 = new stdclass();
+$todo3->name = 'cycle生成的待办3';
+$todo3->config = '{"specify":{"month":"0","day":"1"},"month":"1,8,13,15,27,29,30","type":"month","beforeDays":301,"end":"' . $end . '","begin":"' . $begin . '"}';
+
+$todo = new todoTest();
+
+r($todo->createByCycleTest($todo1)) && p() && e('11'); // 测试创建周期日待办
+r($todo->createByCycleTest($todo2)) && p() && e('9'); // 测试创建周期周待办
+r($todo->createByCycleTest($todo3)) && p() && e('`%d`'); // 测试创建周期月待办
diff --git a/module/todo/test/model/finish.php b/module/todo/test/model/finish.php
new file mode 100755
index 0000000000..0881743378
--- /dev/null
+++ b/module/todo/test/model/finish.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+finish();
+cid=1
+pid=1
+
+结束一个状态为wait的todo >> done
+结束一个状态为doing的todo >> done
+结束一个状态为done的todo >> done
+
+*/
+
+$todoIDList = array('1', '2', '3');
+
+$todo = new todoTest();
+
+r($todo->finishTest($todoIDList[0])) && p('status') && e('done'); // 结束一个状态为wait的todo
+r($todo->finishTest($todoIDList[1])) && p('status') && e('done'); // 结束一个状态为doing的todo
+r($todo->finishTest($todoIDList[2])) && p('status') && e('done'); // 结束一个状态为done的todo
diff --git a/module/todo/test/model/getbyid.php b/module/todo/test/model/getbyid.php
new file mode 100755
index 0000000000..6334d3fbbb
--- /dev/null
+++ b/module/todo/test/model/getbyid.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getById();
+cid=1
+pid=1
+
+获取id为1的todo信息 >> 自定义1的待办,custom,wait
+获取id为2的todo信息 >> BUG1,bug,doing
+获取id为3的todo信息 >> 开发任务12,task,done
+获取id为4的todo信息 >> 用户需求3,story,closed
+获取id不存在的todo信息 >> 0
+
+*/
+
+$todoIDList = array('1', '2', '3', '4', '100001');
+
+$todo = new todoTest();
+
+r($todo->getByIdTest($todoIDList[0])) && p('name,type,status') && e('自定义1的待办,custom,wait'); // 获取id为1的todo信息
+r($todo->getByIdTest($todoIDList[1])) && p('name,type,status') && e('BUG1,bug,doing'); // 获取id为2的todo信息
+r($todo->getByIdTest($todoIDList[2])) && p('name,type,status') && e('开发任务12,task,done'); // 获取id为3的todo信息
+r($todo->getByIdTest($todoIDList[3])) && p('name,type,status') && e('用户需求3,story,closed'); // 获取id为4的todo信息
+r($todo->getByIdTest($todoIDList[4])) && p('name,type,status') && e('0'); // 获取id不存在的todo信息
\ No newline at end of file
diff --git a/module/todo/test/model/getbylist.php b/module/todo/test/model/getbylist.php
new file mode 100755
index 0000000000..426f22dd00
--- /dev/null
+++ b/module/todo/test/model/getbylist.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+getByList();
+cid=1
+pid=1
+
+获取todo 1 2 3 4的名称 >> 自定义1的待办,BUG2的待办,任务3的待办,需求4的待办
+获取todo 5 6 7 8的名称 >> 测试单5的待办,自定义6的待办,BUG7的待办,任务8的待办
+获取todo 9 10 11 12的名称 >> 需求9的待办,测试单10的待办,自定义11的待办,BUG12的待办
+
+*/
+
+$todoIDList1 = array('1', '2', '3', '4');
+$todoIDList2 = array('5', '6', '7', '8');
+$todoIDList3 = array('9', '10', '11', '12');
+
+$todo = new todoTest();
+
+r($todo->getByListTest($todoIDList1)) && p() && e('自定义1的待办,BUG2的待办,任务3的待办,需求4的待办'); // 获取todo 1 2 3 4的名称
+r($todo->getByListTest($todoIDList2)) && p() && e('测试单5的待办,自定义6的待办,BUG7的待办,任务8的待办'); // 获取todo 5 6 7 8的名称
+r($todo->getByListTest($todoIDList3)) && p() && e('需求9的待办,测试单10的待办,自定义11的待办,BUG12的待办'); // 获取todo 9 10 11 12的名称
\ No newline at end of file
diff --git a/module/todo/test/model/getcount.php b/module/todo/test/model/getcount.php
new file mode 100755
index 0000000000..5761568b4f
--- /dev/null
+++ b/module/todo/test/model/getcount.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+getCount();
+cid=1
+pid=1
+
+获取用户admin的所有待办个数 >> 2
+获取用户user1的所有待办个数 >> 2
+获取用户user2的所有待办个数 >> 2
+获取用户user3的所有待办个数 >> 2
+获取不存在的用户所有待办个数 >> 0
+
+*/
+
+$accountList = array('admin', 'user1', 'user2', 'user3', 'user10001');
+
+$todo = new todoTest();
+
+r($todo->getCountTest($accountList[0])) && p() && e('2'); // 获取用户admin的所有待办个数
+r($todo->getCountTest($accountList[1])) && p() && e('2'); // 获取用户user1的所有待办个数
+r($todo->getCountTest($accountList[2])) && p() && e('2'); // 获取用户user2的所有待办个数
+r($todo->getCountTest($accountList[3])) && p() && e('2'); // 获取用户user3的所有待办个数
+r($todo->getCountTest($accountList[4])) && p() && e('0'); // 获取不存在的用户所有待办个数
\ No newline at end of file
diff --git a/module/todo/test/model/getlist.php b/module/todo/test/model/getlist.php
new file mode 100755
index 0000000000..09e52a63aa
--- /dev/null
+++ b/module/todo/test/model/getlist.php
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+getList();
+cid=1
+pid=1
+
+获取type为today 当前用户的代办数量 >> 0
+获取type为yesterday 当前用户的代办数量 >> 0
+获取type为thisweek 当前用户的代办数量 >> 0
+获取type为lastweek 当前用户的代办数量 >> 1
+获取type为thismonth 当前用户的代办数量 >> 1
+获取type为lastmonth 当前用户的代办数量 >> 1
+获取type为thisseason 当前用户的代办数量 >> 2
+获取type为thisyear 当前用户的代办数量 >> 2
+获取type为future 当前用户的代办数量 >> 0
+获取type为before 当前用户的代办数量 >> 2
+获取type为cycle 当前用户的代办数量 >> 1
+获取type为today user1的代办数量 >> 0
+获取type为yesterday user1的代办数量 >> 0
+获取type为thisweek user1的代办数量 >> 0
+获取type为lastweek user1的代办数量 >> 1
+获取type为thismonth user1的代办数量 >> 1
+获取type为lastmonth user1的代办数量 >> 1
+获取type为thisseason user1的代办数量 >> 2
+获取type为thisyear user1的代办数量 >> 2
+获取type为future user1的代办数量 >> 0
+获取type为before user1的代办数量 >> 2
+获取type为cycle user1的代办数量 >> 1
+
+*/
+
+$typeList = array('today', 'yesterday', 'thisweek', 'lastweek', 'thismonth', 'lastmonth', 'thisseason', 'thisyear', 'future', 'before', 'cycle');
+$account = 'user1';
+
+$todo = new todoTest();
+
+r($todo->getListTest($typeList[0])) && p() && e('0'); // 获取type为today 当前用户的代办数量
+r($todo->getListTest($typeList[1])) && p() && e('0'); // 获取type为yesterday 当前用户的代办数量
+r($todo->getListTest($typeList[2])) && p() && e('0'); // 获取type为thisweek 当前用户的代办数量
+r($todo->getListTest($typeList[3])) && p() && e('1'); // 获取type为lastweek 当前用户的代办数量
+r($todo->getListTest($typeList[4])) && p() && e('1'); // 获取type为thismonth 当前用户的代办数量
+r($todo->getListTest($typeList[5])) && p() && e('1'); // 获取type为lastmonth 当前用户的代办数量
+r($todo->getListTest($typeList[6])) && p() && e('2'); // 获取type为thisseason 当前用户的代办数量
+r($todo->getListTest($typeList[7])) && p() && e('2'); // 获取type为thisyear 当前用户的代办数量
+r($todo->getListTest($typeList[8])) && p() && e('0'); // 获取type为future 当前用户的代办数量
+r($todo->getListTest($typeList[9])) && p() && e('2'); // 获取type为before 当前用户的代办数量
+r($todo->getListTest($typeList[10])) && p() && e('1'); // 获取type为cycle 当前用户的代办数量
+r($todo->getListTest($typeList[0], $account)) && p() && e('0'); // 获取type为today user1的代办数量
+r($todo->getListTest($typeList[1], $account)) && p() && e('0'); // 获取type为yesterday user1的代办数量
+r($todo->getListTest($typeList[2], $account)) && p() && e('0'); // 获取type为thisweek user1的代办数量
+r($todo->getListTest($typeList[3], $account)) && p() && e('1'); // 获取type为lastweek user1的代办数量
+r($todo->getListTest($typeList[4], $account)) && p() && e('1'); // 获取type为thismonth user1的代办数量
+r($todo->getListTest($typeList[5], $account)) && p() && e('1'); // 获取type为lastmonth user1的代办数量
+r($todo->getListTest($typeList[6], $account)) && p() && e('2'); // 获取type为thisseason user1的代办数量
+r($todo->getListTest($typeList[7], $account)) && p() && e('2'); // 获取type为thisyear user1的代办数量
+r($todo->getListTest($typeList[8], $account)) && p() && e('0'); // 获取type为future user1的代办数量
+r($todo->getListTest($typeList[9], $account)) && p() && e('2'); // 获取type为before user1的代办数量
+r($todo->getListTest($typeList[10], $account)) && p() && e('1'); // 获取type为cycle user1的代办数量
\ No newline at end of file
diff --git a/module/todo/test/model/start.php b/module/todo/test/model/start.php
new file mode 100755
index 0000000000..00b4d7d9c8
--- /dev/null
+++ b/module/todo/test/model/start.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+start();
+cid=1
+pid=1
+
+开始一个状态为wait的todo >> doing
+开始一个状态为doing的todo >> doing
+开始一个状态为done的todo >> doing
+
+*/
+
+$todoIDList = array('1', '2', '3');
+
+$todo = new todoTest();
+
+r($todo->startTest($todoIDList[0])) && p('status') && e('doing'); // 开始一个状态为wait的todo
+r($todo->startTest($todoIDList[1])) && p('status') && e('doing'); // 开始一个状态为doing的todo
+r($todo->startTest($todoIDList[2])) && p('status') && e('doing'); // 开始一个状态为done的todo
diff --git a/module/todo/test/model/update.php b/module/todo/test/model/update.php
new file mode 100755
index 0000000000..65e2a3a481
--- /dev/null
+++ b/module/todo/test/model/update.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新todo名称 >> name,自定义1的待办,john
+测试更新todo类型 >> type,custom,bug
+测试更新todo名称和类型 >> type,bug,custom;name,BUG2的待办,jack
+测试不更新todo任何数据 >> 没有数据更新
+
+*/
+
+$todoIDList = array('1', '2');
+
+$t_upname = array('name' => 'john');
+$t_uptype = array('type' => 'bug', 'idvalue' => '1');
+$t_typename = array('name' => 'jack', 'type' => 'custom');
+$t_unname = array('name' => 'john');
+
+$todo = new todoTest();
+
+r($todo->updateTest($todoIDList[0], $t_upname)) && p('0:field,old,new') && e('name,自定义1的待办,john'); // 测试更新todo名称
+r($todo->updateTest($todoIDList[0], $t_uptype)) && p('0:field,old,new') && e('type,custom,bug'); // 测试更新todo类型
+r($todo->updateTest($todoIDList[1], $t_typename)) && p('0:field,old,new;1:field,old,new') && e('type,bug,custom;name,BUG2的待办,jack'); // 测试更新todo名称和类型
+r($todo->updateTest($todoIDList[0], $t_unname)) && p() && e('没有数据更新'); // 测试不更新todo任何数据
diff --git a/module/todo/test/todo.class.php b/module/todo/test/todo.class.php
new file mode 100755
index 0000000000..9ba0799c57
--- /dev/null
+++ b/module/todo/test/todo.class.php
@@ -0,0 +1,367 @@
+objectModel = $tester->loadModel('todo');
+ $tester->app->loadClass('dao');
+ $_SERVER['HTTP_HOST'] = 'test.zentao.net';
+ }
+
+ /**
+ * Test create a todo.
+ *
+ * @param string $account
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function createTest($account, $param = array())
+ {
+ $config = array('day' => '', 'specify' => array('month' => 0, 'day' => 1), 'type' => 'day', 'beforeDays' => 0, 'end' => '');
+ if(isset($param->date)) $param->date = $param->date == 'today' ? date('Y-m-d',time()) : date('Y-m-d',strtotime('+3 days'));
+
+ $createFields['config'] = $config;
+ $createFields['type'] = 'custom';
+ $createFields['name'] = '';
+ $createFields['pri'] = 3;
+ $createFields['desc'] = '';
+ $createFields['status'] = 'wait';
+ $createFields['begin'] = '0830';
+ $createFields['end'] = '0900';
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objectID = $this->objectModel->create(date('Y').date('m'), $account);
+
+ unset($_POST);
+
+ if(dao::isError()) return array_values(dao::getError())[0][0];
+
+ $object = $objectID ? $this->objectModel->getByID($objectID) : 0;
+ return $object;
+ }
+
+ /**
+ * Test batch create todos.
+ *
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function batchCreateTest($param = array())
+ {
+ $createFields['date'] = date('Y-m-d',time());
+
+ foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $objects = $this->objectModel->batchCreate();
+
+ $todos = $this->objectModel->getByList($objects);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $todos;
+ }
+
+ /**
+ * Test update a todo.
+ *
+ * @param int $todoID
+ * @param array $param
+ * @access public
+ * @return array
+ */
+ public function updateTest($todoID, $param)
+ {
+ global $tester;
+ $object = $tester->dbh->query("SELECT * FROM " . TABLE_TODO ." WHERE id = $todoID")->fetch();
+
+ foreach($object as $field => $value)
+ {
+ if(in_array($field, array_keys($param)))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $value;
+ }
+ }
+
+ $change = $this->objectModel->update($todoID);
+ if($change == array()) $change = '没有数据更新';
+
+ unset($_POST);
+ if(dao::isError()) return dao::getError();
+
+ return $change;
+ }
+
+ /**
+ * Test batch update todos.
+ *
+ * @param array $param
+ * @param int $todoID
+ * @access public
+ * @return array
+ */
+ public function batchUpdateTest($param, $todoID)
+ {
+ $todoIDList = array('1' => '1', '2' => '2', '3' => '3');
+ $dates = array('1' => date('Y-m-d',strtotime('+1 month')), '2' => date('Y-m-d',strtotime('-1 month +1 day')), '3' => date('Y-m-d',strtotime('-1 month +2 day')));
+ $types = array('1' => 'custom', '2' => 'bug', '3' => 'task');
+ $pris = array('1' => '1', '2' => '2', '3' => '3');
+ $names = array('1' => '自定义1的待办', '2' => 'BUG2的待办', '3' => '任务3的待办');
+ $descs = array('1' => '这是一个待办的描述1', '2' => '这是一个待办的描述2', '3' => '这是一个待办的描述3');
+ $begins = array('1' => '1000', '2' => '1002', '3' => '1004');
+ $ends = array('1' => '1400', '2' => '1402', '3' => '1404');
+ $status = array('1' => 'wait', '2' => 'doing', '3' => 'done');
+
+ $batchUpdateFields['todoIDList'] = $todoIDList;
+ $batchUpdateFields['dates'] = $dates;
+ $batchUpdateFields['types'] = $types;
+ $batchUpdateFields['pris'] = $pris;
+ $batchUpdateFields['names'] = $names;
+ $batchUpdateFields['descs'] = $descs;
+ $batchUpdateFields['begins'] = $begins;
+ $batchUpdateFields['ends'] = $ends;
+ $batchUpdateFields['status'] = $status;
+
+ foreach($batchUpdateFields as $field => $value) $_POST[$field] = $value;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $changes = $this->objectModel->batchUpdate();
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ return $changes[$todoID];
+ }
+
+ /**
+ * Test start a todo.
+ *
+ * @param int $todoID
+ * @access public
+ * @return object
+ */
+ public function startTest($todoID)
+ {
+ $this->objectModel->start($todoID);
+ $object = $this->objectModel->getByID($todoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test finish a todo.
+ *
+ * @param int $todoID
+ * @access public
+ * @return object
+ */
+ public function finishTest($todoID)
+ {
+ $this->objectModel->finish($todoID);
+ $object = $this->objectModel->getByID($todoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get info of a todo.
+ *
+ * @param int $todoID
+ * @param bool $setImgSize
+ * @access public
+ * @return object
+ */
+ public function getByIdTest($todoID, $setImgSize = false)
+ {
+ $object = $this->objectModel->getById($todoID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get todo list of a user.
+ *
+ * @param string $type
+ * @param string $account
+ * @param string $status
+ * @param int $limit
+ * @param mixed $pager
+ * @param string $orderBy
+ * @param status $status
+ * @param begin" $begin"
+ * @access public
+ * @return void
+ */
+ public function getListTest($type = 'today', $account = '', $status = 'all', $limit = 0, $pager = null, $orderBy = "date, status, begin")
+ {
+ $objects = $this->objectModel->getList($type, $account, $status, $limit, $pager, $orderBy);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test get todo by id list.
+ *
+ * @parami array $todoIDList
+ * @access public
+ * @return void
+ */
+ public function getByListTest($todoIDList = 0)
+ {
+ $objects = $this->objectModel->getByList($todoIDList);
+
+ $name = '';
+ foreach($objects as $todo) $name .= ',' . $todo->name;
+ $name = trim($name, ',');
+
+ if(dao::isError()) return dao::getError();
+
+ return $name;
+ }
+
+ /**
+ * isClickableTest
+ *
+ * @param object $todo
+ * @param string $action
+ * @access public
+ * @return int
+ */
+ public function isClickableTest($todo, $action)
+ {
+ $object = $this->objectModel->isClickable($todo, $action);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object ? 1 : 2;
+ }
+
+ public function createByCycleTest($todo)
+ {
+ $todo->cycle = '1';
+ $todo->type = 'cycle';
+ $todo->pri = 3;
+ $todo->desc = '';
+ $todo->status = 'wait';
+ $todo->begin = '0830';
+ $todo->end = '0900';
+ $todo->account = 'admin';
+ $todo->idvalue = '0';
+ $todo->vision = 'rnd';
+ $todo->assignedTo = 'admin';
+ $todo->assignedBy = 'admin';
+ $todo->assignedDate = date('Y-m-d', time());
+ $todo->date = date('Y-m-d', time());
+
+ $todo->config = str_replace('2022-03-23', date('Y-m-d', time()), $todo->config);
+
+ global $tester;
+ $tester->dao->insert(TABLE_TODO)->data($todo)->autoCheck()->exec();
+ $todoID = $tester->dao->lastInsertID();
+
+ $this->objectModel->createByCycle(array($todoID => $todo));
+
+ $objects = $tester->dao->select('id')->from(TABLE_TODO)->where('idvalue')->eq($todoID)->andWhere('deleted')->eq('0')->fetchAll();
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test activate todo.
+ *
+ * @param int $todoID
+ * @access public
+ * @return object
+ */
+ public function activateTest($todoID)
+ {
+ $this->objectModel->activate($todoID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getById($todoID);
+ return $object;
+ }
+
+ /**
+ * Test close a todo.
+ *
+ * @param int $todoID
+ * @access public
+ * @return object
+ */
+ public function closeTest($todoID)
+ {
+ $this->objectModel->close($todoID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getById($todoID);
+ return $object;
+ }
+
+ /**
+ * Test assign todo.
+ *
+ * @param int $todoID
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function assignToTest($todoID, $param = array())
+ {
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ if(!isset($_POST['future']) and !isset($_POST['date'])) $_POST['date'] = date('Y-m-d', time());
+
+ $this->objectModel->assignTo($todoID);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getById($todoID);
+ return $object;
+ }
+
+ /**
+ * Test get todo count.
+ *
+ * @param string $account
+ * @access public
+ * @return int
+ */
+ public function getCountTest($account = '')
+ {
+ $count = $this->objectModel->getCount($account);
+
+ if(dao::isError()) return dao::getError();
+
+ return $count;
+ }
+}
diff --git a/module/tree/test/model/buildmenuquery.php b/module/tree/test/model/buildmenuquery.php
new file mode 100755
index 0000000000..abf9b9844d
--- /dev/null
+++ b/module/tree/test/model/buildmenuquery.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+buildMenuQuery();
+cid=1
+pid=1
+
+测试查询root 1 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '1' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 2 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '2' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 3 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '3' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 41 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 42 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '42' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 43 type story 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '43' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 101 type task 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '101' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc
+测试查询root 102 type task 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '102' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc
+测试查询root 103 type task 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '103' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc
+测试查询root 41 type story startModule 1821的查询语句 >> SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND path LIKE ',1821,%' AND deleted = '0' ORDER BY `grade` desc,`order`
+测试查询root 41 type story startModule 0 branch 1 的查询语句 >> SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND path LIKE ',1982,%' AND (branch = '0' OR branch = '1
+
+*/
+
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'task');
+$startModule = array(1821, 1982);
+$branch = 1;
+
+$tree = new treeTest();
+
+r($tree->buildMenuQueryTest($root[0], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '1' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 1 type story 的查询语句
+r($tree->buildMenuQueryTest($root[1], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '2' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 2 type story 的查询语句
+r($tree->buildMenuQueryTest($root[2], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '3' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 3 type story 的查询语句
+r($tree->buildMenuQueryTest($root[3], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 41 type story 的查询语句
+r($tree->buildMenuQueryTest($root[4], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '42' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 42 type story 的查询语句
+r($tree->buildMenuQueryTest($root[5], $type[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '43' AND type = 'story' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 43 type story 的查询语句
+r($tree->buildMenuQueryTest($root[6], $type[1])) && p() && e("SELECT * FROM `zt_module` WHERE root = '101' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc"); // 测试查询root 101 type task 的查询语句
+r($tree->buildMenuQueryTest($root[7], $type[1])) && p() && e("SELECT * FROM `zt_module` WHERE root = '102' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc"); // 测试查询root 102 type task 的查询语句
+r($tree->buildMenuQueryTest($root[8], $type[1])) && p() && e("SELECT * FROM `zt_module` WHERE root = '103' AND type = 'task' AND deleted = '0' ORDER BY `grade` desc,`order`,`type` desc"); // 测试查询root 103 type task 的查询语句
+r($tree->buildMenuQueryTest($root[3], $type[0], $startModule[0])) && p() && e("SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND path LIKE ',1821,%' AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 41 type story startModule 1821的查询语句
+r($tree->buildMenuQueryTest($root[3], $type[0], $startModule[1], $branch)) && p() && e("SELECT * FROM `zt_module` WHERE root = '41' AND type = 'story' AND path LIKE ',1982,%' AND (branch = '0' OR branch = '1') AND deleted = '0' ORDER BY `grade` desc,`order`"); // 测试查询root 41 type story startModule 0 branch 1 的查询语句
\ No newline at end of file
diff --git a/module/tree/test/model/buildtreearray.php b/module/tree/test/model/buildtreearray.php
new file mode 100755
index 0000000000..836e798e34
--- /dev/null
+++ b/module/tree/test/model/buildtreearray.php
@@ -0,0 +1,51 @@
+#!/usr/bin/env php
+buildTreeArray();
+cid=1
+pid=1
+
+测试创建树选项的字符串长度 1 >> 56
+测试创建树选项的字符串长度 2 >> 56;58
+测试创建树选项的字符串长度 3 >> 112;58
+测试创建树选项的字符串长度 4 >> 112;116
+测试创建树选项的字符串长度 5 >> 112;116;148
+测试创建树选项的字符串长度 6 >> 112;116;300
+测试创建树选项的字符串长度 7 >> 112;116;336
+测试创建树选项的字符串长度 8 >> 112;116;372
+测试创建树选项的字符串长度 9 >> 112;116;408
+测试创建树选项的字符串长度 10 >> 112;116;444
+测试创建树选项的字符串长度 11 >> 112;116;480
+测试创建树选项的字符串长度 12 >> 112;116;516
+
+*/
+$tree = new treeTest();
+
+$treeMenu = array();
+
+$root = array(41, 42, 43, 101, 102, 103);
+$type = array('story', 'task');
+
+$stmt = $tester->dbh->query($tree->buildMenuQueryTest($root[0], $type[0]));
+$modules = array();
+while($module = $stmt->fetch()) $modules[$module->id] = $module;
+
+$moduleIDList = array_keys($modules);
+
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[0])) && p('1981') && e('56'); // 测试创建树选项的字符串长度 1
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[1])) && p('1981;2381') && e('56;58'); // 测试创建树选项的字符串长度 2
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[2])) && p('1981;2381') && e('112;58'); // 测试创建树选项的字符串长度 3
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[3])) && p('1981;2381') && e('112;116'); // 测试创建树选项的字符串长度 4
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[4])) && p('1981;2381;0') && e('112;116;148'); // 测试创建树选项的字符串长度 5
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[5])) && p('1981;2381;0') && e('112;116;300'); // 测试创建树选项的字符串长度 6
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[6])) && p('1981;2381;0') && e('112;116;336'); // 测试创建树选项的字符串长度 7
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[7])) && p('1981;2381;0') && e('112;116;372'); // 测试创建树选项的字符串长度 8
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[8])) && p('1981;2381;0') && e('112;116;408'); // 测试创建树选项的字符串长度 9
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[9])) && p('1981;2381;0') && e('112;116;444'); // 测试创建树选项的字符串长度 10
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[10])) && p('1981;2381;0') && e('112;116;480'); // 测试创建树选项的字符串长度 11
+r($tree->buildTreeArrayTest($treeMenu, $modules, $moduleIDList[11])) && p('1981;2381;0') && e('112;116;516'); // 测试创建树选项的字符串长度 12
\ No newline at end of file
diff --git a/module/tree/test/model/changeroot.php b/module/tree/test/model/changeroot.php
new file mode 100755
index 0000000000..cbb294e08b
--- /dev/null
+++ b/module/tree/test/model/changeroot.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+changeRoot();
+cid=1
+pid=1
+
+测试修改module 1821 的root从 1 修改为 2 >> 0
+测试修改module 1822 的root从 1 修改为 2 >> 0
+测试修改module 1825 的root从 2 修改为 1 >> 0
+测试修改module 1826 的root从 2 修改为 1 >> 0
+测试修改module 1981 的root从 41 修改为 42 >> 0
+测试修改module 1982 的root从 41 修改为 42 >> 0
+测试修改module 1985 的root从 42 修改为 41 >> 0
+测试修改module 1986 的root从 42 修改为 41 >> 0
+测试修改module 21 的root从 101 修改为 102 >> 0
+测试修改module 22 的root从 101 修改为 102 >> 0
+测试修改module 24 的root从 102 修改为 101 >> 0
+测试修改module 25 的root从 102 修改为 101 >> 0
+
+*/
+$moduleID = array(1821, 1822, 1825, 1826, 1981, 1982, 1985, 1986, 21, 22, 24, 25);
+$root = array(1, 2, 41, 42, 101, 102);
+$type = array('story', 'task');
+
+$tree = new treeTest();
+
+r($tree->changeRootTest($moduleID[0], $root[0], $root[1], $type[0])) && p('id,root') && e('0'); // 测试修改module 1821 的root从 1 修改为 2
+r($tree->changeRootTest($moduleID[1], $root[0], $root[1], $type[0])) && p('id,root') && e('0'); // 测试修改module 1822 的root从 1 修改为 2
+r($tree->changeRootTest($moduleID[2], $root[1], $root[0], $type[0])) && p('id,root') && e('0'); // 测试修改module 1825 的root从 2 修改为 1
+r($tree->changeRootTest($moduleID[3], $root[1], $root[0], $type[0])) && p('id,root') && e('0'); // 测试修改module 1826 的root从 2 修改为 1
+r($tree->changeRootTest($moduleID[4], $root[2], $root[3], $type[0])) && p('id,root') && e('0'); // 测试修改module 1981 的root从 41 修改为 42
+r($tree->changeRootTest($moduleID[5], $root[2], $root[3], $type[0])) && p('id,root') && e('0'); // 测试修改module 1982 的root从 41 修改为 42
+r($tree->changeRootTest($moduleID[6], $root[3], $root[2], $type[0])) && p('id,root') && e('0'); // 测试修改module 1985 的root从 42 修改为 41
+r($tree->changeRootTest($moduleID[7], $root[3], $root[2], $type[0])) && p('id,root') && e('0'); // 测试修改module 1986 的root从 42 修改为 41
+r($tree->changeRootTest($moduleID[8], $root[4], $root[5], $type[1])) && p('id,root') && e('0'); // 测试修改module 21 的root从 101 修改为 102
+r($tree->changeRootTest($moduleID[9], $root[4], $root[5], $type[1])) && p('id,root') && e('0'); // 测试修改module 22 的root从 101 修改为 102
+r($tree->changeRootTest($moduleID[10], $root[5], $root[4], $type[1])) && p('id,root') && e('0'); // 测试修改module 24 的root从 102 修改为 101
+r($tree->changeRootTest($moduleID[11], $root[5], $root[4], $type[1])) && p('id,root') && e('0'); // 测试修改module 25 的root从 102 修改为 101
diff --git a/module/tree/test/model/checkunique.php b/module/tree/test/model/checkunique.php
new file mode 100755
index 0000000000..c2d99fd1c6
--- /dev/null
+++ b/module/tree/test/model/checkunique.php
@@ -0,0 +1,85 @@
+#!/usr/bin/env php
+checkUnique();
+cid=1
+pid=1
+
+测试module1是否与已存在的模块重名 >> 0
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块1
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块2
+测试module1是否与已存在的模块重名 >> 产品模块3
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块1
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块2
+测试module1是否与已存在的模块重名 >> 0
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块161
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品模块161
+测试module1是否与已存在的模块重名 >> 产品子模块281
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 产品子模块281
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 0
+测试module1是否与已存在的模块重名 >> 0
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 0
+测试module1 和 moduleID1 里的模块是否与已存在的模块重名 >> 0
+
+*/
+$module1 = new stdclass();
+$module1->name = '不会重名的模块';
+$module1->root = '1';
+$module1->branch = '0';
+$module1->type = 'story';
+$module1->parent = '0';
+
+$module2 = new stdclass();
+$module2->name = '产品模块3';
+$module2->root = '1';
+$module2->branch = '0';
+$module2->type = 'story';
+$module2->parent = '0';
+
+$module3 = new stdclass();
+$module3->name = '产品模块162';
+$module3->root = '41';
+$module3->branch = '2';
+$module3->type = 'story';
+$module3->parent = '0';
+
+$module4 = new stdclass();
+$module4->name = '产品子模块281';
+$module4->root = '41';
+$module4->branch = '0';
+$module4->type = 'story';
+$module4->parent = '2381';
+
+$module5 = new stdclass();
+$module5->name = '执行子模块1';
+$module5->root = '101';
+$module5->branch = '0';
+$module5->type = 'story';
+$module5->parent = '21';
+
+$moduleID1 = array(1821, 1823, 1825, 1826, 1981, 1982, 1985, 1986, 21, 2901, 3021);
+$moduleID2 = array(1822, 1823, 1825, 1826, 1981, 1822);
+$branches = array(0, 1, 2);
+
+$tree = new treeTest();
+
+r($tree->checkUniqueTest($module1)) && p() && e('0'); // 测试module1是否与已存在的模块重名
+r($tree->checkUniqueTest($module1, $moduleID1, $branches)) && p() && e('产品模块1'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module1, $moduleID2, $branches)) && p() && e('产品模块2'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module2)) && p() && e('产品模块3'); // 测试module1是否与已存在的模块重名
+r($tree->checkUniqueTest($module2, $moduleID1, $branches)) && p() && e('产品模块1'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module2, $moduleID2, $branches)) && p() && e('产品模块2'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module3)) && p() && e('0'); // 测试module1是否与已存在的模块重名
+r($tree->checkUniqueTest($module3, $moduleID1, $branches)) && p() && e('产品模块161'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module3, $moduleID2, $branches)) && p() && e('产品模块161'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module4)) && p() && e('产品子模块281'); // 测试module1是否与已存在的模块重名
+r($tree->checkUniqueTest($module4, $moduleID1, $branches)) && p() && e('产品子模块281'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module4, $moduleID2, $branches)) && p() && e('0'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module5)) && p() && e('0'); // 测试module1是否与已存在的模块重名
+r($tree->checkUniqueTest($module5, $moduleID1, $branches)) && p() && e('0'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
+r($tree->checkUniqueTest($module5, $moduleID2, $branches)) && p() && e('0'); // 测试module1 和 moduleID1 里的模块是否与已存在的模块重名
\ No newline at end of file
diff --git a/module/tree/test/model/createbuglink.php b/module/tree/test/model/createbuglink.php
new file mode 100755
index 0000000000..c83ef32aff
--- /dev/null
+++ b/module/tree/test/model/createbuglink.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+createBugLink();
+cid=1
+pid=1
+
+测试创建module 1821 的buglink >> title='产品模块1'
+测试创建module 1822 的buglink >> title='产品模块2'
+测试创建module 1981 的buglink >> title='产品模块161'
+测试创建module 1982 的buglink >> title='产品模块162'
+测试创建module 1621 的buglink >> title='模块1601'
+测试创建module 1622 的buglink >> title='模块1602'
+测试创建module 21 的buglink >> title='模块1'
+测试创建module 22 的buglink >> title='模块2'
+
+*/
+
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+r($tree->createBugLinkTest($moduleID[0])) && p() && e("title='产品模块1'"); // 测试创建module 1821 的buglink
+r($tree->createBugLinkTest($moduleID[1])) && p() && e("title='产品模块2'"); // 测试创建module 1822 的buglink
+r($tree->createBugLinkTest($moduleID[2])) && p() && e("title='产品模块161'"); // 测试创建module 1981 的buglink
+r($tree->createBugLinkTest($moduleID[3])) && p() && e("title='产品模块162'"); // 测试创建module 1982 的buglink
+r($tree->createBugLinkTest($moduleID[4])) && p() && e("title='模块1601'"); // 测试创建module 1621 的buglink
+r($tree->createBugLinkTest($moduleID[5])) && p() && e("title='模块1602'"); // 测试创建module 1622 的buglink
+r($tree->createBugLinkTest($moduleID[6])) && p() && e("title='模块1'"); // 测试创建module 21 的buglink
+r($tree->createBugLinkTest($moduleID[7])) && p() && e("title='模块2'"); // 测试创建module 22 的buglink
\ No newline at end of file
diff --git a/module/tree/test/model/createcaseliblink.php b/module/tree/test/model/createcaseliblink.php
new file mode 100755
index 0000000000..607556a999
--- /dev/null
+++ b/module/tree/test/model/createcaseliblink.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+createCaseLibLink();
+cid=1
+pid=1
+
+测试创建module 1821 的caseliblink >> title='产品模块1'
+测试创建module 1822 的caseliblink >> title='产品模块2'
+测试创建module 1981 的caseliblink >> title='产品模块161'
+测试创建module 1982 的caseliblink >> title='产品模块162'
+测试创建module 1621 的caseliblink >> title='模块1601'
+测试创建module 1622 的caseliblink >> title='模块1602'
+测试创建module 21 的caseliblink >> title='模块1'
+测试创建module 22 的caseliblink >> title='模块2'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+r($tree->createCaseLibLinkTest($moduleID[0])) && p() && e("title='产品模块1'"); // 测试创建module 1821 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[1])) && p() && e("title='产品模块2'"); // 测试创建module 1822 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[2])) && p() && e("title='产品模块161'"); // 测试创建module 1981 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[3])) && p() && e("title='产品模块162'"); // 测试创建module 1982 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[4])) && p() && e("title='模块1601'"); // 测试创建module 1621 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[5])) && p() && e("title='模块1602'"); // 测试创建module 1622 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[6])) && p() && e("title='模块1'"); // 测试创建module 21 的caseliblink
+r($tree->createCaseLibLinkTest($moduleID[7])) && p() && e("title='模块2'"); // 测试创建module 22 的caseliblink
\ No newline at end of file
diff --git a/module/tree/test/model/createcaselink.php b/module/tree/test/model/createcaselink.php
new file mode 100755
index 0000000000..0dde9c137a
--- /dev/null
+++ b/module/tree/test/model/createcaselink.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+createCaseLink();
+cid=1
+pid=1
+
+测试创建module 1821 的caselink >> title='产品模块1'
+测试创建module 1822 的caselink >> title='产品模块2'
+测试创建module 1983 branch 0 的caselink >> title='产品模块162'
+测试创建module 1983 branch 1 的caselink >> title='产品模块162'
+测试创建module 1983 branch 2 的caselink >> title='产品模块162'
+测试创建module 1983 branch 0 的caselink >> title='产品模块163'
+测试创建module 1983 branch 1 的caselink >> title='产品模块163'
+测试创建module 1983 branch 2 的caselink >> title='产品模块163'
+测试创建module 1621 的caselink >> title='模块1601'
+测试创建module 1622 的caselink >> title='模块1602'
+测试创建module 21 的caselink >> title='模块1'
+测试创建module 22 的caselink >> title='模块2'
+
+*/
+
+$moduleID = array(1821, 1822, 1982, 1983, 1621, 1622, 21, 22);
+$extra = array(0, 1, 2);
+
+$tree = new treeTest();
+
+r($tree->createCaseLinkTest($moduleID[0])) && p() && e("title='产品模块1'"); // 测试创建module 1821 的caselink
+r($tree->createCaseLinkTest($moduleID[1])) && p() && e("title='产品模块2'"); // 测试创建module 1822 的caselink
+r($tree->createCaseLinkTest($moduleID[2], array('branchID' => $extra[0]))) && p() && e("title='产品模块162'"); // 测试创建module 1983 branch 0 的caselink
+r($tree->createCaseLinkTest($moduleID[2], array('branchID' => $extra[1]))) && p() && e("title='产品模块162'"); // 测试创建module 1983 branch 1 的caselink
+r($tree->createCaseLinkTest($moduleID[2], array('branchID' => $extra[2]))) && p() && e("title='产品模块162'"); // 测试创建module 1983 branch 2 的caselink
+r($tree->createCaseLinkTest($moduleID[3], array('branchID' => $extra[0]))) && p() && e("title='产品模块163'"); // 测试创建module 1983 branch 0 的caselink
+r($tree->createCaseLinkTest($moduleID[3], array('branchID' => $extra[1]))) && p() && e("title='产品模块163'"); // 测试创建module 1983 branch 1 的caselink
+r($tree->createCaseLinkTest($moduleID[3], array('branchID' => $extra[2]))) && p() && e("title='产品模块163'"); // 测试创建module 1983 branch 2 的caselink
+r($tree->createCaseLinkTest($moduleID[4])) && p() && e("title='模块1601'"); // 测试创建module 1621 的caselink
+r($tree->createCaseLinkTest($moduleID[5])) && p() && e("title='模块1602'"); // 测试创建module 1622 的caselink
+r($tree->createCaseLinkTest($moduleID[6])) && p() && e("title='模块1'"); // 测试创建module 21 的caselink
+r($tree->createCaseLinkTest($moduleID[7])) && p() && e("title='模块2'"); // 测试创建module 22 的caselink
\ No newline at end of file
diff --git a/module/tree/test/model/createfeedbacklink.php b/module/tree/test/model/createfeedbacklink.php
new file mode 100755
index 0000000000..a756735afa
--- /dev/null
+++ b/module/tree/test/model/createfeedbacklink.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+createFeedbackLink();
+cid=1
+pid=1
+
+测试创建module 1821 的feedbacklink >> title='产品模块1'
+测试创建module 1822 的feedbacklink >> title='产品模块2'
+测试创建module 1981 的feedbacklink >> title='产品模块161'
+测试创建module 1982 的feedbacklink >> title='产品模块162'
+测试创建module 1621 的feedbacklink >> title='模块1601'
+测试创建module 1622 的feedbacklink >> title='模块1602'
+测试创建module 21 的feedbacklink >> title='模块1'
+测试创建module 22 的feedbacklink >> title='模块2'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+r($tree->createFeedbackLinkTest($moduleID[0])) && p() && e("title='产品模块1'"); // 测试创建module 1821 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[1])) && p() && e("title='产品模块2'"); // 测试创建module 1822 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[2])) && p() && e("title='产品模块161'"); // 测试创建module 1981 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[3])) && p() && e("title='产品模块162'"); // 测试创建module 1982 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[4])) && p() && e("title='模块1601'"); // 测试创建module 1621 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[5])) && p() && e("title='模块1602'"); // 测试创建module 1622 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[6])) && p() && e("title='模块1'"); // 测试创建module 21 的feedbacklink
+r($tree->createFeedbackLinkTest($moduleID[7])) && p() && e("title='模块2'"); // 测试创建module 22 的feedbacklink
\ No newline at end of file
diff --git a/module/tree/test/model/createmanagelink.php b/module/tree/test/model/createmanagelink.php
new file mode 100755
index 0000000000..4205d592ac
--- /dev/null
+++ b/module/tree/test/model/createmanagelink.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+createManageLink();
+cid=1
+pid=1
+
+测试创建module 1821 branch 0 的managelink >> 产品模块1 <
+测试创建module 1822 branch 0 的managelink >> 产品模块2 <
+测试创建module 1981 branch 0 的managelink >> 产品模块161
+测试创建module 1981 branch 1 的managelink >> 产品模块161
+测试创建module 1981 branch 2 的managelink >> 产品模块161
+测试创建module 1982 branch 0 的managelink >> 产品模块162
+测试创建module 1982 branch 1 的managelink >> 产品模块162
+测试创建module 1982 branch 2 的managelink >> 产品模块162
+测试创建module 1621 branch 0 的managelink >> 模块1601
> 模块1602 > 模块1 > 模块2 0);
+$extra1 = array('branchID' => 1);
+$extra2 = array('branchID' => 2);
+
+$tree = new treeTest();
+
+r($tree->createManageLinkTest($moduleID[0], $extra0)) && p() && e("产品模块1 <"); // 测试创建module 1821 branch 0 的managelink
+r($tree->createManageLinkTest($moduleID[1], $extra0)) && p() && e("产品模块2 <"); // 测试创建module 1822 branch 0 的managelink
+r($tree->createManageLinkTest($moduleID[2], $extra0)) && p() && e("产品模块161"); // 测试创建module 1981 branch 0 的managelink
+r($tree->createManageLinkTest($moduleID[2], $extra1)) && p() && e("产品模块161"); // 测试创建module 1981 branch 1 的managelink
+r($tree->createManageLinkTest($moduleID[2], $extra2)) && p() && e("产品模块161"); // 测试创建module 1981 branch 2 的managelink
+r($tree->createManageLinkTest($moduleID[3], $extra0)) && p() && e("产品模块162"); // 测试创建module 1982 branch 0 的managelink
+r($tree->createManageLinkTest($moduleID[3], $extra1)) && p() && e("产品模块162"); // 测试创建module 1982 branch 1 的managelink
+r($tree->createManageLinkTest($moduleID[3], $extra2)) && p() && e("产品模块162"); // 测试创建module 1982 branch 2 的managelink
+r($tree->createManageLinkTest($moduleID[4], $extra0)) && p() && e("模块1601 createManageLinkTest($moduleID[5], $extra0)) && p() && e("模块1602 createManageLinkTest($moduleID[6], $extra0)) && p() && e("模块1 createManageLinkTest($moduleID[7], $extra0)) && p() && e("模块2 id->range(1);
+$module->name->range('父模块1');
+$module->grade->range('1');
+$module->root->range('1');
+$module->type->range('doc');
+$module->order->range('10');
+$module->gen(1);
+
+su('admin');
+
+/**
+
+title=测试 treeModel->createModule();
+cid=1
+pid=1
+
+测试空数据创建模块 >> 『目录名称』不能为空。
+测试模块名称为空 >> 『目录名称』不能为空。
+测试创建文档模块 >> 模块1,1
+测试创建名称重复的模块 >> 模块名“模块1”已经存在!
+测试创建文档子模块 >> 模块1的子模块1,2
+测试创建API模块 >> api的模块1,1
+
+*/
+
+$nameList = array('', '模块1', '模块1的子模块1', 'api的模块1');
+$createTypeList = array('','same', 'child');
+$moduleTypeList = array('','doc', 'api');
+
+$emptyData = array('name' => $nameList[0], 'createType' => $createTypeList[0], 'moduleType' => $moduleTypeList[0], 'parentID' => 0);
+$nameEmptyData = array('name' => $nameList[0], 'createType' => $createTypeList[0], 'moduleType' => $moduleTypeList[0], 'parentID' => 0);
+$docModuleData = array('name' => $nameList[1], 'createType' => $createTypeList[2], 'moduleType' => $moduleTypeList[1], 'parentID' => 0);
+$repeatNameData = array('name' => $nameList[1], 'createType' => $createTypeList[1], 'moduleType' => $moduleTypeList[1], 'parentID' => 0);
+$childModuleData = array('name' => $nameList[2], 'createType' => $createTypeList[2], 'moduleType' => $moduleTypeList[1], 'parentID' => 1);
+$apiModuleData = array('name' => $nameList[3], 'createType' => $createTypeList[1], 'moduleType' => $moduleTypeList[2], 'parentID' => 0);
+
+$treeTester = new treeTest();
+
+r($treeTester->createModuleTest($emptyData)) && p() && e('『目录名称』不能为空。'); // 测试空数据创建模块
+r($treeTester->createModuleTest($nameEmptyData)) && p() && e('『目录名称』不能为空。'); // 测试模块名称为空
+r($treeTester->createModuleTest($docModuleData)) && p('name,grade') && e('模块1,1'); // 测试创建文档模块
+r($treeTester->createModuleTest($repeatNameData)) && p() && e('模块名“模块1”已经存在!'); // 测试创建名称重复的模块
+r($treeTester->createModuleTest($childModuleData)) && p('name,grade') && e('模块1的子模块1,2') ; // 测试创建文档子模块
+r($treeTester->createModuleTest($apiModuleData)) && p('name,grade') && e('api的模块1,1'); // 测试创建API模块
diff --git a/module/tree/test/model/createrequirementlink.php b/module/tree/test/model/createrequirementlink.php
new file mode 100755
index 0000000000..f009b78cb8
--- /dev/null
+++ b/module/tree/test/model/createrequirementlink.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+createRequirementLink();
+cid=1
+pid=1
+
+测试创建module 1821 的RequirementLink >> title='产品模块1'
+测试创建module 1822 的RequirementLink >> title='产品模块2'
+测试创建module 1981 的RequirementLink >> title='产品模块161'
+测试创建module 1982 的RequirementLink >> title='产品模块162'
+测试创建module 1621 的RequirementLink >> title='模块1601'
+测试创建module 1622 的RequirementLink >> title='模块1602'
+测试创建module 21 的RequirementLink >> title='模块1'
+测试创建module 22 的RequirementLink >> title='模块2'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+r($tree->createRequirementLinkTest($moduleID[0])) && p() && e("title='产品模块1'"); // 测试创建module 1821 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[1])) && p() && e("title='产品模块2'"); // 测试创建module 1822 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[2])) && p() && e("title='产品模块161'"); // 测试创建module 1981 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[3])) && p() && e("title='产品模块162'"); // 测试创建module 1982 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[4])) && p() && e("title='模块1601'"); // 测试创建module 1621 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[5])) && p() && e("title='模块1602'"); // 测试创建module 1622 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[6])) && p() && e("title='模块1'"); // 测试创建module 21 的RequirementLink
+r($tree->createRequirementLinkTest($moduleID[7])) && p() && e("title='模块2'"); // 测试创建module 22 的RequirementLink
\ No newline at end of file
diff --git a/module/tree/test/model/createstorylink.php b/module/tree/test/model/createstorylink.php
new file mode 100755
index 0000000000..b390f18930
--- /dev/null
+++ b/module/tree/test/model/createstorylink.php
@@ -0,0 +1,50 @@
+#!/usr/bin/env php
+createStoryLink();
+cid=1
+pid=1
+
+测试获取module 1821 project 11 product 1 的 story link >> projectstory title='产品模块1'
+测试获取module 1822 project 11 product 1 的 story link >> projectstory title='产品模块2'
+测试获取module 1981 project 2 product 2 的 story link >> projectstory title='产品模块161'
+测试获取module 1982 product 1 的 story link >> product title='产品模块162'
+测试获取module 1621 execution 101 的 story link >> execution title='模块1601'
+测试获取module 1622 execution 102 的 story link >> execution title='模块1602'
+测试获取module 21 branch 0 的 story link >> product title='模块1'
+测试获取module 22 branch 1 的 story link >> product title='模块2'
+测试获取module 1821 branch 2 的 story link >> product title='产品模块1'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+$projectID = array(11,12);
+$productID = array(1, 2);
+$executionID = array(101, 102);
+$branchID = array(0, 1, 2);
+
+$extra1 = array('branchID' => $branchID[0], 'projectID' => $projectID[0]);
+$extra2 = array('branchID' => $branchID[0], 'projectID' => $projectID[0], 'productID' => $productID[0]);
+$extra3 = array('branchID' => $branchID[0], 'projectID' => $projectID[1], 'productID' => $productID[1]);
+$extra4 = array('branchID' => $branchID[0], 'projectID' => array(), 'productID' => $productID[0]);
+$extra5 = array('branchID' => $branchID[0], 'executionID' => $executionID[0]);
+$extra6 = array('branchID' => $branchID[0], 'executionID' => $executionID[1]);
+$extra7 = array('branchID' => $branchID[0]);
+$extra8 = array('branchID' => $branchID[1]);
+$extra9 = array('branchID' => $branchID[2]);
+
+$tree = new treeTest();
+
+r($tree->createStoryLinkTest($moduleID[0], $extra1)) && p() && e("projectstory title='产品模块1'"); // 测试获取module 1821 project 11 product 1 的 story link
+r($tree->createStoryLinkTest($moduleID[1], $extra2)) && p() && e("projectstory title='产品模块2'"); // 测试获取module 1822 project 11 product 1 的 story link
+r($tree->createStoryLinkTest($moduleID[2], $extra3)) && p() && e("projectstory title='产品模块161'"); // 测试获取module 1981 project 2 product 2 的 story link
+r($tree->createStoryLinkTest($moduleID[3], $extra4)) && p() && e("product title='产品模块162'"); // 测试获取module 1982 product 1 的 story link
+r($tree->createStoryLinkTest($moduleID[4], $extra5)) && p() && e("execution title='模块1601'"); // 测试获取module 1621 execution 101 的 story link
+r($tree->createStoryLinkTest($moduleID[5], $extra6)) && p() && e("execution title='模块1602'"); // 测试获取module 1622 execution 102 的 story link
+r($tree->createStoryLinkTest($moduleID[6], $extra7)) && p() && e("product title='模块1'"); // 测试获取module 21 branch 0 的 story link
+r($tree->createStoryLinkTest($moduleID[7], $extra8)) && p() && e("product title='模块2'"); // 测试获取module 22 branch 1 的 story link
+r($tree->createStoryLinkTest($moduleID[0], $extra9)) && p() && e("product title='产品模块1'"); // 测试获取module 1821 branch 2 的 story link
\ No newline at end of file
diff --git a/module/tree/test/model/createtasklink.php b/module/tree/test/model/createtasklink.php
new file mode 100755
index 0000000000..8483fd993f
--- /dev/null
+++ b/module/tree/test/model/createtasklink.php
@@ -0,0 +1,55 @@
+#!/usr/bin/env php
+createTaskLink();
+cid=1
+pid=1
+
+测试获取module 1821 product 1 execution 101 的 story link >> 101 1821 title='产品模块1'
+测试获取module 1822 product 1 execution 101 的 story link >> 101 1822 title='产品模块2'
+测试获取module 1981 product 1 execution 101 的 story link >> 101 1981 title='产品模块161'
+测试获取module 1982 product 1 execution 101 的 story link >> 101 1982 title='产品模块162'
+测试获取module 1621 product 1 execution 101 的 story link >> 101 1621 title='模块1601'
+测试获取module 1622 product 1 execution 101 的 story link >> 101 1622 title='模块1602'
+测试获取module 21 product 1 execution 101 的 story link >> 101 21 title='模块1'
+测试获取module 22 product 1 execution 101 的 story link >> 101 22 title='模块2'
+测试获取module 1821 product 2 execution 102 的 story link >> 102 1821 title='产品模块1'
+测试获取module 1822 product 2 execution 102 的 story link >> 102 1822 title='产品模块2'
+测试获取module 1981 product 2 execution 102 的 story link >> 102 1981 title='产品模块161'
+测试获取module 1982 product 2 execution 102 的 story link >> 102 1982 title='产品模块162'
+测试获取module 1621 product 2 execution 102 的 story link >> 102 1621 title='模块1601'
+测试获取module 1622 product 2 execution 102 的 story link >> 102 1622 title='模块1602'
+测试获取module 21 product 2 execution 102 的 story link >> 102 21 title='模块1'
+测试获取module 22 product 2 execution 102 的 story link >> 102 22 title='模块2'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+$productID = array(1, 2);
+$executionID = array(101, 102);
+
+$extra1 = array('productID' => $productID[0], 'executionID' => $executionID[0]);
+$extra2 = array('productID' => $productID[1], 'executionID' => $executionID[1]);
+
+$tree = new treeTest();
+
+r($tree->createTaskLinkTest($moduleID[0], $extra1)) && p() && e("101 1821 title='产品模块1'"); // 测试获取module 1821 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[1], $extra1)) && p() && e("101 1822 title='产品模块2'"); // 测试获取module 1822 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[2], $extra1)) && p() && e("101 1981 title='产品模块161'"); // 测试获取module 1981 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[3], $extra1)) && p() && e("101 1982 title='产品模块162'"); // 测试获取module 1982 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[4], $extra1)) && p() && e("101 1621 title='模块1601'"); // 测试获取module 1621 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[5], $extra1)) && p() && e("101 1622 title='模块1602'"); // 测试获取module 1622 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[6], $extra1)) && p() && e("101 21 title='模块1'"); // 测试获取module 21 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[7], $extra1)) && p() && e("101 22 title='模块2'"); // 测试获取module 22 product 1 execution 101 的 story link
+r($tree->createTaskLinkTest($moduleID[0], $extra2)) && p() && e("102 1821 title='产品模块1'"); // 测试获取module 1821 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[1], $extra2)) && p() && e("102 1822 title='产品模块2'"); // 测试获取module 1822 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[2], $extra2)) && p() && e("102 1981 title='产品模块161'"); // 测试获取module 1981 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[3], $extra2)) && p() && e("102 1982 title='产品模块162'"); // 测试获取module 1982 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[4], $extra2)) && p() && e("102 1621 title='模块1601'"); // 测试获取module 1621 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[5], $extra2)) && p() && e("102 1622 title='模块1602'"); // 测试获取module 1622 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[6], $extra2)) && p() && e("102 21 title='模块1'"); // 测试获取module 21 product 2 execution 102 的 story link
+r($tree->createTaskLinkTest($moduleID[7], $extra2)) && p() && e("102 22 title='模块2'"); // 测试获取module 22 product 2 execution 102 的 story link
\ No newline at end of file
diff --git a/module/tree/test/model/createtaskmanagelink.php b/module/tree/test/model/createtaskmanagelink.php
new file mode 100755
index 0000000000..1f5ea84ebf
--- /dev/null
+++ b/module/tree/test/model/createtaskmanagelink.php
@@ -0,0 +1,74 @@
+#!/usr/bin/env php
+createTaskManageLink();
+cid=1
+pid=1
+
+测试获取module 1821 product 1 execution 101 的 story manage link >> 产品模块1 browsetask 子模块
+测试获取module 1822 product 1 execution 101 的 story manage link >> 产品模块2 browsetask 子模块
+测试获取module 1981 product 1 execution 101 的 story manage link >> 产品模块161 browsetask 子模块
+测试获取module 1982 product 1 execution 101 的 story manage link >> 产品模块162 browsetask 子模块
+测试获取module 1621 product 1 execution 101 的 story manage link >> 模块1601 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 1622 product 1 execution 101 的 story manage link >> 模块1602 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 21 product 1 execution 101 的 story manage link >> 模块1 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 22 product 1 execution 101 的 story manage link >> 模块2 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 1821 product 2 execution 102 的 story manage link >> 产品模块1 browsetask 子模块
+测试获取module 1822 product 2 execution 102 的 story manage link >> 产品模块2 browsetask 子模块
+测试获取module 1981 product 2 execution 102 的 story manage link >> 产品模块161 browsetask 子模块
+测试获取module 1982 product 2 execution 102 的 story manage link >> 产品模块162 browsetask 子模块
+测试获取module 1621 product 2 execution 102 的 story manage link >> 模块1601 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 1622 product 2 execution 102 的 story manage link >> 模块1602 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 21 product 2 execution 102 的 story manage link >> 模块1 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 22 product 2 execution 102 的 story manage link >> 模块2 [T] edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 1821 product 1 execution 101 tip null 的 story manage link >> 产品模块1 browsetask 子模块
+测试获取module 1822 product 1 execution 101 tip null 的 story manage link >> 产品模块2 browsetask 子模块
+测试获取module 21 product 1 execution 101 tip null的 story manage link >> 模块1 edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 22 product 1 execution 101 tip null的 story manage link >> 模块2 edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 1821 product 2 execution 102 tip null的 story manage link >> 产品模块1 browsetask 子模块
+测试获取module 1822 product 2 execution 102 tip null的 story manage link >> 产品模块2 browsetask 子模块
+测试获取module 21 product 2 execution 102 tip null 的 story manage link >> 模块1 edit 编辑模块 browsetask 子模块 delete 删除
+测试获取module 22 product 2 execution 102 tip null 的 story manage link >> 模块2 edit 编辑模块 browsetask 子模块 delete 删除
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+$productID = array(1, 2);
+$executionID = array(101, 102);
+$tip = 'tip';
+
+$extra1 = array('productID' => $productID[0], 'executionID' => $executionID[0], 'tip' => $tip);
+$extra2 = array('productID' => $productID[1], 'executionID' => $executionID[1], 'tip' => $tip);
+$extra3 = array('productID' => $productID[0], 'executionID' => $executionID[0], 'tip' => null);
+$extra4 = array('productID' => $productID[1], 'executionID' => $executionID[1], 'tip' => null);
+
+$tree = new treeTest();
+
+r($tree->createTaskManageLinkTest($moduleID[0], $extra1)) && p() && e("产品模块1 browsetask 子模块"); // 测试获取module 1821 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[1], $extra1)) && p() && e("产品模块2 browsetask 子模块"); // 测试获取module 1822 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[2], $extra1)) && p() && e("产品模块161 browsetask 子模块"); // 测试获取module 1981 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[3], $extra1)) && p() && e("产品模块162 browsetask 子模块"); // 测试获取module 1982 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[4], $extra1)) && p() && e("模块1601 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 1621 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[5], $extra1)) && p() && e("模块1602 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 1622 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[6], $extra1)) && p() && e("模块1 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 21 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[7], $extra1)) && p() && e("模块2 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 22 product 1 execution 101 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[0], $extra2)) && p() && e("产品模块1 browsetask 子模块"); // 测试获取module 1821 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[1], $extra2)) && p() && e("产品模块2 browsetask 子模块"); // 测试获取module 1822 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[2], $extra2)) && p() && e("产品模块161 browsetask 子模块"); // 测试获取module 1981 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[3], $extra2)) && p() && e("产品模块162 browsetask 子模块"); // 测试获取module 1982 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[4], $extra2)) && p() && e("模块1601 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 1621 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[5], $extra2)) && p() && e("模块1602 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 1622 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[6], $extra2)) && p() && e("模块1 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 21 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[7], $extra2)) && p() && e("模块2 [T] edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 22 product 2 execution 102 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[0], $extra3)) && p() && e("产品模块1 browsetask 子模块"); // 测试获取module 1821 product 1 execution 101 tip null 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[1], $extra3)) && p() && e("产品模块2 browsetask 子模块"); // 测试获取module 1822 product 1 execution 101 tip null 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[6], $extra3)) && p() && e("模块1 edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 21 product 1 execution 101 tip null的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[7], $extra3)) && p() && e("模块2 edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 22 product 1 execution 101 tip null的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[0], $extra4)) && p() && e("产品模块1 browsetask 子模块"); // 测试获取module 1821 product 2 execution 102 tip null的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[1], $extra4)) && p() && e("产品模块2 browsetask 子模块"); // 测试获取module 1822 product 2 execution 102 tip null的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[6], $extra4)) && p() && e("模块1 edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 21 product 2 execution 102 tip null 的 story manage link
+r($tree->createTaskManageLinkTest($moduleID[7], $extra4)) && p() && e("模块2 edit 编辑模块 browsetask 子模块 delete 删除"); // 测试获取module 22 product 2 execution 102 tip null 的 story manage link
\ No newline at end of file
diff --git a/module/tree/test/model/createtesttasklink.php b/module/tree/test/model/createtesttasklink.php
new file mode 100755
index 0000000000..3bd514dcc5
--- /dev/null
+++ b/module/tree/test/model/createtesttasklink.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+createTestTaskLink();
+cid=1
+pid=1
+
+测试创建module 1821 的TestTasklink >> title='产品模块1'
+测试创建module 1822 的TestTasklink >> title='产品模块2'
+测试创建module 1981 的TestTasklink >> title='产品模块161'
+测试创建module 1982 的TestTasklink >> title='产品模块162'
+测试创建module 1621 的TestTasklink >> title='模块1601'
+测试创建module 1622 的TestTasklink >> title='模块1602'
+测试创建module 21 的TestTasklink >> title='模块1'
+测试创建module 22 的TestTasklink >> title='模块2'
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+$extra = 1;
+
+$tree = new treeTest();
+
+r($tree->createTestTaskLinkTest($moduleID[0], $extra)) && p() && e("title='产品模块1'"); // 测试创建module 1821 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[1], $extra)) && p() && e("title='产品模块2'"); // 测试创建module 1822 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[2], $extra)) && p() && e("title='产品模块161'"); // 测试创建module 1981 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[3], $extra)) && p() && e("title='产品模块162'"); // 测试创建module 1982 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[4], $extra)) && p() && e("title='模块1601'"); // 测试创建module 1621 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[5], $extra)) && p() && e("title='模块1602'"); // 测试创建module 1622 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[6], $extra)) && p() && e("title='模块1'"); // 测试创建module 21 的TestTasklink
+r($tree->createTestTaskLinkTest($moduleID[7], $extra)) && p() && e("title='模块2'"); // 测试创建module 22 的TestTasklink
\ No newline at end of file
diff --git a/module/tree/test/model/delete.php b/module/tree/test/model/delete.php
new file mode 100755
index 0000000000..812174db23
--- /dev/null
+++ b/module/tree/test/model/delete.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+delete();
+cid=1
+pid=1
+
+测试删除module 1821 >> 1
+测试删除module 1822 >> 1
+测试删除module 1981 >> 1
+测试删除module 1982 >> 1
+测试删除module 1621 >> 1
+测试删除module 1622 >> 1
+测试删除module 21 >> 1
+测试删除module 22 >> 1
+
+*/
+
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+ob_start();
+r($tree->deleteTest($moduleID[0])) && p('deleted') && e('1'); // 测试删除module 1821
+r($tree->deleteTest($moduleID[1])) && p('deleted') && e('1'); // 测试删除module 1822
+r($tree->deleteTest($moduleID[2])) && p('deleted') && e('1'); // 测试删除module 1981
+r($tree->deleteTest($moduleID[3])) && p('deleted') && e('1'); // 测试删除module 1982
+r($tree->deleteTest($moduleID[4])) && p('deleted') && e('1'); // 测试删除module 1621
+r($tree->deleteTest($moduleID[5])) && p('deleted') && e('1'); // 测试删除module 1622
+r($tree->deleteTest($moduleID[6])) && p('deleted') && e('1'); // 测试删除module 21
+r($tree->deleteTest($moduleID[7])) && p('deleted') && e('1'); // 测试删除module 22
+ob_end_flush();
diff --git a/module/tree/test/model/fixmodulepath.php b/module/tree/test/model/fixmodulepath.php
new file mode 100755
index 0000000000..4c7b16354d
--- /dev/null
+++ b/module/tree/test/model/fixmodulepath.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+fixModulePath();
+cid=1
+pid=1
+
+修复root为 1 的module path >> ,1821,;,1821,2621,;,2221,2821,
+修复root为 2 的module path >> ,1825,;,1825,2623,;,2225,2823,
+修复root为 3 的module path >> ,1829,;,1829,2625,;,2229,2825,
+修复root为 41 的module path >> ,1981,;,1981,2701,;,2381,2901,
+修复root为 42 的module path >> ,1985,;,1985,2703,;,2385,2903,
+修复root为 43 的module path >> ,1989,;,1989,2705,;,2389,2905,
+修复root为 101 的module path >> ,21,;,22,;,21,3021,
+修复root为 102 的module path >> ,24,;,25,;,23,3022
+修复root为 103 的module path >> ,27,;,28,;,25,3023
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'task');
+
+$tree = new treeTest();
+
+r($tree->fixModulePathTest($root[0], $type[0])) && p('1821:path;2621:path;2821:path') && e(',1821,;,1821,2621,;,2221,2821,'); // 修复root为 1 的module path
+r($tree->fixModulePathTest($root[1], $type[0])) && p('1825:path;2623:path;2823:path') && e(',1825,;,1825,2623,;,2225,2823,'); // 修复root为 2 的module path
+r($tree->fixModulePathTest($root[2], $type[0])) && p('1829:path;2625:path;2825:path') && e(',1829,;,1829,2625,;,2229,2825,'); // 修复root为 3 的module path
+r($tree->fixModulePathTest($root[3], $type[0])) && p('1981:path;2701:path;2901:path') && e(',1981,;,1981,2701,;,2381,2901,'); // 修复root为 41 的module path
+r($tree->fixModulePathTest($root[4], $type[0])) && p('1985:path;2703:path;2903:path') && e(',1985,;,1985,2703,;,2385,2903,'); // 修复root为 42 的module path
+r($tree->fixModulePathTest($root[5], $type[0])) && p('1989:path;2705:path;2905:path') && e(',1989,;,1989,2705,;,2389,2905,'); // 修复root为 43 的module path
+r($tree->fixModulePathTest($root[6], $type[1])) && p('21:path;22:path;3021:path') && e(',21,;,22,;,21,3021,'); // 修复root为 101 的module path
+r($tree->fixModulePathTest($root[7], $type[1])) && p('24:path;25:path;3022:path') && e(',24,;,25,;,23,3022'); // 修复root为 102 的module path
+r($tree->fixModulePathTest($root[8], $type[1])) && p('27:path;28:path;3023:path') && e(',27,;,28,;,25,3023'); // 修复root为 103 的module path
diff --git a/module/tree/test/model/getallchildid.php b/module/tree/test/model/getallchildid.php
new file mode 100755
index 0000000000..15b1437fec
--- /dev/null
+++ b/module/tree/test/model/getallchildid.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getAllChildId();
+cid=1
+pid=1
+
+测试获取module 1821 的全部子项 >> ,1821,2621,2622
+测试获取module 1821 的全部子项 >> ,1822
+测试获取module 1821 的全部子项 >> ,1825,2623,2624
+测试获取module 1821 的全部子项 >> ,1826
+测试获取module 1821 的全部子项 >> ,1981,2701,2702
+测试获取module 1821 的全部子项 >> ,1982
+测试获取module 1821 的全部子项 >> ,1985,2703,2704
+测试获取module 1821 的全部子项 >> ,1986
+测试获取module 1821 的全部子项 >> ,21,3021
+测试获取module 1821 的全部子项 >> ,22
+测试获取module 1821 的全部子项 >> ,24
+测试获取module 1821 的全部子项 >> ,25,3023
+
+*/
+$moduleID = array(1821, 1822, 1825, 1826, 1981, 1982, 1985, 1986, 21, 22, 24, 25);
+
+$tree = new treeTest();
+
+r($tree->getAllChildIdTest($moduleID[0])) && p() && e(',1821,2621,2622 '); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[1])) && p() && e(',1822'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[2])) && p() && e(',1825,2623,2624 '); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[3])) && p() && e(',1826'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[4])) && p() && e(',1981,2701,2702 '); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[5])) && p() && e(',1982'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[6])) && p() && e(',1985,2703,2704 '); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[7])) && p() && e(',1986'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[8])) && p() && e(',21,3021'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[9])) && p() && e(',22'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[10])) && p() && e(',24'); // 测试获取module 1821 的全部子项
+r($tree->getAllChildIdTest($moduleID[11])) && p() && e(',25,3023'); // 测试获取module 1821 的全部子项
\ No newline at end of file
diff --git a/module/tree/test/model/getallmodulepairs.php b/module/tree/test/model/getallmodulepairs.php
new file mode 100755
index 0000000000..84d6ef3415
--- /dev/null
+++ b/module/tree/test/model/getallmodulepairs.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getAllModulePairs();
+cid=1
+pid=1
+
+测试获取默认(task)的模块信息 >> 3601
+测试获取默认(task)的模块信息 >> 1501
+测试获取默认(task)的模块信息 >> 1501
+测试获取默认(task)的模块信息 >> 3601
+
+*/
+$type = array('bug', 'case', 'task');
+
+$tree = new treeTest();
+
+r($tree->getAllModulePairsTest()) && p() && e('3601'); // 测试获取默认(task)的模块信息
+r($tree->getAllModulePairsTest($type[0])) && p() && e('1501'); // 测试获取默认(task)的模块信息
+r($tree->getAllModulePairsTest($type[1])) && p() && e('1501'); // 测试获取默认(task)的模块信息
+r($tree->getAllModulePairsTest($type[2])) && p() && e('3601'); // 测试获取默认(task)的模块信息
\ No newline at end of file
diff --git a/module/tree/test/model/getbyid.php b/module/tree/test/model/getbyid.php
new file mode 100755
index 0000000000..ec5439a09e
--- /dev/null
+++ b/module/tree/test/model/getbyid.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getByID();
+cid=1
+pid=1
+
+测试获取module 1821 的信息 >> 1,产品模块1,模块简称1
+测试获取module 1822 的信息 >> 1,产品模块2,模块简称2
+测试获取module 1981 的信息 >> 41,产品模块161,模块简称161
+测试获取module 1982 的信息 >> 41,产品模块162,模块简称162
+测试获取module 1621 的信息 >> 634,模块1601,模块简称1601
+测试获取module 1622 的信息 >> 634,模块1602,模块简称1602
+测试获取module 21 的信息 >> 101,模块1,模块简称1
+测试获取module 22 的信息 >> 101,模块2,模块简称2
+
+*/
+$moduleID = array(1821, 1822, 1981, 1982, 1621, 1622, 21, 22);
+
+$tree = new treeTest();
+
+r($tree->getByIDTest($moduleID[0])) && p('root,name,short') && e('1,产品模块1,模块简称1'); // 测试获取module 1821 的信息
+r($tree->getByIDTest($moduleID[1])) && p('root,name,short') && e('1,产品模块2,模块简称2'); // 测试获取module 1822 的信息
+r($tree->getByIDTest($moduleID[2])) && p('root,name,short') && e('41,产品模块161,模块简称161'); // 测试获取module 1981 的信息
+r($tree->getByIDTest($moduleID[3])) && p('root,name,short') && e('41,产品模块162,模块简称162'); // 测试获取module 1982 的信息
+r($tree->getByIDTest($moduleID[4])) && p('root,name,short') && e('634,模块1601,模块简称1601'); // 测试获取module 1621 的信息
+r($tree->getByIDTest($moduleID[5])) && p('root,name,short') && e('634,模块1602,模块简称1602'); // 测试获取module 1622 的信息
+r($tree->getByIDTest($moduleID[6])) && p('root,name,short') && e('101,模块1,模块简称1'); // 测试获取module 21 的信息
+r($tree->getByIDTest($moduleID[7])) && p('root,name,short') && e('101,模块2,模块简称2'); // 测试获取module 22 的信息
\ No newline at end of file
diff --git a/module/tree/test/model/getdatastructure.php b/module/tree/test/model/getdatastructure.php
new file mode 100755
index 0000000000..20989c7549
--- /dev/null
+++ b/module/tree/test/model/getdatastructure.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getDataStructure();
+cid=1
+pid=1
+
+测试获取root 1 type story 的树结构 >> 1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;
+测试获取root 2 type story 的树结构 >> 1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;
+测试获取root 3 type story 的树结构 >> 1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;
+测试获取root 41 type story 的树结构 >> 1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;
+测试获取root 42 type story 的树结构 >> 1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;
+测试获取root 43 type story 的树结构 >> 1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;
+测试获取root 101 type task 的树结构 >> 0
+测试获取root 102 type task 的树结构 >> 0
+测试获取root 103 type task 的树结构 >> 0
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'task');
+
+$tree = new treeTest();
+
+r($tree->getDataStructureTest($root[0], $type[0])) && p() && e('1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;'); // 测试获取root 1 type story 的树结构
+r($tree->getDataStructureTest($root[1], $type[0])) && p() && e('1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;'); // 测试获取root 2 type story 的树结构
+r($tree->getDataStructureTest($root[2], $type[0])) && p() && e('1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;'); // 测试获取root 3 type story 的树结构
+r($tree->getDataStructureTest($root[3], $type[0])) && p() && e('1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;'); // 测试获取root 41 type story 的树结构
+r($tree->getDataStructureTest($root[4], $type[0])) && p() && e('1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;'); // 测试获取root 42 type story 的树结构
+r($tree->getDataStructureTest($root[5], $type[0])) && p() && e('1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;'); // 测试获取root 43 type story 的树结构
+r($tree->getDataStructureTest($root[6], $type[1])) && p() && e('0'); // 测试获取root 101 type task 的树结构
+r($tree->getDataStructureTest($root[7], $type[1])) && p() && e('0'); // 测试获取root 102 type task 的树结构
+r($tree->getDataStructureTest($root[8], $type[1])) && p() && e('0'); // 测试获取root 103 type task 的树结构
\ No newline at end of file
diff --git a/module/tree/test/model/getdocstructure.php b/module/tree/test/model/getdocstructure.php
new file mode 100755
index 0000000000..6f8844dad5
--- /dev/null
+++ b/module/tree/test/model/getdocstructure.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getDocStructure();
+cid=1
+pid=1
+
+测试获取doc树 >> 3621:2;3626:2;3631:2;3636:2;3641:2;3646:2;3651:2;3656:2;3661:2;3666:2;3671:2;3676:2;3681:2;3686:2;3691:2;3696:2;3701:2;3706:2;3711:2;3716:2;3622:2;3627:2;3632:2;3637:2;3642:2;3647:2;3652:2;3657:2;3662:2;3667:2;3672:2;3677:2;3682:2;3687:2;3692:2;3697:2;3702:2;3707:2;3712:2;3717:2;3623:2;3628:2;3633:2;3638:2;3643:2;3648:2;3653:2;3658:2;3663:2;3668:2;3673:2;3678:2;3683:2;3688:2;3693:2;3698:2;3703:2;3708:2;3713:2;3718:2;3624:2;3629:2;3634:2;3639:2;3644:2;3649:2;3654:2;3659:2;3664:2;3669:2;3674:2;3679:2;3684:2;3689:2;3694:2;3699:2;3704:2;3709:2;3714:2;3719:2;3625:2;3630:2;3635:2;3640:2;3645:2;3650:2;3655:2;3660:2;3665:2;3670:2;3675:2;3680:2;3685:2;3690:2;3695:2;3700:2;3705:2;3710:2;3715:2;3720:2;
+
+*/
+
+$tree = new treeTest();
+
+r($tree->getDocStructureTest()) && p() && e('3621:2;3626:2;3631:2;3636:2;3641:2;3646:2;3651:2;3656:2;3661:2;3666:2;3671:2;3676:2;3681:2;3686:2;3691:2;3696:2;3701:2;3706:2;3711:2;3716:2;3622:2;3627:2;3632:2;3637:2;3642:2;3647:2;3652:2;3657:2;3662:2;3667:2;3672:2;3677:2;3682:2;3687:2;3692:2;3697:2;3702:2;3707:2;3712:2;3717:2;3623:2;3628:2;3633:2;3638:2;3643:2;3648:2;3653:2;3658:2;3663:2;3668:2;3673:2;3678:2;3683:2;3688:2;3693:2;3698:2;3703:2;3708:2;3713:2;3718:2;3624:2;3629:2;3634:2;3639:2;3644:2;3649:2;3654:2;3659:2;3664:2;3669:2;3674:2;3679:2;3684:2;3689:2;3694:2;3699:2;3704:2;3709:2;3714:2;3719:2;3625:2;3630:2;3635:2;3640:2;3645:2;3650:2;3655:2;3660:2;3665:2;3670:2;3675:2;3680:2;3685:2;3690:2;3695:2;3700:2;3705:2;3710:2;3715:2;3720:2;'); //测试获取doc树
\ No newline at end of file
diff --git a/module/tree/test/model/getmodulepairs.php b/module/tree/test/model/getmodulepairs.php
new file mode 100755
index 0000000000..933c08a1ea
--- /dev/null
+++ b/module/tree/test/model/getmodulepairs.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+getModulePairs();
+cid=1
+pid=1
+
+测试获取root 1 type story 的树结构 >> 12
+测试获取root 2 type story 的树结构 >> 12
+测试获取root 3 type story 的树结构 >> 12
+测试获取root 41 type story 的树结构 >> 12
+测试获取root 42 type story 的树结构 >> 12
+测试获取root 43 type story 的树结构 >> 12
+测试获取root 101 type task 的树结构 >> 40
+测试获取root 102 type task 的树结构 >> 40
+测试获取root 103 type task 的树结构 >> 40
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'task');
+
+$tree = new treeTest();
+
+r($tree->getModulePairsTest($root[0], $type[0])) && p() && e('12'); // 测试获取root 1 type story 的树结构
+r($tree->getModulePairsTest($root[1], $type[0])) && p() && e('12'); // 测试获取root 2 type story 的树结构
+r($tree->getModulePairsTest($root[2], $type[0])) && p() && e('12'); // 测试获取root 3 type story 的树结构
+r($tree->getModulePairsTest($root[3], $type[0])) && p() && e('12'); // 测试获取root 41 type story 的树结构
+r($tree->getModulePairsTest($root[4], $type[0])) && p() && e('12'); // 测试获取root 42 type story 的树结构
+r($tree->getModulePairsTest($root[5], $type[0])) && p() && e('12'); // 测试获取root 43 type story 的树结构
+r($tree->getModulePairsTest($root[6], $type[1])) && p() && e('40'); // 测试获取root 101 type task 的树结构
+r($tree->getModulePairsTest($root[7], $type[1])) && p() && e('40'); // 测试获取root 102 type task 的树结构
+r($tree->getModulePairsTest($root[8], $type[1])) && p() && e('40'); // 测试获取root 103 type task 的树结构
\ No newline at end of file
diff --git a/module/tree/test/model/getmodulesname.php b/module/tree/test/model/getmodulesname.php
new file mode 100755
index 0000000000..7527bd7344
--- /dev/null
+++ b/module/tree/test/model/getmodulesname.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+getModulesName();
+cid=1
+pid=1
+
+测试获取module 1821 1981 的module name >> /产品模块1;/产品模块161
+测试获取module 1982 1621 的module name >> /产品模块162;/模块1601
+测试获取module 1822 22 的module name >> /产品模块2;/模块2
+测试获取module 1622 21 的module name >> /模块1602;/模块1
+
+*/
+$moduleIDList = array(array(1821, 1981), array(1982, 1621), array(1822, 22), array(1622, 21));
+
+$tree = new treeTest();
+
+r($tree->getModulesNameTest($moduleIDList[0])) && p('1821;1981') && e('/产品模块1;/产品模块161'); // 测试获取module 1821 1981 的module name
+r($tree->getModulesNameTest($moduleIDList[1])) && p('1982;1621') && e('/产品模块162;/模块1601'); // 测试获取module 1982 1621 的module name
+r($tree->getModulesNameTest($moduleIDList[2])) && p('1822;22') && e('/产品模块2;/模块2'); // 测试获取module 1822 22 的module name
+r($tree->getModulesNameTest($moduleIDList[3])) && p('1622;21') && e('/模块1602;/模块1'); // 测试获取module 1622 21 的module name
\ No newline at end of file
diff --git a/module/tree/test/model/getoptionmenu.php b/module/tree/test/model/getoptionmenu.php
new file mode 100755
index 0000000000..b1b1d6b2a2
--- /dev/null
+++ b/module/tree/test/model/getoptionmenu.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+getOptionMenu();
+cid=1
+pid=1
+
+测试获取root 1 type story 的目录 >> 13
+测试获取root 2 type story 的目录 >> 13
+测试获取root 41 type story 的目录 >> 11
+测试获取root 42 type story 的目录 >> 11
+测试获取root 101 type task 的目录 >> 5
+测试获取root 102 type task 的目录 >> 4
+测试获取root 1 type doc 的目录 >> 4
+测试获取root 2 type doc 的目录 >> 4
+
+*/
+$root = array(1, 2, 41, 42, 101, 102);
+$type = array('story', 'task', 'doc');
+
+$tree = new treeTest();
+
+r($tree->getOptionMenuTest($root[0], $type[0])) && p() && e('13'); // 测试获取root 1 type story 的目录
+r($tree->getOptionMenuTest($root[1], $type[0])) && p() && e('13'); // 测试获取root 2 type story 的目录
+r($tree->getOptionMenuTest($root[2], $type[0])) && p() && e('11'); // 测试获取root 41 type story 的目录
+r($tree->getOptionMenuTest($root[3], $type[0])) && p() && e('11'); // 测试获取root 42 type story 的目录
+r($tree->getOptionMenuTest($root[4], $type[1])) && p() && e('5'); // 测试获取root 101 type task 的目录
+r($tree->getOptionMenuTest($root[5], $type[1])) && p() && e('4'); // 测试获取root 102 type task 的目录
+r($tree->getOptionMenuTest($root[0], $type[2])) && p() && e('4'); // 测试获取root 1 type doc 的目录
+r($tree->getOptionMenuTest($root[1], $type[2])) && p() && e('4'); // 测试获取root 2 type doc 的目录
\ No newline at end of file
diff --git a/module/tree/test/model/getparents.php b/module/tree/test/model/getparents.php
new file mode 100755
index 0000000000..bc93a05a1a
--- /dev/null
+++ b/module/tree/test/model/getparents.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+getParents();
+cid=1
+pid=1
+
+获取 module 1821 的父module >> ,1821
+获取 module 2621 的父module >> ,1821,2621
+获取 module 2622 的父module >> ,1821,2622
+获取 module 21 的父module >> ,21
+获取 module 3021 的父module >> ,21,3021
+获取 module 3022 的父module >> ,23,3022
+获取 module 3621 的父module >> ,3621
+获取 module 3721 的父module >> ,3621,3721
+获取 module 3722 的父module >> ,3621,3722
+获取 module 0 的父module >> 0
+
+*/
+
+$moduleID = array(1821, 2621, 2622, 21, 3021, 3022, 3621, 3721, 3722, 0);
+
+$tree = new treeTest();
+
+r($tree->getParentsTest($moduleID[0])) && p() && e(',1821'); // 获取 module 1821 的父module
+r($tree->getParentsTest($moduleID[1])) && p() && e(',1821,2621'); // 获取 module 2621 的父module
+r($tree->getParentsTest($moduleID[2])) && p() && e(',1821,2622'); // 获取 module 2622 的父module
+r($tree->getParentsTest($moduleID[3])) && p() && e(',21'); // 获取 module 21 的父module
+r($tree->getParentsTest($moduleID[4])) && p() && e(',21,3021'); // 获取 module 3021 的父module
+r($tree->getParentsTest($moduleID[5])) && p() && e(',23,3022'); // 获取 module 3022 的父module
+r($tree->getParentsTest($moduleID[6])) && p() && e(',3621'); // 获取 module 3621 的父module
+r($tree->getParentsTest($moduleID[7])) && p() && e(',3621,3721'); // 获取 module 3721 的父module
+r($tree->getParentsTest($moduleID[8])) && p() && e(',3621,3722'); // 获取 module 3722 的父module
+r($tree->getParentsTest($moduleID[9])) && p() && e('0'); // 获取 module 0 的父module
\ No newline at end of file
diff --git a/module/tree/test/model/getproduct.php b/module/tree/test/model/getproduct.php
new file mode 100755
index 0000000000..a3d18d6ff9
--- /dev/null
+++ b/module/tree/test/model/getproduct.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+getProduct();
+cid=1
+pid=1
+
+获取module 1821 的产品 >> 正常产品1
+获取module 1825 的产品 >> 正常产品2
+获取module 2621 的产品 >> 正常产品1
+获取module 21 的产品 >> 0
+获取module 25 的产品 >> 0
+获取module 3021 的产品 >> 0
+获取module 3621 的产品 >> 0
+获取module 3622 的产品 >> 0
+获取module 3722 的产品 >> 0
+获取module 0 的产品 >> 0
+
+*/
+$moduleID = array(1821, 1825, 2621, 21, 25, 3021, 3621, 3622, 3722, 0);
+
+$tree = new treeTest();
+
+r($tree->getProductTest($moduleID[0])) && p('name') && e('正常产品1'); // 获取module 1821 的产品
+r($tree->getProductTest($moduleID[1])) && p('name') && e('正常产品2'); // 获取module 1825 的产品
+r($tree->getProductTest($moduleID[2])) && p('name') && e('正常产品1'); // 获取module 2621 的产品
+r($tree->getProductTest($moduleID[3])) && p('name') && e('0'); // 获取module 21 的产品
+r($tree->getProductTest($moduleID[4])) && p('name') && e('0'); // 获取module 25 的产品
+r($tree->getProductTest($moduleID[5])) && p('name') && e('0'); // 获取module 3021 的产品
+r($tree->getProductTest($moduleID[6])) && p('name') && e('0'); // 获取module 3621 的产品
+r($tree->getProductTest($moduleID[7])) && p('name') && e('0'); // 获取module 3622 的产品
+r($tree->getProductTest($moduleID[8])) && p('name') && e('0'); // 获取module 3722 的产品
+r($tree->getProductTest($moduleID[9])) && p('name') && e('0'); // 获取module 0 的产品
\ No newline at end of file
diff --git a/module/tree/test/model/getproductstructure.php b/module/tree/test/model/getproductstructure.php
new file mode 100755
index 0000000000..2ac8bfb526
--- /dev/null
+++ b/module/tree/test/model/getproductstructure.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+getProductStructure();
+cid=1
+pid=1
+
+测试获取 root 1 type story 的树结构 >> 1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;
+测试获取 root 2 type story 的树结构 >> 1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;
+测试获取 root 3 type story 的树结构 >> 1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;
+测试获取 root 41 type story 的树结构 >> 1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;
+测试获取 root 42 type story 的树结构 >> 1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;
+测试获取 root 43 type story 的树结构 >> 1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;
+测试获取 root 101 type task 的树结构 >> 0
+测试获取 root 102 type task 的树结构 >> 0
+测试获取 root 103 type task 的树结构 >> 0
+测试获取 root 1 type doc 的树结构 >> 3621:2;
+测试获取 root 2 type doc 的树结构 >> 3622:2;
+测试获取 root 3 type doc 的树结构 >> 3623:2;
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'task', 'doc');
+
+$tree = new treeTest();
+
+r($tree->getProductStructureTest($root[0], $type[0])) && p() && e('1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;'); // 测试获取 root 1 type story 的树结构
+r($tree->getProductStructureTest($root[1], $type[0])) && p() && e('1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;'); // 测试获取 root 2 type story 的树结构
+r($tree->getProductStructureTest($root[2], $type[0])) && p() && e('1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;'); // 测试获取 root 3 type story 的树结构
+r($tree->getProductStructureTest($root[3], $type[0])) && p() && e('1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;'); // 测试获取 root 41 type story 的树结构
+r($tree->getProductStructureTest($root[4], $type[0])) && p() && e('1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;'); // 测试获取 root 42 type story 的树结构
+r($tree->getProductStructureTest($root[5], $type[0])) && p() && e('1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;'); // 测试获取 root 43 type story 的树结构
+r($tree->getProductStructureTest($root[6], $type[1])) && p() && e('0'); // 测试获取 root 101 type task 的树结构
+r($tree->getProductStructureTest($root[7], $type[1])) && p() && e('0'); // 测试获取 root 102 type task 的树结构
+r($tree->getProductStructureTest($root[8], $type[1])) && p() && e('0'); // 测试获取 root 103 type task 的树结构
+r($tree->getProductStructureTest($root[0], $type[2])) && p() && e('3621:2;'); // 测试获取 root 1 type doc 的树结构
+r($tree->getProductStructureTest($root[1], $type[2])) && p() && e('3622:2;'); // 测试获取 root 2 type doc 的树结构
+r($tree->getProductStructureTest($root[2], $type[2])) && p() && e('3623:2;'); // 测试获取 root 3 type doc 的树结构
\ No newline at end of file
diff --git a/module/tree/test/model/getprojectmodule.php b/module/tree/test/model/getprojectmodule.php
new file mode 100755
index 0000000000..6d72165239
--- /dev/null
+++ b/module/tree/test/model/getprojectmodule.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getProjectModule();
+cid=1
+pid=1
+
+测试获取项目模块 1 >> ,1821,2621,2622,1822,1823,1824,2221,2821,2822,2222,2223,2224
+测试获取项目模块 2 >> ,1825,2623,2624,1826,1827,1828,2225,2823,2824,2226,2227,2228
+测试获取项目模块 3 >> ,1829,2625,2626,1830,1831,1832,2229,2825,2826,2230,2231,2232
+测试获取项目模块 4 >> ,1833,2627,2628,1834,1835,1836,2233,2827,2828,2234,2235,2236
+测试获取项目模块 5 >> ,1837,2629,2630,1838,1839,1840,2237,2829,2830,2238,2239,2240
+测试获取项目模块 6 >> ,1841,2631,2632,1842,1843,1844,2241,2831,2832,2242,2243,2244
+
+*/
+$projectID = 1;
+$productID = array(1, 2, 3, 4, 5, 6);
+
+$tree = new treeTest();
+
+r($tree->getProjectModuleTest($projectID, $productID[0])) && p() && e(',1821,2621,2622,1822,1823,1824,2221,2821,2822,2222,2223,2224'); // 测试获取项目模块 1
+r($tree->getProjectModuleTest($projectID, $productID[1])) && p() && e(',1825,2623,2624,1826,1827,1828,2225,2823,2824,2226,2227,2228'); // 测试获取项目模块 2
+r($tree->getProjectModuleTest($projectID, $productID[2])) && p() && e(',1829,2625,2626,1830,1831,1832,2229,2825,2826,2230,2231,2232'); // 测试获取项目模块 3
+r($tree->getProjectModuleTest($projectID, $productID[3])) && p() && e(',1833,2627,2628,1834,1835,1836,2233,2827,2828,2234,2235,2236'); // 测试获取项目模块 4
+r($tree->getProjectModuleTest($projectID, $productID[4])) && p() && e(',1837,2629,2630,1838,1839,1840,2237,2829,2830,2238,2239,2240'); // 测试获取项目模块 5
+r($tree->getProjectModuleTest($projectID, $productID[5])) && p() && e(',1841,2631,2632,1842,1843,1844,2241,2831,2832,2242,2243,2244'); // 测试获取项目模块 6
\ No newline at end of file
diff --git a/module/tree/test/model/getsons.php b/module/tree/test/model/getsons.php
new file mode 100755
index 0000000000..e6f3f9b2ea
--- /dev/null
+++ b/module/tree/test/model/getsons.php
@@ -0,0 +1,57 @@
+#!/usr/bin/env php
+getSons();
+cid=1
+pid=1
+
+测试获取root 1 module 1821 type story branch 0 的子module >> ,2621,2622
+测试获取root 2 module 1822 type story branch 0 的子module >> ,2623,2624
+测试获取root 41 module 1981 type story branch 0 的子module >> ,2701,2702
+测试获取root 41 module 1981 type story branch 1 的子module >> ,2701,2702
+测试获取root 41 module 1981 type story branch 2 的子module >> ,2701,2702
+测试获取root 41 module 1982 type story branch 0 的子module >> 0
+测试获取root 41 module 1982 type story branch 1 的子module >> 0
+测试获取root 41 module 1982 type story branch 2 的子module >> 0
+测试获取root 42 module 1985 type story branch 0 的子module >> ,2703,2704
+测试获取root 42 module 1985 type story branch 1 的子module >> ,2703,2704
+测试获取root 42 module 1985 type story branch 2 的子module >> ,2703,2704
+测试获取root 42 module 1987 type story branch 0 的子module >> 0
+测试获取root 42 module 1987 type story branch 1 的子module >> 0
+测试获取root 42 module 1987 type story branch 2 的子module >> 0
+测试获取root 101 module 21 type task branch 0 的子module >> ,3021
+测试获取root 102 module 22 type task branch 0 的子module >> 0
+测试获取root 1 module 3621 type doc branch 0 的子module >> ,3721,3722
+测试获取root 2 module 3621 type doc branch 0 的子module >> ,3723,3724
+
+*/
+$root = array(1, 2, 41, 42, 101, 102);
+$module = array(1821, 1825, 1981, 1982, 1985, 1987, 21, 24, 3621, 3622);
+$type = array('story', 'task', 'doc');
+$branch = array(0, 1, 2);
+
+$tree = new treeTest();
+
+r($tree->getSonsTest($root[0], $module[0], $type[0], $branch[0])) && p() && e(',2621,2622'); // 测试获取root 1 module 1821 type story branch 0 的子module
+r($tree->getSonsTest($root[1], $module[1], $type[0], $branch[0])) && p() && e(',2623,2624'); // 测试获取root 2 module 1822 type story branch 0 的子module
+r($tree->getSonsTest($root[2], $module[2], $type[0], $branch[0])) && p() && e(',2701,2702'); // 测试获取root 41 module 1981 type story branch 0 的子module
+r($tree->getSonsTest($root[2], $module[2], $type[0], $branch[1])) && p() && e(',2701,2702'); // 测试获取root 41 module 1981 type story branch 1 的子module
+r($tree->getSonsTest($root[2], $module[2], $type[0], $branch[2])) && p() && e(',2701,2702'); // 测试获取root 41 module 1981 type story branch 2 的子module
+r($tree->getSonsTest($root[2], $module[3], $type[0], $branch[0])) && p() && e('0'); // 测试获取root 41 module 1982 type story branch 0 的子module
+r($tree->getSonsTest($root[2], $module[3], $type[0], $branch[1])) && p() && e('0'); // 测试获取root 41 module 1982 type story branch 1 的子module
+r($tree->getSonsTest($root[2], $module[3], $type[0], $branch[2])) && p() && e('0'); // 测试获取root 41 module 1982 type story branch 2 的子module
+r($tree->getSonsTest($root[3], $module[4], $type[0], $branch[0])) && p() && e(',2703,2704'); // 测试获取root 42 module 1985 type story branch 0 的子module
+r($tree->getSonsTest($root[3], $module[4], $type[0], $branch[1])) && p() && e(',2703,2704'); // 测试获取root 42 module 1985 type story branch 1 的子module
+r($tree->getSonsTest($root[3], $module[4], $type[0], $branch[2])) && p() && e(',2703,2704'); // 测试获取root 42 module 1985 type story branch 2 的子module
+r($tree->getSonsTest($root[3], $module[5], $type[0], $branch[0])) && p() && e('0'); // 测试获取root 42 module 1987 type story branch 0 的子module
+r($tree->getSonsTest($root[3], $module[5], $type[0], $branch[1])) && p() && e('0'); // 测试获取root 42 module 1987 type story branch 1 的子module
+r($tree->getSonsTest($root[3], $module[5], $type[0], $branch[2])) && p() && e('0'); // 测试获取root 42 module 1987 type story branch 2 的子module
+r($tree->getSonsTest($root[4], $module[6], $type[1], $branch[0])) && p() && e(',3021'); // 测试获取root 101 module 21 type task branch 0 的子module
+r($tree->getSonsTest($root[5], $module[7], $type[1], $branch[0])) && p() && e('0'); // 测试获取root 102 module 22 type task branch 0 的子module
+r($tree->getSonsTest($root[0], $module[8], $type[2], $branch[0])) && p() && e(',3721,3722'); // 测试获取root 1 module 3621 type doc branch 0 的子module
+r($tree->getSonsTest($root[1], $module[9], $type[2], $branch[0])) && p() && e(',3723,3724'); // 测试获取root 2 module 3621 type doc branch 0 的子module
\ No newline at end of file
diff --git a/module/tree/test/model/getstorymodule.php b/module/tree/test/model/getstorymodule.php
new file mode 100755
index 0000000000..910b728ba3
--- /dev/null
+++ b/module/tree/test/model/getstorymodule.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+getStoryModule();
+cid=1
+pid=1
+
+测试获取module 1821 的story模块 >> 1821
+测试获取module 1822 的story模块 >> 1822
+测试获取module 1982 的story模块 >> 1982
+测试获取module 1983 的story模块 >> 1983
+测试获取module 2621 的story模块 >> 2621
+测试获取module 2622 的story模块 >> 2622
+测试获取module 21 的story模块 >> 0
+测试获取module 3021 的story模块 >> 0
+
+*/
+$moduleID = array(1821, 1822, 1982, 1983, 2621, 2622, 21, 3021);
+
+$tree = new treeTest();
+
+r($tree->getStoryModuleTest($moduleID[0])) && p() && e('1821'); // 测试获取module 1821 的story模块
+r($tree->getStoryModuleTest($moduleID[1])) && p() && e('1822'); // 测试获取module 1822 的story模块
+r($tree->getStoryModuleTest($moduleID[2])) && p() && e('1982'); // 测试获取module 1982 的story模块
+r($tree->getStoryModuleTest($moduleID[3])) && p() && e('1983'); // 测试获取module 1983 的story模块
+r($tree->getStoryModuleTest($moduleID[4])) && p() && e('2621'); // 测试获取module 2621 的story模块
+r($tree->getStoryModuleTest($moduleID[5])) && p() && e('2622'); // 测试获取module 2622 的story模块
+r($tree->getStoryModuleTest($moduleID[6])) && p() && e('0'); // 测试获取module 21 的story模块
+r($tree->getStoryModuleTest($moduleID[7])) && p() && e('0'); // 测试获取module 3021 的story模块
\ No newline at end of file
diff --git a/module/tree/test/model/gettaskoptionmenu.php b/module/tree/test/model/gettaskoptionmenu.php
new file mode 100755
index 0000000000..a115809a58
--- /dev/null
+++ b/module/tree/test/model/gettaskoptionmenu.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+getTaskOptionMenu();
+cid=1
+pid=1
+
+测试获取 root 1 task目录 >> ,/
+测试获取 root 2 task目录 >> ,/
+测试获取 root 3 task目录 >> ,/
+测试获取 root 41 task目录 >> ,/,/已关闭的正常产品31/产品模块122,/已关闭的正常产品31/产品模块124
+测试获取 root 42 task目录 >> ,/,/已关闭的正常产品32/产品模块126,/已关闭的正常产品32/产品模块128
+测试获取 root 43 task目录 >> ,/,/已关闭的正常产品33/产品模块132,/已关闭的正常产品33/产品模块130
+测试获取 root 101 task目录 >> ,/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3
+测试获取 root 101 product 1 task目录 >> ,/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3
+测试获取 root 101 product 1 startModule 3021 task目录 >> ,/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3
+测试获取 root 101 product 1 startModule 3021 allModule task目录 >> ,/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3
+测试获取 root 102 task目录 >> ,/,/正常产品2/产品模块6,/正常产品2/产品模块8,/模块4,/模块5,/模块6
+测试获取 root 103 task目录 >> ,/,/正常产品3/产品模块12,/正常产品3/产品模块10,/模块7,/模块8,/模块9
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$productID = 1;
+$startModule = 3021;
+$extra = 'allModule';
+
+$tree = new treeTest();
+
+r($tree->getTaskOptionMenuTest($root[0])) && p() && e(',/'); // 测试获取 root 1 task目录
+r($tree->getTaskOptionMenuTest($root[1])) && p() && e(',/'); // 测试获取 root 2 task目录
+r($tree->getTaskOptionMenuTest($root[2])) && p() && e(',/'); // 测试获取 root 3 task目录
+r($tree->getTaskOptionMenuTest($root[3])) && p() && e(',/,/已关闭的正常产品31/产品模块122,/已关闭的正常产品31/产品模块124'); // 测试获取 root 41 task目录
+r($tree->getTaskOptionMenuTest($root[4])) && p() && e(',/,/已关闭的正常产品32/产品模块126,/已关闭的正常产品32/产品模块128'); // 测试获取 root 42 task目录
+r($tree->getTaskOptionMenuTest($root[5])) && p() && e(',/,/已关闭的正常产品33/产品模块132,/已关闭的正常产品33/产品模块130'); // 测试获取 root 43 task目录
+r($tree->getTaskOptionMenuTest($root[6])) && p() && e(',/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3'); // 测试获取 root 101 task目录
+r($tree->getTaskOptionMenuTest($root[6], $productID)) && p() && e(',/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3'); // 测试获取 root 101 product 1 task目录
+r($tree->getTaskOptionMenuTest($root[6], $productID, $startModule)) && p() && e(',/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3'); // 测试获取 root 101 product 1 startModule 3021 task目录
+r($tree->getTaskOptionMenuTest($root[6], $productID, $startModule, $extra)) && p() && e(',/,/正常产品1/产品模块2,/正常产品1/产品模块4,/模块1,/模块1/执行子模块1,/模块2,/模块3'); // 测试获取 root 101 product 1 startModule 3021 allModule task目录
+r($tree->getTaskOptionMenuTest($root[7])) && p() && e(',/,/正常产品2/产品模块6,/正常产品2/产品模块8,/模块4,/模块5,/模块6'); // 测试获取 root 102 task目录
+r($tree->getTaskOptionMenuTest($root[8])) && p() && e(',/,/正常产品3/产品模块12,/正常产品3/产品模块10,/模块7,/模块8,/模块9'); // 测试获取 root 103 task目录
\ No newline at end of file
diff --git a/module/tree/test/model/gettasksons.php b/module/tree/test/model/gettasksons.php
new file mode 100755
index 0000000000..284f4217f5
--- /dev/null
+++ b/module/tree/test/model/gettasksons.php
@@ -0,0 +1,68 @@
+#!/usr/bin/env php
+getTaskSons();
+cid=1
+pid=1
+
+测试获取 root 1 product 1 task模块的子模块 >> ,1821,2221,1822,2222,1823,2223,1824,2224
+测试获取 root 1 product 2 task模块的子模块 >> ,1825,2225,1826,2226,1827,2227,1828,2228
+测试获取 root 1 module 1821 task模块的子模块 >> ,2621,2622
+测试获取 root 1 module 1825 task模块的子模块 >> 0
+测试获取 root 1 module 21 task模块的子模块 >> 0
+测试获取 root 1 module 23 task模块的子模块 >> 0
+测试获取 root 2 product 1 task模块的子模块 >> ,1821,2221,1822,2222,1823,2223,1824,2224
+测试获取 root 2 product 2 task模块的子模块 >> ,1825,2225,1826,2226,1827,2227,1828,2228
+测试获取 root 2 module 1821 task模块的子模块 >> 0
+测试获取 root 2 module 1825 task模块的子模块 >> ,2623,2624
+测试获取 root 2 module 21 task模块的子模块 >> 0
+测试获取 root 2 module 23 task模块的子模块 >> 0
+测试获取 root 101 product 1 task模块的子模块 >> ,1821,2221,21,1822,2222,22,1823,2223,23,1824,2224
+测试获取 root 101 product 2 task模块的子模块 >> ,21,22,23,1825,2225,1826,2226,1827,2227,1828,2228
+测试获取 root 101 module 1821 task模块的子模块 >> 0
+测试获取 root 101 module 1825 task模块的子模块 >> 0
+测试获取 root 101 module 21 task模块的子模块 >> ,3021
+测试获取 root 101 module 23 task模块的子模块 >> 0
+测试获取 root 102 product 1 task模块的子模块 >> ,1821,2221,1822,2222,1823,2223,1824,2224,24,25,26
+测试获取 root 102 product 2 task模块的子模块 >> ,24,1825,2225,25,1826,2226,26,1827,2227,1828,2228
+测试获取 root 102 module 1821 task模块的子模块 >> 0
+测试获取 root 102 module 1825 task模块的子模块 >> 0
+测试获取 root 102 module 21 task模块的子模块 >> 0
+测试获取 root 102 module 23 task模块的子模块 >> ,3022
+
+*/
+$rootID = array(1, 2, 101, 102);
+$productID = array(0, 1, 2);
+$moduleID = array(0, 1821, 1825, 21, 23);
+
+$tree = new treeTest();
+
+r($tree->getTaskSonsTest($rootID[0], $productID[1], $moduleID[0])) && p() && e(',1821,2221,1822,2222,1823,2223,1824,2224'); // 测试获取 root 1 product 1 task模块的子模块
+r($tree->getTaskSonsTest($rootID[0], $productID[2], $moduleID[0])) && p() && e(',1825,2225,1826,2226,1827,2227,1828,2228'); // 测试获取 root 1 product 2 task模块的子模块
+r($tree->getTaskSonsTest($rootID[0], $productID[0], $moduleID[1])) && p() && e(',2621,2622'); // 测试获取 root 1 module 1821 task模块的子模块
+r($tree->getTaskSonsTest($rootID[0], $productID[0], $moduleID[2])) && p() && e('0'); // 测试获取 root 1 module 1825 task模块的子模块
+r($tree->getTaskSonsTest($rootID[0], $productID[0], $moduleID[3])) && p() && e('0'); // 测试获取 root 1 module 21 task模块的子模块
+r($tree->getTaskSonsTest($rootID[0], $productID[0], $moduleID[4])) && p() && e('0'); // 测试获取 root 1 module 23 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[1], $moduleID[0])) && p() && e(',1821,2221,1822,2222,1823,2223,1824,2224'); // 测试获取 root 2 product 1 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[2], $moduleID[0])) && p() && e(',1825,2225,1826,2226,1827,2227,1828,2228'); // 测试获取 root 2 product 2 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[0], $moduleID[1])) && p() && e('0'); // 测试获取 root 2 module 1821 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[0], $moduleID[2])) && p() && e(',2623,2624'); // 测试获取 root 2 module 1825 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[0], $moduleID[3])) && p() && e('0'); // 测试获取 root 2 module 21 task模块的子模块
+r($tree->getTaskSonsTest($rootID[1], $productID[0], $moduleID[4])) && p() && e('0'); // 测试获取 root 2 module 23 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[1], $moduleID[0])) && p() && e(',1821,2221,21,1822,2222,22,1823,2223,23,1824,2224 '); // 测试获取 root 101 product 1 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[2], $moduleID[0])) && p() && e(',21,22,23,1825,2225,1826,2226,1827,2227,1828,2228 '); // 测试获取 root 101 product 2 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[0], $moduleID[1])) && p() && e('0'); // 测试获取 root 101 module 1821 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[0], $moduleID[2])) && p() && e('0'); // 测试获取 root 101 module 1825 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[0], $moduleID[3])) && p() && e(',3021'); // 测试获取 root 101 module 21 task模块的子模块
+r($tree->getTaskSonsTest($rootID[2], $productID[0], $moduleID[4])) && p() && e('0'); // 测试获取 root 101 module 23 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[1], $moduleID[0])) && p() && e(',1821,2221,1822,2222,1823,2223,1824,2224,24,25,26 '); // 测试获取 root 102 product 1 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[2], $moduleID[0])) && p() && e(',24,1825,2225,25,1826,2226,26,1827,2227,1828,2228 '); // 测试获取 root 102 product 2 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[0], $moduleID[1])) && p() && e('0'); // 测试获取 root 102 module 1821 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[0], $moduleID[2])) && p() && e('0'); // 测试获取 root 102 module 1825 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[0], $moduleID[3])) && p() && e('0'); // 测试获取 root 102 module 21 task模块的子模块
+r($tree->getTaskSonsTest($rootID[3], $productID[0], $moduleID[4])) && p() && e(',3022'); // 测试获取 root 102 module 23 task模块的子模块
\ No newline at end of file
diff --git a/module/tree/test/model/gettaskstructure.php b/module/tree/test/model/gettaskstructure.php
new file mode 100755
index 0000000000..52d3bace99
--- /dev/null
+++ b/module/tree/test/model/gettaskstructure.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+getTaskStructure();
+cid=1
+pid=1
+
+获取root 101 的task 结构 >> 正常产品1:2;多平台产品81:0;多平台产品91:0;模块1:1;模块2:0模块3:0
+获取root 102 的task 结构 >> 正常产品2:2;多平台产品82:0;多平台产品92:0;模块4:0模块5:0模块6:0
+获取root 103 的task 结构 >> 正常产品3:2;多平台产品83:0;多平台产品93:0;模块7:0模块8:0模块9:0
+获取root 104 的task 结构 >> 正常产品4:2;多平台产品84:0;多平台产品94:0;模块11:0模块12:0模块10:0
+获取root 105 的task 结构 >> 正常产品5:2;多平台产品85:0;多平台产品95:0;模块13:0模块14:0模块15:0
+获取root 106 的task 结构 >> 正常产品6:2;多平台产品86:0;多平台产品96:0;模块16:0模块17:0模块18:0
+
+*/
+$root = array(101, 102, 103, 104, 105, 106);
+
+$tree = new treeTest();
+
+r($tree->getTaskStructureTest($root[0])) && p() && e('正常产品1:2;多平台产品81:0;多平台产品91:0;模块1:1;模块2:0模块3:0'); // 获取root 101 的task 结构
+r($tree->getTaskStructureTest($root[1])) && p() && e('正常产品2:2;多平台产品82:0;多平台产品92:0;模块4:0模块5:0模块6:0'); // 获取root 102 的task 结构
+r($tree->getTaskStructureTest($root[2])) && p() && e('正常产品3:2;多平台产品83:0;多平台产品93:0;模块7:0模块8:0模块9:0'); // 获取root 103 的task 结构
+r($tree->getTaskStructureTest($root[3])) && p() && e('正常产品4:2;多平台产品84:0;多平台产品94:0;模块11:0模块12:0模块10:0'); // 获取root 104 的task 结构
+r($tree->getTaskStructureTest($root[4])) && p() && e('正常产品5:2;多平台产品85:0;多平台产品95:0;模块13:0模块14:0模块15:0'); // 获取root 105 的task 结构
+r($tree->getTaskStructureTest($root[5])) && p() && e('正常产品6:2;多平台产品86:0;多平台产品96:0;模块16:0模块17:0模块18:0'); // 获取root 106 的task 结构
\ No newline at end of file
diff --git a/module/tree/test/model/gettasktreemodules.php b/module/tree/test/model/gettasktreemodules.php
new file mode 100755
index 0000000000..af540b2952
--- /dev/null
+++ b/module/tree/test/model/gettasktreemodules.php
@@ -0,0 +1,52 @@
+#!/usr/bin/env php
+getTaskTreeModules();
+cid=1
+pid=1
+
+测试获取 execution 101 parent false story 的树 >> ,1822,1824,21,22,23,3021
+测试获取 execution 102 parent false story 的树 >> ,1826,1828,24,25,26,3022
+测试获取 execution 103 parent false story 的树 >> ,1830,1832,27,28,29,3023
+测试获取 execution 104 parent false story 的树 >> ,1834,1836,30,31,32,3024
+测试获取 execution 101 parent true story 的树 >> ,,1822,1824,21,22,23,3021
+测试获取 execution 102 parent true story 的树 >> ,,1826,1828,24,25,26,23,3022
+测试获取 execution 103 parent true story 的树 >> ,,1830,1832,27,28,29,25,3023
+测试获取 execution 104 parent true story 的树 >> ,,1834,1836,30,31,32,27,3024
+测试获取 execution 101 parent false case 的树 >> ,21,22,23,3021
+测试获取 execution 102 parent false case 的树 >> ,24,25,26,3022
+测试获取 execution 103 parent false case 的树 >> ,27,28,29,3023
+测试获取 execution 104 parent false case 的树 >> ,30,31,32,3024
+测试获取 execution 101 parent true case 的树 >> ,,21,22,23,3021
+测试获取 execution 102 parent true case 的树 >> ,,24,25,26,23,3022
+测试获取 execution 103 parent true case 的树 >> ,,27,28,29,25,3023
+测试获取 execution 104 parent true case 的树 >> ,,30,31,32,27,3024
+
+*/
+$executionID = array(101, 102, 103, 104);
+$parent = array(false, true);
+$linkObject = array('story', 'case');
+
+$tree = new treeTest();
+
+r($tree->getTaskTreeModulesTest($executionID[0], $parent[0], $linkObject[0])) && p() && e(',1822,1824,21,22,23,3021'); // 测试获取 execution 101 parent false story 的树
+r($tree->getTaskTreeModulesTest($executionID[1], $parent[0], $linkObject[0])) && p() && e(',1826,1828,24,25,26,3022'); // 测试获取 execution 102 parent false story 的树
+r($tree->getTaskTreeModulesTest($executionID[2], $parent[0], $linkObject[0])) && p() && e(',1830,1832,27,28,29,3023'); // 测试获取 execution 103 parent false story 的树
+r($tree->getTaskTreeModulesTest($executionID[3], $parent[0], $linkObject[0])) && p() && e(',1834,1836,30,31,32,3024'); // 测试获取 execution 104 parent false story 的树
+r($tree->getTaskTreeModulesTest($executionID[0], $parent[1], $linkObject[0])) && p() && e(',,1822,1824,21,22,23,3021'); // 测试获取 execution 101 parent true story 的树
+r($tree->getTaskTreeModulesTest($executionID[1], $parent[1], $linkObject[0])) && p() && e(',,1826,1828,24,25,26,23,3022'); // 测试获取 execution 102 parent true story 的树
+r($tree->getTaskTreeModulesTest($executionID[2], $parent[1], $linkObject[0])) && p() && e(',,1830,1832,27,28,29,25,3023'); // 测试获取 execution 103 parent true story 的树
+r($tree->getTaskTreeModulesTest($executionID[3], $parent[1], $linkObject[0])) && p() && e(',,1834,1836,30,31,32,27,3024'); // 测试获取 execution 104 parent true story 的树
+r($tree->getTaskTreeModulesTest($executionID[0], $parent[0], $linkObject[1])) && p() && e(',21,22,23,3021'); // 测试获取 execution 101 parent false case 的树
+r($tree->getTaskTreeModulesTest($executionID[1], $parent[0], $linkObject[1])) && p() && e(',24,25,26,3022'); // 测试获取 execution 102 parent false case 的树
+r($tree->getTaskTreeModulesTest($executionID[2], $parent[0], $linkObject[1])) && p() && e(',27,28,29,3023'); // 测试获取 execution 103 parent false case 的树
+r($tree->getTaskTreeModulesTest($executionID[3], $parent[0], $linkObject[1])) && p() && e(',30,31,32,3024'); // 测试获取 execution 104 parent false case 的树
+r($tree->getTaskTreeModulesTest($executionID[0], $parent[1], $linkObject[1])) && p() && e(',,21,22,23,3021'); // 测试获取 execution 101 parent true case 的树
+r($tree->getTaskTreeModulesTest($executionID[1], $parent[1], $linkObject[1])) && p() && e(',,24,25,26,23,3022'); // 测试获取 execution 102 parent true case 的树
+r($tree->getTaskTreeModulesTest($executionID[2], $parent[1], $linkObject[1])) && p() && e(',,27,28,29,25,3023'); // 测试获取 execution 103 parent true case 的树
+r($tree->getTaskTreeModulesTest($executionID[3], $parent[1], $linkObject[1])) && p() && e(',,30,31,32,27,3024'); // 测试获取 execution 104 parent true case 的树
\ No newline at end of file
diff --git a/module/tree/test/model/gettreestructure.php b/module/tree/test/model/gettreestructure.php
new file mode 100755
index 0000000000..fef1bb3889
--- /dev/null
+++ b/module/tree/test/model/gettreestructure.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+getTreeStructure();
+cid=1
+pid=1
+
+测试获取root 1 story 的树结构 >> 1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;
+测试获取root 2 story 的树结构 >> 1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;
+测试获取root 3 story 的树结构 >> 1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;
+测试获取root 41 story 的树结构 >> 1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;
+测试获取root 42 story 的树结构 >> 1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;
+测试获取root 43 story 的树结构 >> 1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;
+测试获取root 1 case 的树结构 >> 1821:2;2221:2;3921:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;
+测试获取root 2 case 的树结构 >> 3922:2;1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;
+测试获取root 3 case 的树结构 >> 1831:0;2231:0;1832:0;2232:0;3923:2;1829:2;2229:2;1830:0;2230:0;
+测试获取root 1 doc 的树结构 >> 3621:2;
+测试获取root 2 doc 的树结构 >> 3622:2;
+测试获取root 3 doc 的树结构 >> 3623:2;
+测试获取root 101 task 的树结构 >> 0
+测试获取root 102 task 的树结构 >> 0
+测试获取root 103 task 的树结构 >> 0
+
+*/
+$root = array(1, 2, 3, 41, 42, 43, 101, 102, 103);
+$type = array('story', 'case', 'doc', 'task');
+
+$tree = new treeTest();
+
+r($tree->getTreeStructureTest($root[0], $type[0])) && p() && e('1821:2;2221:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;'); // 测试获取root 1 story 的树结构
+r($tree->getTreeStructureTest($root[1], $type[0])) && p() && e('1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;'); // 测试获取root 2 story 的树结构
+r($tree->getTreeStructureTest($root[2], $type[0])) && p() && e('1831:0;2231:0;1832:0;2232:0;1829:2;2229:2;1830:0;2230:0;'); // 测试获取root 3 story 的树结构
+r($tree->getTreeStructureTest($root[3], $type[0])) && p() && e('1981:2;2381:2;1982:0;2382:0;1983:0;2383:0;1984:0;2384:0;'); // 测试获取root 41 story 的树结构
+r($tree->getTreeStructureTest($root[4], $type[0])) && p() && e('1985:2;2385:2;1986:0;2386:0;1987:0;2387:0;1988:0;2388:0;'); // 测试获取root 42 story 的树结构
+r($tree->getTreeStructureTest($root[5], $type[0])) && p() && e('1991:0;2391:0;1992:0;2392:0;1989:2;2389:2;1990:0;2390:0;'); // 测试获取root 43 story 的树结构
+r($tree->getTreeStructureTest($root[0], $type[1])) && p() && e('1821:2;2221:2;3921:2;1822:0;2222:0;1823:0;2223:0;1824:0;2224:0;'); // 测试获取root 1 case 的树结构
+r($tree->getTreeStructureTest($root[1], $type[1])) && p() && e('3922:2;1825:2;2225:2;1826:0;2226:0;1827:0;2227:0;1828:0;2228:0;'); // 测试获取root 2 case 的树结构
+r($tree->getTreeStructureTest($root[2], $type[1])) && p() && e('1831:0;2231:0;1832:0;2232:0;3923:2;1829:2;2229:2;1830:0;2230:0;'); // 测试获取root 3 case 的树结构
+r($tree->getTreeStructureTest($root[0], $type[2])) && p() && e('3621:2;'); // 测试获取root 1 doc 的树结构
+r($tree->getTreeStructureTest($root[1], $type[2])) && p() && e('3622:2;'); // 测试获取root 2 doc 的树结构
+r($tree->getTreeStructureTest($root[2], $type[2])) && p() && e('3623:2;'); // 测试获取root 3 doc 的树结构
+r($tree->getTreeStructureTest($root[6], $type[3])) && p() && e('0'); // 测试获取root 101 task 的树结构
+r($tree->getTreeStructureTest($root[7], $type[3])) && p() && e('0'); // 测试获取root 102 task 的树结构
+r($tree->getTreeStructureTest($root[8], $type[3])) && p() && e('0'); // 测试获取root 103 task 的树结构
\ No newline at end of file
diff --git a/module/tree/test/model/ismergemodule.php b/module/tree/test/model/ismergemodule.php
new file mode 100755
index 0000000000..e26ae7702e
--- /dev/null
+++ b/module/tree/test/model/ismergemodule.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+isMergeModule();
+cid=1
+pid=1
+
+测试检查root 1 type bug 合并模块版本 >> 1
+测试检查root 2 type bug 合并模块版本 >> 1
+测试检查root 3 type bug 合并模块版本 >> 1
+测试检查root 1 type case 合并模块版本 >> 1
+测试检查root 2 type case 合并模块版本 >> 1
+测试检查root 3 type case 合并模块版本 >> 1
+测试检查root 101 type task 合并模块版本 >> 1
+测试检查root 102 type task 合并模块版本 >> 1
+测试检查root 103 type task 合并模块版本 >> 1
+
+*/
+$root = array(1, 2, 3, 101, 102, 103);
+$type = array('bug', 'case', 'task');
+
+$tree = new treeTest();
+
+r($tree->isMergeModuleTest($root[0], $type[0])) && p() && e('1'); // 测试检查root 1 type bug 合并模块版本
+r($tree->isMergeModuleTest($root[1], $type[0])) && p() && e('1'); // 测试检查root 2 type bug 合并模块版本
+r($tree->isMergeModuleTest($root[2], $type[0])) && p() && e('1'); // 测试检查root 3 type bug 合并模块版本
+r($tree->isMergeModuleTest($root[0], $type[1])) && p() && e('1'); // 测试检查root 1 type case 合并模块版本
+r($tree->isMergeModuleTest($root[1], $type[1])) && p() && e('1'); // 测试检查root 2 type case 合并模块版本
+r($tree->isMergeModuleTest($root[2], $type[1])) && p() && e('1'); // 测试检查root 3 type case 合并模块版本
+r($tree->isMergeModuleTest($root[3], $type[2])) && p() && e('1'); // 测试检查root 101 type task 合并模块版本
+r($tree->isMergeModuleTest($root[4], $type[2])) && p() && e('1'); // 测试检查root 102 type task 合并模块版本
+r($tree->isMergeModuleTest($root[5], $type[2])) && p() && e('1'); // 测试检查root 103 type task 合并模块版本
\ No newline at end of file
diff --git a/module/tree/test/model/managechild.php b/module/tree/test/model/managechild.php
new file mode 100755
index 0000000000..2485dd7505
--- /dev/null
+++ b/module/tree/test/model/managechild.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+manageChild();
+cid=1
+pid=1
+
+测试管理module 1821 的子模块 >> ,修改名称的产品子模块1,产品子模块2,新建产品子模块1,新建产品子模块2
+测试管理module 2621 的子模块 >> ,新建产品子模块3,新建产品子模块4
+测试管理module 1981 的子模块 >> ,修改名称的产品子模块81,产品子模块82,新建产品子模块5,新建产品子模块6
+测试管理module 1982 的子模块 >> ,新建产品子模块7,新建产品子模块8
+
+*/
+$root = array(1, 41);
+$parentModuleID = array(1821, 2621, 1981, 1982);
+$branch = array(0, 0, 0, 0, 0);
+$type = 'story';
+
+$modules1 = array('id2621' => '修改名称的产品子模块1', 'id2622' => '产品子模块2', '0' => '新建产品子模块1', '2' => '', '3' => '新建产品子模块2', '4' => '', '5' => '');
+$short1 = array('id2621' => '模块简称1', 'id2622' => '修改简称的模块简称2', '0' => '新建模块简称1', '2' => '新建模块简称3', '3' => '新建模块简称2', '4' => '', '5' => '');
+$order1 = array('id2621' => 10, 'id2622' => 20);
+$tree1 = array('maxOrder' => 20, 'parentModuleID' => $parentModuleID[0], 'modules' => $modules1, 'shorts' => $short1, 'order' => $order1);
+
+$modules2 = array('0' => '新建产品子模块3', '2' => '', '3' => '新建产品子模块4', '4' => '', '5' => '');
+$short2 = array('0' => '新建模块简称3', '2' => '新建模块简称5', '3' => '新建模块简称4', '4' => '', '5' => '');
+$tree2 = array('maxOrder' => 20, 'parentModuleID' => $parentModuleID[1], 'modules' => $modules2, 'shorts' => $short2);
+
+$modules3 = array('id2701' => '修改名称的产品子模块81', 'id2702' => '产品子模块82', '0' => '新建产品子模块5', '2' => '', '3' => '新建产品子模块6', '4' => '', '5' => '');
+$short3 = array('id2701' => '模块简称81', 'id2702' => '修改简称的模块简称82', '0' => '新建模块简称5', '2' => '新建模块简称7', '3' => '新建模块简称6', '4' => '', '5' => '');
+$order3 = array('id2701' => 10, 'id2702' => 20);
+$branch3 = array(0, 0, 0, 0, 0, 0);
+$tree3 = array('maxOrder' => 20, 'parentModuleID' => $parentModuleID[2], 'modules' => $modules3, 'shorts' => $short3, 'order' => $order3, 'branch' => $branch3);
+
+$modules4 = array('0' => '新建产品子模块7', '2' => '', '3' => '新建产品子模块8', '4' => '', '5' => '');
+$short4 = array('0' => '新建模块简称7', '2' => '新建模块简称9', '3' => '新建模块简称8', '4' => '', '5' => '');
+$branch4 = array(1, 1, 1, 1, 1, 1);
+$tree4 = array('maxOrder' => 20, 'parentModuleID' => $parentModuleID[3], 'modules' => $modules4, 'shorts' => $short4, 'branch' => $branch4);
+
+$tree = new treeTest();
+
+r($tree->manageChildTest($root[0], $type, $tree1)) && p() && e(',修改名称的产品子模块1,产品子模块2,新建产品子模块1,新建产品子模块2'); // 测试管理module 1821 的子模块
+r($tree->manageChildTest($root[0], $type, $tree2)) && p() && e(',新建产品子模块3,新建产品子模块4'); // 测试管理module 2621 的子模块
+r($tree->manageChildTest($root[1], $type, $tree3)) && p() && e(',修改名称的产品子模块81,产品子模块82,新建产品子模块5,新建产品子模块6'); // 测试管理module 1981 的子模块
+r($tree->manageChildTest($root[1], $type, $tree4)) && p() && e(',新建产品子模块7,新建产品子模块8'); // 测试管理module 1982 的子模块
diff --git a/module/tree/test/model/update.php b/module/tree/test/model/update.php
new file mode 100755
index 0000000000..dfb1c9ec84
--- /dev/null
+++ b/module/tree/test/model/update.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+update();
+cid=1
+pid=1
+
+测试更新module 1821 的 root >> 2,0,0,产品模块1,模块简称1
+测试更新module 1821 的 root >> 2,0,1822,产品模块1,模块简称1
+测试更新module 1821 的 root >> 2,0,1822,修改后的模块名,模块简称1
+测试更新module 1821 的 root >> 2,0,1822,修改后的模块名,修改后的简称
+测试更新module 1981 的 root >> 41,1,0,产品模块161,模块简称161
+
+*/
+$moduleID = array(1821, 1981);
+
+$changeRoot = array('root' => '2');
+$changeParent = array('parent' => 1822);
+$changeName = array('name' => '修改后的模块名');
+$changeShort = array('short' => '修改后的简称');
+$changeBranch = array('branch' => 1);
+
+$tree = new treeTest();
+
+r($tree->updateTest($moduleID[0], $changeRoot)) && p('root,branch,parent,name,short') && e('2,0,0,产品模块1,模块简称1'); // 测试更新module 1821 的 root
+r($tree->updateTest($moduleID[0], $changeParent)) && p('root,branch,parent,name,short') && e('2,0,1822,产品模块1,模块简称1'); // 测试更新module 1821 的 root
+r($tree->updateTest($moduleID[0], $changeName)) && p('root,branch,parent,name,short') && e('2,0,1822,修改后的模块名,模块简称1'); // 测试更新module 1821 的 root
+r($tree->updateTest($moduleID[0], $changeShort)) && p('root,branch,parent,name,short') && e('2,0,1822,修改后的模块名,修改后的简称'); // 测试更新module 1821 的 root
+r($tree->updateTest($moduleID[1], $changeBranch)) && p('root,branch,parent,name,short') && e('41,1,0,产品模块161,模块简称161'); // 测试更新module 1981 的 root
diff --git a/module/tree/test/model/updateorder.php b/module/tree/test/model/updateorder.php
new file mode 100755
index 0000000000..0d71bb6eb1
--- /dev/null
+++ b/module/tree/test/model/updateorder.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+updateOrder();
+cid=1
+pid=1
+
+测试更新模块顺序 1 >> ,2221,2821,1822,2822,1823,2222,2223,1824,2224
+测试更新模块顺序 2 >> ,2221,2821,1822,2822,1823,1824,2222,2223,2224
+测试更新模块顺序 3 >> ,2221,2822,1822,2821,1823,1824,2222,2223,2224
+测试更新模块顺序 4 >> ,1984,2901,2381,2902,2382,2383,2384
+
+*/
+$orders1 = array('2221' => 0, '2821' => 1, '2822' => 2, '1822' => 3, '1823' => 4, '2222' => 5, '2223' => 6, '1824' => 7, '2224' => 8);
+$orders2 = array('2221' => 0, '2821' => 1, '2822' => 2, '1822' => 3, '1823' => 4, '1824' => 5, '2222' => 6, '2223' => 7, '2224' => 8);
+$orders3 = array('2221' => 0, '2822' => 1, '2821' => 2, '1822' => 3, '1823' => 4, '1824' => 5, '2222' => 6, '2223' => 7, '2224' => 8);
+$orders4 = array('1984' => 0, '2381' => 1, '2901' => 2, '2902' => 3, '2382' => 4, '2383' => 5, '2384' => 6);
+
+$tree = new treeTest();
+
+r($tree->updateOrderTest($orders1)) && p() && e(',2221,2821,1822,2822,1823,2222,2223,1824,2224'); // 测试更新模块顺序 1
+r($tree->updateOrderTest($orders2)) && p() && e(',2221,2821,1822,2822,1823,1824,2222,2223,2224'); // 测试更新模块顺序 2
+r($tree->updateOrderTest($orders3)) && p() && e(',2221,2822,1822,2821,1823,1824,2222,2223,2224'); // 测试更新模块顺序 3
+r($tree->updateOrderTest($orders4)) && p() && e(',1984,2901,2381,2902,2382,2383,2384'); // 测试更新模块顺序 4
diff --git a/module/tree/test/tree.class.php b/module/tree/test/tree.class.php
new file mode 100644
index 0000000000..ac893f8880
--- /dev/null
+++ b/module/tree/test/tree.class.php
@@ -0,0 +1,828 @@
+objectModel = $tester->loadModel('tree');
+ }
+
+ /**
+ * Test get module by id.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return object
+ */
+ public function getByIDTest($moduleID)
+ {
+ $object = $this->objectModel->getByID($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * get all module pairs with path.
+ *
+ * @param string $type
+ * @access public
+ * @return int
+ */
+ public function getAllModulePairsTest($type = 'task')
+ {
+ $objects = $this->objectModel->getAllModulePairs($type);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test build the sql query.
+ *
+ * @param int $rootID
+ * @param string $type
+ * @param int $startModule
+ * @param string $branch
+ * @access public
+ * @return string
+ */
+ public function buildMenuQueryTest($rootID, $type, $startModule = 0, $branch = 'all')
+ {
+ $string = $this->objectModel->buildMenuQuery($rootID, $type, $startModule, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return $string;
+ }
+
+ /**
+ * Test create an option menu in html.
+ *
+ * @param int $rootID
+ * @param string $type
+ * @param int $startModule
+ * @param int $branch
+ * @access public
+ * @return int
+ */
+ public function getOptionMenuTest($rootID, $type = 'story', $startModule = 0, $branch = 0)
+ {
+ $objects = $this->objectModel->getOptionMenu($rootID, $type, $startModule, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * getModulePairsTest
+ *
+ * @param int $rootID
+ * @param string $viewType
+ * @param string $showModule
+ * @param string $extra
+ * @access public
+ * @return int
+ */
+ public function getModulePairsTest($rootID, $viewType = 'story', $showModule = 'end', $extra = '')
+ {
+ $objects = $this->objectModel->getModulePairs($rootID, $viewType, $showModule, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ return count($objects);
+ }
+
+ /**
+ * Test create an option menu of task in html.
+ *
+ * @param int $rootID
+ * @param int $productID
+ * @param int $startModule
+ * @param string $extra
+ * @access public
+ * @return string
+ */
+ public function getTaskOptionMenuTest($rootID, $productID = 0, $startModule = 0, $extra = '')
+ {
+ $objects = $this->objectModel->getTaskOptionMenu($rootID, $productID = 0, $startModule = 0, $extra = '');
+
+ if(dao::isError()) return dao::getError();
+
+ $names = '';
+ foreach($objects as $object) $names .= ',' . $object;
+ return $names;
+ }
+
+ /**
+ * Test build tree array.
+ *
+ * @param array & $&treeMenu
+ * @param array $modules
+ * @param int $moduleID
+ * @param string $moduleName
+ * @access public
+ * @return array
+ */
+ public function buildTreeArrayTest(& $treeMenu, $modules, $moduleID, $moduleName = '/')
+ {
+ $module = $this->objectModel->getByID($moduleID);
+ $moduleName = $module->name;
+
+ $this->objectModel->buildTreeArray($treeMenu, $modules, $module, $moduleName);
+
+ if(dao::isError()) return dao::getError();
+
+ $objects = array();
+ foreach($treeMenu as $id => $string) $objects[$id] = strlen($string);
+ return $objects;
+ }
+
+ /**
+ * Test get full task tree.
+ *
+ * @param int $rootID
+ * @param int $productID
+ * @access public
+ * @return string
+ */
+ public function getTaskStructureTest($rootID, $productID = 0)
+ {
+ $objects = $this->objectModel->getTaskStructure($rootID, $productID = 0);
+
+ if(dao::isError()) return dao::getError();
+
+ $child = '';
+ foreach($objects as $object)
+ {
+ if(is_array($object)) $child .= isset($object['children']) ? $object['name'] . ':' . count($object['children']) . ';' : $object['name'] . ':0';
+ if(is_object($object)) $child .= isset($object->children) ? "$object->name:" . count($object->children) . ';' : "$object->name:0";
+ }
+ return $child;
+ }
+
+ /**
+ * Test get tree structure.
+ *
+ * @param int $rootID
+ * @param string $type
+ * @access public
+ * @return string
+ */
+ public function getTreeStructureTest($rootID, $type)
+ {
+ $objects = $this->objectModel->getTreeStructure($rootID, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ $child = '';
+ foreach($objects as $object) $child .= isset($object->children) ? "$object->id:" . count($object->children) . ';' : "$object->id:0;";
+ return $child;
+ }
+
+ /**
+ * Test get execution modules.
+ *
+ * @param int $executionID
+ * @param bool $parent
+ * @param string $linkObject
+ * @access public
+ * @return string
+ */
+ public function getTaskTreeModulesTest($executionID, $parent = false, $linkObject = 'story')
+ {
+ $objects = $this->objectModel->getTaskTreeModules($executionID, $parent, $linkObject);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object;
+ return $ids;
+ }
+
+ /**
+ * Test create story link.
+ *
+ * @param int $moduleID
+ * @param array $extra
+ * @access public
+ * @return string
+ */
+ public function createStoryLinkTest($moduleID, $extra = array())
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createStoryLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(projectstory|execution|product).*(title='.*').*/", '$1 $2', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create task link.
+ *
+ * @param int $moduleID
+ * @param int $extra
+ * @access public
+ * @return string
+ */
+ public function createTaskLinkTest($moduleID, $extra)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createTaskLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*task.(\d*).*byModule.(\d*).*(title='.*').*/", '$1 $2 $3', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create requirment link.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function createRequirementLinkTest($moduleID)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createBugLink($type, $module);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create manage link.
+ *
+ * @param int $moduleID
+ * @param array $extra
+ * @access public
+ * @return string
+ */
+ public function createManageLinkTest($moduleID, $extra)
+ {
+ $type = 0;
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createManageLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ return substr($link, 0, 15);
+ }
+
+ /**
+ * Test create task manage link.
+ *
+ * @param int $moduleID
+ * @param array $extra
+ * @access public
+ * @return string
+ */
+ public function createTaskManageLinkTest($moduleID, $extra)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createTaskManageLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/((.*) ([\x{4e00}-\x{9fa5}]*)<\/a>.*)|( )/u", '$2 $3 $4', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test reate link of a bug.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function createBugLinkTest($moduleID)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createBugLink($type, $module);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Create case link.
+ *
+ * @param int $moduleID
+ * @param array $extra
+ * @access public
+ * @return string
+ */
+ public function createCaseLinkTest($moduleID, $extra = array('branchID' => 0))
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createCaseLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create test task link.
+ *
+ * @param int $moduleID
+ * @param int $extra
+ * @access public
+ * @return string
+ */
+ public function createTestTaskLinkTest($moduleID, $extra)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createTestTaskLink($type, $module, $extra);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create case lib link.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function createCaseLibLinkTest($moduleID)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createCaseLibLink($type, $module);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test create feedback link.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function createFeedbackLinkTest($moduleID)
+ {
+ $type = '';
+ $module = $this->objectModel->getByID($moduleID);
+
+ $link = $this->objectModel->createFeedbackLink($type, $module);
+
+ if(dao::isError()) return dao::getError();
+
+ $string = preg_replace("/.*(title='.*').*/", '$1', $link);
+ $string = str_replace("\n", '', $string);
+ return $string;
+ }
+
+ /**
+ * Test get sons of a module.
+ *
+ * @param int $rootID
+ * @param int $moduleID
+ * @param string $type
+ * @param int $branch
+ * @access public
+ * @return string
+ */
+ public function getSonsTest($rootID, $moduleID, $type = 'root', $branch = 0)
+ {
+ $objects = $this->objectModel->getSons($rootID, $moduleID, $type, $branch);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object->id;
+ return $ids;
+ }
+
+ /**
+ * Test get sons of a task module.
+ *
+ * @param int $rootID
+ * @param int $productID
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function getTaskSonsTest($rootID, $productID, $moduleID)
+ {
+ $objects = $this->objectModel->getTaskSons($rootID, $productID, $moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object->id;
+ return $ids;
+ }
+
+ /**
+ * Test get id list of a module's childs.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function getAllChildIdTest($moduleID)
+ {
+ $objects = $this->objectModel->getAllChildId($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $objectID) $ids .= ',' . $objectID;
+ return $ids;
+ }
+
+ /**
+ * Test get project module.
+ *
+ * @param int $projectID
+ * @param int $productID
+ * @access public
+ * @return string
+ */
+ public function getProjectModuleTest($projectID, $productID = 0)
+ {
+ $objects = $this->objectModel->getProjectModule($projectID, $productID);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $objectID) $ids .= ',' . $objectID;
+ return $ids;
+ }
+
+ /**
+ * Test get parents of a module.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return string
+ */
+ public function getParentsTest($moduleID)
+ {
+ $objects = $this->objectModel->getParents($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object->id;
+ return $ids;
+ }
+
+ /**
+ * Test get product by moduleID.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return object
+ */
+ public function getProductTest($moduleID)
+ {
+ $object = $this->objectModel->getProduct($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get the module that its type == 'story'.
+ *
+ * @param int $moduleID
+ * @access public
+ * @return int
+ */
+ public function getStoryModuleTest($moduleID)
+ {
+ $object = $this->objectModel->getStoryModule($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object;
+ }
+
+ /**
+ * Test get modules name.
+ *
+ * @param array $moduleIdList
+ * @param bool $allPath
+ * @param bool $branchPath
+ * @access public
+ * @return array
+ */
+ public function getModulesNameTest($moduleIdList, $allPath = true, $branchPath = false)
+ {
+ $objects = $this->objectModel->getModulesName($moduleIdList, $allPath, $branchPath);
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Test update modules' order.
+ *
+ * @param array $orders
+ * @access public
+ * @return string
+ */
+ public function updateOrderTest($orders)
+ {
+ $objects = $this->objectModel->updateOrder($orders);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_MODULE)->where('id')->in(array_keys($orders))->orderBy('`order` asc')->fetchAll();
+ $ids = '';
+ foreach($objects as $object) $ids .= ',' . $object->id;
+ return $ids;
+ }
+
+ /**
+ * Test manage childs of a module.
+ *
+ * @param int $rootID
+ * @param string $type
+ * @param array $param
+ * @access public
+ * @return string
+ */
+ public function manageChildTest($rootID, $type, $param)
+ {
+ $_POST['allProduct'] = 100;
+ $_POST['productModule'] = 0;
+
+ foreach($param as $key => $value) $_POST[$key] = $value;
+
+ $this->objectModel->manageChild($rootID, $type);
+
+ unset($_POST);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_MODULE)->where('parent')->eq($param['parentModuleID'])->andWhere('deleted')->eq(0)->fetchAll();
+
+ $names = '';
+ foreach($objects as $object) $names .= ',' . $object->name;
+ return $names;
+ }
+
+ /**
+ * Test update a module.
+ *
+ * @param int $moduleID
+ * @param array $param
+ * @access public
+ * @return object
+ */
+ public function updateTest($moduleID, $param)
+ {
+ $fields = array('root', 'branch', 'parent', 'name', 'short');
+ $module = $this->objectModel->getByID($moduleID);
+ foreach($fields as $field)
+ {
+ if(isset($param[$field]))
+ {
+ $_POST[$field] = $param[$field];
+ }
+ else
+ {
+ $_POST[$field] = $module->$field;
+ }
+ }
+
+ $this->objectModel->update($moduleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($moduleID);
+ return $object;
+ }
+
+ /**
+ * Test change root.
+ *
+ * @param int $moduleID
+ * @param int $oldRoot
+ * @param int $newRoot
+ * @param string $type
+ * @access public
+ * @return int
+ */
+ public function changeRootTest($moduleID, $oldRoot, $newRoot, $type)
+ {
+ $this->objectModel->changeRoot($moduleID, $oldRoot, $newRoot, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_STORY)->where('module')->eq($oldRoot)->andWhere('deleted')->eq(0)->fetchAll();
+ return $type == 'story' ? count($objects) : 0;
+ }
+
+ /**
+ * Test delete a module.
+ *
+ * @param int $moduleID
+ * @param object $null
+ * @access public
+ * @return object
+ */
+ public function deleteTest($moduleID, $null = null)
+ {
+ $this->objectModel->delete($moduleID, $null);
+
+ if(dao::isError()) return dao::getError();
+
+ $object = $this->objectModel->getByID($moduleID);
+ return $object;
+ }
+
+ /**
+ * Test fix the path, grade fields according to the id and parent fields.
+ *
+ * @param int $root
+ * @param string $type
+ * @access public
+ * @return object
+ */
+ public function fixModulePathTest($root, $type)
+ {
+ $this->objectModel->fixModulePath($root, $type);
+
+ if(dao::isError()) return dao::getError();
+
+ global $tester;
+ $objects = $tester->dao->select('*')->from(TABLE_MODULE)->where('root')->eq($root)->andWhere('type')->eq($type)->andWhere('deleted')->eq(0)->fetchAll('id');
+ return $objects;
+ }
+
+ /**
+ * Test check unique module name.
+ *
+ * @param object $module
+ * @param array $modules
+ * @param array $branches
+ * @access public
+ * @return string
+ */
+ public function checkUniqueTest($module, $modules = array(), $branches = array())
+ {
+ global $tester;
+ $modules = $tester->dao->select('id,name')->from(TABLE_MODULE)->where('id')->in($modules)->fetchPairs();
+
+ $repeatName = $this->objectModel->checkUnique($module, $modules, $branches);
+
+ if(dao::isError()) return dao::getError();
+
+ return $repeatName;
+ }
+
+ /**
+ * Test check merge module version.
+ *
+ * @param int $rootID
+ * @param string $viewType
+ * @access public
+ * @return int
+ */
+ public function isMergeModuleTest($rootID, $viewType)
+ {
+ $object = $this->objectModel->isMergeModule($rootID, $viewType);
+
+ if(dao::isError()) return dao::getError();
+
+ return $object ? 1 : 2;
+ }
+
+ /**
+ * Test get full trees.
+ *
+ * @param int $rootID
+ * @param string $viewType
+ * @param string $branchID
+ * @param int $currentModuleID
+ * @access public
+ * @return string
+ */
+ public function getProductStructureTest($rootID, $viewType, $branchID = 'all', $currentModuleID = 0)
+ {
+ $objects = $this->objectModel->getProductStructure($rootID, $viewType, $branchID, $currentModuleID);
+
+ if(dao::isError()) return dao::getError();
+
+ $child = '';
+ foreach($objects as $object) $child .= isset($object->children) ? "$object->id:" . count($object->children) . ';' : "$object->id:0;";
+ return $child;
+ }
+
+ /**
+ * Test get full task tree.
+ *
+ * @param int $root
+ * @param string $viewType
+ * @param array $keepModules
+ * @access public
+ * @return string
+ */
+ public function getDataStructureTest($root, $viewType, $keepModules = array())
+ {
+ global $tester;
+
+ $stmt = $tester->dbh->query($this->objectModel->buildMenuQuery($root, $viewType));
+
+ $objects = $this->objectModel->getDataStructure($stmt, $viewType, $keepModules);
+
+ if(dao::isError()) return dao::getError();
+
+ $child = '';
+ foreach($objects as $object) $child .= isset($object->children) ? "$object->id:" . count($object->children) . ';' : "$object->id:0;";
+ return $child;
+ }
+
+ /**
+ * Test get all doc structure.
+ *
+ * @access public
+ * @return string
+ */
+ public function getDocStructureTest()
+ {
+ $objects = $this->objectModel->getDocStructure();
+
+ if(dao::isError()) return dao::getError();
+
+ $child = '';
+ foreach($objects as $object) $child .= isset($object[0]->children) ? $object[0]->id . ':' . count($object[0]->children) . ';' : "$object[0]->id:0;";
+ return $child;
+ }
+
+ /**
+ * Create module.
+ *
+ * @param array $postData
+ * @access public
+ * @return object|bool
+ */
+ public function createModuleTest($postData)
+ {
+ global $tester;
+ foreach($postData as $key => $value) $_POST[$key] = $value;
+ $object = $this->objectModel->createModule();
+
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ return $object;
+ }
+}
diff --git a/module/tutorial/test/model/checknovice.php b/module/tutorial/test/model/checknovice.php
new file mode 100755
index 0000000000..99ed20d57e
--- /dev/null
+++ b/module/tutorial/test/model/checknovice.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+checkNovice();
+cid=1
+pid=1
+
+检查当account是admin的时候的返回值。 >> 0
+检查当->app->user->modifyPassword是不为空的时候的返回值。 >> 0
+检查当account是guest的时候的返回值。 >> 0
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->checkNoviceTest()) && p() && e('0'); //检查当account是admin的时候的返回值。
+r($tutorial->checkNoviceTest()) && p() && e('0'); //检查当$this->app->user->modifyPassword是不为空的时候的返回值。
+su('guest');
+r($tutorial->checkNoviceTest()) && p() && e('0'); //检查当account是guest的时候的返回值。
\ No newline at end of file
diff --git a/module/tutorial/test/model/getexecution.php b/module/tutorial/test/model/getexecution.php
new file mode 100755
index 0000000000..f6c865b990
--- /dev/null
+++ b/module/tutorial/test/model/getexecution.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getExecution();
+cid=1
+pid=1
+
+检查获取数据的id >> 3
+检查获取数据的PM >> admin
+检查获取数据的burns >> 35
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getExecutionTest()) && p('id') && e('3'); //检查获取数据的id
+r($tutorial->getExecutionTest()) && p('PM') && e('admin'); //检查获取数据的PM
+r($tutorial->getExecutionTest()) && p('burns:0') && e('35'); //检查获取数据的burns
\ No newline at end of file
diff --git a/module/tutorial/test/model/getexecutionpairs.php b/module/tutorial/test/model/getexecutionpairs.php
new file mode 100755
index 0000000000..820a671bbf
--- /dev/null
+++ b/module/tutorial/test/model/getexecutionpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getExecutionPairs();
+cid=1
+pid=1
+
+检查获取的数据信息 >> Test execution
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getExecutionPairsTest()) && p('3') && e('Test execution'); //检查获取的数据信息
\ No newline at end of file
diff --git a/module/tutorial/test/model/getexecutionproducts.php b/module/tutorial/test/model/getexecutionproducts.php
new file mode 100755
index 0000000000..518de12fd1
--- /dev/null
+++ b/module/tutorial/test/model/getexecutionproducts.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getExecutionProducts();
+cid=1
+pid=1
+
+测试拿到的数据是否正确 >> normal
+测试拿到的数据是否正确 >> Test branch
+测试拿到的数据是否正确 >> Test plan
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getExecutionProductsTest()) && p('1:type') && e('normal'); //测试拿到的数据是否正确
+r($tutorial->getExecutionProductsTest()) && p('1[branches]:1') && e('Test branch'); //测试拿到的数据是否正确
+r($tutorial->getExecutionProductsTest()) && p('1[plans]:1') && e('Test plan'); //测试拿到的数据是否正确
\ No newline at end of file
diff --git a/module/tutorial/test/model/getexecutionstories.php b/module/tutorial/test/model/getexecutionstories.php
new file mode 100755
index 0000000000..d84989aa6d
--- /dev/null
+++ b/module/tutorial/test/model/getexecutionstories.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getExecutionStories();
+cid=1
+pid=1
+
+检查是否获取到数据 >> wait
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getExecutionStoriesTest()) && p('1:stage') && e('wait'); //检查是否获取到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getexecutionstorypairs.php b/module/tutorial/test/model/getexecutionstorypairs.php
new file mode 100755
index 0000000000..66203680a4
--- /dev/null
+++ b/module/tutorial/test/model/getexecutionstorypairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getExecutionStoryPairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> Test story
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getExecutionStoryPairsTest()) && p('1') && e('Test story'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getmodulepairs.php b/module/tutorial/test/model/getmodulepairs.php
new file mode 100755
index 0000000000..3ee7155d9e
--- /dev/null
+++ b/module/tutorial/test/model/getmodulepairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getModulePairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> Test module
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getModulePairsTest()) && p('1') && e('Test module'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getproduct.php b/module/tutorial/test/model/getproduct.php
new file mode 100755
index 0000000000..bd4b0a26b4
--- /dev/null
+++ b/module/tutorial/test/model/getproduct.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getProduct();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> 1
+测试是否能拿到数据 >> Test branch
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProductTest()) && p('id') && e('1'); //测试是否能拿到数据
+r($tutorial->getProductTest()) && p('branches:1') && e('Test branch'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getproductpairs.php b/module/tutorial/test/model/getproductpairs.php
new file mode 100755
index 0000000000..fe6dcade15
--- /dev/null
+++ b/module/tutorial/test/model/getproductpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getProductPairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> Test product
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProductPairsTest()) && p('1') && e('Test product'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getproductstats.php b/module/tutorial/test/model/getproductstats.php
new file mode 100755
index 0000000000..29a515b7ac
--- /dev/null
+++ b/module/tutorial/test/model/getproductstats.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getProductStats();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> test
+测试是否能拿到数据 >> Test branch
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProductStatsTest()) && p('1:code') && e('test'); //测试是否能拿到数据
+r($tutorial->getProductStatsTest()) && p('1[branches]:1') && e('Test branch'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getproject.php b/module/tutorial/test/model/getproject.php
new file mode 100755
index 0000000000..c56673f485
--- /dev/null
+++ b/module/tutorial/test/model/getproject.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getProject();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> project
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProjectTest()) && p('type') && e('project'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getprojectpairs.php b/module/tutorial/test/model/getprojectpairs.php
new file mode 100755
index 0000000000..d0b6f6a7f8
--- /dev/null
+++ b/module/tutorial/test/model/getprojectpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getProjectPairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> Test Project
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProjectPairsTest()) && p('2') && e('Test Project'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getprojectstats.php b/module/tutorial/test/model/getprojectstats.php
new file mode 100755
index 0000000000..8433d5b6a0
--- /dev/null
+++ b/module/tutorial/test/model/getprojectstats.php
@@ -0,0 +1,23 @@
+#!/usr/bin/env php
+getProjectStats();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> scrum
+测试是否能拿到数据 >> 0
+测试是否能拿到数据 >> admin
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getProjectStatsTest()) && p('2:model') && e('scrum'); //测试是否能拿到数据
+r($tutorial->getProjectStatsTest()) && p('2[hours]:totalLeft') && e('0'); //测试是否能拿到数据
+r($tutorial->getProjectStatsTest()) && p('2[teamMembers]:0') && e('admin'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getstories.php b/module/tutorial/test/model/getstories.php
new file mode 100755
index 0000000000..182b6520d8
--- /dev/null
+++ b/module/tutorial/test/model/getstories.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+getStories();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> 1
+测试是否能拿到数据 >> 3
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getStoriesTest()) && p('0:module') && e('1'); //测试是否能拿到数据
+r($tutorial->getStoriesTest()) && p('1:pri') && e('3'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getteammembers.php b/module/tutorial/test/model/getteammembers.php
new file mode 100755
index 0000000000..72e440a1c7
--- /dev/null
+++ b/module/tutorial/test/model/getteammembers.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getTeamMembers();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> 10
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getTeamMembersTest()) && p('admin:days') && e('10'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getteammemberspairs.php b/module/tutorial/test/model/getteammemberspairs.php
new file mode 100755
index 0000000000..99db13dac6
--- /dev/null
+++ b/module/tutorial/test/model/getteammemberspairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getTeamMembersPairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> admin
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getTeamMembersPairsTest()) && p('admin') && e('admin'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/gettutorialed.php b/module/tutorial/test/model/gettutorialed.php
new file mode 100755
index 0000000000..1dc85ec51d
--- /dev/null
+++ b/module/tutorial/test/model/gettutorialed.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getTutorialed();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> 0
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getTutorialedTest()) && p() && e('0'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/model/getuserpairs.php b/module/tutorial/test/model/getuserpairs.php
new file mode 100755
index 0000000000..e685f575eb
--- /dev/null
+++ b/module/tutorial/test/model/getuserpairs.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getUserPairs();
+cid=1
+pid=1
+
+测试是否能拿到数据 >> admin
+
+*/
+
+$tutorial = new tutorialTest();
+
+r($tutorial->getUserPairsTest()) && p('admin') && e('admin'); //测试是否能拿到数据
\ No newline at end of file
diff --git a/module/tutorial/test/tutorial.class.php b/module/tutorial/test/tutorial.class.php
new file mode 100644
index 0000000000..b7c646167f
--- /dev/null
+++ b/module/tutorial/test/tutorial.class.php
@@ -0,0 +1,281 @@
+objectModel = $tester->loadModel('tutorial');
+ }
+
+ /**
+ * Check novice.
+ *
+ * @access public
+ * @return void
+ */
+ public function checkNoviceTest()
+ {
+ $this->app->user->modifyPassword = 1;
+ $objects = $this->objectModel->checkNovice();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial product pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getProductPairsTest()
+ {
+ $objects = $this->objectModel->getProductPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get module pairs for tutorial.
+ *
+ * @access public
+ * @return void
+ */
+ public function getModulePairsTest()
+ {
+ $objects = $this->objectModel->getModulePairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial product.
+ *
+ * @access public
+ * @return void
+ */
+ public function getProductTest()
+ {
+ $objects = $this->objectModel->getProduct();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get product stats for tutorial.
+ *
+ * @access public
+ * @return void
+ */
+ public function getProductStatsTest()
+ {
+ $objects = $this->objectModel->getProductStats();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects[0][0]['products'];
+ }
+
+ /**
+ * Get project for tutorial.
+ *
+ * @access public
+ * @return void
+ */
+ public function getProjectTest()
+ {
+ $objects = $this->objectModel->getProject();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial project pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getProjectPairsTest()
+ {
+ $objects = $this->objectModel->getProjectPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get project stats for tutorial.
+ *
+ * @param string $browseType
+ * @access public
+ * @return void
+ */
+ public function getProjectStatsTest($browseType = '')
+ {
+ $objects = $this->objectModel->getProjectStats($browseType = '');
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial stories.
+ *
+ * @access public
+ * @return void
+ */
+ public function getStoriesTest()
+ {
+ $objects = $this->objectModel->getStories();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial Execution pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getExecutionPairsTest()
+ {
+ $objects = $this->objectModel->getExecutionPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial execution.
+ *
+ * @access public
+ * @return void
+ */
+ public function getExecutionTest()
+ {
+ $objects = $this->objectModel->getExecution();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial execution products.
+ *
+ * @access public
+ * @return void
+ */
+ public function getExecutionProductsTest()
+ {
+ $objects = $this->objectModel->getExecutionProducts();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial execution stories.
+ *
+ * @access public
+ * @return void
+ */
+ public function getExecutionStoriesTest()
+ {
+ $objects = $this->objectModel->getExecutionStories();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial execution story pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getExecutionStoryPairsTest()
+ {
+ $objects = $this->objectModel->getExecutionStoryPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial team members.
+ *
+ * @access public
+ * @return void
+ */
+ public function getTeamMembersTest()
+ {
+ $objects = $this->objectModel->getTeamMembers();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get team members pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getTeamMembersPairsTest()
+ {
+ $objects = $this->objectModel->getTeamMembersPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorial user pairs.
+ *
+ * @access public
+ * @return void
+ */
+ public function getUserPairsTest()
+ {
+ $objects = $this->objectModel->getUserPairs();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+
+ /**
+ * Get tutorialed.
+ *
+ * @access public
+ * @return void
+ */
+ public function getTutorialedTest()
+ {
+ $objects = $this->objectModel->getTutorialed();
+
+ if(dao::isError()) return dao::getError();
+
+ return $objects;
+ }
+}
diff --git a/module/user/test/model/authorize.php b/module/user/test/model/authorize.php
new file mode 100755
index 0000000000..067467c603
--- /dev/null
+++ b/module/user/test/model/authorize.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+gen(300);
+
+$userGroup = zdTable('usergroup');
+$userGroup->gen(100);
+
+/**
+
+title=测试 userModel->authorize();
+cid=1
+pid=1
+
+获取用户的权限,返回权限列表,是否有产品首页权限 >> 1
+获取游客的权限,返回权限列表,是否有任务详情的权限 >> 1
+获取不存在的用户的可访问项目,返回空 >> 0
+获取空的用户的权限,返回空 >> 0
+
+*/
+
+$user = new userTest();
+
+$normalUser = $user->authorizeTest('test10');
+$guest = $user->authorizeTest('guest');
+$notExistsUser = $user->authorizeTest('sadf!!@#a');
+
+r($normalUser['rights']) && p('product:index') && e('1'); //获取用户的权限,返回权限列表,是否有产品首页权限
+r($guest['rights']) && p('task:view') && e('1'); //获取游客的权限,返回权限列表,是否有任务详情的权限
+r($notExistsUser['projects']) && p('') && e('0'); //获取不存在的用户的可访问项目,返回空
+r($user->authorizeTest('')) && p('') && e('0'); //获取空的用户的权限,返回空
diff --git a/module/user/test/model/batchcreate.php b/module/user/test/model/batchcreate.php
new file mode 100755
index 0000000000..4e11eebd13
--- /dev/null
+++ b/module/user/test/model/batchcreate.php
@@ -0,0 +1,49 @@
+#!/usr/bin/env php
+gen(1);
+
+/**
+
+title=测试 userModel->batchCreate();
+cid=1
+pid=1
+
+获取插入的第一个用户的account >> newtestuser1
+获取插入的最后一个用户的realname >> 新测试用户3
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['account'] = array(1 => 'newtestuser1', 2 => 'newtestuser2', 3 => 'newtestuser3');
+$normalUser['realname'] = array(1 => '新测试用户1', 2 => '新测试用户2', 3 => '新测试用户3');
+$normalUser['visions'] = array(1 => array('rnd'), 2 => array('rnd','lite'), 3 => array('lite'));
+$normalUser['role'] = array(1 => 'qa', 2 => 'dev', 3 => 'pm');
+$normalUser['email'] = array(1 => 'testasd@163.com', 2 => '', 3 => '11773@qq.com');
+$normalUser['password'] = array(1 => 'Zentao123@', 2 => 'Zentao123@', 3 => 'Zentao123@');
+$normalUser['dept'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['join'] = array(1 => '2023-01-01', 2 => '2023-01-01', 3 => '2023-01-01');
+$normalUser['type'] = array(1 => 'inside', 2 => 'inside', 3 => 'inside');
+$normalUser['group'] = array(1 => array(), 2 => array(), 3 => array());
+$normalUser['gender'] = array(1 => 'm', 2 => 'm', 3 => 'm');
+$normalUser['compnay'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['commiter'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['skype'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['qq'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['dingding'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['weixin'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['mobile'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['slack'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['whatsapp'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['phone'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['address'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['zipcode'] = array(1 => '', 2 => '', 3 => '');
+$normalUser['ditto'] = array(1 => '', 2 => '', 3 => '');
+
+r($user->batchCreateUserTest($normalUser)) && p('0:account') && e('newtestuser1'); //获取插入的第一个用户的account
+zdTable('user')->gen(1);
+r($user->batchCreateUserTest($normalUser)) && p('2:realname') && e('新测试用户3'); //获取插入的最后一个用户的realname
diff --git a/module/user/test/model/batchedit.php b/module/user/test/model/batchedit.php
new file mode 100755
index 0000000000..32396f7217
--- /dev/null
+++ b/module/user/test/model/batchedit.php
@@ -0,0 +1,44 @@
+#!/usr/bin/env php
+gen(15);
+
+/**
+
+title=测试 userModel->batchEdit();
+cid=1
+pid=1
+
+获取编辑后的第一个用户的account >> newtestuser1
+获取编辑的最后一个用户的真实姓名 >> 新测试用户3
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['account'] = array(8 => 'newtestuser1', 9 => 'newtestuser2', 10 => 'newtestuser3');
+$normalUser['realname'] = array(8 => '新测试用户1', 9 => '新测试用户2', 10 => '新测试用户3');
+$normalUser['commiter'] = array(8 => 'user1', 9 => 'user2', 10 => 'user3');
+$normalUser['email'] = array(8 => 'testasd@163.com', 9 => '', 10 => '11773@qq.com');
+$normalUser['type'] = array(8 => 'inside', 9 => 'inside', 10 => 'outside');
+$normalUser['join'] = array(8 => '0000-00-00', 9 => '0000-00-00', 10 => '0000-00-00');
+$normalUser['skype'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['qq'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['dingding'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['weixin'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['mobile'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['slack'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['whatsapp'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['phone'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['address'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['zipcode'] = array(8 => '', 9 => '', 10 => '');
+$normalUser['visions'] = array(8 => array('rnd'), 9 => array('rnd', 'lite'), 10 => array('lite'));
+$normalUser['dept'] = array(8 => '1', 9 => '1', 10 => '1');
+$normalUser['role'] = array(8 => 'qa', 9 => 'dev', 10 => 'pm');
+$normalUser['password'] = array(8 => 'e10adc3949ba59abbe56e057f20f883e', 9 => 'e10adc3949ba59abbe56e057f20f883e', 10 => 'e10adc3949ba59abbe56e057f20f883e');
+
+r($user->batchEditUserTest($normalUser)) && p('8:account') && e('newtestuser1'); //获取编辑后的第一个用户的account
+r($user->batchEditUserTest($normalUser)) && p('10:realname') && e('新测试用户3'); //获取编辑的最后一个用户的真实姓名
diff --git a/module/user/test/model/checklocked.php b/module/user/test/model/checklocked.php
new file mode 100755
index 0000000000..efecefe3f2
--- /dev/null
+++ b/module/user/test/model/checklocked.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+id->range('1-10');
+$user->account->range('admin,user1,user2,user3,user4,user5,user6,user7,user8,user9');
+$user->password->range('a0933c1218a4e745bacdcf572b10eba7');
+$user->realname->range('1-10')->prefix('用户');
+$user->locked->range("$now:2m")->type('timestamp')->format('YY/MM/DD hh:mm:ss');
+$user->gen(10);
+
+/**
+
+title=测试 userModel->cleanLocked();
+cid=1
+pid=1
+
+获取user2账号的锁定状态 >> unlocked
+获取user7账号的锁定状态 >> locked
+
+*/
+
+$user = new userTest();
+$userLocked = $user->checkLockedTest('user2');
+$unlockedUser = $user->checkLockedTest('user7');
+
+r($userLocked) && p() && e('unlocked'); //获取user2账号的锁定状态
+r($unlockedUser) && p() && e('locked'); //获取user7账号的锁定状态
diff --git a/module/user/test/model/checkpassword.php b/module/user/test/model/checkpassword.php
new file mode 100755
index 0000000000..a1b4b84781
--- /dev/null
+++ b/module/user/test/model/checkpassword.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel->checkPassword();
+cid=1
+pid=1
+
+正常的用户密码 >> 无报错
+两次密码不相同的情况 >> 两次密码应该相同。
+密码强度小于系统设定 >> 密码必须6位及以上,且包含大小写字母、数字。
+使用常见简单密码,给出错误提示 >> 密码不能使用【123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123】这些常用弱口令。
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['password1'] = 'Adsd@#!%qaz';
+$normalUser['password2'] = 'Adsd@#!%qaz';
+$normalUser['passwordStrength'] = 1;
+
+$weakPassword = $normalUser;
+$weakPassword['passwordStrength'] = '0';
+
+$differentPassword = $normalUser;
+$differentPassword['password2'] = '!@#!@#asfasf';
+
+$simplePassword = $normalUser;
+$simplePassword['password1'] = 'e10adc3949ba59abbe56e057f20f883e';
+$simplePassword['password2'] = 'e10adc3949ba59abbe56e057f20f883e';
+
+r($user->checkPasswordTest($normalUser)) && p('password') && e('无报错'); //正常的用户密码
+r($user->checkPasswordTest($differentPassword)) && p('password1:0') && e('两次密码应该相同。
'); //两次密码不相同的情况
+r($user->checkPasswordTest($weakPassword)) && p('password1:0') && e('密码必须6位及以上,且包含大小写字母、数字。
'); //密码强度小于系统设定
+r($user->checkPasswordTest($simplePassword)) && p('password1') && e('密码不能使用【123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123】这些常用弱口令。'); //使用常见简单密码,给出错误提示
diff --git a/module/user/test/model/checkproductpriv.php b/module/user/test/model/checkproductpriv.php
new file mode 100755
index 0000000000..6274890f83
--- /dev/null
+++ b/module/user/test/model/checkproductpriv.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('user')->gen(200);
+su('admin');
+
+/**
+
+title=测试 userModel->checkProductPriv();
+cid=1
+pid=1
+
+传入admin,判断admin用户是否有权限 >> 1
+传入产品、用户名,判断test3用户是否对此产品有权限 >> 0
+传入产品、用户名,判断test2用户是否对此产品有权限 >> 1
+传入产品、用户名、干系人、白名单,判断user10用户是否对此产品有权限 >> 1
+传入产品、用户名、干系人、白名单,判断user60用户是否对此产品有权限 >> 0
+
+*/
+
+$user = new userTest();
+$product = new stdclass();
+$product->id = 1;
+$product->name = '测试产品';
+$product->PO = 'test2';
+$product->openedBy = 'pm1';
+
+$stakeholders['user10'] = 'user10';
+$whiteList['user60'] = 'user60';
+
+r($user->checkProductPrivTest('', 'admin')) && p() && e('1'); //传入admin,判断admin用户是否有权限
+r($user->checkProductPrivTest($product, 'test3')) && p() && e('0'); //传入产品、用户名,判断test3用户是否对此产品有权限
+r($user->checkProductPrivTest($product, 'test2')) && p() && e('1'); //传入产品、用户名,判断test2用户是否对此产品有权限
+r($user->checkProductPrivTest($product, 'user10', array(), array(), $stakeholders)) && p() && e('1'); //传入产品、用户名、干系人、白名单,判断user10用户是否对此产品有权限
+r($user->checkProductPrivTest($product, 'user60', array(), array(), $stakeholders, array(), $whiteList)) && p() && e('0'); //传入产品、用户名、干系人、白名单,判断user60用户是否对此产品有权限
diff --git a/module/user/test/model/checkprogrampriv.php b/module/user/test/model/checkprogrampriv.php
new file mode 100755
index 0000000000..71854ea096
--- /dev/null
+++ b/module/user/test/model/checkprogrampriv.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+checkProgramPriv();
+cid=1
+pid=1
+
+传入admin,判断admin用户是否有权限 >> 1
+传入项目集、用户名,判断test3用户是否对此项目集有权限 >> 0
+传入项目集、用户名,判断test2用户是否对此项目集有权限 >> 1
+传入项目集、用户名、干系人、白名单,判断user10用户是否对此项目集有权限 >> 1
+传入项目集、用户名、干系人、白名单,判断user60用户是否对此项目集有权限 >> 1
+
+*/
+
+$user = new userTest();
+$program = new stdclass();
+$program->id = 1;
+$program->name = '测试项目集';
+$program->PM = 'test2';
+$program->openedBy = 'pm1';
+
+$stakeholders['user10'] = 'user10';
+$whiteList['user60'] = 'user60';
+
+r($user->checkProgramPrivTest('', 'admin')) && p() && e('1'); //传入admin,判断admin用户是否有权限
+r($user->checkProgramPrivTest($program, 'test3')) && p() && e('0'); //传入项目集、用户名,判断test3用户是否对此项目集有权限
+r($user->checkProgramPrivTest($program, 'test2')) && p() && e('1'); //传入项目集、用户名,判断test2用户是否对此项目集有权限
+r($user->checkProgramPrivTest($program, 'user10', $stakeholders, array())) && p() && e('1'); //传入项目集、用户名、干系人、白名单,判断user10用户是否对此项目集有权限
+r($user->checkProgramPrivTest($program, 'user60', $stakeholders, $whiteList)) && p() && e('1'); //传入项目集、用户名、干系人、白名单,判断user60用户是否对此项目集有权限
\ No newline at end of file
diff --git a/module/user/test/model/checkprojectpriv.php b/module/user/test/model/checkprojectpriv.php
new file mode 100755
index 0000000000..841dfb355a
--- /dev/null
+++ b/module/user/test/model/checkprojectpriv.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+checkProjectPriv();
+cid=1
+pid=1
+
+传入admin,判断admin用户是否有权限 >> 1
+传入项目、用户名,判断test3用户是否对此项目有权限 >> 0
+传入项目、用户名,判断test2用户是否对此项目有权限 >> 1
+传入项目、用户名、干系人、白名单,判断user10用户是否对此项目有权限 >> 1
+传入项目、用户名、干系人、白名单,判断user60用户是否对此项目有权限 >> 1
+
+*/
+
+$user = new userTest();
+$project = new stdclass();
+$project->id = 10;
+$project->name = '测试项目';
+$project->PM = 'test2';
+$project->openedBy = 'pm1';
+
+$stakeholders['user10'] = 'user10';
+$whiteList['user60'] = 'user60';
+
+r($user->checkProjectPrivTest('', 'admin')) && p() && e('1'); //传入admin,判断admin用户是否有权限
+r($user->checkProjectPrivTest($project, 'test3')) && p() && e('0'); //传入项目、用户名,判断test3用户是否对此项目有权限
+r($user->checkProjectPrivTest($project, 'test2')) && p() && e('1'); //传入项目、用户名,判断test2用户是否对此项目有权限
+r($user->checkProjectPrivTest($project, 'user10', $stakeholders, array(), array())) && p() && e('1'); //传入项目、用户名、干系人、白名单,判断user10用户是否对此项目有权限
+r($user->checkProjectPrivTest($project, 'user60', $stakeholders, array(), $whiteList)) && p() && e('1'); //传入项目、用户名、干系人、白名单,判断user60用户是否对此项目有权限
\ No newline at end of file
diff --git a/module/user/test/model/checksprintpriv.php b/module/user/test/model/checksprintpriv.php
new file mode 100755
index 0000000000..2c6c33f530
--- /dev/null
+++ b/module/user/test/model/checksprintpriv.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+checkSprintPriv();
+cid=1
+pid=1
+
+传入admin,判断admin用户是否有权限 >> 1
+传入执行、用户名,判断test3用户是否对此执行有权限 >> 0
+传入执行、用户名,判断test2用户是否对此执行有权限 >> 1
+传入执行、用户名、干系人、白名单,判断user10用户是否对此执行有权限 >> 1
+传入执行、用户名、干系人、白名单,判断user60用户是否对此执行有权限 >> 1
+
+*/
+
+$user = new userTest();
+$sprint = new stdclass();
+$sprint->id = 1;
+$sprint->name = '测试项目集';
+$sprint->PM = 'test2';
+$sprint->openedBy = 'pm1';
+
+$stakeholders['user10'] = 'user10';
+$whiteList['user60'] = 'user60';
+
+r($user->checkSprintPrivTest('', 'admin')) && p() && e('1'); //传入admin,判断admin用户是否有权限
+r($user->checkSprintPrivTest($sprint, 'test3')) && p() && e('0'); //传入执行、用户名,判断test3用户是否对此执行有权限
+r($user->checkSprintPrivTest($sprint, 'test2')) && p() && e('1'); //传入执行、用户名,判断test2用户是否对此执行有权限
+r($user->checkSprintPrivTest($sprint, 'user10', $stakeholders, array(), array())) && p() && e('1'); //传入执行、用户名、干系人、白名单,判断user10用户是否对此执行有权限
+r($user->checkSprintPrivTest($sprint, 'user60', $stakeholders, array(), $whiteList)) && p() && e('1'); //传入执行、用户名、干系人、白名单,判断user60用户是否对此执行有权限
\ No newline at end of file
diff --git a/module/user/test/model/cleanlocked.php b/module/user/test/model/cleanlocked.php
new file mode 100755
index 0000000000..728e05904c
--- /dev/null
+++ b/module/user/test/model/cleanlocked.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+id->range('1-10');
+$user->account->range('admin,user1,user2,user3,user4,user5,user6,user7,user8,user9');
+$user->password->range('a0933c1218a4e745bacdcf572b10eba7');
+$user->realname->range('1-10')->prefix('用户');
+$user->locked->range("20230110 143412")->type('timestamp')->format('YY/MM/DD hh:mm:ss');
+$user->gen(10);
+
+/**
+
+title=测试 userModel->cleanLocked();
+cid=1
+pid=1
+
+获取user8的锁定时间,重置为空 >> success
+获取不存在的用户的锁定时间,返回空 >> fail
+
+*/
+
+$user = new userTest();
+$userLocked = $user->cleanLockedTest('user8');
+$notExistUser = $user->cleanLockedTest('test999');
+
+r($userLocked) && p('') && e('success'); //获取user8的锁定时间,重置为空
+r($notExistUser) && p('') && e('fail'); //获取不存在的用户的锁定时间,返回空
diff --git a/module/user/test/model/computepasswordstrengthtest.php b/module/user/test/model/computepasswordstrengthtest.php
new file mode 100755
index 0000000000..20a32eb74c
--- /dev/null
+++ b/module/user/test/model/computepasswordstrengthtest.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+computePasswordStrength();
+cid=1
+pid=1
+
+获取空密码的强度 >> 0
+获取[123456]密码的强度 >> 0
+获取[qaz123]密码的强度 >> 0
+获取[qaz67911334]密码的强度 >> 1
+获取[ZENFBQfy3xpRarDwG3lN]密码的强度 >> 2
+
+*/
+
+$user = new userTest();
+
+r($user->computePasswordStrengthTest('')) && p() && e('0'); //获取空密码的强度
+r($user->computePasswordStrengthTest('123456')) && p() && e('0'); //获取[123456]密码的强度
+r($user->computePasswordStrengthTest('qaz123')) && p() && e('0'); //获取[qaz123]密码的强度
+r($user->computePasswordStrengthTest('qaz67911334')) && p() && e('1'); //获取[qaz67911334]密码的强度
+r($user->computePasswordStrengthTest('ZENFBQfy3xpRarDwG3lN')) && p() && e('2'); //获取[ZENFBQfy3xpRarDwG3lN]密码的强度
\ No newline at end of file
diff --git a/module/user/test/model/computeuserview.php b/module/user/test/model/computeuserview.php
new file mode 100755
index 0000000000..54d66481b7
--- /dev/null
+++ b/module/user/test/model/computeuserview.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+computeUserView();
+cid=1
+pid=1
+
+获取强制计算前admin账户可见的前两个项目集ID >> ,1,2,
+获取强制计算前admin账户可见的前两个产品ID >> ,1,2,
+获取强制计算前admin账户可见的前两个项目集ID >> 5,6
+获取强制计算前admin账户可见的前两个产品ID >> ,11,12,
+获取user10账户可见的产品ID >> 99
+获取test2账户可见的项目ID >> ,12
+用户名传null,则获取当前登录账户的views >> admin
+
+*/
+
+$user = new userTest();
+
+$adminViews = $user->computeUserViewTest('admin');
+$adminPrograms = substr($adminViews->programs, 0, 5);
+$adminProducts = substr($adminViews->products, 0, 5);
+
+$computedAdminViews = $user->computeUserViewTest('admin', true);
+$computedAdminPrograms = substr($computedAdminViews->programs, 0, 3);
+$computedAdminProducts = substr($computedAdminViews->products, 0, 5);
+
+r($adminPrograms) && p() && e(',1,2,'); //获取强制计算前admin账户可见的前两个项目集ID
+r($adminProducts) && p() && e(',1,2,'); //获取强制计算前admin账户可见的前两个产品ID
+r($computedAdminPrograms) && p() && e('5,6'); //获取强制计算前admin账户可见的前两个项目集ID
+r($computedAdminProducts) && p() && e(',11,12,'); //获取强制计算前admin账户可见的前两个产品ID
+r($user->computeUserViewTest('user10')) && p('products') && e('99'); //获取user10账户可见的产品ID
+r($user->computeUserViewTest('test2')) && p('projects') && e(',12'); //获取test2账户可见的项目ID
+r($user->computeUserViewTest(null)) && p('account') && e('admin'); //用户名传null,则获取当前登录账户的views
diff --git a/module/user/test/model/create.php b/module/user/test/model/create.php
new file mode 100755
index 0000000000..749f04162e
--- /dev/null
+++ b/module/user/test/model/create.php
@@ -0,0 +1,59 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel->createUser();
+cid=1
+pid=1
+
+密码较弱的情况 >> 密码必须6位及以上,且包含大小写字母、数字。
+Visions为空的情况 >> 『界面类型』不能为空。
+用户名为空的情况 >> 『用户名』不能为空。
+用户名特殊的情况 >> 『用户名』只能是字母、数字或下划线的组合三位以上。
+两次密码不相同的情况 >> 两次密码应该相同。
+插入重复的用户名,返回报错信息 >> 『用户名』已经有『admin』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+正常插入用户,返回新插入的真实姓名 >> 新的测试用户
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['account'] = 'newtestuser';
+$normalUser['realname'] = '新的测试用户';
+$normalUser['password1'] = '6da8a7c05e2aa1774828500a8370feea';
+$normalUser['password2'] = '6da8a7c05e2aa1774828500a8370feea';
+$normalUser['type'] = 'inside';
+$normalUser['passwordStrength'] = 1;
+$normalUser['visions'] = 'rnd';
+
+$weakPassword = $normalUser;
+$weakPassword['passwordStrength'] = 0;
+
+$emptyVisions = $normalUser;
+unset($emptyVisions['visions']);
+
+$emptyAccount = $normalUser;
+$emptyAccount['account'] = '';
+
+$specialAccount = $normalUser;
+$specialAccount['account'] = 'sa!@#asdf';
+
+$differentPassword = $normalUser;
+$differentPassword['password2'] = 'asfjhjkahf9012asd123';
+
+$existUser = $normalUser;
+$existUser['account'] = 'admin';
+
+r($user->createUserTest($weakPassword)) && p('password1:0') && e(' 密码必须6位及以上,且包含大小写字母、数字。
'); //密码较弱的情况
+r($user->createUserTest($emptyVisions)) && p('visions:0') && e('『界面类型』不能为空。'); //Visions为空的情况
+r($user->createUserTest($emptyAccount)) && p('account:0') && e('『用户名』不能为空。'); //用户名为空的情况
+r($user->createUserTest($specialAccount)) && p('account:0') && e('『用户名』只能是字母、数字或下划线的组合三位以上。'); //用户名特殊的情况
+r($user->createUserTest($differentPassword)) && p('password1:0') && e('两次密码应该相同。
'); //两次密码不相同的情况
+r($user->createUserTest($existUser)) && p('account:0') && e('『用户名』已经有『admin』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); //插入重复的用户名,返回报错信息
+r($user->createUserTest($normalUser)) && p('realname') && e('新的测试用户'); //正常插入用户,返回新插入的真实姓名
diff --git a/module/user/test/model/createcontactlist.php b/module/user/test/model/createcontactlist.php
new file mode 100755
index 0000000000..edc8bee58e
--- /dev/null
+++ b/module/user/test/model/createcontactlist.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+gen(1);
+
+/**
+
+title=测试 userModel->createContactList();
+cid=1
+pid=1
+
+插入一条联系人列表,获取插入的联系人列表名称 >> 新的列表名称1
+插入一条联系人列表,获取插入的联系人列表 >> admin,test2,user29,assfjg
+列表名称重复时 >> 『列表名称』已经有『新的列表名称1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+列表名称为空时 >> 1
+
+*/
+
+$userTester = new userTest();
+$userList = array('admin,test2,user29,assfjg');
+
+r($userTester->createContactListTest('新的列表名称1', $userList)) && p('listName') && e('新的列表名称1'); // 插入一条联系人列表,获取插入的联系人列表名称
+r($userTester->createContactListTest('新的列表名称2', $userList)) && p('userList') && e('admin,test2,user29,assfjg'); // 插入一条联系人列表,获取插入的联系人列表名称
+r($userTester->createContactListTest('新的列表名称1', array())) && p('message[listName]:0') && e('『列表名称』已经有『新的列表名称1』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。'); // 列表名称重复时
+r($userTester->createContactListTest('', array())) && p('message[listName]:0') && e('1'); // 列表名称为空时
diff --git a/module/user/test/model/data/sql/bug.sql b/module/user/test/model/data/sql/bug.sql
new file mode 100644
index 0000000000..3043b50396
--- /dev/null
+++ b/module/user/test/model/data/sql/bug.sql
@@ -0,0 +1,121 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_bug`
+--
+
+DROP TABLE IF EXISTS `zt_bug`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_bug` (
+ `id` mediumint(8) NOT NULL AUTO_INCREMENT,
+ `project` mediumint(8) unsigned NOT NULL,
+ `product` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `injection` mediumint(8) unsigned NOT NULL,
+ `identify` mediumint(8) unsigned NOT NULL,
+ `branch` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `module` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `execution` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `plan` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `story` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `storyVersion` smallint(6) NOT NULL DEFAULT 1,
+ `task` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `toTask` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `toStory` mediumint(8) NOT NULL DEFAULT 0,
+ `title` varchar(255) NOT NULL,
+ `keywords` varchar(255) NOT NULL,
+ `severity` tinyint(4) NOT NULL DEFAULT 0,
+ `pri` tinyint(3) unsigned NOT NULL,
+ `type` varchar(30) NOT NULL DEFAULT '',
+ `os` varchar(255) NOT NULL DEFAULT '',
+ `browser` varchar(255) NOT NULL DEFAULT '',
+ `hardware` varchar(30) NOT NULL,
+ `found` varchar(30) NOT NULL DEFAULT '',
+ `steps` mediumtext NOT NULL,
+ `status` enum('active','resolved','closed') NOT NULL DEFAULT 'active',
+ `subStatus` varchar(30) NOT NULL DEFAULT '',
+ `color` char(7) NOT NULL,
+ `confirmed` tinyint(1) NOT NULL DEFAULT 0,
+ `activatedCount` smallint(6) NOT NULL,
+ `activatedDate` datetime NOT NULL,
+ `feedbackBy` varchar(100) NOT NULL,
+ `notifyEmail` varchar(100) NOT NULL,
+ `mailto` text DEFAULT NULL,
+ `openedBy` varchar(30) NOT NULL DEFAULT '',
+ `openedDate` datetime NOT NULL,
+ `openedBuild` varchar(255) NOT NULL,
+ `assignedTo` varchar(30) NOT NULL DEFAULT '',
+ `assignedDate` datetime NOT NULL,
+ `deadline` date NOT NULL,
+ `resolvedBy` varchar(30) NOT NULL DEFAULT '',
+ `resolution` varchar(30) NOT NULL DEFAULT '',
+ `resolvedBuild` varchar(30) NOT NULL DEFAULT '',
+ `resolvedDate` datetime NOT NULL,
+ `closedBy` varchar(30) NOT NULL DEFAULT '',
+ `closedDate` datetime NOT NULL,
+ `duplicateBug` mediumint(8) unsigned NOT NULL,
+ `linkBug` varchar(255) NOT NULL,
+ `case` mediumint(8) unsigned NOT NULL,
+ `caseVersion` smallint(6) NOT NULL DEFAULT 1,
+ `feedback` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `result` mediumint(8) unsigned NOT NULL,
+ `repo` mediumint(8) unsigned NOT NULL,
+ `mr` mediumint(8) unsigned NOT NULL,
+ `entry` text NOT NULL,
+ `lines` varchar(10) NOT NULL,
+ `v1` varchar(40) NOT NULL,
+ `v2` varchar(40) NOT NULL,
+ `repoType` varchar(30) NOT NULL DEFAULT '',
+ `issueKey` varchar(50) NOT NULL DEFAULT '',
+ `testtask` mediumint(8) unsigned NOT NULL,
+ `lastEditedBy` varchar(30) NOT NULL DEFAULT '',
+ `lastEditedDate` datetime NOT NULL,
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `product` (`product`),
+ KEY `execution` (`execution`),
+ KEY `status` (`status`),
+ KEY `plan` (`plan`),
+ KEY `story` (`story`),
+ KEY `case` (`case`),
+ KEY `toStory` (`toStory`),
+ KEY `result` (`result`),
+ KEY `assignedTo` (`assignedTo`)
+) ENGINE=InnoDB AUTO_INCREMENT=501 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_bug`
+--
+
+LOCK TABLES `zt_bug` WRITE;
+/*!40000 ALTER TABLE `zt_bug` DISABLE KEYS */;
+INSERT INTO `zt_bug` VALUES (1,11,1,0,0,0,1821,101,1,2,1,0,0,0,'BUG1','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-14 15:33:08','1','admin','2022-12-14 00:00:00','2022-12-14','','','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(2,11,1,0,0,0,1822,101,1,6,1,0,0,0,'BUG2','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-15 15:33:08','0','admin','2022-12-15 00:00:00','2022-12-15','','','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(3,11,1,0,0,0,1823,101,1,10,1,0,0,0,'BUG3','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-16 15:33:08','1','admin','2022-12-16 00:00:00','2022-12-16','','','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(4,12,2,0,0,0,1825,102,4,14,1,0,0,0,'BUG4','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-17 15:33:08','trunk','admin','2022-12-17 00:00:00','2022-12-17','','','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(5,12,2,0,0,0,1826,102,4,18,1,0,0,0,'BUG5','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-18 15:33:08','trunk','admin','2022-12-18 00:00:00','2022-12-18','','','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(6,12,2,0,0,0,1827,102,4,22,1,0,0,0,'BUG6','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-19 15:33:08','trunk','admin','2022-12-19 00:00:00','2022-12-19','','','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(7,13,3,0,0,0,1831,103,7,26,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();7','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-20 15:33:08','trunk','admin','2022-12-20 00:00:00','2022-12-20','','','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(8,13,3,0,0,0,1832,103,7,30,1,0,0,0,'bug8','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-21 15:33:08','trunk','admin','2022-12-21 00:00:00','2022-12-21','','','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(9,13,3,0,0,0,1833,103,7,34,1,0,0,0,'BUG9','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-22 15:33:08','trunk','admin','2022-12-22 00:00:00','2022-12-22','','','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(10,14,4,0,0,0,0,104,0,38,1,0,0,0,'BUG10','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-23 15:33:08','trunk','admin','2022-12-23 00:00:00','2022-12-23','','','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(11,14,4,0,0,0,0,104,0,42,1,0,0,0,'BUG11','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-24 15:33:08','trunk','admin','2022-12-24 00:00:00','2022-12-24','','','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(12,14,4,0,0,0,0,104,0,46,1,0,0,0,'BUG12','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-25 15:33:08','trunk','admin','2022-12-25 00:00:00','2022-12-25','','','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(13,15,5,0,0,0,0,105,0,50,1,0,0,0,'BUG13','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-26 15:33:08','trunk','admin','2022-12-26 00:00:00','2022-12-26','','','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(14,15,5,0,0,0,0,105,0,54,1,0,0,0,'BUG14','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-27 15:33:08','trunk','admin','2022-12-27 00:00:00','2022-12-27','','','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(15,15,5,0,0,0,0,105,0,58,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();15','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-28 15:33:08','trunk','admin','2022-12-28 00:00:00','2022-12-28','','','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(16,16,6,0,0,0,0,106,0,62,1,0,0,0,'bug16','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-29 15:33:08','trunk','admin','2022-12-29 00:00:00','2022-12-29','','','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(17,16,6,0,0,0,0,106,0,66,1,0,0,0,'BUG17','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-30 15:33:08','trunk','admin','2022-12-30 00:00:00','2022-12-30','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(18,16,6,0,0,0,0,106,0,70,1,0,0,0,'BUG18','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-31 15:33:08','trunk','admin','2022-12-31 00:00:00','2022-12-31','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(19,17,7,0,0,0,0,107,0,74,1,0,0,0,'BUG19','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-01 15:33:08','trunk','admin','2023-01-01 00:00:00','2023-01-01','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(20,17,7,0,0,0,0,107,0,78,1,0,0,0,'BUG20','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-02 15:33:08','trunk','admin','2023-01-02 00:00:00','2023-01-02','','','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(21,17,7,0,0,0,0,107,0,82,1,0,0,0,'BUG21','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-03 15:33:08','trunk','admin','2023-01-03 00:00:00','2023-01-03','','','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(22,18,8,0,0,0,0,108,0,86,1,0,0,0,'BUG22','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-04 15:33:08','trunk','admin','2023-01-04 00:00:00','2023-01-04','','','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(23,18,8,0,0,0,0,108,0,90,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();23','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-05 15:33:08','trunk','admin','2023-01-05 00:00:00','2023-01-05','','','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(24,18,8,0,0,0,0,108,0,94,1,0,0,0,'bug24','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-06 15:33:08','trunk','admin','2023-01-06 00:00:00','2023-01-06','','','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(25,19,9,0,0,0,0,109,0,98,1,0,0,0,'BUG25','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-07 15:33:08','trunk','admin','2023-01-07 00:00:00','2023-01-07','','','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(26,19,9,0,0,0,0,109,0,102,1,0,0,0,'BUG26','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-08 15:33:08','trunk','admin','2023-01-08 00:00:00','2023-01-08','','','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(27,19,9,0,0,0,0,109,0,106,1,0,0,0,'BUG27','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-09 15:33:08','trunk','admin','2023-01-09 00:00:00','2023-01-09','','','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(28,20,10,0,0,0,0,110,0,110,1,0,0,0,'BUG28','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-10 15:33:08','trunk','admin','2023-01-10 00:00:00','2023-01-10','','','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(29,20,10,0,0,0,0,110,0,114,1,0,0,0,'BUG29','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-11 15:33:08','trunk','admin','2023-01-11 00:00:00','2023-01-11','','','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(30,20,10,0,0,0,0,110,0,118,1,0,0,0,'BUG30','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-12 15:33:08','trunk','admin','2023-01-12 00:00:00','2023-01-12','','','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(31,21,11,0,0,0,0,111,0,122,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();31','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-13 15:33:08','trunk','dev1','2023-01-13 00:00:00','2023-01-13','','','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(32,21,11,0,0,0,0,111,0,126,1,0,0,0,'bug32','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-14 15:33:08','trunk','dev1','2023-01-14 00:00:00','2023-01-14','','','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(33,21,11,0,0,0,0,111,0,130,1,0,0,0,'BUG33','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-15 15:33:08','trunk','dev1','2023-01-15 00:00:00','2023-01-15','','','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(34,22,12,0,0,0,0,112,0,134,1,0,0,0,'BUG34','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-16 15:33:08','trunk','dev1','2023-01-16 00:00:00','2023-01-16','','','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(35,22,12,0,0,0,0,112,0,138,1,0,0,0,'BUG35','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-17 15:33:08','trunk','dev1','2023-01-17 00:00:00','2023-01-17','','','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(36,22,12,0,0,0,0,112,0,142,1,0,0,0,'BUG36','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-18 15:33:08','trunk','dev1','2023-01-18 00:00:00','2023-01-18','','','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(37,23,13,0,0,0,0,113,0,146,1,0,0,0,'BUG37','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-19 15:33:08','trunk','dev1','2023-01-19 00:00:00','2023-01-19','','','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(38,23,13,0,0,0,0,113,0,150,1,0,0,0,'BUG38','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-20 15:33:08','trunk','dev1','2023-01-20 00:00:00','2023-01-20','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(39,23,13,0,0,0,0,113,0,154,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();39','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-14 15:33:08','trunk','dev1','2022-12-14 00:00:00','2022-12-14','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(40,24,14,0,0,0,0,114,0,158,1,0,0,0,'bug40','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-15 15:33:08','trunk','dev1','2022-12-15 00:00:00','2022-12-15','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(41,24,14,0,0,0,0,114,0,162,1,0,0,0,'BUG41','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-16 15:33:08','trunk','dev1','2022-12-16 00:00:00','2022-12-16','','','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(42,24,14,0,0,0,0,114,0,166,1,0,0,0,'BUG42','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-17 15:33:08','trunk','dev1','2022-12-17 00:00:00','2022-12-17','','','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(43,25,15,0,0,0,0,115,0,170,1,0,0,0,'BUG43','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-18 15:33:08','trunk','dev1','2022-12-18 00:00:00','2022-12-18','','','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(44,25,15,0,0,0,0,115,0,174,1,0,0,0,'BUG44','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-19 15:33:08','trunk','dev1','2022-12-19 00:00:00','2022-12-19','','','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(45,25,15,0,0,0,0,115,0,178,1,0,0,0,'BUG45','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-20 15:33:08','trunk','dev1','2022-12-20 00:00:00','2022-12-20','','','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(46,26,16,0,0,0,0,116,0,182,1,0,0,0,'BUG46','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-21 15:33:08','trunk','dev1','2022-12-21 00:00:00','2022-12-21','','','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(47,26,16,0,0,0,0,116,0,186,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();47','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-22 15:33:08','trunk','dev1','2022-12-22 00:00:00','2022-12-22','','','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(48,26,16,0,0,0,0,116,0,190,1,0,0,0,'bug48','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-23 15:33:08','trunk','dev1','2022-12-23 00:00:00','2022-12-23','','','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(49,27,17,0,0,0,0,117,0,194,1,0,0,0,'BUG49','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-24 15:33:08','trunk','dev1','2022-12-24 00:00:00','2022-12-24','','','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(50,27,17,0,0,0,0,117,0,198,1,0,0,0,'BUG50','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-25 15:33:08','trunk','dev1','2022-12-25 00:00:00','2022-12-25','','','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(51,27,17,0,0,0,0,117,0,202,1,0,0,0,'BUG51','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-26 15:33:08','trunk','dev1','2022-12-26 00:00:00','2022-12-26','$assignedTo','bydesign','','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(52,28,18,0,0,0,0,118,0,206,1,0,0,0,'BUG52','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-27 15:33:08','trunk','dev1','2022-12-27 00:00:00','2022-12-27','$assignedTo','bydesign','','2023-01-12 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(53,28,18,0,0,0,0,118,0,210,1,0,0,0,'BUG53','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-28 15:33:08','trunk','dev1','2022-12-28 00:00:00','2022-12-28','$assignedTo','bydesign','','2023-01-11 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(54,28,18,0,0,0,0,118,0,214,1,0,0,0,'BUG54','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-29 15:33:08','trunk','dev1','2022-12-29 00:00:00','2022-12-29','$assignedTo','bydesign','','2023-01-10 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(55,29,19,0,0,0,0,119,0,218,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();55','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-30 15:33:08','trunk','dev1','2022-12-30 00:00:00','2022-12-30','$assignedTo','bydesign','','2023-01-09 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(56,29,19,0,0,0,0,119,0,222,1,0,0,0,'bug56','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-31 15:33:08','trunk','dev1','2022-12-31 00:00:00','2022-12-31','$assignedTo','duplicate','trunk','2023-01-08 00:00:00','admin','0000-00-00 00:00:00',1,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(57,29,19,0,0,0,0,119,0,226,1,0,0,0,'BUG57','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-01 15:33:08','trunk','dev1','2023-01-01 00:00:00','2023-01-01','$assignedTo','duplicate','trunk','2023-01-07 00:00:00','admin','0000-00-00 00:00:00',2,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(58,30,20,0,0,0,0,120,0,230,1,0,0,0,'BUG58','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-02 15:33:08','trunk','dev1','2023-01-02 00:00:00','2023-01-02','$assignedTo','duplicate','trunk','2023-01-06 00:00:00','admin','0000-00-00 00:00:00',3,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(59,30,20,0,0,0,0,120,0,234,1,0,0,0,'BUG59','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-03 15:33:08','trunk','dev1','2023-01-03 00:00:00','2023-01-03','$assignedTo','duplicate','trunk','2023-01-05 00:00:00','admin','0000-00-00 00:00:00',4,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(60,30,20,0,0,0,0,120,0,238,1,0,0,0,'BUG60','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-04 15:33:08','trunk','dev1','2023-01-04 00:00:00','2023-01-04','$assignedTo','duplicate','trunk','2023-01-04 00:00:00','admin','0000-00-00 00:00:00',5,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(61,31,21,0,0,0,0,121,0,242,1,0,0,0,'BUG61','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-05 15:33:08','trunk','test1','2023-01-05 00:00:00','2023-01-05','$assignedTo','external','trunk','2023-01-03 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(62,31,21,0,0,0,0,121,0,246,1,0,0,0,'BUG62','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-06 15:33:08','trunk','test1','2023-01-06 00:00:00','2023-01-06','$assignedTo','external','trunk','2023-01-02 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(63,31,21,0,0,0,0,121,0,250,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();63','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-07 15:33:08','trunk','test1','2023-01-07 00:00:00','2023-01-07','$assignedTo','external','trunk','2023-01-01 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(64,32,22,0,0,0,0,122,0,254,1,0,0,0,'bug64','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-08 15:33:08','trunk','test1','2023-01-08 00:00:00','2023-01-08','$assignedTo','external','trunk','2023-01-21 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(65,32,22,0,0,0,0,122,0,258,1,0,0,0,'BUG65','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-09 15:33:08','trunk','test1','2023-01-09 00:00:00','2023-01-09','$assignedTo','external','trunk','2023-01-20 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(66,32,22,0,0,0,0,122,0,262,1,0,0,0,'BUG66','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-10 15:33:08','trunk','test1','2023-01-10 00:00:00','2023-01-10','$assignedTo','fixed','trunk','2023-01-19 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(67,33,23,0,0,0,0,123,0,266,1,0,0,0,'BUG67','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-11 15:33:08','trunk','test1','2023-01-11 00:00:00','2023-01-11','$assignedTo','fixed','trunk','2023-01-18 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(68,33,23,0,0,0,0,123,0,270,1,0,0,0,'BUG68','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-12 15:33:08','trunk','test1','2023-01-12 00:00:00','2023-01-12','$assignedTo','fixed','trunk','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(69,33,23,0,0,0,0,123,0,274,1,0,0,0,'BUG69','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-13 15:33:08','trunk','test1','2023-01-13 00:00:00','2023-01-13','$assignedTo','fixed','trunk','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(70,34,24,0,0,0,0,124,0,278,1,0,0,0,'BUG70','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-14 15:33:08','trunk','test1','2023-01-14 00:00:00','2023-01-14','$assignedTo','fixed','trunk','2023-01-15 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(71,34,24,0,0,0,0,124,0,282,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();71','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-15 15:33:08','trunk','test1','2023-01-15 00:00:00','2023-01-15','$assignedTo','notrepro','','2023-01-14 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(72,34,24,0,0,0,0,124,0,286,1,0,0,0,'bug72','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-16 15:33:08','trunk','test1','2023-01-16 00:00:00','2023-01-16','$assignedTo','notrepro','','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(73,35,25,0,0,0,0,125,0,290,1,0,0,0,'BUG73','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-17 15:33:08','trunk','test1','2023-01-17 00:00:00','2023-01-17','$assignedTo','postponed','','2023-01-12 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(74,35,25,0,0,0,0,125,0,294,1,0,0,0,'BUG74','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-18 15:33:08','trunk','test1','2023-01-18 00:00:00','2023-01-18','$assignedTo','postponed','','2023-01-11 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(75,35,25,0,0,0,0,125,0,298,1,0,0,0,'BUG75','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-19 15:33:08','trunk','test1','2023-01-19 00:00:00','2023-01-19','$assignedTo','postponed','','2023-01-10 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(76,36,26,0,0,0,0,126,0,302,1,0,0,0,'BUG76','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-20 15:33:08','trunk','test1','2023-01-20 00:00:00','2023-01-20','$assignedTo','willnotfix','','2023-01-09 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(77,36,26,0,0,0,0,126,0,306,1,0,0,0,'BUG77','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-14 15:33:08','trunk','test1','2022-12-14 00:00:00','2022-12-14','$assignedTo','willnotfix','','2023-01-08 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(78,36,26,0,0,0,0,126,0,310,1,0,0,0,'BUG78','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-15 15:33:08','trunk','test1','2022-12-15 00:00:00','2022-12-15','$assignedTo','willnotfix','','2023-01-07 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(79,37,27,0,0,0,0,127,0,314,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();79','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-16 15:33:08','trunk','test1','2022-12-16 00:00:00','2022-12-16','$assignedTo','willnotfix','','2023-01-06 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(80,37,27,0,0,0,0,127,0,318,1,0,0,0,'bug80','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-17 15:33:08','trunk','test1','2022-12-17 00:00:00','2022-12-17','$assignedTo','willnotfix','','2023-01-05 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(81,37,27,0,0,0,0,127,0,322,1,0,0,0,'BUG81','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-18 15:33:08','trunk','test1','2022-12-18 00:00:00','2022-12-18','admin','fixed','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(82,38,28,0,0,0,0,128,0,326,1,0,0,0,'BUG82','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-19 15:33:08','trunk','test1','2022-12-19 00:00:00','2022-12-19','admin','fixed','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(83,38,28,0,0,0,0,128,0,330,1,0,0,0,'BUG83','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-20 15:33:08','trunk','test1','2022-12-20 00:00:00','2022-12-20','admin','fixed','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(84,38,28,0,0,0,0,128,0,334,1,0,0,0,'BUG84','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-21 15:33:08','trunk','test1','2022-12-21 00:00:00','2022-12-21','admin','fixed','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(85,39,29,0,0,0,0,129,0,338,1,0,0,0,'BUG85','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-22 15:33:08','trunk','test1','2022-12-22 00:00:00','2022-12-22','admin','fixed','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(86,39,29,0,0,0,0,129,0,342,1,0,0,0,'BUG86','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-23 15:33:08','trunk','test1','2022-12-23 00:00:00','2022-12-23','admin','fixed','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(87,39,29,0,0,0,0,129,0,346,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();87','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-24 15:33:08','trunk','test1','2022-12-24 00:00:00','2022-12-24','admin','fixed','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(88,40,30,0,0,0,0,130,0,350,1,0,0,0,'bug88','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-25 15:33:08','trunk','test1','2022-12-25 00:00:00','2022-12-25','admin','fixed','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(89,40,30,0,0,0,0,130,0,354,1,0,0,0,'BUG89','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-26 15:33:08','trunk','test1','2022-12-26 00:00:00','2022-12-26','admin','fixed','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(90,40,30,0,0,0,0,130,0,358,1,0,0,0,'BUG90','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-27 15:33:08','trunk','test1','2022-12-27 00:00:00','2022-12-27','admin','fixed','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(91,41,31,0,0,0,0,131,0,362,1,0,0,0,'BUG91','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-28 15:33:08','trunk','','2022-12-28 00:00:00','2022-12-28','admin','bydesign','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(92,41,31,0,0,0,0,131,0,366,1,0,0,0,'BUG92','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-29 15:33:08','trunk','','2022-12-29 00:00:00','2022-12-29','admin','external','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(93,41,31,0,0,0,0,131,0,370,1,0,0,0,'BUG93','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-30 15:33:08','trunk','','2022-12-30 00:00:00','2022-12-30','admin','notrepro','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(94,42,32,0,0,0,0,132,0,374,1,0,0,0,'BUG94','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2022-12-31 15:33:08','trunk','','2022-12-31 00:00:00','2022-12-31','admin','postponed','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(95,42,32,0,0,0,0,132,0,378,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();95','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-01 15:33:08','trunk','','2023-01-01 00:00:00','2023-01-01','admin','willnotfix','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(96,42,32,0,0,0,0,132,0,382,1,0,0,0,'bug96','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-02 15:33:08','trunk','','2023-01-02 00:00:00','2023-01-02','admin','duplicate','trunk','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(97,43,33,0,0,0,0,133,0,386,1,0,0,0,'BUG97','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-03 15:33:08','trunk','','2023-01-03 00:00:00','2023-01-03','admin','duplicate','trunk','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(98,43,33,0,0,0,0,133,0,390,1,0,0,0,'BUG98','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-04 15:33:08','trunk','','2023-01-04 00:00:00','2023-01-04','admin','duplicate','trunk','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(99,43,33,0,0,0,0,133,0,394,1,0,0,0,'BUG99','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-05 15:33:08','trunk','','2023-01-05 00:00:00','2023-01-05','admin','duplicate','trunk','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(100,44,34,0,0,0,0,134,0,398,1,0,0,0,'BUG100','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','admin','admin','2023-01-06 15:33:08','trunk','','2023-01-06 00:00:00','2023-01-06','admin','duplicate','trunk','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(101,44,34,0,0,0,0,134,0,2,1,0,0,0,'BUG101','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','1','','2023-01-07 00:00:00','2023-01-07','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',10,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(102,44,34,0,0,0,0,134,0,6,1,0,0,0,'BUG102','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','0','','2023-01-08 00:00:00','2023-01-08','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',11,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(103,45,35,0,0,0,0,135,0,10,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();103','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','1','','2023-01-09 00:00:00','2023-01-09','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',12,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(104,45,35,0,0,0,0,135,0,14,1,0,0,0,'bug104','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','','2023-01-10 00:00:00','2023-01-10','','','','2023-01-02 00:00:00','','0000-00-00 00:00:00',13,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(105,45,35,0,0,0,0,135,0,18,1,0,0,0,'BUG105','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','','2023-01-11 00:00:00','2023-01-11','','','','2023-01-01 00:00:00','','0000-00-00 00:00:00',14,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(106,46,36,0,0,0,0,136,0,22,1,0,0,0,'BUG106','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','','2023-01-12 00:00:00','2023-01-12','','','','2023-01-21 00:00:00','','0000-00-00 00:00:00',15,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(107,46,36,0,0,0,0,136,0,26,1,0,0,0,'BUG107','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','','2023-01-13 00:00:00','2023-01-13','','','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(108,46,36,0,0,0,0,136,0,30,1,0,0,0,'BUG108','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','','2023-01-14 00:00:00','2023-01-14','','','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(109,47,37,0,0,0,0,137,0,34,1,0,0,0,'BUG109','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','','2023-01-15 00:00:00','2023-01-15','','','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(110,47,37,0,0,0,0,137,0,38,1,0,0,0,'BUG110','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','','2023-01-16 00:00:00','2023-01-16','','','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(111,47,37,0,0,0,0,137,0,42,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();111','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-17 15:33:08','trunk','admin','2023-01-17 00:00:00','2023-01-17','','','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(112,48,38,0,0,0,0,138,0,46,1,0,0,0,'bug112','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-18 15:33:08','trunk','admin','2023-01-18 00:00:00','2023-01-18','','','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(113,48,38,0,0,0,0,138,0,50,1,0,0,0,'BUG113','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-19 15:33:08','trunk','admin','2023-01-19 00:00:00','2023-01-19','','','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(114,48,38,0,0,0,0,138,0,54,1,0,0,0,'BUG114','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-20 15:33:08','trunk','admin','2023-01-20 00:00:00','2023-01-20','','','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(115,49,39,0,0,0,0,139,0,58,1,0,0,0,'BUG115','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-14 15:33:08','trunk','admin','2022-12-14 00:00:00','2022-12-14','','','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(116,49,39,0,0,0,0,139,0,62,1,0,0,0,'BUG116','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-15 15:33:08','trunk','admin','2022-12-15 00:00:00','2022-12-15','','','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(117,49,39,0,0,0,0,139,0,66,1,0,0,0,'BUG117','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-16 15:33:08','trunk','admin','2022-12-16 00:00:00','2022-12-16','','','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(118,50,40,0,0,0,0,140,0,70,1,0,0,0,'BUG118','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-17 15:33:08','trunk','admin','2022-12-17 00:00:00','2022-12-17','','','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(119,50,40,0,0,0,0,140,0,74,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();119','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-18 15:33:08','trunk','admin','2022-12-18 00:00:00','2022-12-18','','','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(120,50,40,0,0,0,0,140,0,78,1,0,0,0,'bug120','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-19 15:33:08','trunk','admin','2022-12-19 00:00:00','2022-12-19','','','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(121,51,41,0,0,0,0,141,0,82,1,0,0,0,'BUG121','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-20 15:33:08','trunk','admin','2022-12-20 00:00:00','2022-12-20','','','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(122,51,41,0,0,1,0,141,0,86,1,0,0,0,'BUG122','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-21 15:33:08','trunk','admin','2022-12-21 00:00:00','2022-12-21','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(123,51,41,0,0,2,0,141,0,90,1,0,0,0,'BUG123','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-22 15:33:08','trunk','admin','2022-12-22 00:00:00','2022-12-22','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(124,52,42,0,0,0,0,142,0,94,1,0,0,0,'BUG124','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-23 15:33:08','trunk','admin','2022-12-23 00:00:00','2022-12-23','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(125,52,42,0,0,3,0,142,0,98,1,0,0,0,'BUG125','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-24 15:33:08','trunk','admin','2022-12-24 00:00:00','2022-12-24','','','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(126,52,42,0,0,4,0,142,0,102,1,0,0,0,'BUG126','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-25 15:33:08','trunk','admin','2022-12-25 00:00:00','2022-12-25','','','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(127,53,43,0,0,0,0,143,0,106,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();127','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-26 15:33:08','trunk','admin','2022-12-26 00:00:00','2022-12-26','','','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(128,53,43,0,0,5,0,143,0,110,1,0,0,0,'bug128','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-27 15:33:08','trunk','admin','2022-12-27 00:00:00','2022-12-27','','','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(129,53,43,0,0,6,0,143,0,114,1,0,0,0,'BUG129','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-28 15:33:08','trunk','admin','2022-12-28 00:00:00','2022-12-28','','','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(130,54,44,0,0,0,0,144,0,118,1,0,0,0,'BUG130','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-29 15:33:08','trunk','admin','2022-12-29 00:00:00','2022-12-29','','','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(131,54,44,0,0,7,0,144,0,122,1,0,0,0,'BUG131','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-30 15:33:08','trunk','dev1','2022-12-30 00:00:00','2022-12-30','','','','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(132,54,44,0,0,8,0,144,0,126,1,0,0,0,'BUG132','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-31 15:33:08','trunk','dev1','2022-12-31 00:00:00','2022-12-31','','','','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(133,55,45,0,0,0,0,145,0,130,1,0,0,0,'BUG133','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-01 15:33:08','trunk','dev1','2023-01-01 00:00:00','2023-01-01','','','','2023-01-15 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(134,55,45,0,0,9,0,145,0,134,1,0,0,0,'BUG134','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-02 15:33:08','trunk','dev1','2023-01-02 00:00:00','2023-01-02','','','','2023-01-14 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(135,55,45,0,0,10,0,145,0,138,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();135','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-03 15:33:08','trunk','dev1','2023-01-03 00:00:00','2023-01-03','','','','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(136,56,46,0,0,0,0,146,0,142,1,0,0,0,'bug136','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-04 15:33:08','trunk','dev1','2023-01-04 00:00:00','2023-01-04','','','','2023-01-12 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(137,56,46,0,0,0,0,146,0,146,1,0,0,0,'BUG137','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-05 15:33:08','trunk','dev1','2023-01-05 00:00:00','2023-01-05','','','','2023-01-11 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(138,56,46,0,0,0,0,146,0,150,1,0,0,0,'BUG138','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-06 15:33:08','trunk','dev1','2023-01-06 00:00:00','2023-01-06','','','','2023-01-10 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(139,57,47,0,0,0,0,147,0,154,1,0,0,0,'BUG139','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','trunk','dev1','2023-01-07 00:00:00','2023-01-07','','','','2023-01-09 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(140,57,47,0,0,0,0,147,0,158,1,0,0,0,'BUG140','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','trunk','dev1','2023-01-08 00:00:00','2023-01-08','','','','2023-01-08 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(141,57,47,0,0,0,0,147,0,162,1,0,0,0,'BUG141','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','trunk','dev1','2023-01-09 00:00:00','2023-01-09','','','','2023-01-07 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(142,58,48,0,0,0,0,148,0,166,1,0,0,0,'BUG142','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','dev1','2023-01-10 00:00:00','2023-01-10','','','','2023-01-06 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(143,58,48,0,0,0,0,148,0,170,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();143','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','dev1','2023-01-11 00:00:00','2023-01-11','','','','2023-01-05 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(144,58,48,0,0,0,0,148,0,174,1,0,0,0,'bug144','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','dev1','2023-01-12 00:00:00','2023-01-12','','','','2023-01-04 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(145,59,49,0,0,0,0,149,0,178,1,0,0,0,'BUG145','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','dev1','2023-01-13 00:00:00','2023-01-13','','','','2023-01-03 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(146,59,49,0,0,0,0,149,0,182,1,0,0,0,'BUG146','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','dev1','2023-01-14 00:00:00','2023-01-14','','','','2023-01-02 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(147,59,49,0,0,0,0,149,0,186,1,0,0,0,'BUG147','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','dev1','2023-01-15 00:00:00','2023-01-15','','','','2023-01-01 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(148,60,50,0,0,0,0,150,0,190,1,0,0,0,'BUG148','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','dev1','2023-01-16 00:00:00','2023-01-16','','','','2023-01-21 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(149,60,50,0,0,0,0,150,0,194,1,0,0,0,'BUG149','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-17 15:33:08','trunk','dev1','2023-01-17 00:00:00','2023-01-17','','','','2023-01-20 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(150,60,50,0,0,0,0,150,0,198,1,0,0,0,'BUG150','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-18 15:33:08','trunk','dev1','2023-01-18 00:00:00','2023-01-18','','','','2023-01-19 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(151,61,51,0,0,0,0,151,0,202,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();151','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-19 15:33:08','trunk','test1','2023-01-19 00:00:00','2023-01-19','$assignedTo','bydesign','','2023-01-18 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(152,61,51,0,0,0,0,151,0,206,1,0,0,0,'bug152','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-20 15:33:08','trunk','test1','2023-01-20 00:00:00','2023-01-20','$assignedTo','bydesign','','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(153,61,51,0,0,0,0,151,0,210,1,0,0,0,'BUG153','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-14 15:33:08','trunk','test1','2022-12-14 00:00:00','2022-12-14','$assignedTo','bydesign','','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(154,62,52,0,0,0,0,152,0,214,1,0,0,0,'BUG154','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-15 15:33:08','trunk','test1','2022-12-15 00:00:00','2022-12-15','$assignedTo','bydesign','','2023-01-15 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(155,62,52,0,0,0,0,152,0,218,1,0,0,0,'BUG155','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-16 15:33:08','trunk','test1','2022-12-16 00:00:00','2022-12-16','$assignedTo','bydesign','','2023-01-14 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(156,62,52,0,0,0,0,152,0,222,1,0,0,0,'BUG156','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-17 15:33:08','trunk','test1','2022-12-17 00:00:00','2022-12-17','$assignedTo','duplicate','trunk','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(157,63,53,0,0,0,0,153,0,226,1,0,0,0,'BUG157','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-18 15:33:08','trunk','test1','2022-12-18 00:00:00','2022-12-18','$assignedTo','duplicate','trunk','2023-01-12 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(158,63,53,0,0,0,0,153,0,230,1,0,0,0,'BUG158','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-19 15:33:08','trunk','test1','2022-12-19 00:00:00','2022-12-19','$assignedTo','duplicate','trunk','2023-01-11 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(159,63,53,0,0,0,0,153,0,234,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();159','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-20 15:33:08','trunk','test1','2022-12-20 00:00:00','2022-12-20','$assignedTo','duplicate','trunk','2023-01-10 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(160,64,54,0,0,0,0,154,0,238,1,0,0,0,'bug160','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-21 15:33:08','trunk','test1','2022-12-21 00:00:00','2022-12-21','$assignedTo','duplicate','trunk','2023-01-09 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(161,64,54,0,0,0,0,154,0,242,1,0,0,0,'BUG161','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-22 15:33:08','trunk','test1','2022-12-22 00:00:00','2022-12-22','$assignedTo','external','trunk','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(162,64,54,0,0,0,0,154,0,246,1,0,0,0,'BUG162','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-23 15:33:08','trunk','test1','2022-12-23 00:00:00','2022-12-23','$assignedTo','external','trunk','2023-01-07 00:00:00','','0000-00-00 00:00:00',1,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(163,65,55,0,0,0,0,155,0,250,1,0,0,0,'BUG163','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-24 15:33:08','trunk','test1','2022-12-24 00:00:00','2022-12-24','$assignedTo','external','trunk','2023-01-06 00:00:00','','0000-00-00 00:00:00',2,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(164,65,55,0,0,0,0,155,0,254,1,0,0,0,'BUG164','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-25 15:33:08','trunk','test1','2022-12-25 00:00:00','2022-12-25','$assignedTo','external','trunk','2023-01-05 00:00:00','','0000-00-00 00:00:00',3,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(165,65,55,0,0,0,0,155,0,258,1,0,0,0,'BUG165','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-26 15:33:08','trunk','test1','2022-12-26 00:00:00','2022-12-26','$assignedTo','external','trunk','2023-01-04 00:00:00','','0000-00-00 00:00:00',4,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(166,66,56,0,0,0,0,156,0,262,1,0,0,0,'BUG166','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-27 15:33:08','trunk','test1','2022-12-27 00:00:00','2022-12-27','$assignedTo','fixed','trunk','2023-01-03 00:00:00','','0000-00-00 00:00:00',5,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(167,66,56,0,0,0,0,156,0,266,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();167','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-28 15:33:08','trunk','test1','2022-12-28 00:00:00','2022-12-28','$assignedTo','fixed','trunk','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(168,66,56,0,0,0,0,156,0,270,1,0,0,0,'bug168','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-29 15:33:08','trunk','test1','2022-12-29 00:00:00','2022-12-29','$assignedTo','fixed','trunk','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(169,67,57,0,0,0,0,157,0,274,1,0,0,0,'BUG169','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-30 15:33:08','trunk','test1','2022-12-30 00:00:00','2022-12-30','$assignedTo','fixed','trunk','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(170,67,57,0,0,0,0,157,0,278,1,0,0,0,'BUG170','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-31 15:33:08','trunk','test1','2022-12-31 00:00:00','2022-12-31','$assignedTo','fixed','trunk','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(171,67,57,0,0,0,0,157,0,282,1,0,0,0,'BUG171','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-01 15:33:08','trunk','','2023-01-01 00:00:00','2023-01-01','$assignedTo','notrepro','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(172,68,58,0,0,0,0,158,0,286,1,0,0,0,'BUG172','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-02 15:33:08','trunk','','2023-01-02 00:00:00','2023-01-02','$assignedTo','notrepro','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(173,68,58,0,0,0,0,158,0,290,1,0,0,0,'BUG173','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-03 15:33:08','trunk','','2023-01-03 00:00:00','2023-01-03','$assignedTo','postponed','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(174,68,58,0,0,0,0,158,0,294,1,0,0,0,'BUG174','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-04 15:33:08','trunk','','2023-01-04 00:00:00','2023-01-04','$assignedTo','postponed','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(175,69,59,0,0,0,0,159,0,298,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();175','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-05 15:33:08','trunk','','2023-01-05 00:00:00','2023-01-05','$assignedTo','postponed','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(176,69,59,0,0,0,0,159,0,302,1,0,0,0,'bug176','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-06 15:33:08','trunk','','2023-01-06 00:00:00','2023-01-06','$assignedTo','willnotfix','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(177,69,59,0,0,0,0,159,0,306,1,0,0,0,'BUG177','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','trunk','','2023-01-07 00:00:00','2023-01-07','$assignedTo','willnotfix','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(178,70,60,0,0,0,0,160,0,310,1,0,0,0,'BUG178','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','trunk','','2023-01-08 00:00:00','2023-01-08','$assignedTo','willnotfix','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(179,70,60,0,0,0,0,160,0,314,1,0,0,0,'BUG179','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','trunk','','2023-01-09 00:00:00','2023-01-09','$assignedTo','willnotfix','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(180,70,60,0,0,0,0,160,0,318,1,0,0,0,'BUG180','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','','2023-01-10 00:00:00','2023-01-10','$assignedTo','willnotfix','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(181,71,61,0,0,0,0,161,0,322,1,0,0,0,'BUG181','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','closed','2023-01-11 00:00:00','2023-01-11','admin','fixed','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(182,71,61,0,0,0,0,161,0,326,1,0,0,0,'BUG182','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','closed','2023-01-12 00:00:00','2023-01-12','admin','fixed','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(183,71,61,0,0,0,0,161,0,330,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();183','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','closed','2023-01-13 00:00:00','2023-01-13','admin','fixed','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(184,72,62,0,0,0,0,162,0,334,1,0,0,0,'bug184','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','closed','2023-01-14 00:00:00','2023-01-14','admin','fixed','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(185,72,62,0,0,0,0,162,0,338,1,0,0,0,'BUG185','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','closed','2023-01-15 00:00:00','2023-01-15','admin','fixed','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(186,72,62,0,0,0,0,162,0,342,1,0,0,0,'BUG186','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','closed','2023-01-16 00:00:00','2023-01-16','admin','fixed','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(187,73,63,0,0,0,0,163,0,346,1,0,0,0,'BUG187','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-17 15:33:08','trunk','closed','2023-01-17 00:00:00','2023-01-17','admin','fixed','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(188,73,63,0,0,0,0,163,0,350,1,0,0,0,'BUG188','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-18 15:33:08','trunk','closed','2023-01-18 00:00:00','2023-01-18','admin','fixed','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(189,73,63,0,0,0,0,163,0,354,1,0,0,0,'BUG189','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-19 15:33:08','trunk','closed','2023-01-19 00:00:00','2023-01-19','admin','fixed','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(190,74,64,0,0,0,0,164,0,358,1,0,0,0,'BUG190','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-20 15:33:08','trunk','closed','2023-01-20 00:00:00','2023-01-20','admin','fixed','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(191,74,64,0,0,0,0,164,0,362,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();191','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-14 15:33:08','trunk','closed','2022-12-14 00:00:00','2022-12-14','admin','bydesign','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(192,74,64,0,0,0,0,164,0,366,1,0,0,0,'bug192','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-15 15:33:08','trunk','closed','2022-12-15 00:00:00','2022-12-15','admin','external','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(193,75,65,0,0,0,0,165,0,370,1,0,0,0,'BUG193','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-16 15:33:08','trunk','closed','2022-12-16 00:00:00','2022-12-16','admin','notrepro','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(194,75,65,0,0,0,0,165,0,374,1,0,0,0,'BUG194','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-17 15:33:08','trunk','closed','2022-12-17 00:00:00','2022-12-17','admin','postponed','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(195,75,65,0,0,0,0,165,0,378,1,0,0,0,'BUG195','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-18 15:33:08','trunk','closed','2022-12-18 00:00:00','2022-12-18','admin','willnotfix','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(196,76,66,0,0,0,0,166,0,382,1,0,0,0,'BUG196','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-19 15:33:08','trunk','closed','2022-12-19 00:00:00','2022-12-19','admin','duplicate','trunk','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(197,76,66,0,0,0,0,166,0,386,1,0,0,0,'BUG197','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-20 15:33:08','trunk','closed','2022-12-20 00:00:00','2022-12-20','admin','duplicate','trunk','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(198,76,66,0,0,0,0,166,0,390,1,0,0,0,'BUG198','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-21 15:33:08','trunk','closed','2022-12-21 00:00:00','2022-12-21','admin','duplicate','trunk','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(199,77,67,0,0,0,0,167,0,394,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();199','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-22 15:33:08','trunk','closed','2022-12-22 00:00:00','2022-12-22','admin','duplicate','trunk','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(200,77,67,0,0,0,0,167,0,398,1,0,0,0,'bug200','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-23 15:33:08','trunk','closed','2022-12-23 00:00:00','2022-12-23','admin','duplicate','trunk','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(201,77,67,0,0,0,0,167,0,2,1,0,0,0,'BUG201','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-24 15:33:08','1','admin','2022-12-24 00:00:00','2022-12-24','','','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(202,78,68,0,0,0,0,168,0,6,1,0,0,0,'BUG202','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-25 15:33:08','0','admin','2022-12-25 00:00:00','2022-12-25','','','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(203,78,68,0,0,0,0,168,0,10,1,0,0,0,'BUG203','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-26 15:33:08','1','admin','2022-12-26 00:00:00','2022-12-26','','','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(204,78,68,0,0,0,0,168,0,14,1,0,0,0,'BUG204','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-27 15:33:08','trunk','admin','2022-12-27 00:00:00','2022-12-27','','','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(205,79,69,0,0,0,0,169,0,18,1,0,0,0,'BUG205','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-28 15:33:08','trunk','admin','2022-12-28 00:00:00','2022-12-28','','','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(206,79,69,0,0,0,0,169,0,22,1,0,0,0,'BUG206','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-29 15:33:08','trunk','admin','2022-12-29 00:00:00','2022-12-29','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(207,79,69,0,0,0,0,169,0,26,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();207','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-30 15:33:08','trunk','admin','2022-12-30 00:00:00','2022-12-30','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',10,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(208,80,70,0,0,0,0,170,0,30,1,0,0,0,'bug208','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-31 15:33:08','trunk','admin','2022-12-31 00:00:00','2022-12-31','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',11,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(209,80,70,0,0,0,0,170,0,34,1,0,0,0,'BUG209','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-01 15:33:08','trunk','admin','2023-01-01 00:00:00','2023-01-01','','','','2023-01-02 00:00:00','','0000-00-00 00:00:00',12,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(210,80,70,0,0,0,0,170,0,38,1,0,0,0,'BUG210','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-02 15:33:08','trunk','admin','2023-01-02 00:00:00','2023-01-02','','','','2023-01-01 00:00:00','','0000-00-00 00:00:00',13,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(211,81,71,0,0,0,0,171,0,42,1,0,0,0,'BUG211','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-03 15:33:08','trunk','admin','2023-01-03 00:00:00','2023-01-03','','','','2023-01-21 00:00:00','admin','0000-00-00 00:00:00',14,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(212,81,71,0,0,0,0,171,0,46,1,0,0,0,'BUG212','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-04 15:33:08','trunk','admin','2023-01-04 00:00:00','2023-01-04','','','','2023-01-20 00:00:00','admin','0000-00-00 00:00:00',15,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(213,81,71,0,0,0,0,171,0,50,1,0,0,0,'BUG213','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-05 15:33:08','trunk','admin','2023-01-05 00:00:00','2023-01-05','','','','2023-01-19 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(214,82,72,0,0,0,0,172,0,54,1,0,0,0,'BUG214','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-06 15:33:08','trunk','admin','2023-01-06 00:00:00','2023-01-06','','','','2023-01-18 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(215,82,72,0,0,0,0,172,0,58,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();215','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','trunk','admin','2023-01-07 00:00:00','2023-01-07','','','','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(216,82,72,0,0,0,0,172,0,62,1,0,0,0,'bug216','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','trunk','admin','2023-01-08 00:00:00','2023-01-08','','','','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(217,83,73,0,0,0,0,173,0,66,1,0,0,0,'BUG217','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','trunk','admin','2023-01-09 00:00:00','2023-01-09','','','','2023-01-15 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(218,83,73,0,0,0,0,173,0,70,1,0,0,0,'BUG218','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','admin','2023-01-10 00:00:00','2023-01-10','','','','2023-01-14 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(219,83,73,0,0,0,0,173,0,74,1,0,0,0,'BUG219','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','admin','2023-01-11 00:00:00','2023-01-11','','','','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(220,84,74,0,0,0,0,174,0,78,1,0,0,0,'BUG220','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','admin','2023-01-12 00:00:00','2023-01-12','','','','2023-01-12 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(221,84,74,0,0,0,0,174,0,82,1,0,0,0,'BUG221','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','admin','2023-01-13 00:00:00','2023-01-13','','','','2023-01-11 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(222,84,74,0,0,0,0,174,0,86,1,0,0,0,'BUG222','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','admin','2023-01-14 00:00:00','2023-01-14','','','','2023-01-10 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(223,85,75,0,0,0,0,175,0,90,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();223','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','admin','2023-01-15 00:00:00','2023-01-15','','','','2023-01-09 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(224,85,75,0,0,0,0,175,0,94,1,0,0,0,'bug224','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','admin','2023-01-16 00:00:00','2023-01-16','','','','2023-01-08 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(225,85,75,0,0,0,0,175,0,98,1,0,0,0,'BUG225','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-17 15:33:08','trunk','admin','2023-01-17 00:00:00','2023-01-17','','','','2023-01-07 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(226,86,76,0,0,0,0,176,0,102,1,0,0,0,'BUG226','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-18 15:33:08','trunk','admin','2023-01-18 00:00:00','2023-01-18','','','','2023-01-06 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(227,86,76,0,0,0,0,176,0,106,1,0,0,0,'BUG227','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-19 15:33:08','trunk','admin','2023-01-19 00:00:00','2023-01-19','','','','2023-01-05 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(228,86,76,0,0,0,0,176,0,110,1,0,0,0,'BUG228','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-20 15:33:08','trunk','admin','2023-01-20 00:00:00','2023-01-20','','','','2023-01-04 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(229,87,77,0,0,0,0,177,0,114,1,0,0,0,'BUG229','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-14 15:33:08','trunk','admin','2022-12-14 00:00:00','2022-12-14','','','','2023-01-03 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(230,87,77,0,0,0,0,177,0,118,1,0,0,0,'BUG230','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-15 15:33:08','trunk','admin','2022-12-15 00:00:00','2022-12-15','','','','2023-01-02 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(231,87,77,0,0,0,0,177,0,122,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();231','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-16 15:33:08','trunk','dev1','2022-12-16 00:00:00','2022-12-16','','','','2023-01-01 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(232,88,78,0,0,0,0,178,0,126,1,0,0,0,'bug232','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-17 15:33:08','trunk','dev1','2022-12-17 00:00:00','2022-12-17','','','','2023-01-21 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(233,88,78,0,0,0,0,178,0,130,1,0,0,0,'BUG233','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-18 15:33:08','trunk','dev1','2022-12-18 00:00:00','2022-12-18','','','','2023-01-20 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(234,88,78,0,0,0,0,178,0,134,1,0,0,0,'BUG234','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-19 15:33:08','trunk','dev1','2022-12-19 00:00:00','2022-12-19','','','','2023-01-19 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(235,89,79,0,0,0,0,179,0,138,1,0,0,0,'BUG235','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-20 15:33:08','trunk','dev1','2022-12-20 00:00:00','2022-12-20','','','','2023-01-18 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(236,89,79,0,0,0,0,179,0,142,1,0,0,0,'BUG236','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-21 15:33:08','trunk','dev1','2022-12-21 00:00:00','2022-12-21','','','','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(237,89,79,0,0,0,0,179,0,146,1,0,0,0,'BUG237','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-22 15:33:08','trunk','dev1','2022-12-22 00:00:00','2022-12-22','','','','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(238,90,80,0,0,0,0,180,0,150,1,0,0,0,'BUG238','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-23 15:33:08','trunk','dev1','2022-12-23 00:00:00','2022-12-23','','','','2023-01-15 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(239,90,80,0,0,0,0,180,0,154,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();239','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-24 15:33:08','trunk','dev1','2022-12-24 00:00:00','2022-12-24','','','','2023-01-14 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(240,90,80,0,0,0,0,180,0,158,1,0,0,0,'bug240','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-25 15:33:08','trunk','dev1','2022-12-25 00:00:00','2022-12-25','','','','2023-01-13 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(241,91,81,0,0,0,0,181,0,162,1,0,0,0,'BUG241','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-26 15:33:08','trunk','dev1','2022-12-26 00:00:00','2022-12-26','','','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(242,91,81,0,0,0,0,181,0,166,1,0,0,0,'BUG242','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-27 15:33:08','trunk','dev1','2022-12-27 00:00:00','2022-12-27','','','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(243,91,81,0,0,0,0,181,0,170,1,0,0,0,'BUG243','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-28 15:33:08','trunk','dev1','2022-12-28 00:00:00','2022-12-28','','','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(244,92,82,0,0,0,0,182,0,174,1,0,0,0,'BUG244','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-29 15:33:08','trunk','dev1','2022-12-29 00:00:00','2022-12-29','','','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(245,92,82,0,0,0,0,182,0,178,1,0,0,0,'BUG245','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','active','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-30 15:33:08','trunk','dev1','2022-12-30 00:00:00','2022-12-30','','','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(246,92,82,0,0,0,0,182,0,182,1,0,0,0,'BUG246','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-31 15:33:08','trunk','dev1','2022-12-31 00:00:00','2022-12-31','','','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(247,93,83,0,0,0,0,183,0,186,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();247','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','active','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-01 15:33:08','trunk','dev1','2023-01-01 00:00:00','2023-01-01','','','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(248,93,83,0,0,0,0,183,0,190,1,0,0,0,'bug248','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-02 15:33:08','trunk','dev1','2023-01-02 00:00:00','2023-01-02','','','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(249,93,83,0,0,0,0,183,0,194,1,0,0,0,'BUG249','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','active','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-03 15:33:08','trunk','dev1','2023-01-03 00:00:00','2023-01-03','','','','2023-01-04 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(250,94,84,0,0,0,0,184,0,198,1,0,0,0,'BUG250','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','active','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-04 15:33:08','trunk','dev1','2023-01-04 00:00:00','2023-01-04','','','','2023-01-03 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','1'),(251,94,84,0,0,0,0,184,0,202,1,0,0,0,'BUG251','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-05 15:33:08','trunk','dev1','2023-01-05 00:00:00','2023-01-05','$assignedTo','bydesign','','2023-01-02 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(252,94,84,0,0,0,0,184,0,206,1,0,0,0,'BUG252','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-06 15:33:08','trunk','dev1','2023-01-06 00:00:00','2023-01-06','$assignedTo','bydesign','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(253,95,85,0,0,0,0,185,0,210,1,0,0,0,'BUG253','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','trunk','dev1','2023-01-07 00:00:00','2023-01-07','$assignedTo','bydesign','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(254,95,85,0,0,0,0,185,0,214,1,0,0,0,'BUG254','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','trunk','dev1','2023-01-08 00:00:00','2023-01-08','$assignedTo','bydesign','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(255,95,85,0,0,0,0,185,0,218,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();255','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','trunk','dev1','2023-01-09 00:00:00','2023-01-09','$assignedTo','bydesign','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(256,96,86,0,0,0,0,186,0,222,1,0,0,0,'bug256','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','dev1','2023-01-10 00:00:00','2023-01-10','$assignedTo','duplicate','trunk','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(257,96,86,0,0,0,0,186,0,226,1,0,0,0,'BUG257','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','dev1','2023-01-11 00:00:00','2023-01-11','$assignedTo','duplicate','trunk','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(258,96,86,0,0,0,0,186,0,230,1,0,0,0,'BUG258','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','dev1','2023-01-12 00:00:00','2023-01-12','$assignedTo','duplicate','trunk','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(259,97,87,0,0,0,0,187,0,234,1,0,0,0,'BUG259','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','dev1','2023-01-13 00:00:00','2023-01-13','$assignedTo','duplicate','trunk','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(260,97,87,0,0,0,0,187,0,238,1,0,0,0,'BUG260','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','dev1','2023-01-14 00:00:00','2023-01-14','$assignedTo','duplicate','trunk','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(261,97,87,0,0,0,0,187,0,242,1,0,0,0,'BUG261','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','test1','2023-01-15 00:00:00','2023-01-15','$assignedTo','external','trunk','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(262,98,88,0,0,0,0,188,0,246,1,0,0,0,'BUG262','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','test1','2023-01-16 00:00:00','2023-01-16','$assignedTo','external','trunk','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(263,98,88,0,0,0,0,188,0,250,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();263','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-17 15:33:08','trunk','test1','2023-01-17 00:00:00','2023-01-17','$assignedTo','external','trunk','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(264,98,88,0,0,0,0,188,0,254,1,0,0,0,'bug264','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-18 15:33:08','trunk','test1','2023-01-18 00:00:00','2023-01-18','$assignedTo','external','trunk','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(265,99,89,0,0,0,0,189,0,258,1,0,0,0,'BUG265','',1,1,'security','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-19 15:33:08','trunk','test1','2023-01-19 00:00:00','2023-01-19','$assignedTo','external','trunk','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(266,99,89,0,0,0,0,189,0,262,1,0,0,0,'BUG266','',2,2,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-20 15:33:08','trunk','test1','2023-01-20 00:00:00','2023-01-20','$assignedTo','fixed','trunk','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(267,99,89,0,0,0,0,189,0,266,1,0,0,0,'BUG267','',3,3,'standard','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-14 15:33:08','trunk','test1','2022-12-14 00:00:00','2022-12-14','$assignedTo','fixed','trunk','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(268,100,90,0,0,0,0,190,0,270,1,0,0,0,'BUG268','',4,4,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-15 15:33:08','trunk','test1','2022-12-15 00:00:00','2022-12-15','$assignedTo','fixed','trunk','2023-01-06 00:00:00','','0000-00-00 00:00:00',1,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(269,100,90,0,0,0,0,190,0,274,1,0,0,0,'BUG269','',1,1,'designdefect','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-16 15:33:08','trunk','test1','2022-12-16 00:00:00','2022-12-16','$assignedTo','fixed','trunk','2023-01-05 00:00:00','','0000-00-00 00:00:00',2,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(270,100,90,0,0,0,0,190,0,278,1,0,0,0,'BUG270','',2,2,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-17 15:33:08','trunk','test1','2022-12-17 00:00:00','2022-12-17','$assignedTo','fixed','trunk','2023-01-04 00:00:00','','0000-00-00 00:00:00',3,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(271,0,91,0,0,0,0,191,0,282,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();271','',3,3,'codeerror','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-18 15:33:08','trunk','test1','2022-12-18 00:00:00','2022-12-18','$assignedTo','notrepro','','2023-01-03 00:00:00','','0000-00-00 00:00:00',4,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(272,0,91,0,0,0,0,191,0,286,1,0,0,0,'bug272','',4,4,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-19 15:33:08','trunk','test1','2022-12-19 00:00:00','2022-12-19','$assignedTo','notrepro','','2023-01-02 00:00:00','','0000-00-00 00:00:00',5,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(273,0,91,0,0,0,0,191,0,290,1,0,0,0,'BUG273','',1,1,'install','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-20 15:33:08','trunk','test1','2022-12-20 00:00:00','2022-12-20','$assignedTo','postponed','','2023-01-01 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(274,0,92,0,0,0,0,192,0,294,1,0,0,0,'BUG274','',2,2,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-21 15:33:08','trunk','test1','2022-12-21 00:00:00','2022-12-21','$assignedTo','postponed','','2023-01-21 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(275,0,92,0,0,0,0,192,0,298,1,0,0,0,'BUG275','',3,3,'performance','android','','','','【步骤】
【结果】
【期望】
','resolved','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-22 15:33:08','trunk','test1','2022-12-22 00:00:00','2022-12-22','$assignedTo','postponed','','2023-01-20 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(276,0,92,0,0,0,0,192,0,302,1,0,0,0,'BUG276','',4,4,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-23 15:33:08','trunk','test1','2022-12-23 00:00:00','2022-12-23','$assignedTo','willnotfix','','2023-01-19 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(277,0,93,0,0,0,0,193,0,306,1,0,0,0,'BUG277','',1,1,'automation','','','','','【步骤】
【结果】
【期望】
','resolved','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-24 15:33:08','trunk','test1','2022-12-24 00:00:00','2022-12-24','$assignedTo','willnotfix','','2023-01-18 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(278,0,93,0,0,0,0,193,0,310,1,0,0,0,'BUG278','',2,2,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-25 15:33:08','trunk','test1','2022-12-25 00:00:00','2022-12-25','$assignedTo','willnotfix','','2023-01-17 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(279,0,93,0,0,0,0,193,0,314,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();279','',3,3,'others','win10','','','','【步骤】
【结果】
【期望】
','resolved','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-26 15:33:08','trunk','test1','2022-12-26 00:00:00','2022-12-26','$assignedTo','willnotfix','','2023-01-16 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(280,0,94,0,0,0,0,194,0,318,1,0,0,0,'bug280','',4,4,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','resolved','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-27 15:33:08','trunk','test1','2022-12-27 00:00:00','2022-12-27','$assignedTo','willnotfix','','2023-01-15 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(281,0,94,0,0,0,0,194,0,322,1,0,0,0,'BUG281','',1,1,'config','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-28 15:33:08','trunk','test1','2022-12-28 00:00:00','2022-12-28','admin','fixed','','2023-01-14 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(282,0,94,0,0,0,0,194,0,326,1,0,0,0,'BUG282','',2,2,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-29 15:33:08','trunk','test1','2022-12-29 00:00:00','2022-12-29','admin','fixed','','2023-01-13 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(283,0,95,0,0,0,0,195,0,330,1,0,0,0,'BUG283','',3,3,'security','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2022-12-30 15:33:08','trunk','test1','2022-12-30 00:00:00','2022-12-30','admin','fixed','','2023-01-12 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(284,0,95,0,0,0,0,195,0,334,1,0,0,0,'BUG284','',4,4,'performance','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2022-12-31 15:33:08','trunk','test1','2022-12-31 00:00:00','2022-12-31','admin','fixed','','2023-01-11 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(285,0,95,0,0,0,0,195,0,338,1,0,0,0,'BUG285','',1,1,'standard','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-01 15:33:08','trunk','test1','2023-01-01 00:00:00','2023-01-01','admin','fixed','','2023-01-10 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(286,0,96,0,0,0,0,196,0,342,1,0,0,0,'BUG286','',2,2,'automation','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-02 15:33:08','trunk','test1','2023-01-02 00:00:00','2023-01-02','admin','fixed','','2023-01-09 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(287,0,96,0,0,0,0,196,0,346,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();287','',3,3,'designdefect','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-03 15:33:08','trunk','test1','2023-01-03 00:00:00','2023-01-03','admin','fixed','','2023-01-08 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(288,0,96,0,0,0,0,196,0,350,1,0,0,0,'bug288','',4,4,'others','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-04 15:33:08','trunk','test1','2023-01-04 00:00:00','2023-01-04','admin','fixed','','2023-01-07 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(289,0,97,0,0,0,0,197,0,354,1,0,0,0,'BUG289','',1,1,'codeerror','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-05 15:33:08','trunk','test1','2023-01-05 00:00:00','2023-01-05','admin','fixed','','2023-01-06 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(290,0,97,0,0,0,0,197,0,358,1,0,0,0,'BUG290','',2,2,'config','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-06 15:33:08','trunk','test1','2023-01-06 00:00:00','2023-01-06','admin','fixed','','2023-01-05 00:00:00','','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(291,0,97,0,0,0,0,197,0,362,1,0,0,0,'BUG291','',3,3,'install','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-07 15:33:08','trunk','','2023-01-07 00:00:00','2023-01-07','admin','bydesign','','2023-01-04 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(292,0,98,0,0,0,0,198,0,366,1,0,0,0,'BUG292','',4,4,'security','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-08 15:33:08','trunk','','2023-01-08 00:00:00','2023-01-08','admin','external','','2023-01-03 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(293,0,98,0,0,0,0,198,0,370,1,0,0,0,'BUG293','',1,1,'performance','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-09 15:33:08','trunk','','2023-01-09 00:00:00','2023-01-09','admin','notrepro','','2023-01-02 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(294,0,98,0,0,0,0,198,0,374,1,0,0,0,'BUG294','',2,2,'standard','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-10 15:33:08','trunk','','2023-01-10 00:00:00','2023-01-10','admin','postponed','','2023-01-01 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(295,0,99,0,0,0,0,199,0,378,1,0,0,0,'缺陷!@()(){}|+=%^&*$#测试bug名称到底可以有多长!@#¥%&*\'\":.<>。?/();295','',3,3,'automation','','','','','【步骤】
【结果】
【期望】
','closed','','#3da7f5',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-11 15:33:08','trunk','','2023-01-11 00:00:00','2023-01-11','admin','willnotfix','','2023-01-21 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(296,0,99,0,0,0,0,199,0,382,1,0,0,0,'bug296','',4,4,'designdefect','','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#75c941',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-12 15:33:08','trunk','','2023-01-12 00:00:00','2023-01-12','admin','duplicate','trunk','2023-01-20 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(297,0,99,0,0,0,0,199,0,386,1,0,0,0,'BUG297','',1,1,'others','win10','','','','【步骤】
【结果】
【期望】
','closed','','#2dbdb2',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-13 15:33:08','trunk','','2023-01-13 00:00:00','2023-01-13','admin','duplicate','trunk','2023-01-19 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(298,0,100,0,0,0,0,200,0,390,1,0,0,0,'BUG298','',2,2,'codeerror','windows','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#797ec9',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-14 15:33:08','trunk','','2023-01-14 00:00:00','2023-01-14','admin','duplicate','trunk','2023-01-18 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(299,0,100,0,0,0,0,200,0,394,1,0,0,0,'BUG299','',3,3,'config','android','','','','【步骤】
【结果】
【期望】
','closed','','#ffaf38',0,0,'0000-00-00 00:00:00','','','','admin','2023-01-15 15:33:08','trunk','','2023-01-15 00:00:00','2023-01-15','admin','duplicate','trunk','2023-01-17 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0'),(300,0,100,0,0,0,0,200,0,398,1,0,0,0,'BUG300','',4,4,'install','ios','','','','【步骤】进入成果展示
【结果】乱码
【期望】正常显示
','closed','','#ff4e3e',1,0,'0000-00-00 00:00:00','','','','admin','2023-01-16 15:33:08','trunk','','2023-01-16 00:00:00','2023-01-16','admin','duplicate','trunk','2023-01-16 00:00:00','admin','0000-00-00 00:00:00',0,'',0,0,0,0,0,0,'','','','','','',0,'','0000-00-00 00:00:00','0');
+/*!40000 ALTER TABLE `zt_bug` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:33:15
diff --git a/module/user/test/model/data/sql/case.sql b/module/user/test/model/data/sql/case.sql
new file mode 100644
index 0000000000..3857b20f9a
--- /dev/null
+++ b/module/user/test/model/data/sql/case.sql
@@ -0,0 +1,97 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_case`
+--
+
+DROP TABLE IF EXISTS `zt_case`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_case` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `project` mediumint(8) unsigned NOT NULL,
+ `product` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `execution` mediumint(8) unsigned NOT NULL,
+ `branch` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `lib` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `module` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `path` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `story` mediumint(30) unsigned NOT NULL DEFAULT 0,
+ `storyVersion` smallint(6) NOT NULL DEFAULT 1,
+ `title` varchar(255) NOT NULL,
+ `precondition` text NOT NULL,
+ `keywords` varchar(255) NOT NULL,
+ `pri` tinyint(3) unsigned NOT NULL DEFAULT 3,
+ `type` char(30) NOT NULL DEFAULT '1',
+ `auto` varchar(10) NOT NULL DEFAULT 'no',
+ `frame` varchar(10) NOT NULL,
+ `stage` varchar(255) NOT NULL,
+ `howRun` varchar(30) NOT NULL,
+ `script` longtext NOT NULL,
+ `scriptedBy` varchar(30) NOT NULL,
+ `scriptedDate` date NOT NULL,
+ `scriptStatus` varchar(30) NOT NULL,
+ `scriptLocation` varchar(255) NOT NULL,
+ `status` char(30) NOT NULL DEFAULT '1',
+ `subStatus` varchar(30) NOT NULL DEFAULT '',
+ `color` char(7) NOT NULL,
+ `frequency` enum('1','2','3') NOT NULL DEFAULT '1',
+ `order` tinyint(30) unsigned NOT NULL DEFAULT 0,
+ `openedBy` char(30) NOT NULL DEFAULT '',
+ `openedDate` datetime NOT NULL,
+ `reviewedBy` varchar(255) NOT NULL,
+ `reviewedDate` date NOT NULL,
+ `lastEditedBy` char(30) NOT NULL DEFAULT '',
+ `lastEditedDate` datetime NOT NULL,
+ `version` tinyint(3) unsigned NOT NULL DEFAULT 0,
+ `linkCase` varchar(255) NOT NULL,
+ `fromBug` mediumint(8) unsigned NOT NULL,
+ `fromCaseID` mediumint(8) unsigned NOT NULL,
+ `fromCaseVersion` mediumint(8) unsigned NOT NULL DEFAULT 1,
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ `lastRunner` varchar(30) NOT NULL,
+ `lastRunDate` datetime NOT NULL,
+ `lastRunResult` char(30) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `product` (`product`),
+ KEY `story` (`story`),
+ KEY `fromBug` (`fromBug`),
+ KEY `module` (`module`)
+) ENGINE=InnoDB AUTO_INCREMENT=561 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_case`
+--
+
+LOCK TABLES `zt_case` WRITE;
+/*!40000 ALTER TABLE `zt_case` DISABLE KEYS */;
+INSERT INTO `zt_case` VALUES (1,0,1,101,0,0,0,0,2,1,'这个是测试用例1','这是前置条件1','这是关键词1',1,'feature','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',1,'test1','2023-01-14 00:00:00','admin','2023-01-14','admin','2023-01-14 00:00:00',1,'0',0,0,1,'0','test1','2023-01-14 00:00:00','pass'),(2,0,1,101,0,0,0,0,2,1,'这个是测试用例2','这是前置条件2','这是关键词2',2,'performance','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',6,'test2','2023-01-14 00:10:00','admin','2023-01-14','admin','2023-01-14 00:05:00',1,'0',0,0,1,'0','test2','2023-01-14 00:08:20','fail'),(3,0,1,101,0,0,0,0,2,1,'这个是测试用例3','这是前置条件3','这是关键词3',3,'config','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',11,'test3','2023-01-14 00:20:00','admin','2023-01-14','admin','2023-01-14 00:10:00',1,'0',0,0,1,'0','test3','2023-01-14 00:16:40','pass'),(4,0,1,101,0,0,0,0,2,1,'这个是测试用例4','这是前置条件4','这是关键词4',4,'install','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',16,'test4','2023-01-14 00:30:00','admin','2023-01-14','admin','2023-01-14 00:15:00',1,'0',0,0,1,'0','test4','2023-01-14 00:25:00','fail'),(5,0,2,102,0,0,0,0,6,1,'这个是测试用例5','这是前置条件5','这是关键词5',1,'security','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',21,'test5','2023-01-14 00:40:00','admin','2023-01-14','admin','2023-01-14 00:20:00',1,'0',0,0,1,'0','test5','2023-01-14 00:33:20','pass'),(6,0,2,102,0,0,0,0,6,1,'这个是测试用例6','这是前置条件6','这是关键词6',2,'interface','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',26,'test6','2023-01-14 00:50:00','admin','2023-01-14','admin','2023-01-14 00:25:00',1,'0',0,0,1,'0','test6','2023-01-14 00:41:40','fail'),(7,0,2,102,0,0,0,0,6,1,'这个是测试用例7','这是前置条件7','这是关键词7',3,'other','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',31,'test7','2023-01-14 01:00:00','admin','2023-01-14','admin','2023-01-14 00:30:00',1,'0',0,0,1,'0','test7','2023-01-14 00:50:00','pass'),(8,0,2,102,0,0,0,0,6,1,'这个是测试用例8','这是前置条件8','这是关键词8',4,'feature','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',36,'test8','2023-01-14 01:10:00','admin','2023-01-14','admin','2023-01-14 00:35:00',1,'0',0,0,1,'0','test8','2023-01-14 00:58:20','fail'),(9,0,3,103,0,0,0,0,10,1,'这个是测试用例9','这是前置条件9','这是关键词9',1,'performance','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',41,'test9','2023-01-14 01:20:00','admin','2023-01-14','admin','2023-01-14 00:40:00',1,'0',0,0,1,'0','test9','2023-01-14 01:06:40','pass'),(10,0,3,103,0,0,0,0,10,1,'这个是测试用例10','这是前置条件10','这是关键词10',2,'config','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',46,'test10','2023-01-14 01:30:00','admin','2023-01-14','admin','2023-01-14 00:45:00',1,'0',0,0,1,'0','test10','2023-01-14 01:15:00','fail'),(11,0,3,103,0,0,0,0,10,1,'这个是测试用例11','这是前置条件11','这是关键词11',3,'install','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',51,'test11','2023-01-14 01:40:00','admin','2023-01-14','admin','2023-01-14 00:50:00',1,'0',0,0,1,'0','test11','2023-01-14 01:23:20','pass'),(12,0,3,103,0,0,0,0,10,1,'这个是测试用例12','这是前置条件12','这是关键词12',4,'security','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',56,'test12','2023-01-14 01:50:00','admin','2023-01-14','admin','2023-01-14 00:55:00',1,'0',0,0,1,'0','test12','2023-01-14 01:31:40','fail'),(13,0,4,104,0,0,0,0,14,1,'这个是测试用例13','这是前置条件13','这是关键词13',1,'interface','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',61,'test13','2023-01-14 02:00:00','admin','2023-01-14','admin','2023-01-14 01:00:00',1,'0',0,0,1,'0','test13','2023-01-14 01:40:00','pass'),(14,0,4,104,0,0,0,0,14,1,'这个是测试用例14','这是前置条件14','这是关键词14',2,'other','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',66,'test14','2023-01-14 02:10:00','admin','2023-01-14','admin','2023-01-14 01:05:00',1,'0',0,0,1,'0','test14','2023-01-14 01:48:20','fail'),(15,0,4,104,0,0,0,0,14,1,'这个是测试用例15','这是前置条件15','这是关键词15',3,'feature','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',71,'test15','2023-01-14 02:20:00','admin','2023-01-14','admin','2023-01-14 01:10:00',1,'0',0,0,1,'0','test15','2023-01-14 01:56:40','pass'),(16,0,4,104,0,0,0,0,14,1,'这个是测试用例16','这是前置条件16','这是关键词16',4,'performance','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',76,'test16','2023-01-14 02:30:00','admin','2023-01-14','admin','2023-01-14 01:15:00',1,'0',0,0,1,'0','test16','2023-01-14 02:05:00','fail'),(17,0,5,105,0,0,0,0,18,1,'这个是测试用例17','这是前置条件17','这是关键词17',1,'config','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',81,'test17','2023-01-14 02:40:00','admin','2023-01-14','admin','2023-01-14 01:20:00',1,'0',0,0,1,'0','test17','2023-01-14 02:13:20','pass'),(18,0,5,105,0,0,0,0,18,1,'这个是测试用例18','这是前置条件18','这是关键词18',2,'install','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',86,'test18','2023-01-14 02:50:00','admin','2023-01-14','admin','2023-01-14 01:25:00',1,'0',0,0,1,'0','test18','2023-01-14 02:21:40','fail'),(19,0,5,105,0,0,0,0,18,1,'这个是测试用例19','这是前置条件19','这是关键词19',3,'security','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',91,'test19','2023-01-14 03:00:00','admin','2023-01-14','admin','2023-01-14 01:30:00',1,'0',0,0,1,'0','test19','2023-01-14 02:30:00','pass'),(20,0,5,105,0,0,0,0,18,1,'这个是测试用例20','这是前置条件20','这是关键词20',4,'interface','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',96,'test20','2023-01-14 03:10:00','admin','2023-01-14','admin','2023-01-14 01:35:00',1,'0',0,0,1,'0','test20','2023-01-14 02:38:20','fail'),(21,0,6,106,0,0,0,0,22,1,'这个是测试用例21','这是前置条件21','这是关键词21',1,'other','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',101,'test21','2023-01-14 03:20:00','admin','2023-01-14','admin','2023-01-14 01:40:00',1,'0',0,0,1,'0','test21','2023-01-14 02:46:40','pass'),(22,0,6,106,0,0,0,0,22,1,'这个是测试用例22','这是前置条件22','这是关键词22',2,'feature','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',106,'test22','2023-01-14 03:30:00','admin','2023-01-14','admin','2023-01-14 01:45:00',1,'0',0,0,1,'0','test22','2023-01-14 02:55:00','fail'),(23,0,6,106,0,0,0,0,22,1,'这个是测试用例23','这是前置条件23','这是关键词23',3,'performance','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',111,'test23','2023-01-14 03:40:00','admin','2023-01-14','admin','2023-01-14 01:50:00',1,'0',0,0,1,'0','test23','2023-01-14 03:03:20','pass'),(24,0,6,106,0,0,0,0,22,1,'这个是测试用例24','这是前置条件24','这是关键词24',4,'config','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',116,'test24','2023-01-14 03:50:00','admin','2023-01-14','admin','2023-01-14 01:55:00',1,'0',0,0,1,'0','test24','2023-01-14 03:11:40','fail'),(25,0,7,107,0,0,0,0,26,1,'这个是测试用例25','这是前置条件25','这是关键词25',1,'install','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',121,'test25','2023-01-14 04:00:00','admin','2023-01-14','admin','2023-01-14 02:00:00',1,'0',0,0,1,'0','test25','2023-01-14 03:20:00','pass'),(26,0,7,107,0,0,0,0,26,1,'这个是测试用例26','这是前置条件26','这是关键词26',2,'security','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',126,'test26','2023-01-14 04:10:00','admin','2023-01-14','admin','2023-01-14 02:05:00',1,'0',0,0,1,'0','test26','2023-01-14 03:28:20','fail'),(27,0,7,107,0,0,0,0,26,1,'这个是测试用例27','这是前置条件27','这是关键词27',3,'interface','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',131,'test27','2023-01-14 04:20:00','admin','2023-01-14','admin','2023-01-14 02:10:00',1,'0',0,0,1,'0','test27','2023-01-14 03:36:40','pass'),(28,0,7,107,0,0,0,0,26,1,'这个是测试用例28','这是前置条件28','这是关键词28',4,'other','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',136,'test28','2023-01-14 04:30:00','admin','2023-01-14','admin','2023-01-14 02:15:00',1,'0',0,0,1,'0','test28','2023-01-14 03:45:00','fail'),(29,0,8,108,0,0,0,0,30,1,'这个是测试用例29','这是前置条件29','这是关键词29',1,'feature','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',141,'test29','2023-01-14 04:40:00','admin','2023-01-14','admin','2023-01-14 02:20:00',1,'0',0,0,1,'0','test29','2023-01-14 03:53:20','pass'),(30,0,8,108,0,0,0,0,30,1,'这个是测试用例30','这是前置条件30','这是关键词30',2,'performance','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',146,'test30','2023-01-14 04:50:00','admin','2023-01-14','admin','2023-01-14 02:25:00',1,'0',0,0,1,'0','test30','2023-01-14 04:01:40','fail'),(31,0,8,108,0,0,0,0,30,1,'这个是测试用例31','这是前置条件31','这是关键词31',3,'config','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',151,'test31','2023-01-14 05:00:00','admin','2023-01-14','admin','2023-01-14 02:30:00',1,'0',0,0,1,'0','test31','2023-01-14 04:10:00','pass'),(32,0,8,108,0,0,0,0,30,1,'这个是测试用例32','这是前置条件32','这是关键词32',4,'install','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',156,'test32','2023-01-14 05:10:00','admin','2023-01-14','admin','2023-01-14 02:35:00',1,'0',0,0,1,'0','test32','2023-01-14 04:18:20','fail'),(33,0,9,109,0,0,0,0,34,1,'这个是测试用例33','这是前置条件33','这是关键词33',1,'security','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',161,'test33','2023-01-14 05:20:00','admin','2023-01-14','admin','2023-01-14 02:40:00',1,'0',0,0,1,'0','test33','2023-01-14 04:26:40','pass'),(34,0,9,109,0,0,0,0,34,1,'这个是测试用例34','这是前置条件34','这是关键词34',2,'interface','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',166,'test34','2023-01-14 05:30:00','admin','2023-01-14','admin','2023-01-14 02:45:00',1,'0',0,0,1,'0','test34','2023-01-14 04:35:00','fail'),(35,0,9,109,0,0,0,0,34,1,'这个是测试用例35','这是前置条件35','这是关键词35',3,'other','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',171,'test35','2023-01-14 05:40:00','admin','2023-01-14','admin','2023-01-14 02:50:00',1,'0',0,0,1,'0','test35','2023-01-14 04:43:20','pass'),(36,0,9,109,0,0,0,0,34,1,'这个是测试用例36','这是前置条件36','这是关键词36',4,'feature','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',176,'test36','2023-01-14 05:50:00','admin','2023-01-14','admin','2023-01-14 02:55:00',1,'0',0,0,1,'0','test36','2023-01-14 04:51:40','fail'),(37,0,10,110,0,0,0,0,38,1,'这个是测试用例37','这是前置条件37','这是关键词37',1,'performance','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',181,'test37','2023-01-14 06:00:00','admin','2023-01-14','admin','2023-01-14 03:00:00',1,'0',0,0,1,'0','test37','2023-01-14 05:00:00','pass'),(38,0,10,110,0,0,0,0,38,1,'这个是测试用例38','这是前置条件38','这是关键词38',2,'config','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',186,'test38','2023-01-14 06:10:00','admin','2023-01-14','admin','2023-01-14 03:05:00',1,'0',0,0,1,'0','test38','2023-01-14 05:08:20','fail'),(39,0,10,110,0,0,0,0,38,1,'这个是测试用例39','这是前置条件39','这是关键词39',3,'install','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',191,'test39','2023-01-14 06:20:00','admin','2023-01-14','admin','2023-01-14 03:10:00',1,'0',0,0,1,'0','test39','2023-01-14 05:16:40','pass'),(40,0,10,110,0,0,0,0,38,1,'这个是测试用例40','这是前置条件40','这是关键词40',4,'security','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',196,'test40','2023-01-14 06:30:00','admin','2023-01-14','admin','2023-01-14 03:15:00',1,'0',0,0,1,'0','test40','2023-01-14 05:25:00','fail'),(41,0,11,111,0,0,0,0,42,1,'这个是测试用例41','这是前置条件41','这是关键词41',1,'interface','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',201,'test41','2023-01-14 06:40:00','admin','2023-01-14','admin','2023-01-14 03:20:00',1,'0',0,0,1,'0','test41','2023-01-14 05:33:20','pass'),(42,0,11,111,0,0,0,0,42,1,'这个是测试用例42','这是前置条件42','这是关键词42',2,'other','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',206,'test42','2023-01-14 06:50:00','admin','2023-01-14','admin','2023-01-14 03:25:00',1,'0',0,0,1,'0','test42','2023-01-14 05:41:40','fail'),(43,0,11,111,0,0,0,0,42,1,'这个是测试用例43','这是前置条件43','这是关键词43',3,'feature','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',211,'test43','2023-01-14 07:00:00','admin','2023-01-14','admin','2023-01-14 03:30:00',1,'0',0,0,1,'0','test43','2023-01-14 05:50:00','pass'),(44,0,11,111,0,0,0,0,42,1,'这个是测试用例44','这是前置条件44','这是关键词44',4,'performance','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',216,'test44','2023-01-14 07:10:00','admin','2023-01-14','admin','2023-01-14 03:35:00',1,'0',0,0,1,'0','test44','2023-01-14 05:58:20','fail'),(45,0,12,112,0,0,0,0,46,1,'这个是测试用例45','这是前置条件45','这是关键词45',1,'config','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',221,'test45','2023-01-14 07:20:00','admin','2023-01-14','admin','2023-01-14 03:40:00',1,'0',0,0,1,'0','test45','2023-01-14 06:06:40','pass'),(46,0,12,112,0,0,0,0,46,1,'这个是测试用例46','这是前置条件46','这是关键词46',2,'install','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',226,'test46','2023-01-14 07:30:00','admin','2023-01-14','admin','2023-01-14 03:45:00',1,'0',0,0,1,'0','test46','2023-01-14 06:15:00','fail'),(47,0,12,112,0,0,0,0,46,1,'这个是测试用例47','这是前置条件47','这是关键词47',3,'security','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',231,'test47','2023-01-14 07:40:00','admin','2023-01-14','admin','2023-01-14 03:50:00',1,'0',0,0,1,'0','test47','2023-01-14 06:23:20','pass'),(48,0,12,112,0,0,0,0,46,1,'这个是测试用例48','这是前置条件48','这是关键词48',4,'interface','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',236,'test48','2023-01-14 07:50:00','admin','2023-01-14','admin','2023-01-14 03:55:00',1,'0',0,0,1,'0','test48','2023-01-14 06:31:40','fail'),(49,0,13,113,0,0,0,0,50,1,'这个是测试用例49','这是前置条件49','这是关键词49',1,'other','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',241,'test49','2023-01-14 08:00:00','admin','2023-01-14','admin','2023-01-14 04:00:00',1,'0',0,0,1,'0','test49','2023-01-14 06:40:00','pass'),(50,0,13,113,0,0,0,0,50,1,'这个是测试用例50','这是前置条件50','这是关键词50',2,'feature','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',246,'test50','2023-01-14 08:10:00','admin','2023-01-14','admin','2023-01-14 04:05:00',1,'0',0,0,1,'0','test50','2023-01-14 06:48:20','fail'),(51,0,13,113,0,0,0,0,50,1,'这个是测试用例51','这是前置条件51','这是关键词51',3,'performance','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',251,'test51','2023-01-14 08:20:00','admin','2023-01-14','admin','2023-01-14 04:10:00',1,'0',0,0,1,'0','test51','2023-01-14 06:56:40','pass'),(52,0,13,113,0,0,0,0,50,1,'这个是测试用例52','这是前置条件52','这是关键词52',4,'config','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test52','2023-01-14 08:30:00','admin','2023-01-14','admin','2023-01-14 04:15:00',1,'0',0,0,1,'0','test52','2023-01-14 07:05:00','fail'),(53,0,14,114,0,0,0,0,54,1,'这个是测试用例53','这是前置条件53','这是关键词53',1,'install','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test53','2023-01-14 08:40:00','admin','2023-01-14','admin','2023-01-14 04:20:00',1,'0',0,0,1,'0','test53','2023-01-14 07:13:20','pass'),(54,0,14,114,0,0,0,0,54,1,'这个是测试用例54','这是前置条件54','这是关键词54',2,'security','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test54','2023-01-14 08:50:00','admin','2023-01-14','admin','2023-01-14 04:25:00',1,'0',0,0,1,'0','test54','2023-01-14 07:21:40','fail'),(55,0,14,114,0,0,0,0,54,1,'这个是测试用例55','这是前置条件55','这是关键词55',3,'interface','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test55','2023-01-14 09:00:00','admin','2023-01-14','admin','2023-01-14 04:30:00',1,'0',0,0,1,'0','test55','2023-01-14 07:30:00','pass'),(56,0,14,114,0,0,0,0,54,1,'这个是测试用例56','这是前置条件56','这是关键词56',4,'other','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test56','2023-01-14 09:10:00','admin','2023-01-14','admin','2023-01-14 04:35:00',1,'0',0,0,1,'0','test56','2023-01-14 07:38:20','fail'),(57,0,15,115,0,0,0,0,58,1,'这个是测试用例57','这是前置条件57','这是关键词57',1,'feature','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test57','2023-01-14 09:20:00','admin','2023-01-14','admin','2023-01-14 04:40:00',1,'0',0,0,1,'0','test57','2023-01-14 07:46:40','pass'),(58,0,15,115,0,0,0,0,58,1,'这个是测试用例58','这是前置条件58','这是关键词58',2,'performance','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test58','2023-01-14 09:30:00','admin','2023-01-14','admin','2023-01-14 04:45:00',1,'0',0,0,1,'0','test58','2023-01-14 07:55:00','fail'),(59,0,15,115,0,0,0,0,58,1,'这个是测试用例59','这是前置条件59','这是关键词59',3,'config','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test59','2023-01-14 09:40:00','admin','2023-01-14','admin','2023-01-14 04:50:00',1,'0',0,0,1,'0','test59','2023-01-14 08:03:20','pass'),(60,0,15,115,0,0,0,0,58,1,'这个是测试用例60','这是前置条件60','这是关键词60',4,'install','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test60','2023-01-14 09:50:00','admin','2023-01-14','admin','2023-01-14 04:55:00',1,'0',0,0,1,'0','test60','2023-01-14 08:11:40','fail'),(61,0,16,116,0,0,0,0,62,1,'这个是测试用例61','这是前置条件61','这是关键词61',1,'security','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test61','2023-01-14 10:00:00','admin','2023-01-14','admin','2023-01-14 05:00:00',1,'0',0,0,1,'0','test61','2023-01-14 08:20:00','pass'),(62,0,16,116,0,0,0,0,62,1,'这个是测试用例62','这是前置条件62','这是关键词62',2,'interface','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test62','2023-01-14 10:10:00','admin','2023-01-14','admin','2023-01-14 05:05:00',1,'0',0,0,1,'0','test62','2023-01-14 08:28:20','fail'),(63,0,16,116,0,0,0,0,62,1,'这个是测试用例63','这是前置条件63','这是关键词63',3,'other','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test63','2023-01-14 10:20:00','admin','2023-01-14','admin','2023-01-14 05:10:00',1,'0',0,0,1,'0','test63','2023-01-14 08:36:40','pass'),(64,0,16,116,0,0,0,0,62,1,'这个是测试用例64','这是前置条件64','这是关键词64',4,'feature','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test64','2023-01-14 10:30:00','admin','2023-01-14','admin','2023-01-14 05:15:00',1,'0',0,0,1,'0','test64','2023-01-14 08:45:00','fail'),(65,0,17,117,0,0,0,0,66,1,'这个是测试用例65','这是前置条件65','这是关键词65',1,'performance','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test65','2023-01-14 10:40:00','admin','2023-01-14','admin','2023-01-14 05:20:00',1,'0',0,0,1,'0','test65','2023-01-14 08:53:20','pass'),(66,0,17,117,0,0,0,0,66,1,'这个是测试用例66','这是前置条件66','这是关键词66',2,'config','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test66','2023-01-14 10:50:00','admin','2023-01-14','admin','2023-01-14 05:25:00',1,'0',0,0,1,'0','test66','2023-01-14 09:01:40','fail'),(67,0,17,117,0,0,0,0,66,1,'这个是测试用例67','这是前置条件67','这是关键词67',3,'install','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test67','2023-01-14 11:00:00','admin','2023-01-14','admin','2023-01-14 05:30:00',1,'0',0,0,1,'0','test67','2023-01-14 09:10:00','pass'),(68,0,17,117,0,0,0,0,66,1,'这个是测试用例68','这是前置条件68','这是关键词68',4,'security','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test68','2023-01-14 11:10:00','admin','2023-01-14','admin','2023-01-14 05:35:00',1,'0',0,0,1,'0','test68','2023-01-14 09:18:20','fail'),(69,0,18,118,0,0,0,0,70,1,'这个是测试用例69','这是前置条件69','这是关键词69',1,'interface','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test69','2023-01-14 11:20:00','admin','2023-01-14','admin','2023-01-14 05:40:00',1,'0',0,0,1,'0','test69','2023-01-14 09:26:40','pass'),(70,0,18,118,0,0,0,0,70,1,'这个是测试用例70','这是前置条件70','这是关键词70',2,'other','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test70','2023-01-14 11:30:00','admin','2023-01-14','admin','2023-01-14 05:45:00',1,'0',0,0,1,'0','test70','2023-01-14 09:35:00','fail'),(71,0,18,118,0,0,0,0,70,1,'这个是测试用例71','这是前置条件71','这是关键词71',3,'feature','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test71','2023-01-14 11:40:00','admin','2023-01-14','admin','2023-01-14 05:50:00',1,'0',0,0,1,'0','test71','2023-01-14 09:43:20','pass'),(72,0,18,118,0,0,0,0,70,1,'这个是测试用例72','这是前置条件72','这是关键词72',4,'performance','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test72','2023-01-14 11:50:00','admin','2023-01-14','admin','2023-01-14 05:55:00',1,'0',0,0,1,'0','test72','2023-01-14 09:51:40','fail'),(73,0,19,119,0,0,0,0,74,1,'这个是测试用例73','这是前置条件73','这是关键词73',1,'config','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test73','2023-01-14 12:00:00','admin','2023-01-14','admin','2023-01-14 06:00:00',1,'0',0,0,1,'0','test73','2023-01-14 10:00:00','pass'),(74,0,19,119,0,0,0,0,74,1,'这个是测试用例74','这是前置条件74','这是关键词74',2,'install','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test74','2023-01-14 12:10:00','admin','2023-01-14','admin','2023-01-14 06:05:00',1,'0',0,0,1,'0','test74','2023-01-14 10:08:20','fail'),(75,0,19,119,0,0,0,0,74,1,'这个是测试用例75','这是前置条件75','这是关键词75',3,'security','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test75','2023-01-14 12:20:00','admin','2023-01-14','admin','2023-01-14 06:10:00',1,'0',0,0,1,'0','test75','2023-01-14 10:16:40','pass'),(76,0,19,119,0,0,0,0,74,1,'这个是测试用例76','这是前置条件76','这是关键词76',4,'interface','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test76','2023-01-14 12:30:00','admin','2023-01-14','admin','2023-01-14 06:15:00',1,'0',0,0,1,'0','test76','2023-01-14 10:25:00','fail'),(77,0,20,120,0,0,0,0,78,1,'这个是测试用例77','这是前置条件77','这是关键词77',1,'other','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test77','2023-01-14 12:40:00','admin','2023-01-14','admin','2023-01-14 06:20:00',1,'0',0,0,1,'0','test77','2023-01-14 10:33:20','pass'),(78,0,20,120,0,0,0,0,78,1,'这个是测试用例78','这是前置条件78','这是关键词78',2,'feature','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test78','2023-01-14 12:50:00','admin','2023-01-14','admin','2023-01-14 06:25:00',1,'0',0,0,1,'0','test78','2023-01-14 10:41:40','fail'),(79,0,20,120,0,0,0,0,78,1,'这个是测试用例79','这是前置条件79','这是关键词79',3,'performance','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test79','2023-01-14 13:00:00','admin','2023-01-14','admin','2023-01-14 06:30:00',1,'0',0,0,1,'0','test79','2023-01-14 10:50:00','pass'),(80,0,20,120,0,0,0,0,78,1,'这个是测试用例80','这是前置条件80','这是关键词80',4,'config','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test80','2023-01-14 13:10:00','admin','2023-01-14','admin','2023-01-14 06:35:00',1,'0',0,0,1,'0','test80','2023-01-14 10:58:20','fail'),(81,0,21,121,0,0,0,0,82,1,'这个是测试用例81','这是前置条件81','这是关键词81',1,'install','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test81','2023-01-14 13:20:00','admin','2023-01-14','admin','2023-01-14 06:40:00',1,'0',0,0,1,'0','test81','2023-01-14 11:06:40','pass'),(82,0,21,121,0,0,0,0,82,1,'这个是测试用例82','这是前置条件82','这是关键词82',2,'security','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test82','2023-01-14 13:30:00','admin','2023-01-14','admin','2023-01-14 06:45:00',1,'0',0,0,1,'0','test82','2023-01-14 11:15:00','fail'),(83,0,21,121,0,0,0,0,82,1,'这个是测试用例83','这是前置条件83','这是关键词83',3,'interface','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test83','2023-01-14 13:40:00','admin','2023-01-14','admin','2023-01-14 06:50:00',1,'0',0,0,1,'0','test83','2023-01-14 11:23:20','pass'),(84,0,21,121,0,0,0,0,82,1,'这个是测试用例84','这是前置条件84','这是关键词84',4,'other','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test84','2023-01-14 13:50:00','admin','2023-01-14','admin','2023-01-14 06:55:00',1,'0',0,0,1,'0','test84','2023-01-14 11:31:40','fail'),(85,0,22,122,0,0,0,0,86,1,'这个是测试用例85','这是前置条件85','这是关键词85',1,'feature','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test85','2023-01-14 14:00:00','admin','2023-01-14','admin','2023-01-14 07:00:00',1,'0',0,0,1,'0','test85','2023-01-14 11:40:00','pass'),(86,0,22,122,0,0,0,0,86,1,'这个是测试用例86','这是前置条件86','这是关键词86',2,'performance','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test86','2023-01-14 14:10:00','admin','2023-01-14','admin','2023-01-14 07:05:00',1,'0',0,0,1,'0','test86','2023-01-14 11:48:20','fail'),(87,0,22,122,0,0,0,0,86,1,'这个是测试用例87','这是前置条件87','这是关键词87',3,'config','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test87','2023-01-14 14:20:00','admin','2023-01-14','admin','2023-01-14 07:10:00',1,'0',0,0,1,'0','test87','2023-01-14 11:56:40','pass'),(88,0,22,122,0,0,0,0,86,1,'这个是测试用例88','这是前置条件88','这是关键词88',4,'install','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test88','2023-01-14 14:30:00','admin','2023-01-14','admin','2023-01-14 07:15:00',1,'0',0,0,1,'0','test88','2023-01-14 12:05:00','fail'),(89,0,23,123,0,0,0,0,90,1,'这个是测试用例89','这是前置条件89','这是关键词89',1,'security','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test89','2023-01-14 14:40:00','admin','2023-01-14','admin','2023-01-14 07:20:00',1,'0',0,0,1,'0','test89','2023-01-14 12:13:20','pass'),(90,0,23,123,0,0,0,0,90,1,'这个是测试用例90','这是前置条件90','这是关键词90',2,'interface','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test90','2023-01-14 14:50:00','admin','2023-01-14','admin','2023-01-14 07:25:00',1,'0',0,0,1,'0','test90','2023-01-14 12:21:40','fail'),(91,0,23,123,0,0,0,0,90,1,'这个是测试用例91','这是前置条件91','这是关键词91',3,'other','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test91','2023-01-14 15:00:00','admin','2023-01-14','admin','2023-01-14 07:30:00',1,'0',0,0,1,'0','test91','2023-01-14 12:30:00','pass'),(92,0,23,123,0,0,0,0,90,1,'这个是测试用例92','这是前置条件92','这是关键词92',4,'feature','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test92','2023-01-14 15:10:00','admin','2023-01-14','admin','2023-01-14 07:35:00',1,'0',0,0,1,'0','test92','2023-01-14 12:38:20','fail'),(93,0,24,124,0,0,0,0,94,1,'这个是测试用例93','这是前置条件93','这是关键词93',1,'performance','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test93','2023-01-14 15:20:00','admin','2023-01-14','admin','2023-01-14 07:40:00',1,'0',0,0,1,'0','test93','2023-01-14 12:46:40','pass'),(94,0,24,124,0,0,0,0,94,1,'这个是测试用例94','这是前置条件94','这是关键词94',2,'config','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test94','2023-01-14 15:30:00','admin','2023-01-14','admin','2023-01-14 07:45:00',1,'0',0,0,1,'0','test94','2023-01-14 12:55:00','fail'),(95,0,24,124,0,0,0,0,94,1,'这个是测试用例95','这是前置条件95','这是关键词95',3,'install','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test95','2023-01-14 15:40:00','admin','2023-01-14','admin','2023-01-14 07:50:00',1,'0',0,0,1,'0','test95','2023-01-14 13:03:20','pass'),(96,0,24,124,0,0,0,0,94,1,'这个是测试用例96','这是前置条件96','这是关键词96',4,'security','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test96','2023-01-14 15:50:00','admin','2023-01-14','admin','2023-01-14 07:55:00',1,'0',0,0,1,'0','test96','2023-01-14 13:11:40','fail'),(97,0,25,125,0,0,0,0,98,1,'这个是测试用例97','这是前置条件97','这是关键词97',1,'interface','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test97','2023-01-14 16:00:00','admin','2023-01-14','admin','2023-01-14 08:00:00',1,'0',0,0,1,'0','test97','2023-01-14 13:20:00','pass'),(98,0,25,125,0,0,0,0,98,1,'这个是测试用例98','这是前置条件98','这是关键词98',2,'other','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test98','2023-01-14 16:10:00','admin','2023-01-14','admin','2023-01-14 08:05:00',1,'0',0,0,1,'0','test98','2023-01-14 13:28:20','fail'),(99,0,25,125,0,0,0,0,98,1,'这个是测试用例99','这是前置条件99','这是关键词99',3,'feature','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test99','2023-01-14 16:20:00','admin','2023-01-14','admin','2023-01-14 08:10:00',1,'0',0,0,1,'0','test99','2023-01-14 13:36:40','pass'),(100,0,25,125,0,0,0,0,98,1,'这个是测试用例100','这是前置条件100','这是关键词100',4,'performance','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test100','2023-01-14 16:30:00','admin','2023-01-14','admin','2023-01-14 08:15:00',1,'0',0,0,1,'0','test100','2023-01-14 13:45:00','fail'),(101,0,26,126,0,0,0,0,102,1,'这个是测试用例101','这是前置条件101','这是关键词101',1,'config','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',1,'test1','2023-01-14 16:40:00','admin','2023-01-14','admin','2023-01-14 08:20:00',1,'0',0,0,1,'0','test1','2023-01-14 13:53:20','pass'),(102,0,26,126,0,0,0,0,102,1,'这个是测试用例102','这是前置条件102','这是关键词102',2,'install','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',6,'test2','2023-01-14 16:50:00','admin','2023-01-14','admin','2023-01-14 08:25:00',1,'0',0,0,1,'0','test2','2023-01-14 14:01:40','fail'),(103,0,26,126,0,0,0,0,102,1,'这个是测试用例103','这是前置条件103','这是关键词103',3,'security','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',11,'test3','2023-01-14 17:00:00','admin','2023-01-14','admin','2023-01-14 08:30:00',1,'0',0,0,1,'0','test3','2023-01-14 14:10:00','pass'),(104,0,26,126,0,0,0,0,102,1,'这个是测试用例104','这是前置条件104','这是关键词104',4,'interface','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',16,'test4','2023-01-14 17:10:00','admin','2023-01-14','admin','2023-01-14 08:35:00',1,'0',0,0,1,'0','test4','2023-01-14 14:18:20','fail'),(105,0,27,127,0,0,0,0,106,1,'这个是测试用例105','这是前置条件105','这是关键词105',1,'other','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',21,'test5','2023-01-14 17:20:00','admin','2023-01-14','admin','2023-01-14 08:40:00',1,'0',0,0,1,'0','test5','2023-01-14 14:26:40','pass'),(106,0,27,127,0,0,0,0,106,1,'这个是测试用例106','这是前置条件106','这是关键词106',2,'feature','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',26,'test6','2023-01-14 17:30:00','admin','2023-01-14','admin','2023-01-14 08:45:00',1,'0',0,0,1,'0','test6','2023-01-14 14:35:00','fail'),(107,0,27,127,0,0,0,0,106,1,'这个是测试用例107','这是前置条件107','这是关键词107',3,'performance','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',31,'test7','2023-01-14 17:40:00','admin','2023-01-14','admin','2023-01-14 08:50:00',1,'0',0,0,1,'0','test7','2023-01-14 14:43:20','pass'),(108,0,27,127,0,0,0,0,106,1,'这个是测试用例108','这是前置条件108','这是关键词108',4,'config','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',36,'test8','2023-01-14 17:50:00','admin','2023-01-14','admin','2023-01-14 08:55:00',1,'0',0,0,1,'0','test8','2023-01-14 14:51:40','fail'),(109,0,28,128,0,0,0,0,110,1,'这个是测试用例109','这是前置条件109','这是关键词109',1,'install','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',41,'test9','2023-01-14 18:00:00','admin','2023-01-14','admin','2023-01-14 09:00:00',1,'0',0,0,1,'0','test9','2023-01-14 15:00:00','pass'),(110,0,28,128,0,0,0,0,110,1,'这个是测试用例110','这是前置条件110','这是关键词110',2,'security','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',46,'test10','2023-01-14 18:10:00','admin','2023-01-14','admin','2023-01-14 09:05:00',1,'0',0,0,1,'0','test10','2023-01-14 15:08:20','fail'),(111,0,28,128,0,0,0,0,110,1,'这个是测试用例111','这是前置条件111','这是关键词111',3,'interface','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',51,'test11','2023-01-14 18:20:00','admin','2023-01-14','admin','2023-01-14 09:10:00',1,'0',0,0,1,'0','test11','2023-01-14 15:16:40','pass'),(112,0,28,128,0,0,0,0,110,1,'这个是测试用例112','这是前置条件112','这是关键词112',4,'other','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',56,'test12','2023-01-14 18:30:00','admin','2023-01-14','admin','2023-01-14 09:15:00',1,'0',0,0,1,'0','test12','2023-01-14 15:25:00','fail'),(113,0,29,129,0,0,0,0,114,1,'这个是测试用例113','这是前置条件113','这是关键词113',1,'feature','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',61,'test13','2023-01-14 18:40:00','admin','2023-01-14','admin','2023-01-14 09:20:00',1,'0',0,0,1,'0','test13','2023-01-14 15:33:20','pass'),(114,0,29,129,0,0,0,0,114,1,'这个是测试用例114','这是前置条件114','这是关键词114',2,'performance','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',66,'test14','2023-01-14 18:50:00','admin','2023-01-14','admin','2023-01-14 09:25:00',1,'0',0,0,1,'0','test14','2023-01-14 15:41:40','fail'),(115,0,29,129,0,0,0,0,114,1,'这个是测试用例115','这是前置条件115','这是关键词115',3,'config','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',71,'test15','2023-01-14 19:00:00','admin','2023-01-14','admin','2023-01-14 09:30:00',1,'0',0,0,1,'0','test15','2023-01-14 15:50:00','pass'),(116,0,29,129,0,0,0,0,114,1,'这个是测试用例116','这是前置条件116','这是关键词116',4,'install','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',76,'test16','2023-01-14 19:10:00','admin','2023-01-14','admin','2023-01-14 09:35:00',1,'0',0,0,1,'0','test16','2023-01-14 15:58:20','fail'),(117,0,30,130,0,0,0,0,118,1,'这个是测试用例117','这是前置条件117','这是关键词117',1,'security','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',81,'test17','2023-01-14 19:20:00','admin','2023-01-14','admin','2023-01-14 09:40:00',1,'0',0,0,1,'0','test17','2023-01-14 16:06:40','pass'),(118,0,30,130,0,0,0,0,118,1,'这个是测试用例118','这是前置条件118','这是关键词118',2,'interface','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',86,'test18','2023-01-14 19:30:00','admin','2023-01-14','admin','2023-01-14 09:45:00',1,'0',0,0,1,'0','test18','2023-01-14 16:15:00','fail'),(119,0,30,130,0,0,0,0,118,1,'这个是测试用例119','这是前置条件119','这是关键词119',3,'other','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',91,'test19','2023-01-14 19:40:00','admin','2023-01-14','admin','2023-01-14 09:50:00',1,'0',0,0,1,'0','test19','2023-01-14 16:23:20','pass'),(120,0,30,130,0,0,0,0,118,1,'这个是测试用例120','这是前置条件120','这是关键词120',4,'feature','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',96,'test20','2023-01-14 19:50:00','admin','2023-01-14','admin','2023-01-14 09:55:00',1,'0',0,0,1,'0','test20','2023-01-14 16:31:40','fail'),(121,0,31,131,0,0,0,0,122,1,'这个是测试用例121','这是前置条件121','这是关键词121',1,'performance','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',101,'test21','2023-01-14 20:00:00','admin','2023-01-14','admin','2023-01-14 10:00:00',1,'0',0,0,1,'0','test21','2023-01-14 16:40:00','pass'),(122,0,31,131,0,0,0,0,122,1,'这个是测试用例122','这是前置条件122','这是关键词122',2,'config','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',106,'test22','2023-01-14 20:10:00','admin','2023-01-14','admin','2023-01-14 10:05:00',1,'0',0,0,1,'0','test22','2023-01-14 16:48:20','fail'),(123,0,31,131,0,0,0,0,122,1,'这个是测试用例123','这是前置条件123','这是关键词123',3,'install','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',111,'test23','2023-01-14 20:20:00','admin','2023-01-14','admin','2023-01-14 10:10:00',1,'0',0,0,1,'0','test23','2023-01-14 16:56:40','pass'),(124,0,31,131,0,0,0,0,122,1,'这个是测试用例124','这是前置条件124','这是关键词124',4,'security','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',116,'test24','2023-01-14 20:30:00','admin','2023-01-14','admin','2023-01-14 10:15:00',1,'0',0,0,1,'0','test24','2023-01-14 17:05:00','fail'),(125,0,32,132,0,0,0,0,126,1,'这个是测试用例125','这是前置条件125','这是关键词125',1,'interface','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',121,'test25','2023-01-14 20:40:00','admin','2023-01-14','admin','2023-01-14 10:20:00',1,'0',0,0,1,'0','test25','2023-01-14 17:13:20','pass'),(126,0,32,132,0,0,0,0,126,1,'这个是测试用例126','这是前置条件126','这是关键词126',2,'other','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',126,'test26','2023-01-14 20:50:00','admin','2023-01-14','admin','2023-01-14 10:25:00',1,'0',0,0,1,'0','test26','2023-01-14 17:21:40','fail'),(127,0,32,132,0,0,0,0,126,1,'这个是测试用例127','这是前置条件127','这是关键词127',3,'feature','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',131,'test27','2023-01-14 21:00:00','admin','2023-01-14','admin','2023-01-14 10:30:00',1,'0',0,0,1,'0','test27','2023-01-14 17:30:00','pass'),(128,0,32,132,0,0,0,0,126,1,'这个是测试用例128','这是前置条件128','这是关键词128',4,'performance','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',136,'test28','2023-01-14 21:10:00','admin','2023-01-14','admin','2023-01-14 10:35:00',1,'0',0,0,1,'0','test28','2023-01-14 17:38:20','fail'),(129,0,33,133,0,0,0,0,130,1,'这个是测试用例129','这是前置条件129','这是关键词129',1,'config','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',141,'test29','2023-01-14 21:20:00','admin','2023-01-14','admin','2023-01-14 10:40:00',1,'0',0,0,1,'0','test29','2023-01-14 17:46:40','pass'),(130,0,33,133,0,0,0,0,130,1,'这个是测试用例130','这是前置条件130','这是关键词130',2,'install','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',146,'test30','2023-01-14 21:30:00','admin','2023-01-14','admin','2023-01-14 10:45:00',1,'0',0,0,1,'0','test30','2023-01-14 17:55:00','fail'),(131,0,33,133,0,0,0,0,130,1,'这个是测试用例131','这是前置条件131','这是关键词131',3,'security','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',151,'test31','2023-01-14 21:40:00','admin','2023-01-14','admin','2023-01-14 10:50:00',1,'0',0,0,1,'0','test31','2023-01-14 18:03:20','pass'),(132,0,33,133,0,0,0,0,130,1,'这个是测试用例132','这是前置条件132','这是关键词132',4,'interface','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',156,'test32','2023-01-14 21:50:00','admin','2023-01-14','admin','2023-01-14 10:55:00',1,'0',0,0,1,'0','test32','2023-01-14 18:11:40','fail'),(133,0,34,134,0,0,0,0,134,1,'这个是测试用例133','这是前置条件133','这是关键词133',1,'other','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',161,'test33','2023-01-14 22:00:00','admin','2023-01-14','admin','2023-01-14 11:00:00',1,'0',0,0,1,'0','test33','2023-01-14 18:20:00','pass'),(134,0,34,134,0,0,0,0,134,1,'这个是测试用例134','这是前置条件134','这是关键词134',2,'feature','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',166,'test34','2023-01-14 22:10:00','admin','2023-01-14','admin','2023-01-14 11:05:00',1,'0',0,0,1,'0','test34','2023-01-14 18:28:20','fail'),(135,0,34,134,0,0,0,0,134,1,'这个是测试用例135','这是前置条件135','这是关键词135',3,'performance','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',171,'test35','2023-01-14 22:20:00','admin','2023-01-14','admin','2023-01-14 11:10:00',1,'0',0,0,1,'0','test35','2023-01-14 18:36:40','pass'),(136,0,34,134,0,0,0,0,134,1,'这个是测试用例136','这是前置条件136','这是关键词136',4,'config','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',176,'test36','2023-01-14 22:30:00','admin','2023-01-14','admin','2023-01-14 11:15:00',1,'0',0,0,1,'0','test36','2023-01-14 18:45:00','fail'),(137,0,35,135,0,0,0,0,138,1,'这个是测试用例137','这是前置条件137','这是关键词137',1,'install','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',181,'test37','2023-01-14 22:40:00','admin','2023-01-14','admin','2023-01-14 11:20:00',1,'0',0,0,1,'0','test37','2023-01-14 18:53:20','pass'),(138,0,35,135,0,0,0,0,138,1,'这个是测试用例138','这是前置条件138','这是关键词138',2,'security','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',186,'test38','2023-01-14 22:50:00','admin','2023-01-14','admin','2023-01-14 11:25:00',1,'0',0,0,1,'0','test38','2023-01-14 19:01:40','fail'),(139,0,35,135,0,0,0,0,138,1,'这个是测试用例139','这是前置条件139','这是关键词139',3,'interface','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',191,'test39','2023-01-14 23:00:00','admin','2023-01-14','admin','2023-01-14 11:30:00',1,'0',0,0,1,'0','test39','2023-01-14 19:10:00','pass'),(140,0,35,135,0,0,0,0,138,1,'这个是测试用例140','这是前置条件140','这是关键词140',4,'other','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',196,'test40','2023-01-14 23:10:00','admin','2023-01-14','admin','2023-01-14 11:35:00',1,'0',0,0,1,'0','test40','2023-01-14 19:18:20','fail'),(141,0,36,136,0,0,0,0,142,1,'这个是测试用例141','这是前置条件141','这是关键词141',1,'feature','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',201,'test41','2023-01-14 23:20:00','admin','2023-01-14','admin','2023-01-14 11:40:00',1,'0',0,0,1,'0','test41','2023-01-14 19:26:40','pass'),(142,0,36,136,0,0,0,0,142,1,'这个是测试用例142','这是前置条件142','这是关键词142',2,'performance','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',206,'test42','2023-01-14 23:30:00','admin','2023-01-14','admin','2023-01-14 11:45:00',1,'0',0,0,1,'0','test42','2023-01-14 19:35:00','fail'),(143,0,36,136,0,0,0,0,142,1,'这个是测试用例143','这是前置条件143','这是关键词143',3,'config','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',211,'test43','2023-01-14 23:40:00','admin','2023-01-14','admin','2023-01-14 11:50:00',1,'0',0,0,1,'0','test43','2023-01-14 19:43:20','pass'),(144,0,36,136,0,0,0,0,142,1,'这个是测试用例144','这是前置条件144','这是关键词144',4,'install','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',216,'test44','2023-01-14 23:50:00','admin','2023-01-14','admin','2023-01-14 11:55:00',1,'0',0,0,1,'0','test44','2023-01-14 19:51:40','fail'),(145,0,37,137,0,0,0,0,146,1,'这个是测试用例145','这是前置条件145','这是关键词145',1,'security','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',221,'test45','2023-01-14 00:00:00','admin','2023-01-14','admin','2023-01-14 12:00:00',1,'0',0,0,1,'0','test45','2023-01-14 20:00:00','pass'),(146,0,37,137,0,0,0,0,146,1,'这个是测试用例146','这是前置条件146','这是关键词146',2,'interface','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',226,'test46','2023-01-14 00:10:00','admin','2023-01-14','admin','2023-01-14 12:05:00',1,'0',0,0,1,'0','test46','2023-01-14 20:08:20','fail'),(147,0,37,137,0,0,0,0,146,1,'这个是测试用例147','这是前置条件147','这是关键词147',3,'other','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',231,'test47','2023-01-14 00:20:00','admin','2023-01-14','admin','2023-01-14 12:10:00',1,'0',0,0,1,'0','test47','2023-01-14 20:16:40','pass'),(148,0,37,137,0,0,0,0,146,1,'这个是测试用例148','这是前置条件148','这是关键词148',4,'feature','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',236,'test48','2023-01-14 00:30:00','admin','2023-01-14','admin','2023-01-14 12:15:00',1,'0',0,0,1,'0','test48','2023-01-14 20:25:00','fail'),(149,0,38,138,0,0,0,0,150,1,'这个是测试用例149','这是前置条件149','这是关键词149',1,'performance','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',241,'test49','2023-01-14 00:40:00','admin','2023-01-14','admin','2023-01-14 12:20:00',1,'0',0,0,1,'0','test49','2023-01-14 20:33:20','pass'),(150,0,38,138,0,0,0,0,150,1,'这个是测试用例150','这是前置条件150','这是关键词150',2,'config','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',246,'test50','2023-01-14 00:50:00','admin','2023-01-14','admin','2023-01-14 12:25:00',1,'0',0,0,1,'0','test50','2023-01-14 20:41:40','fail'),(151,0,38,138,0,0,0,0,150,1,'这个是测试用例151','这是前置条件151','这是关键词151',3,'install','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',251,'test51','2023-01-14 01:00:00','admin','2023-01-14','admin','2023-01-14 12:30:00',1,'0',0,0,1,'0','test51','2023-01-14 20:50:00','pass'),(152,0,38,138,0,0,0,0,150,1,'这个是测试用例152','这是前置条件152','这是关键词152',4,'security','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test52','2023-01-14 01:10:00','admin','2023-01-14','admin','2023-01-14 12:35:00',1,'0',0,0,1,'0','test52','2023-01-14 20:58:20','fail'),(153,0,39,139,0,0,0,0,154,1,'这个是测试用例153','这是前置条件153','这是关键词153',1,'interface','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test53','2023-01-14 01:20:00','admin','2023-01-14','admin','2023-01-14 12:40:00',1,'0',0,0,1,'0','test53','2023-01-14 21:06:40','pass'),(154,0,39,139,0,0,0,0,154,1,'这个是测试用例154','这是前置条件154','这是关键词154',2,'other','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test54','2023-01-14 01:30:00','admin','2023-01-14','admin','2023-01-14 12:45:00',1,'0',0,0,1,'0','test54','2023-01-14 21:15:00','fail'),(155,0,39,139,0,0,0,0,154,1,'这个是测试用例155','这是前置条件155','这是关键词155',3,'feature','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test55','2023-01-14 01:40:00','admin','2023-01-14','admin','2023-01-14 12:50:00',1,'0',0,0,1,'0','test55','2023-01-14 21:23:20','pass'),(156,0,39,139,0,0,0,0,154,1,'这个是测试用例156','这是前置条件156','这是关键词156',4,'performance','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test56','2023-01-14 01:50:00','admin','2023-01-14','admin','2023-01-14 12:55:00',1,'0',0,0,1,'0','test56','2023-01-14 21:31:40','fail'),(157,0,40,140,0,0,0,0,158,1,'这个是测试用例157','这是前置条件157','这是关键词157',1,'config','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test57','2023-01-14 02:00:00','admin','2023-01-14','admin','2023-01-14 13:00:00',1,'0',0,0,1,'0','test57','2023-01-14 21:40:00','pass'),(158,0,40,140,0,0,0,0,158,1,'这个是测试用例158','这是前置条件158','这是关键词158',2,'install','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test58','2023-01-14 02:10:00','admin','2023-01-14','admin','2023-01-14 13:05:00',1,'0',0,0,1,'0','test58','2023-01-14 21:48:20','fail'),(159,0,40,140,0,0,0,0,158,1,'这个是测试用例159','这是前置条件159','这是关键词159',3,'security','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test59','2023-01-14 02:20:00','admin','2023-01-14','admin','2023-01-14 13:10:00',1,'0',0,0,1,'0','test59','2023-01-14 21:56:40','pass'),(160,0,40,140,0,0,0,0,158,1,'这个是测试用例160','这是前置条件160','这是关键词160',4,'interface','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test60','2023-01-14 02:30:00','admin','2023-01-14','admin','2023-01-14 13:15:00',1,'0',0,0,1,'0','test60','2023-01-14 22:05:00','fail'),(161,0,41,141,0,0,0,0,162,1,'这个是测试用例161','这是前置条件161','这是关键词161',1,'other','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test61','2023-01-14 02:40:00','admin','2023-01-14','admin','2023-01-14 13:20:00',1,'0',0,0,1,'0','test61','2023-01-14 22:13:20','pass'),(162,0,41,141,0,0,0,0,162,1,'这个是测试用例162','这是前置条件162','这是关键词162',2,'feature','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test62','2023-01-14 02:50:00','admin','2023-01-14','admin','2023-01-14 13:25:00',1,'0',0,0,1,'0','test62','2023-01-14 22:21:40','fail'),(163,0,41,141,0,0,0,0,162,1,'这个是测试用例163','这是前置条件163','这是关键词163',3,'performance','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test63','2023-01-14 03:00:00','admin','2023-01-14','admin','2023-01-14 13:30:00',1,'0',0,0,1,'0','test63','2023-01-14 22:30:00','pass'),(164,0,41,141,0,0,0,0,162,1,'这个是测试用例164','这是前置条件164','这是关键词164',4,'config','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test64','2023-01-14 03:10:00','admin','2023-01-14','admin','2023-01-14 13:35:00',1,'0',0,0,1,'0','test64','2023-01-14 22:38:20','fail'),(165,0,42,142,0,0,0,0,166,1,'这个是测试用例165','这是前置条件165','这是关键词165',1,'install','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test65','2023-01-14 03:20:00','admin','2023-01-14','admin','2023-01-14 13:40:00',1,'0',0,0,1,'0','test65','2023-01-14 22:46:40','pass'),(166,0,42,142,0,0,0,0,166,1,'这个是测试用例166','这是前置条件166','这是关键词166',2,'security','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test66','2023-01-14 03:30:00','admin','2023-01-14','admin','2023-01-14 13:45:00',1,'0',0,0,1,'0','test66','2023-01-14 22:55:00','fail'),(167,0,42,142,0,0,0,0,166,1,'这个是测试用例167','这是前置条件167','这是关键词167',3,'interface','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test67','2023-01-14 03:40:00','admin','2023-01-14','admin','2023-01-14 13:50:00',1,'0',0,0,1,'0','test67','2023-01-14 23:03:20','pass'),(168,0,42,142,0,0,0,0,166,1,'这个是测试用例168','这是前置条件168','这是关键词168',4,'other','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test68','2023-01-14 03:50:00','admin','2023-01-14','admin','2023-01-14 13:55:00',1,'0',0,0,1,'0','test68','2023-01-14 23:11:40','fail'),(169,0,43,143,0,0,0,0,170,1,'这个是测试用例169','这是前置条件169','这是关键词169',1,'feature','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test69','2023-01-14 04:00:00','admin','2023-01-14','admin','2023-01-14 14:00:00',1,'0',0,0,1,'0','test69','2023-01-14 23:20:00','pass'),(170,0,43,143,0,0,0,0,170,1,'这个是测试用例170','这是前置条件170','这是关键词170',2,'performance','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test70','2023-01-14 04:10:00','admin','2023-01-14','admin','2023-01-14 14:05:00',1,'0',0,0,1,'0','test70','2023-01-14 23:28:20','fail'),(171,0,43,143,0,0,0,0,170,1,'这个是测试用例171','这是前置条件171','这是关键词171',3,'config','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test71','2023-01-14 04:20:00','admin','2023-01-14','admin','2023-01-14 14:10:00',1,'0',0,0,1,'0','test71','2023-01-14 23:36:40','pass'),(172,0,43,143,0,0,0,0,170,1,'这个是测试用例172','这是前置条件172','这是关键词172',4,'install','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test72','2023-01-14 04:30:00','admin','2023-01-14','admin','2023-01-14 14:15:00',1,'0',0,0,1,'0','test72','2023-01-14 23:45:00','fail'),(173,0,44,144,0,0,0,0,174,1,'这个是测试用例173','这是前置条件173','这是关键词173',1,'security','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test73','2023-01-14 04:40:00','admin','2023-01-14','admin','2023-01-14 14:20:00',1,'0',0,0,1,'0','test73','2023-01-14 23:53:20','pass'),(174,0,44,144,0,0,0,0,174,1,'这个是测试用例174','这是前置条件174','这是关键词174',2,'interface','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test74','2023-01-14 04:50:00','admin','2023-01-14','admin','2023-01-14 14:25:00',1,'0',0,0,1,'0','test74','2023-01-14 00:00:00','fail'),(175,0,44,144,0,0,0,0,174,1,'这个是测试用例175','这是前置条件175','这是关键词175',3,'other','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test75','2023-01-14 05:00:00','admin','2023-01-14','admin','2023-01-14 14:30:00',1,'0',0,0,1,'0','test75','2023-01-14 00:08:20','pass'),(176,0,44,144,0,0,0,0,174,1,'这个是测试用例176','这是前置条件176','这是关键词176',4,'feature','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test76','2023-01-14 05:10:00','admin','2023-01-14','admin','2023-01-14 14:35:00',1,'0',0,0,1,'0','test76','2023-01-14 00:16:40','fail'),(177,0,45,145,0,0,0,0,178,1,'这个是测试用例177','这是前置条件177','这是关键词177',1,'performance','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test77','2023-01-14 05:20:00','admin','2023-01-14','admin','2023-01-14 14:40:00',1,'0',0,0,1,'0','test77','2023-01-14 00:25:00','pass'),(178,0,45,145,0,0,0,0,178,1,'这个是测试用例178','这是前置条件178','这是关键词178',2,'config','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test78','2023-01-14 05:30:00','admin','2023-01-14','admin','2023-01-14 14:45:00',1,'0',0,0,1,'0','test78','2023-01-14 00:33:20','fail'),(179,0,45,145,0,0,0,0,178,1,'这个是测试用例179','这是前置条件179','这是关键词179',3,'install','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test79','2023-01-14 05:40:00','admin','2023-01-14','admin','2023-01-14 14:50:00',1,'0',0,0,1,'0','test79','2023-01-14 00:41:40','pass'),(180,0,45,145,0,0,0,0,178,1,'这个是测试用例180','这是前置条件180','这是关键词180',4,'security','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test80','2023-01-14 05:50:00','admin','2023-01-14','admin','2023-01-14 14:55:00',1,'0',0,0,1,'0','test80','2023-01-14 00:50:00','fail'),(181,0,46,146,0,0,0,0,182,1,'这个是测试用例181','这是前置条件181','这是关键词181',1,'interface','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test81','2023-01-14 06:00:00','admin','2023-01-14','admin','2023-01-14 15:00:00',1,'0',0,0,1,'0','test81','2023-01-14 00:58:20','pass'),(182,0,46,146,0,0,0,0,182,1,'这个是测试用例182','这是前置条件182','这是关键词182',2,'other','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test82','2023-01-14 06:10:00','admin','2023-01-14','admin','2023-01-14 15:05:00',1,'0',0,0,1,'0','test82','2023-01-14 01:06:40','fail'),(183,0,46,146,0,0,0,0,182,1,'这个是测试用例183','这是前置条件183','这是关键词183',3,'feature','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test83','2023-01-14 06:20:00','admin','2023-01-14','admin','2023-01-14 15:10:00',1,'0',0,0,1,'0','test83','2023-01-14 01:15:00','pass'),(184,0,46,146,0,0,0,0,182,1,'这个是测试用例184','这是前置条件184','这是关键词184',4,'performance','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test84','2023-01-14 06:30:00','admin','2023-01-14','admin','2023-01-14 15:15:00',1,'0',0,0,1,'0','test84','2023-01-14 01:23:20','fail'),(185,0,47,147,0,0,0,0,186,1,'这个是测试用例185','这是前置条件185','这是关键词185',1,'config','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test85','2023-01-14 06:40:00','admin','2023-01-14','admin','2023-01-14 15:20:00',1,'0',0,0,1,'0','test85','2023-01-14 01:31:40','pass'),(186,0,47,147,0,0,0,0,186,1,'这个是测试用例186','这是前置条件186','这是关键词186',2,'install','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test86','2023-01-14 06:50:00','admin','2023-01-14','admin','2023-01-14 15:25:00',1,'0',0,0,1,'0','test86','2023-01-14 01:40:00','fail'),(187,0,47,147,0,0,0,0,186,1,'这个是测试用例187','这是前置条件187','这是关键词187',3,'security','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test87','2023-01-14 07:00:00','admin','2023-01-14','admin','2023-01-14 15:30:00',1,'0',0,0,1,'0','test87','2023-01-14 01:48:20','pass'),(188,0,47,147,0,0,0,0,186,1,'这个是测试用例188','这是前置条件188','这是关键词188',4,'interface','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test88','2023-01-14 07:10:00','admin','2023-01-14','admin','2023-01-14 15:35:00',1,'0',0,0,1,'0','test88','2023-01-14 01:56:40','fail'),(189,0,48,148,0,0,0,0,190,1,'这个是测试用例189','这是前置条件189','这是关键词189',1,'other','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test89','2023-01-14 07:20:00','admin','2023-01-14','admin','2023-01-14 15:40:00',1,'0',0,0,1,'0','test89','2023-01-14 02:05:00','pass'),(190,0,48,148,0,0,0,0,190,1,'这个是测试用例190','这是前置条件190','这是关键词190',2,'feature','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test90','2023-01-14 07:30:00','admin','2023-01-14','admin','2023-01-14 15:45:00',1,'0',0,0,1,'0','test90','2023-01-14 02:13:20','fail'),(191,0,48,148,0,0,0,0,190,1,'这个是测试用例191','这是前置条件191','这是关键词191',3,'performance','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test91','2023-01-14 07:40:00','admin','2023-01-14','admin','2023-01-14 15:50:00',1,'0',0,0,1,'0','test91','2023-01-14 02:21:40','pass'),(192,0,48,148,0,0,0,0,190,1,'这个是测试用例192','这是前置条件192','这是关键词192',4,'config','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test92','2023-01-14 07:50:00','admin','2023-01-14','admin','2023-01-14 15:55:00',1,'0',0,0,1,'0','test92','2023-01-14 02:30:00','fail'),(193,0,49,149,0,0,0,0,194,1,'这个是测试用例193','这是前置条件193','这是关键词193',1,'install','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test93','2023-01-14 08:00:00','admin','2023-01-14','admin','2023-01-14 16:00:00',1,'0',0,0,1,'0','test93','2023-01-14 02:38:20','pass'),(194,0,49,149,0,0,0,0,194,1,'这个是测试用例194','这是前置条件194','这是关键词194',2,'security','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test94','2023-01-14 08:10:00','admin','2023-01-14','admin','2023-01-14 16:05:00',1,'0',0,0,1,'0','test94','2023-01-14 02:46:40','fail'),(195,0,49,149,0,0,0,0,194,1,'这个是测试用例195','这是前置条件195','这是关键词195',3,'interface','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test95','2023-01-14 08:20:00','admin','2023-01-14','admin','2023-01-14 16:10:00',1,'0',0,0,1,'0','test95','2023-01-14 02:55:00','pass'),(196,0,49,149,0,0,0,0,194,1,'这个是测试用例196','这是前置条件196','这是关键词196',4,'other','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test96','2023-01-14 08:30:00','admin','2023-01-14','admin','2023-01-14 16:15:00',1,'0',0,0,1,'0','test96','2023-01-14 03:03:20','fail'),(197,0,50,150,0,0,0,0,198,1,'这个是测试用例197','这是前置条件197','这是关键词197',1,'feature','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test97','2023-01-14 08:40:00','admin','2023-01-14','admin','2023-01-14 16:20:00',1,'0',0,0,1,'0','test97','2023-01-14 03:11:40','pass'),(198,0,50,150,0,0,0,0,198,1,'这个是测试用例198','这是前置条件198','这是关键词198',2,'performance','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test98','2023-01-14 08:50:00','admin','2023-01-14','admin','2023-01-14 16:25:00',1,'0',0,0,1,'0','test98','2023-01-14 03:20:00','fail'),(199,0,50,150,0,0,0,0,198,1,'这个是测试用例199','这是前置条件199','这是关键词199',3,'config','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test99','2023-01-14 09:00:00','admin','2023-01-14','admin','2023-01-14 16:30:00',1,'0',0,0,1,'0','test99','2023-01-14 03:28:20','pass'),(200,0,50,150,0,0,0,0,198,1,'这个是测试用例200','这是前置条件200','这是关键词200',4,'install','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test100','2023-01-14 09:10:00','admin','2023-01-14','admin','2023-01-14 16:35:00',1,'0',0,0,1,'0','test100','2023-01-14 03:36:40','fail'),(201,0,51,151,0,0,0,0,202,1,'这个是测试用例201','这是前置条件201','这是关键词201',1,'security','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',1,'test1','2023-01-14 09:20:00','admin','2023-01-14','admin','2023-01-14 16:40:00',1,'0',0,0,1,'0','test1','2023-01-14 03:45:00','pass'),(202,0,51,151,0,0,0,0,202,1,'这个是测试用例202','这是前置条件202','这是关键词202',2,'interface','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',6,'test2','2023-01-14 09:30:00','admin','2023-01-14','admin','2023-01-14 16:45:00',1,'0',0,0,1,'0','test2','2023-01-14 03:53:20','fail'),(203,0,51,151,0,0,0,0,202,1,'这个是测试用例203','这是前置条件203','这是关键词203',3,'other','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',11,'test3','2023-01-14 09:40:00','admin','2023-01-14','admin','2023-01-14 16:50:00',1,'0',0,0,1,'0','test3','2023-01-14 04:01:40','pass'),(204,0,51,151,0,0,0,0,202,1,'这个是测试用例204','这是前置条件204','这是关键词204',4,'feature','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',16,'test4','2023-01-14 09:50:00','admin','2023-01-14','admin','2023-01-14 16:55:00',1,'0',0,0,1,'0','test4','2023-01-14 04:10:00','fail'),(205,0,52,152,0,0,0,0,206,1,'这个是测试用例205','这是前置条件205','这是关键词205',1,'performance','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',21,'test5','2023-01-14 10:00:00','admin','2023-01-14','admin','2023-01-14 17:00:00',1,'0',0,0,1,'0','test5','2023-01-14 04:18:20','pass'),(206,0,52,152,0,0,0,0,206,1,'这个是测试用例206','这是前置条件206','这是关键词206',2,'config','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',26,'test6','2023-01-14 10:10:00','admin','2023-01-14','admin','2023-01-14 17:05:00',1,'0',0,0,1,'0','test6','2023-01-14 04:26:40','fail'),(207,0,52,152,0,0,0,0,206,1,'这个是测试用例207','这是前置条件207','这是关键词207',3,'install','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',31,'test7','2023-01-14 10:20:00','admin','2023-01-14','admin','2023-01-14 17:10:00',1,'0',0,0,1,'0','test7','2023-01-14 04:35:00','pass'),(208,0,52,152,0,0,0,0,206,1,'这个是测试用例208','这是前置条件208','这是关键词208',4,'security','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',36,'test8','2023-01-14 10:30:00','admin','2023-01-14','admin','2023-01-14 17:15:00',1,'0',0,0,1,'0','test8','2023-01-14 04:43:20','fail'),(209,0,53,153,0,0,0,0,210,1,'这个是测试用例209','这是前置条件209','这是关键词209',1,'interface','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',41,'test9','2023-01-14 10:40:00','admin','2023-01-14','admin','2023-01-14 17:20:00',1,'0',0,0,1,'0','test9','2023-01-14 04:51:40','pass'),(210,0,53,153,0,0,0,0,210,1,'这个是测试用例210','这是前置条件210','这是关键词210',2,'other','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',46,'test10','2023-01-14 10:50:00','admin','2023-01-14','admin','2023-01-14 17:25:00',1,'0',0,0,1,'0','test10','2023-01-14 05:00:00','fail'),(211,0,53,153,0,0,0,0,210,1,'这个是测试用例211','这是前置条件211','这是关键词211',3,'feature','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',51,'test11','2023-01-14 11:00:00','admin','2023-01-14','admin','2023-01-14 17:30:00',1,'0',0,0,1,'0','test11','2023-01-14 05:08:20','pass'),(212,0,53,153,0,0,0,0,210,1,'这个是测试用例212','这是前置条件212','这是关键词212',4,'performance','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',56,'test12','2023-01-14 11:10:00','admin','2023-01-14','admin','2023-01-14 17:35:00',1,'0',0,0,1,'0','test12','2023-01-14 05:16:40','fail'),(213,0,54,154,0,0,0,0,214,1,'这个是测试用例213','这是前置条件213','这是关键词213',1,'config','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',61,'test13','2023-01-14 11:20:00','admin','2023-01-14','admin','2023-01-14 17:40:00',1,'0',0,0,1,'0','test13','2023-01-14 05:25:00','pass'),(214,0,54,154,0,0,0,0,214,1,'这个是测试用例214','这是前置条件214','这是关键词214',2,'install','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',66,'test14','2023-01-14 11:30:00','admin','2023-01-14','admin','2023-01-14 17:45:00',1,'0',0,0,1,'0','test14','2023-01-14 05:33:20','fail'),(215,0,54,154,0,0,0,0,214,1,'这个是测试用例215','这是前置条件215','这是关键词215',3,'security','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',71,'test15','2023-01-14 11:40:00','admin','2023-01-14','admin','2023-01-14 17:50:00',1,'0',0,0,1,'0','test15','2023-01-14 05:41:40','pass'),(216,0,54,154,0,0,0,0,214,1,'这个是测试用例216','这是前置条件216','这是关键词216',4,'interface','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',76,'test16','2023-01-14 11:50:00','admin','2023-01-14','admin','2023-01-14 17:55:00',1,'0',0,0,1,'0','test16','2023-01-14 05:50:00','fail'),(217,0,55,155,0,0,0,0,218,1,'这个是测试用例217','这是前置条件217','这是关键词217',1,'other','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',81,'test17','2023-01-14 12:00:00','admin','2023-01-14','admin','2023-01-14 18:00:00',1,'0',0,0,1,'0','test17','2023-01-14 05:58:20','pass'),(218,0,55,155,0,0,0,0,218,1,'这个是测试用例218','这是前置条件218','这是关键词218',2,'feature','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',86,'test18','2023-01-14 12:10:00','admin','2023-01-14','admin','2023-01-14 18:05:00',1,'0',0,0,1,'0','test18','2023-01-14 06:06:40','fail'),(219,0,55,155,0,0,0,0,218,1,'这个是测试用例219','这是前置条件219','这是关键词219',3,'performance','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',91,'test19','2023-01-14 12:20:00','admin','2023-01-14','admin','2023-01-14 18:10:00',1,'0',0,0,1,'0','test19','2023-01-14 06:15:00','pass'),(220,0,55,155,0,0,0,0,218,1,'这个是测试用例220','这是前置条件220','这是关键词220',4,'config','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',96,'test20','2023-01-14 12:30:00','admin','2023-01-14','admin','2023-01-14 18:15:00',1,'0',0,0,1,'0','test20','2023-01-14 06:23:20','fail'),(221,0,56,156,0,0,0,0,222,1,'这个是测试用例221','这是前置条件221','这是关键词221',1,'install','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',101,'test21','2023-01-14 12:40:00','admin','2023-01-14','admin','2023-01-14 18:20:00',1,'0',0,0,1,'0','test21','2023-01-14 06:31:40','pass'),(222,0,56,156,0,0,0,0,222,1,'这个是测试用例222','这是前置条件222','这是关键词222',2,'security','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',106,'test22','2023-01-14 12:50:00','admin','2023-01-14','admin','2023-01-14 18:25:00',1,'0',0,0,1,'0','test22','2023-01-14 06:40:00','fail'),(223,0,56,156,0,0,0,0,222,1,'这个是测试用例223','这是前置条件223','这是关键词223',3,'interface','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',111,'test23','2023-01-14 13:00:00','admin','2023-01-14','admin','2023-01-14 18:30:00',1,'0',0,0,1,'0','test23','2023-01-14 06:48:20','pass'),(224,0,56,156,0,0,0,0,222,1,'这个是测试用例224','这是前置条件224','这是关键词224',4,'other','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',116,'test24','2023-01-14 13:10:00','admin','2023-01-14','admin','2023-01-14 18:35:00',1,'0',0,0,1,'0','test24','2023-01-14 06:56:40','fail'),(225,0,57,157,0,0,0,0,226,1,'这个是测试用例225','这是前置条件225','这是关键词225',1,'feature','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',121,'test25','2023-01-14 13:20:00','admin','2023-01-14','admin','2023-01-14 18:40:00',1,'0',0,0,1,'0','test25','2023-01-14 07:05:00','pass'),(226,0,57,157,0,0,0,0,226,1,'这个是测试用例226','这是前置条件226','这是关键词226',2,'performance','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',126,'test26','2023-01-14 13:30:00','admin','2023-01-14','admin','2023-01-14 18:45:00',1,'0',0,0,1,'0','test26','2023-01-14 07:13:20','fail'),(227,0,57,157,0,0,0,0,226,1,'这个是测试用例227','这是前置条件227','这是关键词227',3,'config','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',131,'test27','2023-01-14 13:40:00','admin','2023-01-14','admin','2023-01-14 18:50:00',1,'0',0,0,1,'0','test27','2023-01-14 07:21:40','pass'),(228,0,57,157,0,0,0,0,226,1,'这个是测试用例228','这是前置条件228','这是关键词228',4,'install','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',136,'test28','2023-01-14 13:50:00','admin','2023-01-14','admin','2023-01-14 18:55:00',1,'0',0,0,1,'0','test28','2023-01-14 07:30:00','fail'),(229,0,58,158,0,0,0,0,230,1,'这个是测试用例229','这是前置条件229','这是关键词229',1,'security','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',141,'test29','2023-01-14 14:00:00','admin','2023-01-14','admin','2023-01-14 19:00:00',1,'0',0,0,1,'0','test29','2023-01-14 07:38:20','pass'),(230,0,58,158,0,0,0,0,230,1,'这个是测试用例230','这是前置条件230','这是关键词230',2,'interface','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',146,'test30','2023-01-14 14:10:00','admin','2023-01-14','admin','2023-01-14 19:05:00',1,'0',0,0,1,'0','test30','2023-01-14 07:46:40','fail'),(231,0,58,158,0,0,0,0,230,1,'这个是测试用例231','这是前置条件231','这是关键词231',3,'other','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',151,'test31','2023-01-14 14:20:00','admin','2023-01-14','admin','2023-01-14 19:10:00',1,'0',0,0,1,'0','test31','2023-01-14 07:55:00','pass'),(232,0,58,158,0,0,0,0,230,1,'这个是测试用例232','这是前置条件232','这是关键词232',4,'feature','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',156,'test32','2023-01-14 14:30:00','admin','2023-01-14','admin','2023-01-14 19:15:00',1,'0',0,0,1,'0','test32','2023-01-14 08:03:20','fail'),(233,0,59,159,0,0,0,0,234,1,'这个是测试用例233','这是前置条件233','这是关键词233',1,'performance','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',161,'test33','2023-01-14 14:40:00','admin','2023-01-14','admin','2023-01-14 19:20:00',1,'0',0,0,1,'0','test33','2023-01-14 08:11:40','pass'),(234,0,59,159,0,0,0,0,234,1,'这个是测试用例234','这是前置条件234','这是关键词234',2,'config','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',166,'test34','2023-01-14 14:50:00','admin','2023-01-14','admin','2023-01-14 19:25:00',1,'0',0,0,1,'0','test34','2023-01-14 08:20:00','fail'),(235,0,59,159,0,0,0,0,234,1,'这个是测试用例235','这是前置条件235','这是关键词235',3,'install','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',171,'test35','2023-01-14 15:00:00','admin','2023-01-14','admin','2023-01-14 19:30:00',1,'0',0,0,1,'0','test35','2023-01-14 08:28:20','pass'),(236,0,59,159,0,0,0,0,234,1,'这个是测试用例236','这是前置条件236','这是关键词236',4,'security','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',176,'test36','2023-01-14 15:10:00','admin','2023-01-14','admin','2023-01-14 19:35:00',1,'0',0,0,1,'0','test36','2023-01-14 08:36:40','fail'),(237,0,60,160,0,0,0,0,238,1,'这个是测试用例237','这是前置条件237','这是关键词237',1,'interface','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',181,'test37','2023-01-14 15:20:00','admin','2023-01-14','admin','2023-01-14 19:40:00',1,'0',0,0,1,'0','test37','2023-01-14 08:45:00','pass'),(238,0,60,160,0,0,0,0,238,1,'这个是测试用例238','这是前置条件238','这是关键词238',2,'other','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',186,'test38','2023-01-14 15:30:00','admin','2023-01-14','admin','2023-01-14 19:45:00',1,'0',0,0,1,'0','test38','2023-01-14 08:53:20','fail'),(239,0,60,160,0,0,0,0,238,1,'这个是测试用例239','这是前置条件239','这是关键词239',3,'feature','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',191,'test39','2023-01-14 15:40:00','admin','2023-01-14','admin','2023-01-14 19:50:00',1,'0',0,0,1,'0','test39','2023-01-14 09:01:40','pass'),(240,0,60,160,0,0,0,0,238,1,'这个是测试用例240','这是前置条件240','这是关键词240',4,'performance','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',196,'test40','2023-01-14 15:50:00','admin','2023-01-14','admin','2023-01-14 19:55:00',1,'0',0,0,1,'0','test40','2023-01-14 09:10:00','fail'),(241,0,61,161,0,0,0,0,242,1,'这个是测试用例241','这是前置条件241','这是关键词241',1,'config','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',201,'test41','2023-01-14 16:00:00','admin','2023-01-14','admin','2023-01-14 20:00:00',1,'0',0,0,1,'0','test41','2023-01-14 09:18:20','pass'),(242,0,61,161,0,0,0,0,242,1,'这个是测试用例242','这是前置条件242','这是关键词242',2,'install','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',206,'test42','2023-01-14 16:10:00','admin','2023-01-14','admin','2023-01-14 20:05:00',1,'0',0,0,1,'0','test42','2023-01-14 09:26:40','fail'),(243,0,61,161,0,0,0,0,242,1,'这个是测试用例243','这是前置条件243','这是关键词243',3,'security','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',211,'test43','2023-01-14 16:20:00','admin','2023-01-14','admin','2023-01-14 20:10:00',1,'0',0,0,1,'0','test43','2023-01-14 09:35:00','pass'),(244,0,61,161,0,0,0,0,242,1,'这个是测试用例244','这是前置条件244','这是关键词244',4,'interface','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',216,'test44','2023-01-14 16:30:00','admin','2023-01-14','admin','2023-01-14 20:15:00',1,'0',0,0,1,'0','test44','2023-01-14 09:43:20','fail'),(245,0,62,162,0,0,0,0,246,1,'这个是测试用例245','这是前置条件245','这是关键词245',1,'other','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',221,'test45','2023-01-14 16:40:00','admin','2023-01-14','admin','2023-01-14 20:20:00',1,'0',0,0,1,'0','test45','2023-01-14 09:51:40','pass'),(246,0,62,162,0,0,0,0,246,1,'这个是测试用例246','这是前置条件246','这是关键词246',2,'feature','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',226,'test46','2023-01-14 16:50:00','admin','2023-01-14','admin','2023-01-14 20:25:00',1,'0',0,0,1,'0','test46','2023-01-14 10:00:00','fail'),(247,0,62,162,0,0,0,0,246,1,'这个是测试用例247','这是前置条件247','这是关键词247',3,'performance','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',231,'test47','2023-01-14 17:00:00','admin','2023-01-14','admin','2023-01-14 20:30:00',1,'0',0,0,1,'0','test47','2023-01-14 10:08:20','pass'),(248,0,62,162,0,0,0,0,246,1,'这个是测试用例248','这是前置条件248','这是关键词248',4,'config','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',236,'test48','2023-01-14 17:10:00','admin','2023-01-14','admin','2023-01-14 20:35:00',1,'0',0,0,1,'0','test48','2023-01-14 10:16:40','fail'),(249,0,63,163,0,0,0,0,250,1,'这个是测试用例249','这是前置条件249','这是关键词249',1,'install','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',241,'test49','2023-01-14 17:20:00','admin','2023-01-14','admin','2023-01-14 20:40:00',1,'0',0,0,1,'0','test49','2023-01-14 10:25:00','pass'),(250,0,63,163,0,0,0,0,250,1,'这个是测试用例250','这是前置条件250','这是关键词250',2,'security','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',246,'test50','2023-01-14 17:30:00','admin','2023-01-14','admin','2023-01-14 20:45:00',1,'0',0,0,1,'0','test50','2023-01-14 10:33:20','fail'),(251,0,63,163,0,0,0,0,250,1,'这个是测试用例251','这是前置条件251','这是关键词251',3,'interface','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',251,'test51','2023-01-14 17:40:00','admin','2023-01-14','admin','2023-01-14 20:50:00',1,'0',0,0,1,'0','test51','2023-01-14 10:41:40','pass'),(252,0,63,163,0,0,0,0,250,1,'这个是测试用例252','这是前置条件252','这是关键词252',4,'other','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test52','2023-01-14 17:50:00','admin','2023-01-14','admin','2023-01-14 20:55:00',1,'0',0,0,1,'0','test52','2023-01-14 10:50:00','fail'),(253,0,64,164,0,0,0,0,254,1,'这个是测试用例253','这是前置条件253','这是关键词253',1,'feature','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test53','2023-01-14 18:00:00','admin','2023-01-14','admin','2023-01-14 21:00:00',1,'0',0,0,1,'0','test53','2023-01-14 10:58:20','pass'),(254,0,64,164,0,0,0,0,254,1,'这个是测试用例254','这是前置条件254','这是关键词254',2,'performance','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test54','2023-01-14 18:10:00','admin','2023-01-14','admin','2023-01-14 21:05:00',1,'0',0,0,1,'0','test54','2023-01-14 11:06:40','fail'),(255,0,64,164,0,0,0,0,254,1,'这个是测试用例255','这是前置条件255','这是关键词255',3,'config','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test55','2023-01-14 18:20:00','admin','2023-01-14','admin','2023-01-14 21:10:00',1,'0',0,0,1,'0','test55','2023-01-14 11:15:00','pass'),(256,0,64,164,0,0,0,0,254,1,'这个是测试用例256','这是前置条件256','这是关键词256',4,'install','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test56','2023-01-14 18:30:00','admin','2023-01-14','admin','2023-01-14 21:15:00',1,'0',0,0,1,'0','test56','2023-01-14 11:23:20','fail'),(257,0,65,165,0,0,0,0,258,1,'这个是测试用例257','这是前置条件257','这是关键词257',1,'security','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test57','2023-01-14 18:40:00','admin','2023-01-14','admin','2023-01-14 21:20:00',1,'0',0,0,1,'0','test57','2023-01-14 11:31:40','pass'),(258,0,65,165,0,0,0,0,258,1,'这个是测试用例258','这是前置条件258','这是关键词258',2,'interface','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test58','2023-01-14 18:50:00','admin','2023-01-14','admin','2023-01-14 21:25:00',1,'0',0,0,1,'0','test58','2023-01-14 11:40:00','fail'),(259,0,65,165,0,0,0,0,258,1,'这个是测试用例259','这是前置条件259','这是关键词259',3,'other','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test59','2023-01-14 19:00:00','admin','2023-01-14','admin','2023-01-14 21:30:00',1,'0',0,0,1,'0','test59','2023-01-14 11:48:20','pass'),(260,0,65,165,0,0,0,0,258,1,'这个是测试用例260','这是前置条件260','这是关键词260',4,'feature','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test60','2023-01-14 19:10:00','admin','2023-01-14','admin','2023-01-14 21:35:00',1,'0',0,0,1,'0','test60','2023-01-14 11:56:40','fail'),(261,0,66,166,0,0,0,0,262,1,'这个是测试用例261','这是前置条件261','这是关键词261',1,'performance','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test61','2023-01-14 19:20:00','admin','2023-01-14','admin','2023-01-14 21:40:00',1,'0',0,0,1,'0','test61','2023-01-14 12:05:00','pass'),(262,0,66,166,0,0,0,0,262,1,'这个是测试用例262','这是前置条件262','这是关键词262',2,'config','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test62','2023-01-14 19:30:00','admin','2023-01-14','admin','2023-01-14 21:45:00',1,'0',0,0,1,'0','test62','2023-01-14 12:13:20','fail'),(263,0,66,166,0,0,0,0,262,1,'这个是测试用例263','这是前置条件263','这是关键词263',3,'install','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test63','2023-01-14 19:40:00','admin','2023-01-14','admin','2023-01-14 21:50:00',1,'0',0,0,1,'0','test63','2023-01-14 12:21:40','pass'),(264,0,66,166,0,0,0,0,262,1,'这个是测试用例264','这是前置条件264','这是关键词264',4,'security','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test64','2023-01-14 19:50:00','admin','2023-01-14','admin','2023-01-14 21:55:00',1,'0',0,0,1,'0','test64','2023-01-14 12:30:00','fail'),(265,0,67,167,0,0,0,0,266,1,'这个是测试用例265','这是前置条件265','这是关键词265',1,'interface','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test65','2023-01-14 20:00:00','admin','2023-01-14','admin','2023-01-14 22:00:00',1,'0',0,0,1,'0','test65','2023-01-14 12:38:20','pass'),(266,0,67,167,0,0,0,0,266,1,'这个是测试用例266','这是前置条件266','这是关键词266',2,'other','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test66','2023-01-14 20:10:00','admin','2023-01-14','admin','2023-01-14 22:05:00',1,'0',0,0,1,'0','test66','2023-01-14 12:46:40','fail'),(267,0,67,167,0,0,0,0,266,1,'这个是测试用例267','这是前置条件267','这是关键词267',3,'feature','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test67','2023-01-14 20:20:00','admin','2023-01-14','admin','2023-01-14 22:10:00',1,'0',0,0,1,'0','test67','2023-01-14 12:55:00','pass'),(268,0,67,167,0,0,0,0,266,1,'这个是测试用例268','这是前置条件268','这是关键词268',4,'performance','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test68','2023-01-14 20:30:00','admin','2023-01-14','admin','2023-01-14 22:15:00',1,'0',0,0,1,'0','test68','2023-01-14 13:03:20','fail'),(269,0,68,168,0,0,0,0,270,1,'这个是测试用例269','这是前置条件269','这是关键词269',1,'config','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test69','2023-01-14 20:40:00','admin','2023-01-14','admin','2023-01-14 22:20:00',1,'0',0,0,1,'0','test69','2023-01-14 13:11:40','pass'),(270,0,68,168,0,0,0,0,270,1,'这个是测试用例270','这是前置条件270','这是关键词270',2,'install','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test70','2023-01-14 20:50:00','admin','2023-01-14','admin','2023-01-14 22:25:00',1,'0',0,0,1,'0','test70','2023-01-14 13:20:00','fail'),(271,0,68,168,0,0,0,0,270,1,'这个是测试用例271','这是前置条件271','这是关键词271',3,'security','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test71','2023-01-14 21:00:00','admin','2023-01-14','admin','2023-01-14 22:30:00',1,'0',0,0,1,'0','test71','2023-01-14 13:28:20','pass'),(272,0,68,168,0,0,0,0,270,1,'这个是测试用例272','这是前置条件272','这是关键词272',4,'interface','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test72','2023-01-14 21:10:00','admin','2023-01-14','admin','2023-01-14 22:35:00',1,'0',0,0,1,'0','test72','2023-01-14 13:36:40','fail'),(273,0,69,169,0,0,0,0,274,1,'这个是测试用例273','这是前置条件273','这是关键词273',1,'other','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test73','2023-01-14 21:20:00','admin','2023-01-14','admin','2023-01-14 22:40:00',1,'0',0,0,1,'0','test73','2023-01-14 13:45:00','pass'),(274,0,69,169,0,0,0,0,274,1,'这个是测试用例274','这是前置条件274','这是关键词274',2,'feature','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test74','2023-01-14 21:30:00','admin','2023-01-14','admin','2023-01-14 22:45:00',1,'0',0,0,1,'0','test74','2023-01-14 13:53:20','fail'),(275,0,69,169,0,0,0,0,274,1,'这个是测试用例275','这是前置条件275','这是关键词275',3,'performance','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test75','2023-01-14 21:40:00','admin','2023-01-14','admin','2023-01-14 22:50:00',1,'0',0,0,1,'0','test75','2023-01-14 14:01:40','pass'),(276,0,69,169,0,0,0,0,274,1,'这个是测试用例276','这是前置条件276','这是关键词276',4,'config','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test76','2023-01-14 21:50:00','admin','2023-01-14','admin','2023-01-14 22:55:00',1,'0',0,0,1,'0','test76','2023-01-14 14:10:00','fail'),(277,0,70,170,0,0,0,0,278,1,'这个是测试用例277','这是前置条件277','这是关键词277',1,'install','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test77','2023-01-14 22:00:00','admin','2023-01-14','admin','2023-01-14 23:00:00',1,'0',0,0,1,'0','test77','2023-01-14 14:18:20','pass'),(278,0,70,170,0,0,0,0,278,1,'这个是测试用例278','这是前置条件278','这是关键词278',2,'security','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test78','2023-01-14 22:10:00','admin','2023-01-14','admin','2023-01-14 23:05:00',1,'0',0,0,1,'0','test78','2023-01-14 14:26:40','fail'),(279,0,70,170,0,0,0,0,278,1,'这个是测试用例279','这是前置条件279','这是关键词279',3,'interface','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test79','2023-01-14 22:20:00','admin','2023-01-14','admin','2023-01-14 23:10:00',1,'0',0,0,1,'0','test79','2023-01-14 14:35:00','pass'),(280,0,70,170,0,0,0,0,278,1,'这个是测试用例280','这是前置条件280','这是关键词280',4,'other','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test80','2023-01-14 22:30:00','admin','2023-01-14','admin','2023-01-14 23:15:00',1,'0',0,0,1,'0','test80','2023-01-14 14:43:20','fail'),(281,0,71,171,0,0,0,0,282,1,'这个是测试用例281','这是前置条件281','这是关键词281',1,'feature','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test81','2023-01-14 22:40:00','admin','2023-01-14','admin','2023-01-14 23:20:00',1,'0',0,0,1,'0','test81','2023-01-14 14:51:40','pass'),(282,0,71,171,0,0,0,0,282,1,'这个是测试用例282','这是前置条件282','这是关键词282',2,'performance','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test82','2023-01-14 22:50:00','admin','2023-01-14','admin','2023-01-14 23:25:00',1,'0',0,0,1,'0','test82','2023-01-14 15:00:00','fail'),(283,0,71,171,0,0,0,0,282,1,'这个是测试用例283','这是前置条件283','这是关键词283',3,'config','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test83','2023-01-14 23:00:00','admin','2023-01-14','admin','2023-01-14 23:30:00',1,'0',0,0,1,'0','test83','2023-01-14 15:08:20','pass'),(284,0,71,171,0,0,0,0,282,1,'这个是测试用例284','这是前置条件284','这是关键词284',4,'install','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test84','2023-01-14 23:10:00','admin','2023-01-14','admin','2023-01-14 23:35:00',1,'0',0,0,1,'0','test84','2023-01-14 15:16:40','fail'),(285,0,72,172,0,0,0,0,286,1,'这个是测试用例285','这是前置条件285','这是关键词285',1,'security','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test85','2023-01-14 23:20:00','admin','2023-01-14','admin','2023-01-14 23:40:00',1,'0',0,0,1,'0','test85','2023-01-14 15:25:00','pass'),(286,0,72,172,0,0,0,0,286,1,'这个是测试用例286','这是前置条件286','这是关键词286',2,'interface','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test86','2023-01-14 23:30:00','admin','2023-01-14','admin','2023-01-14 23:45:00',1,'0',0,0,1,'0','test86','2023-01-14 15:33:20','fail'),(287,0,72,172,0,0,0,0,286,1,'这个是测试用例287','这是前置条件287','这是关键词287',3,'other','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test87','2023-01-14 23:40:00','admin','2023-01-14','admin','2023-01-14 23:50:00',1,'0',0,0,1,'0','test87','2023-01-14 15:41:40','pass'),(288,0,72,172,0,0,0,0,286,1,'这个是测试用例288','这是前置条件288','这是关键词288',4,'feature','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test88','2023-01-14 23:50:00','admin','2023-01-14','admin','2023-01-14 23:55:00',1,'0',0,0,1,'0','test88','2023-01-14 15:50:00','fail'),(289,0,73,173,0,0,0,0,290,1,'这个是测试用例289','这是前置条件289','这是关键词289',1,'performance','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test89','2023-01-14 00:00:00','admin','2023-01-14','admin','2023-01-14 00:00:00',1,'0',0,0,1,'0','test89','2023-01-14 15:58:20','pass'),(290,0,73,173,0,0,0,0,290,1,'这个是测试用例290','这是前置条件290','这是关键词290',2,'config','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test90','2023-01-14 00:10:00','admin','2023-01-14','admin','2023-01-14 00:05:00',1,'0',0,0,1,'0','test90','2023-01-14 16:06:40','fail'),(291,0,73,173,0,0,0,0,290,1,'这个是测试用例291','这是前置条件291','这是关键词291',3,'install','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test91','2023-01-14 00:20:00','admin','2023-01-14','admin','2023-01-14 00:10:00',1,'0',0,0,1,'0','test91','2023-01-14 16:15:00','pass'),(292,0,73,173,0,0,0,0,290,1,'这个是测试用例292','这是前置条件292','这是关键词292',4,'security','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test92','2023-01-14 00:30:00','admin','2023-01-14','admin','2023-01-14 00:15:00',1,'0',0,0,1,'0','test92','2023-01-14 16:23:20','fail'),(293,0,74,174,0,0,0,0,294,1,'这个是测试用例293','这是前置条件293','这是关键词293',1,'interface','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test93','2023-01-14 00:40:00','admin','2023-01-14','admin','2023-01-14 00:20:00',1,'0',0,0,1,'0','test93','2023-01-14 16:31:40','pass'),(294,0,74,174,0,0,0,0,294,1,'这个是测试用例294','这是前置条件294','这是关键词294',2,'other','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test94','2023-01-14 00:50:00','admin','2023-01-14','admin','2023-01-14 00:25:00',1,'0',0,0,1,'0','test94','2023-01-14 16:40:00','fail'),(295,0,74,174,0,0,0,0,294,1,'这个是测试用例295','这是前置条件295','这是关键词295',3,'feature','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test95','2023-01-14 01:00:00','admin','2023-01-14','admin','2023-01-14 00:30:00',1,'0',0,0,1,'0','test95','2023-01-14 16:48:20','pass'),(296,0,74,174,0,0,0,0,294,1,'这个是测试用例296','这是前置条件296','这是关键词296',4,'performance','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test96','2023-01-14 01:10:00','admin','2023-01-14','admin','2023-01-14 00:35:00',1,'0',0,0,1,'0','test96','2023-01-14 16:56:40','fail'),(297,0,75,175,0,0,0,0,298,1,'这个是测试用例297','这是前置条件297','这是关键词297',1,'config','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test97','2023-01-14 01:20:00','admin','2023-01-14','admin','2023-01-14 00:40:00',1,'0',0,0,1,'0','test97','2023-01-14 17:05:00','pass'),(298,0,75,175,0,0,0,0,298,1,'这个是测试用例298','这是前置条件298','这是关键词298',2,'install','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test98','2023-01-14 01:30:00','admin','2023-01-14','admin','2023-01-14 00:45:00',1,'0',0,0,1,'0','test98','2023-01-14 17:13:20','fail'),(299,0,75,175,0,0,0,0,298,1,'这个是测试用例299','这是前置条件299','这是关键词299',3,'security','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test99','2023-01-14 01:40:00','admin','2023-01-14','admin','2023-01-14 00:50:00',1,'0',0,0,1,'0','test99','2023-01-14 17:21:40','pass'),(300,0,75,175,0,0,0,0,298,1,'这个是测试用例300','这是前置条件300','这是关键词300',4,'interface','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test100','2023-01-14 01:50:00','admin','2023-01-14','admin','2023-01-14 00:55:00',1,'0',0,0,1,'0','test100','2023-01-14 17:30:00','fail'),(301,0,76,176,0,0,0,0,302,1,'这个是测试用例301','这是前置条件301','这是关键词301',1,'other','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',1,'test1','2023-01-14 02:00:00','admin','2023-01-14','admin','2023-01-14 01:00:00',1,'0',0,0,1,'0','test1','2023-01-14 17:38:20','pass'),(302,0,76,176,0,0,0,0,302,1,'这个是测试用例302','这是前置条件302','这是关键词302',2,'feature','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',6,'test2','2023-01-14 02:10:00','admin','2023-01-14','admin','2023-01-14 01:05:00',1,'0',0,0,1,'0','test2','2023-01-14 17:46:40','fail'),(303,0,76,176,0,0,0,0,302,1,'这个是测试用例303','这是前置条件303','这是关键词303',3,'performance','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',11,'test3','2023-01-14 02:20:00','admin','2023-01-14','admin','2023-01-14 01:10:00',1,'0',0,0,1,'0','test3','2023-01-14 17:55:00','pass'),(304,0,76,176,0,0,0,0,302,1,'这个是测试用例304','这是前置条件304','这是关键词304',4,'config','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',16,'test4','2023-01-14 02:30:00','admin','2023-01-14','admin','2023-01-14 01:15:00',1,'0',0,0,1,'0','test4','2023-01-14 18:03:20','fail'),(305,0,77,177,0,0,0,0,306,1,'这个是测试用例305','这是前置条件305','这是关键词305',1,'install','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',21,'test5','2023-01-14 02:40:00','admin','2023-01-14','admin','2023-01-14 01:20:00',1,'0',0,0,1,'0','test5','2023-01-14 18:11:40','pass'),(306,0,77,177,0,0,0,0,306,1,'这个是测试用例306','这是前置条件306','这是关键词306',2,'security','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',26,'test6','2023-01-14 02:50:00','admin','2023-01-14','admin','2023-01-14 01:25:00',1,'0',0,0,1,'0','test6','2023-01-14 18:20:00','fail'),(307,0,77,177,0,0,0,0,306,1,'这个是测试用例307','这是前置条件307','这是关键词307',3,'interface','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',31,'test7','2023-01-14 03:00:00','admin','2023-01-14','admin','2023-01-14 01:30:00',1,'0',0,0,1,'0','test7','2023-01-14 18:28:20','pass'),(308,0,77,177,0,0,0,0,306,1,'这个是测试用例308','这是前置条件308','这是关键词308',4,'other','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',36,'test8','2023-01-14 03:10:00','admin','2023-01-14','admin','2023-01-14 01:35:00',1,'0',0,0,1,'0','test8','2023-01-14 18:36:40','fail'),(309,0,78,178,0,0,0,0,310,1,'这个是测试用例309','这是前置条件309','这是关键词309',1,'feature','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',41,'test9','2023-01-14 03:20:00','admin','2023-01-14','admin','2023-01-14 01:40:00',1,'0',0,0,1,'0','test9','2023-01-14 18:45:00','pass'),(310,0,78,178,0,0,0,0,310,1,'这个是测试用例310','这是前置条件310','这是关键词310',2,'performance','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',46,'test10','2023-01-14 03:30:00','admin','2023-01-14','admin','2023-01-14 01:45:00',1,'0',0,0,1,'0','test10','2023-01-14 18:53:20','fail'),(311,0,78,178,0,0,0,0,310,1,'这个是测试用例311','这是前置条件311','这是关键词311',3,'config','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',51,'test11','2023-01-14 03:40:00','admin','2023-01-14','admin','2023-01-14 01:50:00',1,'0',0,0,1,'0','test11','2023-01-14 19:01:40','pass'),(312,0,78,178,0,0,0,0,310,1,'这个是测试用例312','这是前置条件312','这是关键词312',4,'install','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',56,'test12','2023-01-14 03:50:00','admin','2023-01-14','admin','2023-01-14 01:55:00',1,'0',0,0,1,'0','test12','2023-01-14 19:10:00','fail'),(313,0,79,179,0,0,0,0,314,1,'这个是测试用例313','这是前置条件313','这是关键词313',1,'security','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',61,'test13','2023-01-14 04:00:00','admin','2023-01-14','admin','2023-01-14 02:00:00',1,'0',0,0,1,'0','test13','2023-01-14 19:18:20','pass'),(314,0,79,179,0,0,0,0,314,1,'这个是测试用例314','这是前置条件314','这是关键词314',2,'interface','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',66,'test14','2023-01-14 04:10:00','admin','2023-01-14','admin','2023-01-14 02:05:00',1,'0',0,0,1,'0','test14','2023-01-14 19:26:40','fail'),(315,0,79,179,0,0,0,0,314,1,'这个是测试用例315','这是前置条件315','这是关键词315',3,'other','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',71,'test15','2023-01-14 04:20:00','admin','2023-01-14','admin','2023-01-14 02:10:00',1,'0',0,0,1,'0','test15','2023-01-14 19:35:00','pass'),(316,0,79,179,0,0,0,0,314,1,'这个是测试用例316','这是前置条件316','这是关键词316',4,'feature','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',76,'test16','2023-01-14 04:30:00','admin','2023-01-14','admin','2023-01-14 02:15:00',1,'0',0,0,1,'0','test16','2023-01-14 19:43:20','fail'),(317,0,80,180,0,0,0,0,318,1,'这个是测试用例317','这是前置条件317','这是关键词317',1,'performance','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',81,'test17','2023-01-14 04:40:00','admin','2023-01-14','admin','2023-01-14 02:20:00',1,'0',0,0,1,'0','test17','2023-01-14 19:51:40','pass'),(318,0,80,180,0,0,0,0,318,1,'这个是测试用例318','这是前置条件318','这是关键词318',2,'config','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',86,'test18','2023-01-14 04:50:00','admin','2023-01-14','admin','2023-01-14 02:25:00',1,'0',0,0,1,'0','test18','2023-01-14 20:00:00','fail'),(319,0,80,180,0,0,0,0,318,1,'这个是测试用例319','这是前置条件319','这是关键词319',3,'install','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',91,'test19','2023-01-14 05:00:00','admin','2023-01-14','admin','2023-01-14 02:30:00',1,'0',0,0,1,'0','test19','2023-01-14 20:08:20','pass'),(320,0,80,180,0,0,0,0,318,1,'这个是测试用例320','这是前置条件320','这是关键词320',4,'security','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',96,'test20','2023-01-14 05:10:00','admin','2023-01-14','admin','2023-01-14 02:35:00',1,'0',0,0,1,'0','test20','2023-01-14 20:16:40','fail'),(321,0,81,181,0,0,0,0,322,1,'这个是测试用例321','这是前置条件321','这是关键词321',1,'interface','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',101,'test21','2023-01-14 05:20:00','admin','2023-01-14','admin','2023-01-14 02:40:00',1,'0',0,0,1,'0','test21','2023-01-14 20:25:00','pass'),(322,0,81,181,0,0,0,0,322,1,'这个是测试用例322','这是前置条件322','这是关键词322',2,'other','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',106,'test22','2023-01-14 05:30:00','admin','2023-01-14','admin','2023-01-14 02:45:00',1,'0',0,0,1,'0','test22','2023-01-14 20:33:20','fail'),(323,0,81,181,0,0,0,0,322,1,'这个是测试用例323','这是前置条件323','这是关键词323',3,'feature','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',111,'test23','2023-01-14 05:40:00','admin','2023-01-14','admin','2023-01-14 02:50:00',1,'0',0,0,1,'0','test23','2023-01-14 20:41:40','pass'),(324,0,81,181,0,0,0,0,322,1,'这个是测试用例324','这是前置条件324','这是关键词324',4,'performance','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',116,'test24','2023-01-14 05:50:00','admin','2023-01-14','admin','2023-01-14 02:55:00',1,'0',0,0,1,'0','test24','2023-01-14 20:50:00','fail'),(325,0,82,182,0,0,0,0,326,1,'这个是测试用例325','这是前置条件325','这是关键词325',1,'config','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',121,'test25','2023-01-14 06:00:00','admin','2023-01-14','admin','2023-01-14 03:00:00',1,'0',0,0,1,'0','test25','2023-01-14 20:58:20','pass'),(326,0,82,182,0,0,0,0,326,1,'这个是测试用例326','这是前置条件326','这是关键词326',2,'install','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',126,'test26','2023-01-14 06:10:00','admin','2023-01-14','admin','2023-01-14 03:05:00',1,'0',0,0,1,'0','test26','2023-01-14 21:06:40','fail'),(327,0,82,182,0,0,0,0,326,1,'这个是测试用例327','这是前置条件327','这是关键词327',3,'security','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',131,'test27','2023-01-14 06:20:00','admin','2023-01-14','admin','2023-01-14 03:10:00',1,'0',0,0,1,'0','test27','2023-01-14 21:15:00','pass'),(328,0,82,182,0,0,0,0,326,1,'这个是测试用例328','这是前置条件328','这是关键词328',4,'interface','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',136,'test28','2023-01-14 06:30:00','admin','2023-01-14','admin','2023-01-14 03:15:00',1,'0',0,0,1,'0','test28','2023-01-14 21:23:20','fail'),(329,0,83,183,0,0,0,0,330,1,'这个是测试用例329','这是前置条件329','这是关键词329',1,'other','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',141,'test29','2023-01-14 06:40:00','admin','2023-01-14','admin','2023-01-14 03:20:00',1,'0',0,0,1,'0','test29','2023-01-14 21:31:40','pass'),(330,0,83,183,0,0,0,0,330,1,'这个是测试用例330','这是前置条件330','这是关键词330',2,'feature','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',146,'test30','2023-01-14 06:50:00','admin','2023-01-14','admin','2023-01-14 03:25:00',1,'0',0,0,1,'0','test30','2023-01-14 21:40:00','fail'),(331,0,83,183,0,0,0,0,330,1,'这个是测试用例331','这是前置条件331','这是关键词331',3,'performance','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',151,'test31','2023-01-14 07:00:00','admin','2023-01-14','admin','2023-01-14 03:30:00',1,'0',0,0,1,'0','test31','2023-01-14 21:48:20','pass'),(332,0,83,183,0,0,0,0,330,1,'这个是测试用例332','这是前置条件332','这是关键词332',4,'config','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',156,'test32','2023-01-14 07:10:00','admin','2023-01-14','admin','2023-01-14 03:35:00',1,'0',0,0,1,'0','test32','2023-01-14 21:56:40','fail'),(333,0,84,184,0,0,0,0,334,1,'这个是测试用例333','这是前置条件333','这是关键词333',1,'install','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',161,'test33','2023-01-14 07:20:00','admin','2023-01-14','admin','2023-01-14 03:40:00',1,'0',0,0,1,'0','test33','2023-01-14 22:05:00','pass'),(334,0,84,184,0,0,0,0,334,1,'这个是测试用例334','这是前置条件334','这是关键词334',2,'security','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',166,'test34','2023-01-14 07:30:00','admin','2023-01-14','admin','2023-01-14 03:45:00',1,'0',0,0,1,'0','test34','2023-01-14 22:13:20','fail'),(335,0,84,184,0,0,0,0,334,1,'这个是测试用例335','这是前置条件335','这是关键词335',3,'interface','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',171,'test35','2023-01-14 07:40:00','admin','2023-01-14','admin','2023-01-14 03:50:00',1,'0',0,0,1,'0','test35','2023-01-14 22:21:40','pass'),(336,0,84,184,0,0,0,0,334,1,'这个是测试用例336','这是前置条件336','这是关键词336',4,'other','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',176,'test36','2023-01-14 07:50:00','admin','2023-01-14','admin','2023-01-14 03:55:00',1,'0',0,0,1,'0','test36','2023-01-14 22:30:00','fail'),(337,0,85,185,0,0,0,0,338,1,'这个是测试用例337','这是前置条件337','这是关键词337',1,'feature','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',181,'test37','2023-01-14 08:00:00','admin','2023-01-14','admin','2023-01-14 04:00:00',1,'0',0,0,1,'0','test37','2023-01-14 22:38:20','pass'),(338,0,85,185,0,0,0,0,338,1,'这个是测试用例338','这是前置条件338','这是关键词338',2,'performance','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',186,'test38','2023-01-14 08:10:00','admin','2023-01-14','admin','2023-01-14 04:05:00',1,'0',0,0,1,'0','test38','2023-01-14 22:46:40','fail'),(339,0,85,185,0,0,0,0,338,1,'这个是测试用例339','这是前置条件339','这是关键词339',3,'config','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',191,'test39','2023-01-14 08:20:00','admin','2023-01-14','admin','2023-01-14 04:10:00',1,'0',0,0,1,'0','test39','2023-01-14 22:55:00','pass'),(340,0,85,185,0,0,0,0,338,1,'这个是测试用例340','这是前置条件340','这是关键词340',4,'install','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',196,'test40','2023-01-14 08:30:00','admin','2023-01-14','admin','2023-01-14 04:15:00',1,'0',0,0,1,'0','test40','2023-01-14 23:03:20','fail'),(341,0,86,186,0,0,0,0,342,1,'这个是测试用例341','这是前置条件341','这是关键词341',1,'security','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',201,'test41','2023-01-14 08:40:00','admin','2023-01-14','admin','2023-01-14 04:20:00',1,'0',0,0,1,'0','test41','2023-01-14 23:11:40','pass'),(342,0,86,186,0,0,0,0,342,1,'这个是测试用例342','这是前置条件342','这是关键词342',2,'interface','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',206,'test42','2023-01-14 08:50:00','admin','2023-01-14','admin','2023-01-14 04:25:00',1,'0',0,0,1,'0','test42','2023-01-14 23:20:00','fail'),(343,0,86,186,0,0,0,0,342,1,'这个是测试用例343','这是前置条件343','这是关键词343',3,'other','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',211,'test43','2023-01-14 09:00:00','admin','2023-01-14','admin','2023-01-14 04:30:00',1,'0',0,0,1,'0','test43','2023-01-14 23:28:20','pass'),(344,0,86,186,0,0,0,0,342,1,'这个是测试用例344','这是前置条件344','这是关键词344',4,'feature','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',216,'test44','2023-01-14 09:10:00','admin','2023-01-14','admin','2023-01-14 04:35:00',1,'0',0,0,1,'0','test44','2023-01-14 23:36:40','fail'),(345,0,87,187,0,0,0,0,346,1,'这个是测试用例345','这是前置条件345','这是关键词345',1,'performance','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',221,'test45','2023-01-14 09:20:00','admin','2023-01-14','admin','2023-01-14 04:40:00',1,'0',0,0,1,'0','test45','2023-01-14 23:45:00','pass'),(346,0,87,187,0,0,0,0,346,1,'这个是测试用例346','这是前置条件346','这是关键词346',2,'config','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',226,'test46','2023-01-14 09:30:00','admin','2023-01-14','admin','2023-01-14 04:45:00',1,'0',0,0,1,'0','test46','2023-01-14 23:53:20','fail'),(347,0,87,187,0,0,0,0,346,1,'这个是测试用例347','这是前置条件347','这是关键词347',3,'install','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',231,'test47','2023-01-14 09:40:00','admin','2023-01-14','admin','2023-01-14 04:50:00',1,'0',0,0,1,'0','test47','2023-01-14 00:00:00','pass'),(348,0,87,187,0,0,0,0,346,1,'这个是测试用例348','这是前置条件348','这是关键词348',4,'security','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',236,'test48','2023-01-14 09:50:00','admin','2023-01-14','admin','2023-01-14 04:55:00',1,'0',0,0,1,'0','test48','2023-01-14 00:08:20','fail'),(349,0,88,188,0,0,0,0,350,1,'这个是测试用例349','这是前置条件349','这是关键词349',1,'interface','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',241,'test49','2023-01-14 10:00:00','admin','2023-01-14','admin','2023-01-14 05:00:00',1,'0',0,0,1,'0','test49','2023-01-14 00:16:40','pass'),(350,0,88,188,0,0,0,0,350,1,'这个是测试用例350','这是前置条件350','这是关键词350',2,'other','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',246,'test50','2023-01-14 10:10:00','admin','2023-01-14','admin','2023-01-14 05:05:00',1,'0',0,0,1,'0','test50','2023-01-14 00:25:00','fail'),(351,0,88,188,0,0,0,0,350,1,'这个是测试用例351','这是前置条件351','这是关键词351',3,'feature','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',251,'test51','2023-01-14 10:20:00','admin','2023-01-14','admin','2023-01-14 05:10:00',1,'0',0,0,1,'0','test51','2023-01-14 00:33:20','pass'),(352,0,88,188,0,0,0,0,350,1,'这个是测试用例352','这是前置条件352','这是关键词352',4,'performance','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test52','2023-01-14 10:30:00','admin','2023-01-14','admin','2023-01-14 05:15:00',1,'0',0,0,1,'0','test52','2023-01-14 00:41:40','fail'),(353,0,89,189,0,0,0,0,354,1,'这个是测试用例353','这是前置条件353','这是关键词353',1,'config','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test53','2023-01-14 10:40:00','admin','2023-01-14','admin','2023-01-14 05:20:00',1,'0',0,0,1,'0','test53','2023-01-14 00:50:00','pass'),(354,0,89,189,0,0,0,0,354,1,'这个是测试用例354','这是前置条件354','这是关键词354',2,'install','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test54','2023-01-14 10:50:00','admin','2023-01-14','admin','2023-01-14 05:25:00',1,'0',0,0,1,'0','test54','2023-01-14 00:58:20','fail'),(355,0,89,189,0,0,0,0,354,1,'这个是测试用例355','这是前置条件355','这是关键词355',3,'security','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test55','2023-01-14 11:00:00','admin','2023-01-14','admin','2023-01-14 05:30:00',1,'0',0,0,1,'0','test55','2023-01-14 01:06:40','pass'),(356,0,89,189,0,0,0,0,354,1,'这个是测试用例356','这是前置条件356','这是关键词356',4,'interface','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test56','2023-01-14 11:10:00','admin','2023-01-14','admin','2023-01-14 05:35:00',1,'0',0,0,1,'0','test56','2023-01-14 01:15:00','fail'),(357,0,90,190,0,0,0,0,358,1,'这个是测试用例357','这是前置条件357','这是关键词357',1,'other','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test57','2023-01-14 11:20:00','admin','2023-01-14','admin','2023-01-14 05:40:00',1,'0',0,0,1,'0','test57','2023-01-14 01:23:20','pass'),(358,0,90,190,0,0,0,0,358,1,'这个是测试用例358','这是前置条件358','这是关键词358',2,'feature','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test58','2023-01-14 11:30:00','admin','2023-01-14','admin','2023-01-14 05:45:00',1,'0',0,0,1,'0','test58','2023-01-14 01:31:40','fail'),(359,0,90,190,0,0,0,0,358,1,'这个是测试用例359','这是前置条件359','这是关键词359',3,'performance','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test59','2023-01-14 11:40:00','admin','2023-01-14','admin','2023-01-14 05:50:00',1,'0',0,0,1,'0','test59','2023-01-14 01:40:00','pass'),(360,0,90,190,0,0,0,0,358,1,'这个是测试用例360','这是前置条件360','这是关键词360',4,'config','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test60','2023-01-14 11:50:00','admin','2023-01-14','admin','2023-01-14 05:55:00',1,'0',0,0,1,'0','test60','2023-01-14 01:48:20','fail'),(361,0,91,191,0,0,0,0,362,1,'这个是测试用例361','这是前置条件361','这是关键词361',1,'install','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test61','2023-01-14 12:00:00','admin','2023-01-14','admin','2023-01-14 06:00:00',1,'0',0,0,1,'0','test61','2023-01-14 01:56:40','pass'),(362,0,91,191,0,0,0,0,362,1,'这个是测试用例362','这是前置条件362','这是关键词362',2,'security','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test62','2023-01-14 12:10:00','admin','2023-01-14','admin','2023-01-14 06:05:00',1,'0',0,0,1,'0','test62','2023-01-14 02:05:00','fail'),(363,0,91,191,0,0,0,0,362,1,'这个是测试用例363','这是前置条件363','这是关键词363',3,'interface','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test63','2023-01-14 12:20:00','admin','2023-01-14','admin','2023-01-14 06:10:00',1,'0',0,0,1,'0','test63','2023-01-14 02:13:20','pass'),(364,0,91,191,0,0,0,0,362,1,'这个是测试用例364','这是前置条件364','这是关键词364',4,'other','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test64','2023-01-14 12:30:00','admin','2023-01-14','admin','2023-01-14 06:15:00',1,'0',0,0,1,'0','test64','2023-01-14 02:21:40','fail'),(365,0,92,192,0,0,0,0,366,1,'这个是测试用例365','这是前置条件365','这是关键词365',1,'feature','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test65','2023-01-14 12:40:00','admin','2023-01-14','admin','2023-01-14 06:20:00',1,'0',0,0,1,'0','test65','2023-01-14 02:30:00','pass'),(366,0,92,192,0,0,0,0,366,1,'这个是测试用例366','这是前置条件366','这是关键词366',2,'performance','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test66','2023-01-14 12:50:00','admin','2023-01-14','admin','2023-01-14 06:25:00',1,'0',0,0,1,'0','test66','2023-01-14 02:38:20','fail'),(367,0,92,192,0,0,0,0,366,1,'这个是测试用例367','这是前置条件367','这是关键词367',3,'config','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test67','2023-01-14 13:00:00','admin','2023-01-14','admin','2023-01-14 06:30:00',1,'0',0,0,1,'0','test67','2023-01-14 02:46:40','pass'),(368,0,92,192,0,0,0,0,366,1,'这个是测试用例368','这是前置条件368','这是关键词368',4,'install','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test68','2023-01-14 13:10:00','admin','2023-01-14','admin','2023-01-14 06:35:00',1,'0',0,0,1,'0','test68','2023-01-14 02:55:00','fail'),(369,0,93,193,0,0,0,0,370,1,'这个是测试用例369','这是前置条件369','这是关键词369',1,'security','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test69','2023-01-14 13:20:00','admin','2023-01-14','admin','2023-01-14 06:40:00',1,'0',0,0,1,'0','test69','2023-01-14 03:03:20','pass'),(370,0,93,193,0,0,0,0,370,1,'这个是测试用例370','这是前置条件370','这是关键词370',2,'interface','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test70','2023-01-14 13:30:00','admin','2023-01-14','admin','2023-01-14 06:45:00',1,'0',0,0,1,'0','test70','2023-01-14 03:11:40','fail'),(371,0,93,193,0,0,0,0,370,1,'这个是测试用例371','这是前置条件371','这是关键词371',3,'other','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test71','2023-01-14 13:40:00','admin','2023-01-14','admin','2023-01-14 06:50:00',1,'0',0,0,1,'0','test71','2023-01-14 03:20:00','pass'),(372,0,93,193,0,0,0,0,370,1,'这个是测试用例372','这是前置条件372','这是关键词372',4,'feature','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test72','2023-01-14 13:50:00','admin','2023-01-14','admin','2023-01-14 06:55:00',1,'0',0,0,1,'0','test72','2023-01-14 03:28:20','fail'),(373,0,94,194,0,0,0,0,374,1,'这个是测试用例373','这是前置条件373','这是关键词373',1,'performance','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test73','2023-01-14 14:00:00','admin','2023-01-14','admin','2023-01-14 07:00:00',1,'0',0,0,1,'0','test73','2023-01-14 03:36:40','pass'),(374,0,94,194,0,0,0,0,374,1,'这个是测试用例374','这是前置条件374','这是关键词374',2,'config','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test74','2023-01-14 14:10:00','admin','2023-01-14','admin','2023-01-14 07:05:00',1,'0',0,0,1,'0','test74','2023-01-14 03:45:00','fail'),(375,0,94,194,0,0,0,0,374,1,'这个是测试用例375','这是前置条件375','这是关键词375',3,'install','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test75','2023-01-14 14:20:00','admin','2023-01-14','admin','2023-01-14 07:10:00',1,'0',0,0,1,'0','test75','2023-01-14 03:53:20','pass'),(376,0,94,194,0,0,0,0,374,1,'这个是测试用例376','这是前置条件376','这是关键词376',4,'security','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test76','2023-01-14 14:30:00','admin','2023-01-14','admin','2023-01-14 07:15:00',1,'0',0,0,1,'0','test76','2023-01-14 04:01:40','fail'),(377,0,95,195,0,0,0,0,378,1,'这个是测试用例377','这是前置条件377','这是关键词377',1,'interface','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test77','2023-01-14 14:40:00','admin','2023-01-14','admin','2023-01-14 07:20:00',1,'0',0,0,1,'0','test77','2023-01-14 04:10:00','pass'),(378,0,95,195,0,0,0,0,378,1,'这个是测试用例378','这是前置条件378','这是关键词378',2,'other','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test78','2023-01-14 14:50:00','admin','2023-01-14','admin','2023-01-14 07:25:00',1,'0',0,0,1,'0','test78','2023-01-14 04:18:20','fail'),(379,0,95,195,0,0,0,0,378,1,'这个是测试用例379','这是前置条件379','这是关键词379',3,'feature','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test79','2023-01-14 15:00:00','admin','2023-01-14','admin','2023-01-14 07:30:00',1,'0',0,0,1,'0','test79','2023-01-14 04:26:40','pass'),(380,0,95,195,0,0,0,0,378,1,'这个是测试用例380','这是前置条件380','这是关键词380',4,'performance','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test80','2023-01-14 15:10:00','admin','2023-01-14','admin','2023-01-14 07:35:00',1,'0',0,0,1,'0','test80','2023-01-14 04:35:00','fail'),(381,0,96,196,0,0,0,0,382,1,'这个是测试用例381','这是前置条件381','这是关键词381',1,'config','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test81','2023-01-14 15:20:00','admin','2023-01-14','admin','2023-01-14 07:40:00',1,'0',0,0,1,'0','test81','2023-01-14 04:43:20','pass'),(382,0,96,196,0,0,0,0,382,1,'这个是测试用例382','这是前置条件382','这是关键词382',2,'install','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test82','2023-01-14 15:30:00','admin','2023-01-14','admin','2023-01-14 07:45:00',1,'0',0,0,1,'0','test82','2023-01-14 04:51:40','fail'),(383,0,96,196,0,0,0,0,382,1,'这个是测试用例383','这是前置条件383','这是关键词383',3,'security','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test83','2023-01-14 15:40:00','admin','2023-01-14','admin','2023-01-14 07:50:00',1,'0',0,0,1,'0','test83','2023-01-14 05:00:00','pass'),(384,0,96,196,0,0,0,0,382,1,'这个是测试用例384','这是前置条件384','这是关键词384',4,'interface','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test84','2023-01-14 15:50:00','admin','2023-01-14','admin','2023-01-14 07:55:00',1,'0',0,0,1,'0','test84','2023-01-14 05:08:20','fail'),(385,0,97,197,0,0,0,0,386,1,'这个是测试用例385','这是前置条件385','这是关键词385',1,'other','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test85','2023-01-14 16:00:00','admin','2023-01-14','admin','2023-01-14 08:00:00',1,'0',0,0,1,'0','test85','2023-01-14 05:16:40','pass'),(386,0,97,197,0,0,0,0,386,1,'这个是测试用例386','这是前置条件386','这是关键词386',2,'feature','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test86','2023-01-14 16:10:00','admin','2023-01-14','admin','2023-01-14 08:05:00',1,'0',0,0,1,'0','test86','2023-01-14 05:25:00','fail'),(387,0,97,197,0,0,0,0,386,1,'这个是测试用例387','这是前置条件387','这是关键词387',3,'performance','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test87','2023-01-14 16:20:00','admin','2023-01-14','admin','2023-01-14 08:10:00',1,'0',0,0,1,'0','test87','2023-01-14 05:33:20','pass'),(388,0,97,197,0,0,0,0,386,1,'这个是测试用例388','这是前置条件388','这是关键词388',4,'config','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test88','2023-01-14 16:30:00','admin','2023-01-14','admin','2023-01-14 08:15:00',1,'0',0,0,1,'0','test88','2023-01-14 05:41:40','fail'),(389,0,98,198,0,0,0,0,390,1,'这个是测试用例389','这是前置条件389','这是关键词389',1,'install','no','','smoke','','','','0000-00-00','','','wait','','#ffaf38','2',255,'test89','2023-01-14 16:40:00','admin','2023-01-14','admin','2023-01-14 08:20:00',1,'0',0,0,1,'0','test89','2023-01-14 05:50:00','pass'),(390,0,98,198,0,0,0,0,390,1,'这个是测试用例390','这是前置条件390','这是关键词390',2,'security','no','','bvt','','','','0000-00-00','','','normal','','#ff4e3e','3',255,'test90','2023-01-14 16:50:00','admin','2023-01-14','admin','2023-01-14 08:25:00',1,'0',0,0,1,'0','test90','2023-01-14 05:58:20','fail'),(391,0,98,198,0,0,0,0,390,1,'这个是测试用例391','这是前置条件391','这是关键词391',3,'interface','no','','unittest','','','','0000-00-00','','','blocked','','#3da7f5','1',255,'test91','2023-01-14 17:00:00','admin','2023-01-14','admin','2023-01-14 08:30:00',1,'0',0,0,1,'0','test91','2023-01-14 06:06:40','pass'),(392,0,98,198,0,0,0,0,390,1,'这个是测试用例392','这是前置条件392','这是关键词392',4,'other','no','','feature','','','','0000-00-00','','','investigate','','#75c941','2',255,'test92','2023-01-14 17:10:00','admin','2023-01-14','admin','2023-01-14 08:35:00',1,'0',0,0,1,'0','test92','2023-01-14 06:15:00','fail'),(393,0,99,199,0,0,0,0,394,1,'这个是测试用例393','这是前置条件393','这是关键词393',1,'feature','no','','intergrate','','','','0000-00-00','','','wait','','#2dbdb2','3',255,'test93','2023-01-14 17:20:00','admin','2023-01-14','admin','2023-01-14 08:40:00',1,'0',0,0,1,'0','test93','2023-01-14 06:23:20','pass'),(394,0,99,199,0,0,0,0,394,1,'这个是测试用例394','这是前置条件394','这是关键词394',2,'performance','no','','system','','','','0000-00-00','','','normal','','#797ec9','1',255,'test94','2023-01-14 17:30:00','admin','2023-01-14','admin','2023-01-14 08:45:00',1,'0',0,0,1,'0','test94','2023-01-14 06:31:40','fail'),(395,0,99,199,0,0,0,0,394,1,'这个是测试用例395','这是前置条件395','这是关键词395',3,'config','no','','smoke','','','','0000-00-00','','','blocked','','#ffaf38','2',255,'test95','2023-01-14 17:40:00','admin','2023-01-14','admin','2023-01-14 08:50:00',1,'0',0,0,1,'0','test95','2023-01-14 06:40:00','pass'),(396,0,99,199,0,0,0,0,394,1,'这个是测试用例396','这是前置条件396','这是关键词396',4,'install','no','','bvt','','','','0000-00-00','','','investigate','','#ff4e3e','3',255,'test96','2023-01-14 17:50:00','admin','2023-01-14','admin','2023-01-14 08:55:00',1,'0',0,0,1,'0','test96','2023-01-14 06:48:20','fail'),(397,0,100,200,0,0,0,0,398,1,'这个是测试用例397','这是前置条件397','这是关键词397',1,'security','no','','unittest','','','','0000-00-00','','','wait','','#3da7f5','1',255,'test97','2023-01-14 18:00:00','admin','2023-01-14','admin','2023-01-14 09:00:00',1,'0',0,0,1,'0','test97','2023-01-14 06:56:40','pass'),(398,0,100,200,0,0,0,0,398,1,'这个是测试用例398','这是前置条件398','这是关键词398',2,'interface','no','','feature','','','','0000-00-00','','','normal','','#75c941','2',255,'test98','2023-01-14 18:10:00','admin','2023-01-14','admin','2023-01-14 09:05:00',1,'0',0,0,1,'0','test98','2023-01-14 07:05:00','fail'),(399,0,100,200,0,0,0,0,398,1,'这个是测试用例399','这是前置条件399','这是关键词399',3,'other','no','','intergrate','','','','0000-00-00','','','blocked','','#2dbdb2','3',255,'test99','2023-01-14 18:20:00','admin','2023-01-14','admin','2023-01-14 09:10:00',1,'0',0,0,1,'0','test99','2023-01-14 07:13:20','pass'),(400,0,100,200,0,0,0,0,398,1,'这个是测试用例400','这是前置条件400','这是关键词400',4,'feature','no','','system','','','','0000-00-00','','','investigate','','#797ec9','1',255,'test100','2023-01-14 18:30:00','admin','2023-01-14','admin','2023-01-14 09:15:00',1,'0',0,0,1,'0','test100','2023-01-14 07:21:40','fail');
+/*!40000 ALTER TABLE `zt_case` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:33:15
diff --git a/module/user/test/model/data/sql/product.sql b/module/user/test/model/data/sql/product.sql
new file mode 100644
index 0000000000..e18c167692
--- /dev/null
+++ b/module/user/test/model/data/sql/product.sql
@@ -0,0 +1,76 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_product`
+--
+
+DROP TABLE IF EXISTS `zt_product`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_product` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `program` mediumint(8) unsigned NOT NULL,
+ `name` varchar(110) NOT NULL,
+ `code` varchar(45) NOT NULL,
+ `shadow` tinyint(1) unsigned NOT NULL,
+ `bind` enum('0','1') NOT NULL DEFAULT '0',
+ `line` mediumint(8) NOT NULL,
+ `type` varchar(30) NOT NULL DEFAULT 'normal',
+ `status` varchar(30) NOT NULL DEFAULT '',
+ `subStatus` varchar(30) NOT NULL DEFAULT '',
+ `desc` mediumtext NOT NULL,
+ `PO` varchar(30) NOT NULL,
+ `QD` varchar(30) NOT NULL,
+ `RD` varchar(30) NOT NULL,
+ `feedback` varchar(30) NOT NULL,
+ `ticket` varchar(30) NOT NULL,
+ `acl` enum('open','private','custom') NOT NULL DEFAULT 'open',
+ `whitelist` text NOT NULL,
+ `reviewer` text NOT NULL,
+ `createdBy` varchar(30) NOT NULL,
+ `createdDate` datetime NOT NULL,
+ `createdVersion` varchar(20) NOT NULL,
+ `order` mediumint(8) unsigned NOT NULL,
+ `vision` varchar(10) NOT NULL DEFAULT 'rnd',
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `acl` (`acl`),
+ KEY `order` (`order`)
+) ENGINE=InnoDB AUTO_INCREMENT=121 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_product`
+--
+
+LOCK TABLES `zt_product` WRITE;
+/*!40000 ALTER TABLE `zt_product` DISABLE KEYS */;
+INSERT INTO `zt_product` VALUES (1,0,'正常产品1','code1',0,'0',0,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po1','test1','dev1','','','open','','','po1','2023-01-14 00:00:00','15.6',5,'rnd','0'),(2,1,'正常产品2','code2',0,'0',1,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po2','test2','dev2','','','open','','','po2','2023-01-14 00:01:00','15.6',10,'rnd','0'),(3,2,'正常产品3','code3',0,'0',2,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po3','test3','dev3','','','open','','','po3','2023-01-14 00:02:00','15.6',15,'rnd','0'),(4,3,'正常产品4','code4',0,'0',3,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po4','test4','dev4','','','open','','','po4','2023-01-14 00:03:00','15.6',20,'rnd','0'),(5,4,'正常产品5','code5',0,'0',4,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po5','test5','dev5','','','open','','','po5','2023-01-14 00:04:00','15.6',25,'rnd','0'),(6,5,'正常产品6','code6',0,'0',5,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po6','test6','dev6','','','open','','','po6','2023-01-14 00:05:00','15.6',30,'rnd','0'),(7,6,'正常产品7','code7',0,'0',6,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po7','test7','dev7','','','open','','','po7','2023-01-14 00:06:00','15.6',35,'rnd','0'),(8,7,'正常产品8','code8',0,'0',7,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po8','test8','dev8','','','open','','','po8','2023-01-14 00:07:00','15.6',40,'rnd','0'),(9,8,'正常产品9','code9',0,'0',8,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po9','test9','dev9','','','open','','','po9','2023-01-14 00:08:00','15.6',45,'rnd','0'),(10,9,'正常产品10','code10',0,'0',9,'normal','normal','0',' 一、禅道项目管理软件是做什么的?
禅道由 青岛易软天创网络科技有限公司开发,国产开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整覆盖了研发项目管理的核心流程。禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的API可以调用。禅道,专注研发项目管理
我是数字符号23@#$%#^$
我是英文dashcuscbrewg
','po10','test10','dev10','','','open','','','po10','2023-01-14 00:09:00','15.6',50,'rnd','0');
+/*!40000 ALTER TABLE `zt_product` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 14:04:25
diff --git a/module/user/test/model/data/sql/project.sql b/module/user/test/model/data/sql/project.sql
new file mode 100644
index 0000000000..d585cd74af
--- /dev/null
+++ b/module/user/test/model/data/sql/project.sql
@@ -0,0 +1,113 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_project`
+--
+
+DROP TABLE IF EXISTS `zt_project`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_project` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `project` mediumint(8) NOT NULL DEFAULT 0,
+ `model` char(30) NOT NULL,
+ `type` char(30) NOT NULL DEFAULT 'sprint',
+ `lifetime` char(30) NOT NULL DEFAULT '',
+ `budget` varchar(30) NOT NULL DEFAULT '0',
+ `budgetUnit` char(30) NOT NULL DEFAULT 'CNY',
+ `attribute` varchar(30) NOT NULL DEFAULT '',
+ `percent` float unsigned NOT NULL DEFAULT 0,
+ `milestone` enum('0','1') NOT NULL DEFAULT '0',
+ `output` text NOT NULL,
+ `auth` char(30) NOT NULL,
+ `parent` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `path` varchar(255) NOT NULL,
+ `grade` tinyint(3) unsigned NOT NULL,
+ `name` varchar(90) NOT NULL,
+ `code` varchar(45) NOT NULL,
+ `hasProduct` tinyint(1) unsigned NOT NULL DEFAULT 1,
+ `begin` date NOT NULL,
+ `end` date NOT NULL,
+ `realBegan` date NOT NULL,
+ `realEnd` date NOT NULL,
+ `days` smallint(5) unsigned NOT NULL,
+ `status` varchar(10) NOT NULL,
+ `subStatus` varchar(30) NOT NULL DEFAULT '',
+ `pri` enum('1','2','3','4') NOT NULL DEFAULT '1',
+ `desc` mediumtext NOT NULL,
+ `version` smallint(6) NOT NULL,
+ `parentVersion` smallint(6) NOT NULL,
+ `planDuration` int(11) NOT NULL,
+ `realDuration` int(11) NOT NULL,
+ `openedBy` varchar(30) NOT NULL DEFAULT '',
+ `openedDate` datetime NOT NULL,
+ `openedVersion` varchar(20) NOT NULL,
+ `lastEditedBy` varchar(30) NOT NULL DEFAULT '',
+ `lastEditedDate` datetime NOT NULL,
+ `closedBy` varchar(30) NOT NULL DEFAULT '',
+ `closedDate` datetime NOT NULL,
+ `canceledBy` varchar(30) NOT NULL DEFAULT '',
+ `canceledDate` datetime NOT NULL,
+ `suspendedDate` date NOT NULL,
+ `PO` varchar(30) NOT NULL DEFAULT '',
+ `PM` varchar(30) NOT NULL DEFAULT '',
+ `QD` varchar(30) NOT NULL DEFAULT '',
+ `RD` varchar(30) NOT NULL DEFAULT '',
+ `team` varchar(90) NOT NULL,
+ `acl` char(30) NOT NULL DEFAULT 'open',
+ `whitelist` text NOT NULL,
+ `order` mediumint(8) unsigned NOT NULL,
+ `vision` varchar(10) NOT NULL DEFAULT 'rnd',
+ `division` enum('0','1') NOT NULL DEFAULT '1',
+ `displayCards` smallint(6) NOT NULL DEFAULT 0,
+ `fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
+ `multiple` enum('0','1') NOT NULL DEFAULT '1',
+ `colWidth` smallint(4) NOT NULL DEFAULT 264,
+ `minColWidth` smallint(4) NOT NULL DEFAULT 200,
+ `maxColWidth` smallint(4) NOT NULL DEFAULT 384,
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `parent` (`parent`),
+ KEY `begin` (`begin`),
+ KEY `end` (`end`),
+ KEY `status` (`status`),
+ KEY `acl` (`acl`),
+ KEY `order` (`order`)
+) ENGINE=InnoDB AUTO_INCREMENT=751 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_project`
+--
+
+LOCK TABLES `zt_project` WRITE;
+/*!40000 ALTER TABLE `zt_project` DISABLE KEYS */;
+INSERT INTO `zt_project` VALUES (11,1,'scrum','project','','900000','CNY','',81,'0','','extend',1,',1,11,',2,'项目1','project1',1,'2022-10-14','2023-02-18','0000-00-00','0000-00-00',0,'wait','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','open','',5,'rnd','1',0,'0','1',264,200,384,'0'),(12,2,'scrum','project','','899900','USD','',56,'0','','extend',2,',2,12,',2,'项目2','project2',1,'2022-10-15','2023-02-19','0000-00-00','0000-00-00',0,'wait','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','private','',10,'rnd','1',0,'0','1',264,200,384,'0'),(13,3,'scrum','project','','899800','CNY','',95,'0','','extend',3,',3,13,',2,'项目3','project3',1,'2022-10-16','2023-02-20','0000-00-00','0000-00-00',0,'doing','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','program','',15,'rnd','1',0,'0','1',264,200,384,'0'),(14,4,'scrum','project','','899700','USD','',2,'0','','extend',4,',4,14,',2,'项目4','project4',1,'2022-10-17','2023-02-21','0000-00-00','0000-00-00',0,'doing','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','open','',20,'rnd','1',0,'0','1',264,200,384,'0'),(15,5,'scrum','project','','899600','CNY','',58,'0','','extend',5,',5,15,',2,'项目5','project5',1,'2022-10-18','2023-02-22','0000-00-00','0000-00-00',0,'doing','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','private','',25,'rnd','1',0,'0','1',264,200,384,'0'),(16,6,'scrum','project','','899500','USD','',40,'0','','extend',6,',6,16,',2,'项目6','project6',1,'2022-10-19','2023-02-23','0000-00-00','0000-00-00',0,'doing','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','program','',30,'rnd','1',0,'0','1',264,200,384,'0'),(17,7,'scrum','project','','899400','CNY','',4,'0','','extend',7,',7,17,',2,'项目7','project7',1,'2022-10-20','2023-02-24','0000-00-00','0000-00-00',0,'suspended','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','open','',35,'rnd','1',0,'0','1',264,200,384,'0'),(18,8,'scrum','project','','899300','USD','',87,'0','','extend',8,',8,18,',2,'项目8','project8',1,'2022-10-21','2023-02-25','0000-00-00','0000-00-00',0,'closed','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','private','',40,'rnd','1',0,'0','1',264,200,384,'0'),(19,9,'scrum','project','','899200','CNY','',80,'0','','extend',9,',9,19,',2,'项目9','project9',1,'2022-10-22','2023-02-26','0000-00-00','0000-00-00',0,'wait','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','program','',45,'rnd','1',0,'0','1',264,200,384,'0'),(20,10,'scrum','project','','899100','USD','',28,'0','','extend',10,',10,20,',2,'项目10','project10',1,'2022-10-23','2023-02-27','0000-00-00','0000-00-00',0,'wait','','1','',0,0,0,0,'','0000-00-00 00:00:00','16.5','','0000-00-00 00:00:00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','0000-00-00','','','','','','open','',50,'rnd','1',0,'0','1',264,200,384,'0');
+/*!40000 ALTER TABLE `zt_project` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:53:42
diff --git a/module/user/test/model/data/sql/story.sql b/module/user/test/model/data/sql/story.sql
new file mode 100644
index 0000000000..0c9d87f9a8
--- /dev/null
+++ b/module/user/test/model/data/sql/story.sql
@@ -0,0 +1,105 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_story`
+--
+
+DROP TABLE IF EXISTS `zt_story`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_story` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `vision` varchar(10) NOT NULL DEFAULT 'rnd',
+ `parent` mediumint(9) NOT NULL DEFAULT 0,
+ `product` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `branch` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `module` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `plan` text DEFAULT NULL,
+ `source` varchar(20) NOT NULL,
+ `sourceNote` varchar(255) NOT NULL,
+ `fromBug` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `feedback` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `title` varchar(255) NOT NULL,
+ `keywords` varchar(255) NOT NULL,
+ `type` varchar(30) NOT NULL DEFAULT 'story',
+ `category` varchar(30) NOT NULL DEFAULT 'feature',
+ `pri` tinyint(3) unsigned NOT NULL DEFAULT 3,
+ `estimate` float unsigned NOT NULL,
+ `status` enum('','changing','active','draft','reviewing','closed') NOT NULL DEFAULT '',
+ `subStatus` varchar(30) NOT NULL DEFAULT '',
+ `color` char(7) NOT NULL,
+ `stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released','closed') NOT NULL DEFAULT 'wait',
+ `stagedBy` char(30) NOT NULL,
+ `mailto` text DEFAULT NULL,
+ `lib` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `fromStory` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `fromVersion` smallint(6) NOT NULL DEFAULT 1,
+ `openedBy` varchar(30) NOT NULL DEFAULT '',
+ `openedDate` datetime NOT NULL,
+ `assignedTo` varchar(30) NOT NULL DEFAULT '',
+ `assignedDate` datetime NOT NULL,
+ `approvedDate` date NOT NULL,
+ `lastEditedBy` varchar(30) NOT NULL DEFAULT '',
+ `lastEditedDate` datetime NOT NULL,
+ `changedBy` varchar(30) NOT NULL,
+ `changedDate` datetime NOT NULL,
+ `reviewedBy` varchar(255) NOT NULL,
+ `reviewedDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `closedBy` varchar(30) NOT NULL DEFAULT '',
+ `closedDate` datetime NOT NULL,
+ `closedReason` varchar(30) NOT NULL,
+ `activatedDate` datetime NOT NULL,
+ `toBug` mediumint(8) unsigned NOT NULL,
+ `childStories` varchar(255) NOT NULL,
+ `linkStories` varchar(255) NOT NULL,
+ `linkRequirements` varchar(255) NOT NULL,
+ `twins` varchar(255) NOT NULL,
+ `duplicateStory` mediumint(8) unsigned NOT NULL,
+ `version` smallint(6) NOT NULL DEFAULT 1,
+ `storyChanged` enum('0','1') NOT NULL DEFAULT '0',
+ `feedbackBy` varchar(100) NOT NULL,
+ `notifyEmail` varchar(100) NOT NULL,
+ `URChanged` enum('0','1') NOT NULL DEFAULT '0',
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `product` (`product`),
+ KEY `status` (`status`),
+ KEY `assignedTo` (`assignedTo`)
+) ENGINE=InnoDB AUTO_INCREMENT=1751 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_story`
+--
+
+LOCK TABLES `zt_story` WRITE;
+/*!40000 ALTER TABLE `zt_story` DISABLE KEYS */;
+INSERT INTO `zt_story` VALUES (1351,'rnd',0,1,0,1821,'1','customer','这里是需求来源备注1',0,0,'用户需求1','关键词1','requirement','feature',1,15,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1352,'rnd',0,1,0,1822,'1','user','这里是需求来源备注2',0,0,'软件需求2','关键词2','story','feature',2,4,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1353,'rnd',0,1,0,1823,'1','po','这里是需求来源备注3',0,0,'用户需求3','关键词3','requirement','feature',3,8,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1354,'rnd',0,1,0,1824,'1','market','这里是需求来源备注4',0,0,'软件需求4','关键词4','story','feature',4,5,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1355,'rnd',0,2,0,1825,'4','service','这里是需求来源备注5',0,0,'用户需求5','关键词5','requirement','feature',1,0,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1356,'rnd',0,2,0,1826,'4','operation','这里是需求来源备注6',0,0,'软件需求6','关键词6','story','feature',2,12,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1357,'rnd',0,2,0,1827,'4','support','这里是需求来源备注7',0,0,'用户需求7','关键词7','requirement','feature',3,9,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1358,'rnd',0,2,0,1828,'4','competitor','这里是需求来源备注8',0,0,'软件需求8','关键词8','story','feature',4,16,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1359,'rnd',0,3,0,1829,'7','partner','这里是需求来源备注9',0,0,'用户需求9','关键词9','requirement','feature',1,8,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1360,'rnd',0,3,0,1830,'7','dev','这里是需求来源备注10',0,0,'软件需求10','关键词10','story','feature',2,8,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1361,'rnd',0,3,0,1831,'7','tester','这里是需求来源备注11',0,0,'用户需求11','关键词11','requirement','feature',3,9,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1362,'rnd',0,3,0,1832,'7','bug','这里是需求来源备注12',0,0,'软件需求12','关键词12','story','feature',4,6,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1363,'rnd',0,4,0,1833,'10','forum','这里是需求来源备注13',0,0,'用户需求13','关键词13','requirement','feature',1,7,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1364,'rnd',0,4,0,1834,'10','other','这里是需求来源备注14',0,0,'软件需求14','关键词14','story','feature',2,3,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1365,'rnd',0,4,0,1835,'10','customer','这里是需求来源备注15',0,0,'用户需求15','关键词15','requirement','feature',3,3,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1366,'rnd',0,4,0,1836,'10','user','这里是需求来源备注16',0,0,'软件需求16','关键词16','story','feature',4,9,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1367,'rnd',0,5,0,1837,'13','po','这里是需求来源备注17',0,0,'用户需求17','关键词17','requirement','feature',1,4,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1368,'rnd',0,5,0,1838,'13','market','这里是需求来源备注18',0,0,'软件需求18','关键词18','story','feature',2,8,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1369,'rnd',0,5,0,1839,'13','service','这里是需求来源备注19',0,0,'用户需求19','关键词19','requirement','feature',3,14,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1370,'rnd',0,5,0,1840,'13','operation','这里是需求来源备注20',0,0,'软件需求20','关键词20','story','feature',4,5,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,3,'0','','','0','0'),(1371,'rnd',0,6,0,1841,'16','support','这里是需求来源备注21',0,0,'用户需求21','关键词21','requirement','feature',1,2,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1372,'rnd',0,6,0,1842,'16','competitor','这里是需求来源备注22',0,0,'软件需求22','关键词22','story','feature',2,11,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1373,'rnd',0,6,0,1843,'16','partner','这里是需求来源备注23',0,0,'用户需求23','关键词23','requirement','feature',3,10,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1374,'rnd',0,6,0,1844,'16','dev','这里是需求来源备注24',0,0,'软件需求24','关键词24','story','feature',4,2,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1375,'rnd',0,7,0,1845,'19','tester','这里是需求来源备注25',0,0,'用户需求25','关键词25','requirement','feature',1,6,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1376,'rnd',0,7,0,1846,'19','bug','这里是需求来源备注26',0,0,'软件需求26','关键词26','story','feature',2,8,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1377,'rnd',0,7,0,1847,'19','forum','这里是需求来源备注27',0,0,'用户需求27','关键词27','requirement','feature',3,16,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1378,'rnd',0,7,0,1848,'19','other','这里是需求来源备注28',0,0,'软件需求28','关键词28','story','feature',4,6,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1379,'rnd',0,8,0,1849,'22','customer','这里是需求来源备注29',0,0,'用户需求29','关键词29','requirement','feature',1,15,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1380,'rnd',0,8,0,1850,'22','user','这里是需求来源备注30',0,0,'软件需求30','关键词30','story','feature',2,3,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1381,'rnd',0,8,0,1851,'22','po','这里是需求来源备注31',0,0,'用户需求31','关键词31','requirement','feature',3,8,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1382,'rnd',0,8,0,1852,'22','market','这里是需求来源备注32',0,0,'软件需求32','关键词32','story','feature',4,3,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1383,'rnd',0,9,0,1853,'25','service','这里是需求来源备注33',0,0,'用户需求33','关键词33','requirement','feature',1,10,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1384,'rnd',0,9,0,1854,'25','operation','这里是需求来源备注34',0,0,'软件需求34','关键词34','story','feature',2,2,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1385,'rnd',0,9,0,1855,'25','support','这里是需求来源备注35',0,0,'用户需求35','关键词35','requirement','feature',3,15,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1386,'rnd',0,9,0,1856,'25','competitor','这里是需求来源备注36',0,0,'软件需求36','关键词36','story','feature',4,20,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1387,'rnd',0,10,0,1857,'28','partner','这里是需求来源备注37',0,0,'用户需求37','关键词37','requirement','feature',1,1,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1388,'rnd',0,10,0,1858,'28','dev','这里是需求来源备注38',0,0,'软件需求38','关键词38','story','feature',2,13,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1389,'rnd',0,10,0,1859,'28','tester','这里是需求来源备注39',0,0,'用户需求39','关键词39','requirement','feature',3,3,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1390,'rnd',0,10,0,1860,'28','bug','这里是需求来源备注40',0,0,'软件需求40','关键词40','story','feature',4,16,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1391,'rnd',0,11,0,1861,'31','forum','这里是需求来源备注41',0,0,'用户需求41','关键词41','requirement','feature',1,3,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1392,'rnd',0,11,0,1862,'31','other','这里是需求来源备注42',0,0,'软件需求42','关键词42','story','feature',2,7,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1393,'rnd',0,11,0,1863,'31','customer','这里是需求来源备注43',0,0,'用户需求43','关键词43','requirement','feature',3,4,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1394,'rnd',0,11,0,1864,'31','user','这里是需求来源备注44',0,0,'软件需求44','关键词44','story','feature',4,18,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1395,'rnd',0,12,0,1865,'34','po','这里是需求来源备注45',0,0,'用户需求45','关键词45','requirement','feature',1,3,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1396,'rnd',0,12,0,1866,'34','market','这里是需求来源备注46',0,0,'软件需求46','关键词46','story','feature',2,12,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1397,'rnd',0,12,0,1867,'34','service','这里是需求来源备注47',0,0,'用户需求47','关键词47','requirement','feature',3,19,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1398,'rnd',0,12,0,1868,'34','operation','这里是需求来源备注48',0,0,'软件需求48','关键词48','story','feature',4,6,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1399,'rnd',0,13,0,1869,'37','support','这里是需求来源备注49',0,0,'用户需求49','关键词49','requirement','feature',1,10,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1400,'rnd',0,13,0,1870,'37','competitor','这里是需求来源备注50',0,0,'软件需求50','关键词50','story','feature',2,19,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1401,'rnd',0,13,0,1871,'37','partner','这里是需求来源备注51',0,0,'用户需求51','关键词51','requirement','feature',3,20,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1402,'rnd',0,13,0,1872,'37','dev','这里是需求来源备注52',0,0,'软件需求52','关键词52','story','feature',4,18,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1403,'rnd',0,14,0,1873,'40','tester','这里是需求来源备注53',0,0,'用户需求53','关键词53','requirement','feature',1,16,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1404,'rnd',0,14,0,1874,'40','bug','这里是需求来源备注54',0,0,'软件需求54','关键词54','story','feature',2,19,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1405,'rnd',0,14,0,1875,'40','forum','这里是需求来源备注55',0,0,'用户需求55','关键词55','requirement','feature',3,15,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1406,'rnd',0,14,0,1876,'40','other','这里是需求来源备注56',0,0,'软件需求56','关键词56','story','feature',4,0,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1407,'rnd',0,15,0,1877,'43','customer','这里是需求来源备注57',0,0,'用户需求57','关键词57','requirement','feature',1,20,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1408,'rnd',0,15,0,1878,'43','user','这里是需求来源备注58',0,0,'软件需求58','关键词58','story','feature',2,4,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1409,'rnd',0,15,0,1879,'43','po','这里是需求来源备注59',0,0,'用户需求59','关键词59','requirement','feature',3,16,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1410,'rnd',0,15,0,1880,'43','market','这里是需求来源备注60',0,0,'软件需求60','关键词60','story','feature',4,5,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1411,'rnd',0,16,0,1881,'46','service','这里是需求来源备注61',0,0,'用户需求61','关键词61','requirement','feature',1,1,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1412,'rnd',0,16,0,1882,'46','operation','这里是需求来源备注62',0,0,'软件需求62','关键词62','story','feature',2,1,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1413,'rnd',0,16,0,1883,'46','support','这里是需求来源备注63',0,0,'用户需求63','关键词63','requirement','feature',3,19,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1414,'rnd',0,16,0,1884,'46','competitor','这里是需求来源备注64',0,0,'软件需求64','关键词64','story','feature',4,13,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1415,'rnd',0,17,0,1885,'49','partner','这里是需求来源备注65',0,0,'用户需求65','关键词65','requirement','feature',1,5,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1416,'rnd',0,17,0,1886,'49','dev','这里是需求来源备注66',0,0,'软件需求66','关键词66','story','feature',2,10,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1417,'rnd',0,17,0,1887,'49','tester','这里是需求来源备注67',0,0,'用户需求67','关键词67','requirement','feature',3,0,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1418,'rnd',0,17,0,1888,'49','bug','这里是需求来源备注68',0,0,'软件需求68','关键词68','story','feature',4,19,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1419,'rnd',0,18,0,1889,'52','forum','这里是需求来源备注69',0,0,'用户需求69','关键词69','requirement','feature',1,13,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1420,'rnd',0,18,0,1890,'52','other','这里是需求来源备注70',0,0,'软件需求70','关键词70','story','feature',2,1,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1421,'rnd',0,18,0,1891,'52','customer','这里是需求来源备注71',0,0,'用户需求71','关键词71','requirement','feature',3,2,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1422,'rnd',0,18,0,1892,'52','user','这里是需求来源备注72',0,0,'软件需求72','关键词72','story','feature',4,7,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1423,'rnd',0,19,0,1893,'55','po','这里是需求来源备注73',0,0,'用户需求73','关键词73','requirement','feature',1,20,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1424,'rnd',0,19,0,1894,'55','market','这里是需求来源备注74',0,0,'软件需求74','关键词74','story','feature',2,11,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1425,'rnd',0,19,0,1895,'55','service','这里是需求来源备注75',0,0,'用户需求75','关键词75','requirement','feature',3,6,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1426,'rnd',0,19,0,1896,'55','operation','这里是需求来源备注76',0,0,'软件需求76','关键词76','story','feature',4,9,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1427,'rnd',0,20,0,1897,'58','support','这里是需求来源备注77',0,0,'用户需求77','关键词77','requirement','feature',1,7,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1428,'rnd',0,20,0,1898,'58','competitor','这里是需求来源备注78',0,0,'软件需求78','关键词78','story','feature',2,6,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1429,'rnd',0,20,0,1899,'58','partner','这里是需求来源备注79',0,0,'用户需求79','关键词79','requirement','feature',3,14,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1430,'rnd',0,20,0,1900,'58','dev','这里是需求来源备注80',0,0,'软件需求80','关键词80','story','feature',4,18,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1431,'rnd',0,21,0,1901,'61','tester','这里是需求来源备注81',0,0,'用户需求81','关键词81','requirement','feature',1,1,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1432,'rnd',0,21,0,1902,'61','bug','这里是需求来源备注82',0,0,'软件需求82','关键词82','story','feature',2,12,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1433,'rnd',0,21,0,1903,'61','forum','这里是需求来源备注83',0,0,'用户需求83','关键词83','requirement','feature',3,0,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1434,'rnd',0,21,0,1904,'61','other','这里是需求来源备注84',0,0,'软件需求84','关键词84','story','feature',4,3,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1435,'rnd',0,22,0,1905,'64','customer','这里是需求来源备注85',0,0,'用户需求85','关键词85','requirement','feature',1,1,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1436,'rnd',0,22,0,1906,'64','user','这里是需求来源备注86',0,0,'软件需求86','关键词86','story','feature',2,6,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1437,'rnd',0,22,0,1907,'64','po','这里是需求来源备注87',0,0,'用户需求87','关键词87','requirement','feature',3,1,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1438,'rnd',0,22,0,1908,'64','market','这里是需求来源备注88',0,0,'软件需求88','关键词88','story','feature',4,6,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1439,'rnd',0,23,0,1909,'67','service','这里是需求来源备注89',0,0,'用户需求89','关键词89','requirement','feature',1,15,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1440,'rnd',0,23,0,1910,'67','operation','这里是需求来源备注90',0,0,'软件需求90','关键词90','story','feature',2,3,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1441,'rnd',0,23,0,1911,'67','support','这里是需求来源备注91',0,0,'用户需求91','关键词91','requirement','feature',3,4,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1442,'rnd',0,23,0,1912,'67','competitor','这里是需求来源备注92',0,0,'软件需求92','关键词92','story','feature',4,20,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1443,'rnd',0,24,0,1913,'70','partner','这里是需求来源备注93',0,0,'用户需求93','关键词93','requirement','feature',1,6,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1444,'rnd',0,24,0,1914,'70','dev','这里是需求来源备注94',0,0,'软件需求94','关键词94','story','feature',2,9,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1445,'rnd',0,24,0,1915,'70','tester','这里是需求来源备注95',0,0,'用户需求95','关键词95','requirement','feature',3,0,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1446,'rnd',0,24,0,1916,'70','bug','这里是需求来源备注96',0,0,'软件需求96','关键词96','story','feature',4,2,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1447,'rnd',0,25,0,1917,'1','forum','这里是需求来源备注97',0,0,'用户需求97','关键词97','requirement','feature',1,8,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1448,'rnd',0,25,0,1918,'1','other','这里是需求来源备注98',0,0,'软件需求98','关键词98','story','feature',2,16,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1449,'rnd',0,25,0,1919,'1','customer','这里是需求来源备注99',0,0,'用户需求99','关键词99','requirement','feature',3,2,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1450,'rnd',0,25,0,1920,'1','user','这里是需求来源备注100',0,0,'软件需求100','关键词100','story','feature',4,7,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,2,'0','','','0','0'),(1451,'rnd',0,26,0,1921,'4','po','这里是需求来源备注101',0,0,'用户需求101','关键词101','requirement','feature',1,6,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1452,'rnd',0,26,0,1922,'4','market','这里是需求来源备注102',0,0,'软件需求102','关键词102','story','feature',2,10,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1453,'rnd',0,26,0,1923,'4','service','这里是需求来源备注103',0,0,'用户需求103','关键词103','requirement','feature',3,16,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1454,'rnd',0,26,0,1924,'4','operation','这里是需求来源备注104',0,0,'软件需求104','关键词104','story','feature',4,10,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1455,'rnd',0,27,0,1925,'7','support','这里是需求来源备注105',0,0,'用户需求105','关键词105','requirement','feature',1,2,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1456,'rnd',0,27,0,1926,'7','competitor','这里是需求来源备注106',0,0,'软件需求106','关键词106','story','feature',2,0,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1457,'rnd',0,27,0,1927,'7','partner','这里是需求来源备注107',0,0,'用户需求107','关键词107','requirement','feature',3,6,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1458,'rnd',0,27,0,1928,'7','dev','这里是需求来源备注108',0,0,'软件需求108','关键词108','story','feature',4,17,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1459,'rnd',0,28,0,1929,'10','tester','这里是需求来源备注109',0,0,'用户需求109','关键词109','requirement','feature',1,15,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1460,'rnd',0,28,0,1930,'10','bug','这里是需求来源备注110',0,0,'软件需求110','关键词110','story','feature',2,4,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1461,'rnd',0,28,0,1931,'10','forum','这里是需求来源备注111',0,0,'用户需求111','关键词111','requirement','feature',3,17,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1462,'rnd',0,28,0,1932,'10','other','这里是需求来源备注112',0,0,'软件需求112','关键词112','story','feature',4,10,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1463,'rnd',0,29,0,1933,'13','customer','这里是需求来源备注113',0,0,'用户需求113','关键词113','requirement','feature',1,2,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1464,'rnd',0,29,0,1934,'13','user','这里是需求来源备注114',0,0,'软件需求114','关键词114','story','feature',2,15,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1465,'rnd',0,29,0,1935,'13','po','这里是需求来源备注115',0,0,'用户需求115','关键词115','requirement','feature',3,15,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1466,'rnd',0,29,0,1936,'13','market','这里是需求来源备注116',0,0,'软件需求116','关键词116','story','feature',4,1,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1467,'rnd',0,30,0,1937,'16','service','这里是需求来源备注117',0,0,'用户需求117','关键词117','requirement','feature',1,5,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1468,'rnd',0,30,0,1938,'16','operation','这里是需求来源备注118',0,0,'软件需求118','关键词118','story','feature',2,13,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1469,'rnd',0,30,0,1939,'16','support','这里是需求来源备注119',0,0,'用户需求119','关键词119','requirement','feature',3,0,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1470,'rnd',0,30,0,1940,'16','competitor','这里是需求来源备注120',0,0,'软件需求120','关键词120','story','feature',4,19,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1471,'rnd',0,31,0,1941,'19','partner','这里是需求来源备注121',0,0,'用户需求121','关键词121','requirement','feature',1,8,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1472,'rnd',0,31,0,1942,'19','dev','这里是需求来源备注122',0,0,'软件需求122','关键词122','story','feature',2,13,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1473,'rnd',0,31,0,1943,'19','tester','这里是需求来源备注123',0,0,'用户需求123','关键词123','requirement','feature',3,3,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1474,'rnd',0,31,0,1944,'19','bug','这里是需求来源备注124',0,0,'软件需求124','关键词124','story','feature',4,13,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1475,'rnd',0,32,0,1945,'22','forum','这里是需求来源备注125',0,0,'用户需求125','关键词125','requirement','feature',1,6,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1476,'rnd',0,32,0,1946,'22','other','这里是需求来源备注126',0,0,'软件需求126','关键词126','story','feature',2,20,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1477,'rnd',0,32,0,1947,'22','customer','这里是需求来源备注127',0,0,'用户需求127','关键词127','requirement','feature',3,5,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1478,'rnd',0,32,0,1948,'22','user','这里是需求来源备注128',0,0,'软件需求128','关键词128','story','feature',4,16,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1479,'rnd',0,33,0,1949,'25','po','这里是需求来源备注129',0,0,'用户需求129','关键词129','requirement','feature',1,8,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1480,'rnd',0,33,0,1950,'25','market','这里是需求来源备注130',0,0,'软件需求130','关键词130','story','feature',2,3,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1481,'rnd',0,33,0,1951,'25','service','这里是需求来源备注131',0,0,'用户需求131','关键词131','requirement','feature',3,1,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1482,'rnd',0,33,0,1952,'25','operation','这里是需求来源备注132',0,0,'软件需求132','关键词132','story','feature',4,7,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1483,'rnd',0,34,0,1953,'28','support','这里是需求来源备注133',0,0,'用户需求133','关键词133','requirement','feature',1,1,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1484,'rnd',0,34,0,1954,'28','competitor','这里是需求来源备注134',0,0,'软件需求134','关键词134','story','feature',2,16,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1485,'rnd',0,34,0,1955,'28','partner','这里是需求来源备注135',0,0,'用户需求135','关键词135','requirement','feature',3,11,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1486,'rnd',0,34,0,1956,'28','dev','这里是需求来源备注136',0,0,'软件需求136','关键词136','story','feature',4,3,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1487,'rnd',0,35,0,1957,'31','tester','这里是需求来源备注137',0,0,'用户需求137','关键词137','requirement','feature',1,12,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1488,'rnd',0,35,0,1958,'31','bug','这里是需求来源备注138',0,0,'软件需求138','关键词138','story','feature',2,8,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1489,'rnd',0,35,0,1959,'31','forum','这里是需求来源备注139',0,0,'用户需求139','关键词139','requirement','feature',3,20,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1490,'rnd',0,35,0,1960,'31','other','这里是需求来源备注140',0,0,'软件需求140','关键词140','story','feature',4,2,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1491,'rnd',0,36,0,1961,'34','customer','这里是需求来源备注141',0,0,'用户需求141','关键词141','requirement','feature',1,17,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1492,'rnd',0,36,0,1962,'34','user','这里是需求来源备注142',0,0,'软件需求142','关键词142','story','feature',2,4,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1493,'rnd',0,36,0,1963,'34','po','这里是需求来源备注143',0,0,'用户需求143','关键词143','requirement','feature',3,18,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1494,'rnd',0,36,0,1964,'34','market','这里是需求来源备注144',0,0,'软件需求144','关键词144','story','feature',4,12,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1495,'rnd',0,37,0,1965,'37','service','这里是需求来源备注145',0,0,'用户需求145','关键词145','requirement','feature',1,13,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1496,'rnd',0,37,0,1966,'37','operation','这里是需求来源备注146',0,0,'软件需求146','关键词146','story','feature',2,18,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1497,'rnd',0,37,0,1967,'37','support','这里是需求来源备注147',0,0,'用户需求147','关键词147','requirement','feature',3,10,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1498,'rnd',0,37,0,1968,'37','competitor','这里是需求来源备注148',0,0,'软件需求148','关键词148','story','feature',4,18,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1499,'rnd',0,38,0,1969,'40','partner','这里是需求来源备注149',0,0,'用户需求149','关键词149','requirement','feature',1,14,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1500,'rnd',0,38,0,1970,'40','dev','这里是需求来源备注150',0,0,'软件需求150','关键词150','story','feature',2,9,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1501,'rnd',0,38,0,1971,'40','tester','这里是需求来源备注151',0,0,'用户需求151','关键词151','requirement','feature',3,3,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1502,'rnd',0,38,0,1972,'40','bug','这里是需求来源备注152',0,0,'软件需求152','关键词152','story','feature',4,12,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1503,'rnd',0,39,0,1973,'43','forum','这里是需求来源备注153',0,0,'用户需求153','关键词153','requirement','feature',1,5,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1504,'rnd',0,39,0,1974,'43','other','这里是需求来源备注154',0,0,'软件需求154','关键词154','story','feature',2,14,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1505,'rnd',0,39,0,1975,'43','customer','这里是需求来源备注155',0,0,'用户需求155','关键词155','requirement','feature',3,2,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1506,'rnd',0,39,0,1976,'43','user','这里是需求来源备注156',0,0,'软件需求156','关键词156','story','feature',4,18,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1507,'rnd',0,40,0,1977,'46','po','这里是需求来源备注157',0,0,'用户需求157','关键词157','requirement','feature',1,0,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1508,'rnd',0,40,0,1978,'46','market','这里是需求来源备注158',0,0,'软件需求158','关键词158','story','feature',2,19,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1509,'rnd',0,40,0,1979,'46','service','这里是需求来源备注159',0,0,'用户需求159','关键词159','requirement','feature',3,7,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1510,'rnd',0,40,0,1980,'46','operation','这里是需求来源备注160',0,0,'软件需求160','关键词160','story','feature',4,1,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1511,'rnd',0,41,0,1981,'49','support','这里是需求来源备注161',0,0,'用户需求161','关键词161','requirement','feature',1,18,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1512,'rnd',0,41,0,1982,'49','competitor','这里是需求来源备注162',0,0,'软件需求162','关键词162','story','feature',2,7,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1513,'rnd',0,41,0,1983,'49','partner','这里是需求来源备注163',0,0,'用户需求163','关键词163','requirement','feature',3,6,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1514,'rnd',0,41,0,1984,'49','dev','这里是需求来源备注164',0,0,'软件需求164','关键词164','story','feature',4,0,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1515,'rnd',0,42,0,1985,'52','tester','这里是需求来源备注165',0,0,'用户需求165','关键词165','requirement','feature',1,12,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1516,'rnd',0,42,0,1986,'52','bug','这里是需求来源备注166',0,0,'软件需求166','关键词166','story','feature',2,13,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1517,'rnd',0,42,0,1987,'52','forum','这里是需求来源备注167',0,0,'用户需求167','关键词167','requirement','feature',3,20,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1518,'rnd',0,42,0,1988,'52','other','这里是需求来源备注168',0,0,'软件需求168','关键词168','story','feature',4,19,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1519,'rnd',0,43,0,1989,'55','customer','这里是需求来源备注169',0,0,'用户需求169','关键词169','requirement','feature',1,8,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1520,'rnd',0,43,0,1990,'55','user','这里是需求来源备注170',0,0,'软件需求170','关键词170','story','feature',2,14,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1521,'rnd',0,43,0,1991,'55','po','这里是需求来源备注171',0,0,'用户需求171','关键词171','requirement','feature',3,7,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1522,'rnd',0,43,0,1992,'55','market','这里是需求来源备注172',0,0,'软件需求172','关键词172','story','feature',4,2,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1523,'rnd',0,44,0,1993,'58','service','这里是需求来源备注173',0,0,'用户需求173','关键词173','requirement','feature',1,16,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1524,'rnd',0,44,0,1994,'58','operation','这里是需求来源备注174',0,0,'软件需求174','关键词174','story','feature',2,16,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1525,'rnd',0,44,0,1995,'58','support','这里是需求来源备注175',0,0,'用户需求175','关键词175','requirement','feature',3,0,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1526,'rnd',0,44,0,1996,'58','competitor','这里是需求来源备注176',0,0,'软件需求176','关键词176','story','feature',4,7,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1527,'rnd',0,45,0,1997,'61','partner','这里是需求来源备注177',0,0,'用户需求177','关键词177','requirement','feature',1,5,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1528,'rnd',0,45,0,1998,'61','dev','这里是需求来源备注178',0,0,'软件需求178','关键词178','story','feature',2,4,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1529,'rnd',0,45,0,1999,'61','tester','这里是需求来源备注179',0,0,'用户需求179','关键词179','requirement','feature',3,16,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1530,'rnd',0,45,0,2000,'61','bug','这里是需求来源备注180',0,0,'软件需求180','关键词180','story','feature',4,12,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1531,'rnd',0,46,0,2001,'64','forum','这里是需求来源备注181',0,0,'用户需求181','关键词181','requirement','feature',1,14,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1532,'rnd',0,46,0,2002,'64','other','这里是需求来源备注182',0,0,'软件需求182','关键词182','story','feature',2,15,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1533,'rnd',0,46,0,2003,'64','customer','这里是需求来源备注183',0,0,'用户需求183','关键词183','requirement','feature',3,15,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1534,'rnd',0,46,0,2004,'64','user','这里是需求来源备注184',0,0,'软件需求184','关键词184','story','feature',4,19,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1535,'rnd',0,47,0,2005,'67','po','这里是需求来源备注185',0,0,'用户需求185','关键词185','requirement','feature',1,15,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1536,'rnd',0,47,0,2006,'67','market','这里是需求来源备注186',0,0,'软件需求186','关键词186','story','feature',2,13,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1537,'rnd',0,47,0,2007,'67','service','这里是需求来源备注187',0,0,'用户需求187','关键词187','requirement','feature',3,16,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1538,'rnd',0,47,0,2008,'67','operation','这里是需求来源备注188',0,0,'软件需求188','关键词188','story','feature',4,0,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1539,'rnd',0,48,0,2009,'70','support','这里是需求来源备注189',0,0,'用户需求189','关键词189','requirement','feature',1,1,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1540,'rnd',0,48,0,2010,'70','competitor','这里是需求来源备注190',0,0,'软件需求190','关键词190','story','feature',2,15,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1541,'rnd',0,48,0,2011,'70','partner','这里是需求来源备注191',0,0,'用户需求191','关键词191','requirement','feature',3,20,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1542,'rnd',0,48,0,2012,'70','dev','这里是需求来源备注192',0,0,'软件需求192','关键词192','story','feature',4,1,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1543,'rnd',0,49,0,2013,'1','tester','这里是需求来源备注193',0,0,'用户需求193','关键词193','requirement','feature',1,16,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1544,'rnd',0,49,0,2014,'1','bug','这里是需求来源备注194',0,0,'软件需求194','关键词194','story','feature',2,9,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1545,'rnd',0,49,0,2015,'1','forum','这里是需求来源备注195',0,0,'用户需求195','关键词195','requirement','feature',3,11,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1546,'rnd',0,49,0,2016,'1','other','这里是需求来源备注196',0,0,'软件需求196','关键词196','story','feature',4,3,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1547,'rnd',0,50,0,2017,'4','customer','这里是需求来源备注197',0,0,'用户需求197','关键词197','requirement','feature',1,12,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1548,'rnd',0,50,0,2018,'4','user','这里是需求来源备注198',0,0,'软件需求198','关键词198','story','feature',2,15,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1549,'rnd',0,50,0,2019,'4','po','这里是需求来源备注199',0,0,'用户需求199','关键词199','requirement','feature',3,7,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1550,'rnd',0,50,0,2020,'4','market','这里是需求来源备注200',0,0,'软件需求200','关键词200','story','feature',4,16,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1551,'rnd',0,51,0,2021,'7','service','这里是需求来源备注201',0,0,'用户需求201','关键词201','requirement','feature',1,20,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1552,'rnd',0,51,0,2022,'7','operation','这里是需求来源备注202',0,0,'软件需求202','关键词202','story','feature',2,13,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1553,'rnd',0,51,0,2023,'7','support','这里是需求来源备注203',0,0,'用户需求203','关键词203','requirement','feature',3,11,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1554,'rnd',0,51,0,2024,'7','competitor','这里是需求来源备注204',0,0,'软件需求204','关键词204','story','feature',4,13,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1555,'rnd',0,52,0,2025,'10','partner','这里是需求来源备注205',0,0,'用户需求205','关键词205','requirement','feature',1,10,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1556,'rnd',0,52,0,2026,'10','dev','这里是需求来源备注206',0,0,'软件需求206','关键词206','story','feature',2,1,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1557,'rnd',0,52,0,2027,'10','tester','这里是需求来源备注207',0,0,'用户需求207','关键词207','requirement','feature',3,7,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1558,'rnd',0,52,0,2028,'10','bug','这里是需求来源备注208',0,0,'软件需求208','关键词208','story','feature',4,12,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1559,'rnd',0,53,0,2029,'13','forum','这里是需求来源备注209',0,0,'用户需求209','关键词209','requirement','feature',1,11,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1560,'rnd',0,53,0,2030,'13','other','这里是需求来源备注210',0,0,'软件需求210','关键词210','story','feature',2,4,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1561,'rnd',0,53,0,2031,'13','customer','这里是需求来源备注211',0,0,'用户需求211','关键词211','requirement','feature',3,19,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1562,'rnd',0,53,0,2032,'13','user','这里是需求来源备注212',0,0,'软件需求212','关键词212','story','feature',4,6,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1563,'rnd',0,54,0,2033,'16','po','这里是需求来源备注213',0,0,'用户需求213','关键词213','requirement','feature',1,4,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1564,'rnd',0,54,0,2034,'16','market','这里是需求来源备注214',0,0,'软件需求214','关键词214','story','feature',2,20,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1565,'rnd',0,54,0,2035,'16','service','这里是需求来源备注215',0,0,'用户需求215','关键词215','requirement','feature',3,9,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1566,'rnd',0,54,0,2036,'16','operation','这里是需求来源备注216',0,0,'软件需求216','关键词216','story','feature',4,13,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1567,'rnd',0,55,0,2037,'19','support','这里是需求来源备注217',0,0,'用户需求217','关键词217','requirement','feature',1,1,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1568,'rnd',0,55,0,2038,'19','competitor','这里是需求来源备注218',0,0,'软件需求218','关键词218','story','feature',2,15,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1569,'rnd',0,55,0,2039,'19','partner','这里是需求来源备注219',0,0,'用户需求219','关键词219','requirement','feature',3,1,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1570,'rnd',0,55,0,2040,'19','dev','这里是需求来源备注220',0,0,'软件需求220','关键词220','story','feature',4,17,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1571,'rnd',0,56,0,2041,'22','tester','这里是需求来源备注221',0,0,'用户需求221','关键词221','requirement','feature',1,15,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1572,'rnd',0,56,0,2042,'22','bug','这里是需求来源备注222',0,0,'软件需求222','关键词222','story','feature',2,15,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1573,'rnd',0,56,0,2043,'22','forum','这里是需求来源备注223',0,0,'用户需求223','关键词223','requirement','feature',3,17,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1574,'rnd',0,56,0,2044,'22','other','这里是需求来源备注224',0,0,'软件需求224','关键词224','story','feature',4,19,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1575,'rnd',0,57,0,2045,'25','customer','这里是需求来源备注225',0,0,'用户需求225','关键词225','requirement','feature',1,16,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1576,'rnd',0,57,0,2046,'25','user','这里是需求来源备注226',0,0,'软件需求226','关键词226','story','feature',2,4,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1577,'rnd',0,57,0,2047,'25','po','这里是需求来源备注227',0,0,'用户需求227','关键词227','requirement','feature',3,10,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1578,'rnd',0,57,0,2048,'25','market','这里是需求来源备注228',0,0,'软件需求228','关键词228','story','feature',4,2,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1579,'rnd',0,58,0,2049,'28','service','这里是需求来源备注229',0,0,'用户需求229','关键词229','requirement','feature',1,5,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1580,'rnd',0,58,0,2050,'28','operation','这里是需求来源备注230',0,0,'软件需求230','关键词230','story','feature',2,7,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1581,'rnd',0,58,0,2051,'28','support','这里是需求来源备注231',0,0,'用户需求231','关键词231','requirement','feature',3,5,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1582,'rnd',0,58,0,2052,'28','competitor','这里是需求来源备注232',0,0,'软件需求232','关键词232','story','feature',4,6,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1583,'rnd',0,59,0,2053,'31','partner','这里是需求来源备注233',0,0,'用户需求233','关键词233','requirement','feature',1,19,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1584,'rnd',0,59,0,2054,'31','dev','这里是需求来源备注234',0,0,'软件需求234','关键词234','story','feature',2,11,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1585,'rnd',0,59,0,2055,'31','tester','这里是需求来源备注235',0,0,'用户需求235','关键词235','requirement','feature',3,8,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1586,'rnd',0,59,0,2056,'31','bug','这里是需求来源备注236',0,0,'软件需求236','关键词236','story','feature',4,3,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1587,'rnd',0,60,0,2057,'34','forum','这里是需求来源备注237',0,0,'用户需求237','关键词237','requirement','feature',1,19,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1588,'rnd',0,60,0,2058,'34','other','这里是需求来源备注238',0,0,'软件需求238','关键词238','story','feature',2,0,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1589,'rnd',0,60,0,2059,'34','customer','这里是需求来源备注239',0,0,'用户需求239','关键词239','requirement','feature',3,9,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1590,'rnd',0,60,0,2060,'34','user','这里是需求来源备注240',0,0,'软件需求240','关键词240','story','feature',4,4,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1591,'rnd',0,61,0,2061,'37','po','这里是需求来源备注241',0,0,'用户需求241','关键词241','requirement','feature',1,12,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1592,'rnd',0,61,0,2062,'37','market','这里是需求来源备注242',0,0,'软件需求242','关键词242','story','feature',2,3,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1593,'rnd',0,61,0,2063,'37','service','这里是需求来源备注243',0,0,'用户需求243','关键词243','requirement','feature',3,19,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1594,'rnd',0,61,0,2064,'37','operation','这里是需求来源备注244',0,0,'软件需求244','关键词244','story','feature',4,3,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1595,'rnd',0,62,0,2065,'40','support','这里是需求来源备注245',0,0,'用户需求245','关键词245','requirement','feature',1,0,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1596,'rnd',0,62,0,2066,'40','competitor','这里是需求来源备注246',0,0,'软件需求246','关键词246','story','feature',2,15,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1597,'rnd',0,62,0,2067,'40','partner','这里是需求来源备注247',0,0,'用户需求247','关键词247','requirement','feature',3,0,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1598,'rnd',0,62,0,2068,'40','dev','这里是需求来源备注248',0,0,'软件需求248','关键词248','story','feature',4,1,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1599,'rnd',0,63,0,2069,'43','tester','这里是需求来源备注249',0,0,'用户需求249','关键词249','requirement','feature',1,9,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1600,'rnd',0,63,0,2070,'43','bug','这里是需求来源备注250',0,0,'软件需求250','关键词250','story','feature',2,10,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1601,'rnd',0,63,0,2071,'43','forum','这里是需求来源备注251',0,0,'用户需求251','关键词251','requirement','feature',3,9,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1602,'rnd',0,63,0,2072,'43','other','这里是需求来源备注252',0,0,'软件需求252','关键词252','story','feature',4,9,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1603,'rnd',0,64,0,2073,'46','customer','这里是需求来源备注253',0,0,'用户需求253','关键词253','requirement','feature',1,16,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1604,'rnd',0,64,0,2074,'46','user','这里是需求来源备注254',0,0,'软件需求254','关键词254','story','feature',2,4,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1605,'rnd',0,64,0,2075,'46','po','这里是需求来源备注255',0,0,'用户需求255','关键词255','requirement','feature',3,18,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1606,'rnd',0,64,0,2076,'46','market','这里是需求来源备注256',0,0,'软件需求256','关键词256','story','feature',4,7,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1607,'rnd',0,65,0,2077,'49','service','这里是需求来源备注257',0,0,'用户需求257','关键词257','requirement','feature',1,19,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1608,'rnd',0,65,0,2078,'49','operation','这里是需求来源备注258',0,0,'软件需求258','关键词258','story','feature',2,1,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1609,'rnd',0,65,0,2079,'49','support','这里是需求来源备注259',0,0,'用户需求259','关键词259','requirement','feature',3,11,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1610,'rnd',0,65,0,2080,'49','competitor','这里是需求来源备注260',0,0,'软件需求260','关键词260','story','feature',4,2,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1611,'rnd',0,66,0,2081,'52','partner','这里是需求来源备注261',0,0,'用户需求261','关键词261','requirement','feature',1,16,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1612,'rnd',0,66,0,2082,'52','dev','这里是需求来源备注262',0,0,'软件需求262','关键词262','story','feature',2,1,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1613,'rnd',0,66,0,2083,'52','tester','这里是需求来源备注263',0,0,'用户需求263','关键词263','requirement','feature',3,4,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1614,'rnd',0,66,0,2084,'52','bug','这里是需求来源备注264',0,0,'软件需求264','关键词264','story','feature',4,16,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1615,'rnd',0,67,0,2085,'55','forum','这里是需求来源备注265',0,0,'用户需求265','关键词265','requirement','feature',1,6,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1616,'rnd',0,67,0,2086,'55','other','这里是需求来源备注266',0,0,'软件需求266','关键词266','story','feature',2,3,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1617,'rnd',0,67,0,2087,'55','customer','这里是需求来源备注267',0,0,'用户需求267','关键词267','requirement','feature',3,13,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1618,'rnd',0,67,0,2088,'55','user','这里是需求来源备注268',0,0,'软件需求268','关键词268','story','feature',4,0,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1619,'rnd',0,68,0,2089,'58','po','这里是需求来源备注269',0,0,'用户需求269','关键词269','requirement','feature',1,4,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1620,'rnd',0,68,0,2090,'58','market','这里是需求来源备注270',0,0,'软件需求270','关键词270','story','feature',2,15,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1621,'rnd',0,68,0,2091,'58','service','这里是需求来源备注271',0,0,'用户需求271','关键词271','requirement','feature',3,20,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1622,'rnd',0,68,0,2092,'58','operation','这里是需求来源备注272',0,0,'软件需求272','关键词272','story','feature',4,0,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1623,'rnd',0,69,0,2093,'61','support','这里是需求来源备注273',0,0,'用户需求273','关键词273','requirement','feature',1,11,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1624,'rnd',0,69,0,2094,'61','competitor','这里是需求来源备注274',0,0,'软件需求274','关键词274','story','feature',2,7,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1625,'rnd',0,69,0,2095,'61','partner','这里是需求来源备注275',0,0,'用户需求275','关键词275','requirement','feature',3,9,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1626,'rnd',0,69,0,2096,'61','dev','这里是需求来源备注276',0,0,'软件需求276','关键词276','story','feature',4,4,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1627,'rnd',0,70,0,2097,'64','tester','这里是需求来源备注277',0,0,'用户需求277','关键词277','requirement','feature',1,20,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1628,'rnd',0,70,0,2098,'64','bug','这里是需求来源备注278',0,0,'软件需求278','关键词278','story','feature',2,8,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1629,'rnd',0,70,0,2099,'64','forum','这里是需求来源备注279',0,0,'用户需求279','关键词279','requirement','feature',3,20,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1630,'rnd',0,70,0,2100,'64','other','这里是需求来源备注280',0,0,'软件需求280','关键词280','story','feature',4,1,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1631,'rnd',0,71,0,2101,'67','customer','这里是需求来源备注281',0,0,'用户需求281','关键词281','requirement','feature',1,10,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1632,'rnd',0,71,0,2102,'67','user','这里是需求来源备注282',0,0,'软件需求282','关键词282','story','feature',2,11,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1633,'rnd',0,71,0,2103,'67','po','这里是需求来源备注283',0,0,'用户需求283','关键词283','requirement','feature',3,19,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1634,'rnd',0,71,0,2104,'67','market','这里是需求来源备注284',0,0,'软件需求284','关键词284','story','feature',4,18,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1635,'rnd',0,72,0,2105,'70','service','这里是需求来源备注285',0,0,'用户需求285','关键词285','requirement','feature',1,13,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1636,'rnd',0,72,0,2106,'70','operation','这里是需求来源备注286',0,0,'软件需求286','关键词286','story','feature',2,8,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1637,'rnd',0,72,0,2107,'70','support','这里是需求来源备注287',0,0,'用户需求287','关键词287','requirement','feature',3,2,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1638,'rnd',0,72,0,2108,'70','competitor','这里是需求来源备注288',0,0,'软件需求288','关键词288','story','feature',4,17,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1639,'rnd',0,73,0,2109,'1','partner','这里是需求来源备注289',0,0,'用户需求289','关键词289','requirement','feature',1,18,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1640,'rnd',0,73,0,2110,'1','dev','这里是需求来源备注290',0,0,'软件需求290','关键词290','story','feature',2,14,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1641,'rnd',0,73,0,2111,'1','tester','这里是需求来源备注291',0,0,'用户需求291','关键词291','requirement','feature',3,5,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1642,'rnd',0,73,0,2112,'1','bug','这里是需求来源备注292',0,0,'软件需求292','关键词292','story','feature',4,7,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1643,'rnd',0,74,0,2113,'4','forum','这里是需求来源备注293',0,0,'用户需求293','关键词293','requirement','feature',1,3,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1644,'rnd',0,74,0,2114,'4','other','这里是需求来源备注294',0,0,'软件需求294','关键词294','story','feature',2,14,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1645,'rnd',0,74,0,2115,'4','customer','这里是需求来源备注295',0,0,'用户需求295','关键词295','requirement','feature',3,16,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1646,'rnd',0,74,0,2116,'4','user','这里是需求来源备注296',0,0,'软件需求296','关键词296','story','feature',4,6,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1647,'rnd',0,75,0,2117,'7','po','这里是需求来源备注297',0,0,'用户需求297','关键词297','requirement','feature',1,14,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1648,'rnd',0,75,0,2118,'7','market','这里是需求来源备注298',0,0,'软件需求298','关键词298','story','feature',2,10,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1649,'rnd',0,75,0,2119,'7','service','这里是需求来源备注299',0,0,'用户需求299','关键词299','requirement','feature',3,17,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1650,'rnd',0,75,0,2120,'7','operation','这里是需求来源备注300',0,0,'软件需求300','关键词300','story','feature',4,20,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1651,'rnd',0,76,0,2121,'10','support','这里是需求来源备注301',0,0,'用户需求301','关键词301','requirement','feature',1,17,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1652,'rnd',0,76,0,2122,'10','competitor','这里是需求来源备注302',0,0,'软件需求302','关键词302','story','feature',2,0,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1653,'rnd',0,76,0,2123,'10','partner','这里是需求来源备注303',0,0,'用户需求303','关键词303','requirement','feature',3,8,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1654,'rnd',0,76,0,2124,'10','dev','这里是需求来源备注304',0,0,'软件需求304','关键词304','story','feature',4,18,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1655,'rnd',0,77,0,2125,'13','tester','这里是需求来源备注305',0,0,'用户需求305','关键词305','requirement','feature',1,10,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1656,'rnd',0,77,0,2126,'13','bug','这里是需求来源备注306',0,0,'软件需求306','关键词306','story','feature',2,16,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1657,'rnd',0,77,0,2127,'13','forum','这里是需求来源备注307',0,0,'用户需求307','关键词307','requirement','feature',3,9,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1658,'rnd',0,77,0,2128,'13','other','这里是需求来源备注308',0,0,'软件需求308','关键词308','story','feature',4,15,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1659,'rnd',0,78,0,2129,'16','customer','这里是需求来源备注309',0,0,'用户需求309','关键词309','requirement','feature',1,19,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1660,'rnd',0,78,0,2130,'16','user','这里是需求来源备注310',0,0,'软件需求310','关键词310','story','feature',2,5,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1661,'rnd',0,78,0,2131,'16','po','这里是需求来源备注311',0,0,'用户需求311','关键词311','requirement','feature',3,12,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1662,'rnd',0,78,0,2132,'16','market','这里是需求来源备注312',0,0,'软件需求312','关键词312','story','feature',4,15,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1663,'rnd',0,79,0,2133,'19','service','这里是需求来源备注313',0,0,'用户需求313','关键词313','requirement','feature',1,14,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1664,'rnd',0,79,0,2134,'19','operation','这里是需求来源备注314',0,0,'软件需求314','关键词314','story','feature',2,13,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1665,'rnd',0,79,0,2135,'19','support','这里是需求来源备注315',0,0,'用户需求315','关键词315','requirement','feature',3,9,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1666,'rnd',0,79,0,2136,'19','competitor','这里是需求来源备注316',0,0,'软件需求316','关键词316','story','feature',4,6,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1667,'rnd',0,80,0,2137,'22','partner','这里是需求来源备注317',0,0,'用户需求317','关键词317','requirement','feature',1,14,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1668,'rnd',0,80,0,2138,'22','dev','这里是需求来源备注318',0,0,'软件需求318','关键词318','story','feature',2,18,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1669,'rnd',0,80,0,2139,'22','tester','这里是需求来源备注319',0,0,'用户需求319','关键词319','requirement','feature',3,8,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1670,'rnd',0,80,0,2140,'22','bug','这里是需求来源备注320',0,0,'软件需求320','关键词320','story','feature',4,15,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1671,'rnd',0,81,0,2141,'25','forum','这里是需求来源备注321',0,0,'用户需求321','关键词321','requirement','feature',1,7,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1672,'rnd',0,81,0,2142,'25','other','这里是需求来源备注322',0,0,'软件需求322','关键词322','story','feature',2,2,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1673,'rnd',0,81,0,2143,'25','customer','这里是需求来源备注323',0,0,'用户需求323','关键词323','requirement','feature',3,8,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1674,'rnd',0,81,0,2144,'25','user','这里是需求来源备注324',0,0,'软件需求324','关键词324','story','feature',4,14,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1675,'rnd',0,82,0,2145,'28','po','这里是需求来源备注325',0,0,'用户需求325','关键词325','requirement','feature',1,8,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1676,'rnd',0,82,0,2146,'28','market','这里是需求来源备注326',0,0,'软件需求326','关键词326','story','feature',2,12,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1677,'rnd',0,82,0,2147,'28','service','这里是需求来源备注327',0,0,'用户需求327','关键词327','requirement','feature',3,0,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1678,'rnd',0,82,0,2148,'28','operation','这里是需求来源备注328',0,0,'软件需求328','关键词328','story','feature',4,4,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1679,'rnd',0,83,0,2149,'31','support','这里是需求来源备注329',0,0,'用户需求329','关键词329','requirement','feature',1,15,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1680,'rnd',0,83,0,2150,'31','competitor','这里是需求来源备注330',0,0,'软件需求330','关键词330','story','feature',2,13,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1681,'rnd',0,83,0,2151,'31','partner','这里是需求来源备注331',0,0,'用户需求331','关键词331','requirement','feature',3,1,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1682,'rnd',0,83,0,2152,'31','dev','这里是需求来源备注332',0,0,'软件需求332','关键词332','story','feature',4,14,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1683,'rnd',0,84,0,2153,'34','tester','这里是需求来源备注333',0,0,'用户需求333','关键词333','requirement','feature',1,15,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1684,'rnd',0,84,0,2154,'34','bug','这里是需求来源备注334',0,0,'软件需求334','关键词334','story','feature',2,18,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1685,'rnd',0,84,0,2155,'34','forum','这里是需求来源备注335',0,0,'用户需求335','关键词335','requirement','feature',3,2,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1686,'rnd',0,84,0,2156,'34','other','这里是需求来源备注336',0,0,'软件需求336','关键词336','story','feature',4,17,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1687,'rnd',0,85,0,2157,'37','customer','这里是需求来源备注337',0,0,'用户需求337','关键词337','requirement','feature',1,9,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1688,'rnd',0,85,0,2158,'37','user','这里是需求来源备注338',0,0,'软件需求338','关键词338','story','feature',2,3,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1689,'rnd',0,85,0,2159,'37','po','这里是需求来源备注339',0,0,'用户需求339','关键词339','requirement','feature',3,7,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1690,'rnd',0,85,0,2160,'37','market','这里是需求来源备注340',0,0,'软件需求340','关键词340','story','feature',4,2,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1691,'rnd',0,86,0,2161,'40','service','这里是需求来源备注341',0,0,'用户需求341','关键词341','requirement','feature',1,8,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1692,'rnd',0,86,0,2162,'40','operation','这里是需求来源备注342',0,0,'软件需求342','关键词342','story','feature',2,19,'active','0','#ff4e3e','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1693,'rnd',0,86,0,2163,'40','support','这里是需求来源备注343',0,0,'用户需求343','关键词343','requirement','feature',3,4,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1694,'rnd',0,86,0,2164,'40','competitor','这里是需求来源备注344',0,0,'软件需求344','关键词344','story','feature',4,4,'','0','#75c941','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1695,'rnd',0,87,0,2165,'43','partner','这里是需求来源备注345',0,0,'用户需求345','关键词345','requirement','feature',1,2,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1696,'rnd',0,87,0,2166,'43','dev','这里是需求来源备注346',0,0,'软件需求346','关键词346','story','feature',2,9,'active','0','#797ec9','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1697,'rnd',0,87,0,2167,'43','tester','这里是需求来源备注347',0,0,'用户需求347','关键词347','requirement','feature',3,20,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1698,'rnd',0,87,0,2168,'43','bug','这里是需求来源备注348',0,0,'软件需求348','关键词348','story','feature',4,10,'','0','#ff4e3e','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1699,'rnd',0,88,0,2169,'46','forum','这里是需求来源备注349',0,0,'用户需求349','关键词349','requirement','feature',1,9,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1700,'rnd',0,88,0,2170,'46','other','这里是需求来源备注350',0,0,'软件需求350','关键词350','story','feature',2,3,'active','0','#75c941','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1701,'rnd',0,88,0,2171,'46','customer','这里是需求来源备注351',0,0,'用户需求351','关键词351','requirement','feature',3,18,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1702,'rnd',0,88,0,2172,'46','user','这里是需求来源备注352',0,0,'软件需求352','关键词352','story','feature',4,16,'','0','#797ec9','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin5','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1703,'rnd',0,89,0,2173,'49','po','这里是需求来源备注353',0,0,'用户需求353','关键词353','requirement','feature',1,8,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user6','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1704,'rnd',0,89,0,2174,'49','market','这里是需求来源备注354',0,0,'软件需求354','关键词354','story','feature',2,18,'active','0','#ff4e3e','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1705,'rnd',0,89,0,2175,'49','service','这里是需求来源备注355',0,0,'用户需求355','关键词355','requirement','feature',3,0,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1706,'rnd',0,89,0,2176,'49','operation','这里是需求来源备注356',0,0,'软件需求356','关键词356','story','feature',4,0,'','0','#75c941','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1707,'rnd',0,90,0,2177,'52','support','这里是需求来源备注357',0,0,'用户需求357','关键词357','requirement','feature',1,7,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1708,'rnd',0,90,0,2178,'52','competitor','这里是需求来源备注358',0,0,'软件需求358','关键词358','story','feature',2,5,'active','0','#797ec9','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1709,'rnd',0,90,0,2179,'52','partner','这里是需求来源备注359',0,0,'用户需求359','关键词359','requirement','feature',3,7,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1710,'rnd',0,90,0,2180,'52','dev','这里是需求来源备注360',0,0,'软件需求360','关键词360','story','feature',4,3,'','0','#ff4e3e','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1711,'rnd',0,91,0,2181,'55','tester','这里是需求来源备注361',0,0,'用户需求361','关键词361','requirement','feature',1,18,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1712,'rnd',0,91,0,2182,'55','bug','这里是需求来源备注362',0,0,'软件需求362','关键词362','story','feature',2,2,'active','0','#75c941','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1713,'rnd',0,91,0,2183,'55','forum','这里是需求来源备注363',0,0,'用户需求363','关键词363','requirement','feature',3,13,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1714,'rnd',0,91,0,2184,'55','other','这里是需求来源备注364',0,0,'软件需求364','关键词364','story','feature',4,14,'','0','#797ec9','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1715,'rnd',0,92,0,2185,'58','customer','这里是需求来源备注365',0,0,'用户需求365','关键词365','requirement','feature',1,13,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user5','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1716,'rnd',0,92,0,2186,'58','user','这里是需求来源备注366',0,0,'软件需求366','关键词366','story','feature',2,17,'active','0','#ff4e3e','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test6','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1717,'rnd',0,92,0,2187,'58','po','这里是需求来源备注367',0,0,'用户需求367','关键词367','requirement','feature',3,9,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev7','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1718,'rnd',0,92,0,2188,'58','market','这里是需求来源备注368',0,0,'软件需求368','关键词368','story','feature',4,12,'','0','#75c941','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1719,'rnd',0,93,0,2189,'61','service','这里是需求来源备注369',0,0,'用户需求369','关键词369','requirement','feature',1,15,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1720,'rnd',0,93,0,2190,'61','operation','这里是需求来源备注370',0,0,'软件需求370','关键词370','story','feature',2,20,'active','0','#797ec9','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1721,'rnd',0,93,0,2191,'61','support','这里是需求来源备注371',0,0,'用户需求371','关键词371','requirement','feature',3,8,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1722,'rnd',0,93,0,2192,'61','competitor','这里是需求来源备注372',0,0,'软件需求372','关键词372','story','feature',4,13,'','0','#ff4e3e','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1723,'rnd',0,94,0,2193,'64','partner','这里是需求来源备注373',0,0,'用户需求373','关键词373','requirement','feature',1,20,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1724,'rnd',0,94,0,2194,'64','dev','这里是需求来源备注374',0,0,'软件需求374','关键词374','story','feature',2,18,'active','0','#75c941','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1725,'rnd',0,94,0,2195,'64','tester','这里是需求来源备注375',0,0,'用户需求375','关键词375','requirement','feature',3,19,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1726,'rnd',0,94,0,2196,'64','bug','这里是需求来源备注376',0,0,'软件需求376','关键词376','story','feature',4,19,'','0','#797ec9','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1727,'rnd',0,95,0,2197,'67','forum','这里是需求来源备注377',0,0,'用户需求377','关键词377','requirement','feature',1,20,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1728,'rnd',0,95,0,2198,'67','other','这里是需求来源备注378',0,0,'软件需求378','关键词378','story','feature',2,15,'active','0','#ff4e3e','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1729,'rnd',0,95,0,2199,'67','customer','这里是需求来源备注379',0,0,'用户需求379','关键词379','requirement','feature',3,15,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1730,'rnd',0,95,0,2200,'67','user','这里是需求来源备注380',0,0,'软件需求380','关键词380','story','feature',4,3,'','0','#75c941','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin7','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1731,'rnd',0,96,0,2201,'70','po','这里是需求来源备注381',0,0,'用户需求381','关键词381','requirement','feature',1,3,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1732,'rnd',0,96,0,2202,'70','market','这里是需求来源备注382',0,0,'软件需求382','关键词382','story','feature',2,10,'active','0','#797ec9','wait','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1733,'rnd',0,96,0,2203,'70','service','这里是需求来源备注383',0,0,'用户需求383','关键词383','requirement','feature',3,13,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1734,'rnd',0,96,0,2204,'70','operation','这里是需求来源备注384',0,0,'软件需求384','关键词384','story','feature',4,3,'','0','#ff4e3e','planned','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1735,'rnd',0,97,0,2205,'1','support','这里是需求来源备注385',0,0,'用户需求385','关键词385','requirement','feature',1,10,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1736,'rnd',0,97,0,2206,'1','competitor','这里是需求来源备注386',0,0,'软件需求386','关键词386','story','feature',2,10,'active','0','#75c941','projected','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1737,'rnd',0,97,0,2207,'1','partner','这里是需求来源备注387',0,0,'用户需求387','关键词387','requirement','feature',3,7,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1738,'rnd',0,97,0,2208,'1','dev','这里是需求来源备注388',0,0,'软件需求388','关键词388','story','feature',4,3,'','0','#797ec9','developing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1739,'rnd',0,98,0,2209,'4','tester','这里是需求来源备注389',0,0,'用户需求389','关键词389','requirement','feature',1,16,'draft','0','#ffaf38','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1740,'rnd',0,98,0,2210,'4','bug','这里是需求来源备注390',0,0,'软件需求390','关键词390','story','feature',2,9,'active','0','#ff4e3e','developed','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1741,'rnd',0,98,0,2211,'4','forum','这里是需求来源备注391',0,0,'用户需求391','关键词391','requirement','feature',3,16,'closed','0','#3da7f5','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev5','0000-00-00 00:00:00','test1','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1742,'rnd',0,98,0,2212,'4','other','这里是需求来源备注392',0,0,'软件需求392','关键词392','story','feature',4,15,'','0','#75c941','testing','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin6','0000-00-00 00:00:00','dev2','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1743,'rnd',0,99,0,2213,'7','customer','这里是需求来源备注393',0,0,'用户需求393','关键词393','requirement','feature',1,8,'draft','0','#2dbdb2','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user7','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1744,'rnd',0,99,0,2214,'7','user','这里是需求来源备注394',0,0,'软件需求394','关键词394','story','feature',2,19,'active','0','#797ec9','tested','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','subdivided','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1745,'rnd',0,99,0,2215,'7','po','这里是需求来源备注395',0,0,'用户需求395','关键词395','requirement','feature',3,6,'closed','0','#ffaf38','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test5','0000-00-00 00:00:00','duplicate','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1746,'rnd',0,99,0,2216,'7','market','这里是需求来源备注396',0,0,'软件需求396','关键词396','story','feature',4,15,'','0','#ff4e3e','verified','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev6','0000-00-00 00:00:00','postponed','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1747,'rnd',0,100,0,2217,'10','service','这里是需求来源备注397',0,0,'用户需求397','关键词397','requirement','feature',1,4,'draft','0','#3da7f5','','','',0,0,1,'admin','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','user','0000-00-00 00:00:00','test7','0000-00-00 00:00:00','willnotdo','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1748,'rnd',0,100,0,2218,'10','operation','这里是需求来源备注398',0,0,'软件需求398','关键词398','story','feature',2,0,'active','0','#75c941','released','','',0,0,1,'user2','0000-00-00 00:00:00','user2','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','test','0000-00-00 00:00:00','dev8','0000-00-00 00:00:00','cancel','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1749,'rnd',0,100,0,2219,'10','support','这里是需求来源备注399',0,0,'用户需求399','关键词399','requirement','feature',3,11,'closed','0','#2dbdb2','','','',0,0,1,'test3','0000-00-00 00:00:00','test3','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','dev','0000-00-00 00:00:00','test9','0000-00-00 00:00:00','bydesign','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0'),(1750,'rnd',0,100,0,2220,'10','competitor','这里是需求来源备注400',0,0,'软件需求400','关键词400','story','feature',4,1,'','0','#797ec9','closed','','',0,0,1,'dev4','0000-00-00 00:00:00','dev4','0000-00-00 00:00:00','0000-00-00','','0000-00-00 00:00:00','','0000-00-00 00:00:00','admin','0000-00-00 00:00:00','dev10','0000-00-00 00:00:00','done','0000-00-00 00:00:00',0,'0','0','','',0,1,'0','','','0','0');
+/*!40000 ALTER TABLE `zt_story` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:33:15
diff --git a/module/user/test/model/data/sql/team.sql b/module/user/test/model/data/sql/team.sql
new file mode 100644
index 0000000000..4f1d730b6b
--- /dev/null
+++ b/module/user/test/model/data/sql/team.sql
@@ -0,0 +1,64 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_team`
+--
+
+DROP TABLE IF EXISTS `zt_team`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_team` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `root` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `type` enum('project','task','execution') NOT NULL DEFAULT 'project',
+ `account` char(30) NOT NULL DEFAULT '',
+ `role` char(30) NOT NULL DEFAULT '',
+ `position` varchar(30) NOT NULL,
+ `limited` char(8) NOT NULL DEFAULT 'no',
+ `join` date NOT NULL DEFAULT '0000-00-00',
+ `days` smallint(5) unsigned NOT NULL,
+ `hours` float(3,1) unsigned NOT NULL DEFAULT 0.0,
+ `estimate` decimal(12,2) unsigned NOT NULL DEFAULT 0.00,
+ `consumed` decimal(12,2) unsigned NOT NULL DEFAULT 0.00,
+ `left` decimal(12,2) unsigned NOT NULL DEFAULT 0.00,
+ `order` tinyint(3) NOT NULL DEFAULT 0,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `team` (`root`,`type`,`account`)
+) ENGINE=InnoDB AUTO_INCREMENT=931 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_team`
+--
+
+LOCK TABLES `zt_team` WRITE;
+/*!40000 ALTER TABLE `zt_team` DISABLE KEYS */;
+INSERT INTO `zt_team` VALUES (1,11,'project','admin','研发','','yes','2023-01-14',1,1.0,0.00,0.00,0.00,0),(2,12,'project','user3','研发','','no','2023-01-14',2,2.0,0.00,0.00,0.00,0),(3,13,'project','user4','研发','','yes','2023-01-14',3,3.0,0.00,0.00,0.00,0),(4,14,'project','user5','研发','','no','2023-01-14',4,4.0,0.00,0.00,0.00,0),(5,15,'project','user6','研发','','yes','2023-01-14',5,5.0,0.00,0.00,0.00,0),(6,16,'project','user7','研发','','no','2023-01-14',6,6.0,0.00,0.00,0.00,0),(7,17,'project','user8','研发','','yes','2023-01-14',7,7.0,0.00,0.00,0.00,0),(8,18,'project','user9','研发','','no','2023-01-14',8,8.0,0.00,0.00,0.00,0),(9,19,'project','user10','研发','','yes','2023-01-14',9,1.0,0.00,0.00,0.00,0),(10,20,'project','user11','研发','','no','2023-01-14',10,2.0,0.00,0.00,0.00,0),(11,21,'project','user12','研发','','yes','2023-01-14',11,3.0,0.00,0.00,0.00,0),(12,22,'project','user13','研发','','no','2023-01-14',12,4.0,0.00,0.00,0.00,0),(13,23,'project','user14','研发','','yes','2023-01-14',13,5.0,0.00,0.00,0.00,0),(14,24,'project','user15','研发','','no','2023-01-14',14,6.0,0.00,0.00,0.00,0),(15,25,'project','user16','研发','','yes','2023-01-14',15,7.0,0.00,0.00,0.00,0),(16,26,'project','user17','研发','','no','2023-01-14',16,8.0,0.00,0.00,0.00,0),(17,27,'project','user18','研发','','yes','2023-01-14',17,1.0,0.00,0.00,0.00,0),(18,28,'project','user19','研发','','no','2023-01-14',18,2.0,0.00,0.00,0.00,0),(19,29,'project','user20','研发','','yes','2023-01-14',19,3.0,0.00,0.00,0.00,0),(20,30,'project','user21','研发','','no','2023-01-14',20,4.0,0.00,0.00,0.00,0),(21,31,'project','user22','研发','','yes','2023-01-14',21,5.0,0.00,0.00,0.00,0),(22,32,'project','user23','研发','','no','2023-01-14',22,6.0,0.00,0.00,0.00,0),(23,33,'project','user24','研发','','yes','2023-01-14',23,7.0,0.00,0.00,0.00,0),(24,34,'project','user25','研发','','no','2023-01-14',24,8.0,0.00,0.00,0.00,0),(25,35,'project','user26','研发','','yes','2023-01-14',25,1.0,0.00,0.00,0.00,0),(26,36,'project','user27','研发','','no','2023-01-14',26,2.0,0.00,0.00,0.00,0),(27,37,'project','user28','研发','','yes','2023-01-14',27,3.0,0.00,0.00,0.00,0),(28,38,'project','user29','研发','','no','2023-01-14',28,4.0,0.00,0.00,0.00,0),(29,39,'project','user30','研发','','yes','2023-01-14',29,5.0,0.00,0.00,0.00,0),(30,40,'project','user31','研发','','no','2023-01-14',30,6.0,0.00,0.00,0.00,0),(31,41,'project','user32','研发','','yes','2023-01-14',31,7.0,0.00,0.00,0.00,0),(32,42,'project','user33','研发','','no','2023-01-14',32,8.0,0.00,0.00,0.00,0),(33,43,'project','user34','研发','','yes','2023-01-14',33,1.0,0.00,0.00,0.00,0),(34,44,'project','user35','研发','','no','2023-01-14',34,2.0,0.00,0.00,0.00,0),(35,45,'project','user36','研发','','yes','2023-01-14',35,3.0,0.00,0.00,0.00,0),(36,46,'project','user37','研发','','no','2023-01-14',36,4.0,0.00,0.00,0.00,0),(37,47,'project','user38','研发','','yes','2023-01-14',37,5.0,0.00,0.00,0.00,0),(38,48,'project','user39','研发','','no','2023-01-14',38,6.0,0.00,0.00,0.00,0),(39,49,'project','user40','研发','','yes','2023-01-14',39,7.0,0.00,0.00,0.00,0),(40,50,'project','user41','研发','','no','2023-01-14',40,8.0,0.00,0.00,0.00,0),(41,51,'project','user42','研发','','yes','2023-01-14',41,1.0,0.00,0.00,0.00,0),(42,52,'project','user43','研发','','no','2023-01-14',42,2.0,0.00,0.00,0.00,0),(43,53,'project','user44','研发','','yes','2023-01-14',43,3.0,0.00,0.00,0.00,0),(44,54,'project','user45','研发','','no','2023-01-14',44,4.0,0.00,0.00,0.00,0),(45,55,'project','user46','研发','','yes','2023-01-14',45,5.0,0.00,0.00,0.00,0),(46,56,'project','user47','研发','','no','2023-01-14',46,6.0,0.00,0.00,0.00,0),(47,57,'project','user48','研发','','yes','2023-01-14',47,7.0,0.00,0.00,0.00,0),(48,58,'project','user49','研发','','no','2023-01-14',48,8.0,0.00,0.00,0.00,0),(49,59,'project','user50','研发','','yes','2023-01-14',49,1.0,0.00,0.00,0.00,0),(50,60,'project','user51','研发','','no','2023-01-14',50,2.0,0.00,0.00,0.00,0),(51,61,'project','user52','研发','','yes','2023-01-14',1,3.0,0.00,0.00,0.00,0),(52,62,'project','user53','研发','','no','2023-01-14',2,4.0,0.00,0.00,0.00,0),(53,63,'project','user54','研发','','yes','2023-01-14',3,5.0,0.00,0.00,0.00,0),(54,64,'project','user55','研发','','no','2023-01-14',4,6.0,0.00,0.00,0.00,0),(55,65,'project','user56','研发','','yes','2023-01-14',5,7.0,0.00,0.00,0.00,0),(56,66,'project','user57','研发','','no','2023-01-14',6,8.0,0.00,0.00,0.00,0),(57,67,'project','user58','研发','','yes','2023-01-14',7,1.0,0.00,0.00,0.00,0),(58,68,'project','user59','研发','','no','2023-01-14',8,2.0,0.00,0.00,0.00,0),(59,69,'project','user60','研发','','yes','2023-01-14',9,3.0,0.00,0.00,0.00,0),(60,70,'project','user61','研发','','no','2023-01-14',10,4.0,0.00,0.00,0.00,0),(61,71,'project','user62','研发','','yes','2023-01-14',11,5.0,0.00,0.00,0.00,0),(62,72,'project','user63','研发','','no','2023-01-14',12,6.0,0.00,0.00,0.00,0),(63,73,'project','user64','研发','','yes','2023-01-14',13,7.0,0.00,0.00,0.00,0),(64,74,'project','user65','研发','','no','2023-01-14',14,8.0,0.00,0.00,0.00,0),(65,75,'project','user66','研发','','yes','2023-01-14',15,1.0,0.00,0.00,0.00,0),(66,76,'project','user67','研发','','no','2023-01-14',16,2.0,0.00,0.00,0.00,0),(67,77,'project','user68','研发','','yes','2023-01-14',17,3.0,0.00,0.00,0.00,0),(68,78,'project','user69','研发','','no','2023-01-14',18,4.0,0.00,0.00,0.00,0),(69,79,'project','user70','研发','','yes','2023-01-14',19,5.0,0.00,0.00,0.00,0),(70,80,'project','user71','研发','','no','2023-01-14',20,6.0,0.00,0.00,0.00,0),(71,81,'project','user72','研发','','yes','2023-01-14',21,7.0,0.00,0.00,0.00,0),(72,82,'project','user73','研发','','no','2023-01-14',22,8.0,0.00,0.00,0.00,0),(73,83,'project','user74','研发','','yes','2023-01-14',23,1.0,0.00,0.00,0.00,0),(74,84,'project','user75','研发','','no','2023-01-14',24,2.0,0.00,0.00,0.00,0),(75,85,'project','user76','研发','','yes','2023-01-14',25,3.0,0.00,0.00,0.00,0),(76,86,'project','user77','研发','','no','2023-01-14',26,4.0,0.00,0.00,0.00,0),(77,87,'project','user78','研发','','yes','2023-01-14',27,5.0,0.00,0.00,0.00,0),(78,88,'project','user79','研发','','no','2023-01-14',28,6.0,0.00,0.00,0.00,0),(79,89,'project','user80','研发','','yes','2023-01-14',29,7.0,0.00,0.00,0.00,0),(80,90,'project','user81','研发','','no','2023-01-14',30,8.0,0.00,0.00,0.00,0),(81,91,'project','user82','研发','','yes','2023-01-14',31,1.0,0.00,0.00,0.00,0),(82,92,'project','user83','研发','','no','2023-01-14',32,2.0,0.00,0.00,0.00,0),(83,93,'project','user84','研发','','yes','2023-01-14',33,3.0,0.00,0.00,0.00,0),(84,94,'project','user85','研发','','no','2023-01-14',34,4.0,0.00,0.00,0.00,0),(85,95,'project','user86','研发','','yes','2023-01-14',35,5.0,0.00,0.00,0.00,0),(86,96,'project','user87','研发','','no','2023-01-14',36,6.0,0.00,0.00,0.00,0),(87,97,'project','user88','研发','','yes','2023-01-14',37,7.0,0.00,0.00,0.00,0),(88,98,'project','user89','研发','','no','2023-01-14',38,8.0,0.00,0.00,0.00,0),(89,99,'project','user90','研发','','yes','2023-01-14',39,1.0,0.00,0.00,0.00,0),(90,100,'project','user91','研发','','no','2023-01-14',40,2.0,0.00,0.00,0.00,0),(91,101,'execution','user92','研发','','yes','2023-01-14',41,3.0,0.00,0.00,0.00,0),(92,102,'execution','user93','研发','','no','2023-01-14',42,4.0,0.00,0.00,0.00,0),(93,103,'execution','user94','研发','','yes','2023-01-14',43,5.0,0.00,0.00,0.00,0),(94,104,'execution','user95','研发','','no','2023-01-14',44,6.0,0.00,0.00,0.00,0),(95,105,'execution','user96','研发','','yes','2023-01-14',45,7.0,0.00,0.00,0.00,0),(96,106,'execution','user97','研发','','no','2023-01-14',46,8.0,0.00,0.00,0.00,0),(97,107,'execution','user98','研发','','yes','2023-01-14',47,1.0,0.00,0.00,0.00,0),(98,108,'execution','user99','研发','','no','2023-01-14',48,2.0,0.00,0.00,0.00,0),(99,109,'execution','user100','研发','','yes','2023-01-14',49,3.0,0.00,0.00,0.00,0),(100,110,'execution','test1','测试','','no','2023-01-14',50,4.0,0.00,0.00,0.00,0),(101,111,'execution','test2','测试','','yes','2023-01-14',1,5.0,0.00,0.00,0.00,0),(102,112,'execution','test3','测试','','no','2023-01-14',2,6.0,0.00,0.00,0.00,0),(103,113,'execution','test4','测试','','yes','2023-01-14',3,7.0,0.00,0.00,0.00,0),(104,114,'execution','test5','测试','','no','2023-01-14',4,8.0,0.00,0.00,0.00,0),(105,115,'execution','test6','测试','','yes','2023-01-14',5,1.0,0.00,0.00,0.00,0),(106,116,'execution','test7','测试','','no','2023-01-14',6,2.0,0.00,0.00,0.00,0),(107,117,'execution','test8','测试','','yes','2023-01-14',7,3.0,0.00,0.00,0.00,0),(108,118,'execution','test9','测试','','no','2023-01-14',8,4.0,0.00,0.00,0.00,0),(109,119,'execution','test10','测试','','yes','2023-01-14',9,5.0,0.00,0.00,0.00,0),(110,120,'execution','test11','测试','','no','2023-01-14',10,6.0,0.00,0.00,0.00,0),(111,121,'execution','test12','测试','','yes','2023-01-14',11,7.0,0.00,0.00,0.00,0),(112,122,'execution','test13','测试','','no','2023-01-14',12,8.0,0.00,0.00,0.00,0),(113,123,'execution','test14','测试','','yes','2023-01-14',13,1.0,0.00,0.00,0.00,0),(114,124,'execution','test15','测试','','no','2023-01-14',14,2.0,0.00,0.00,0.00,0),(115,125,'execution','test16','测试','','yes','2023-01-14',15,3.0,0.00,0.00,0.00,0),(116,126,'execution','test17','测试','','no','2023-01-14',16,4.0,0.00,0.00,0.00,0),(117,127,'execution','test18','测试','','yes','2023-01-14',17,5.0,0.00,0.00,0.00,0),(118,128,'execution','test19','测试','','no','2023-01-14',18,6.0,0.00,0.00,0.00,0),(119,129,'execution','test20','测试','','yes','2023-01-14',19,7.0,0.00,0.00,0.00,0),(120,130,'execution','test21','测试','','no','2023-01-14',20,8.0,0.00,0.00,0.00,0),(121,131,'execution','test22','测试','','yes','2023-01-14',21,1.0,0.00,0.00,0.00,0),(122,132,'execution','test23','测试','','no','2023-01-14',22,2.0,0.00,0.00,0.00,0),(123,133,'execution','test24','测试','','yes','2023-01-14',23,3.0,0.00,0.00,0.00,0),(124,134,'execution','test25','测试','','no','2023-01-14',24,4.0,0.00,0.00,0.00,0),(125,135,'execution','test26','测试','','yes','2023-01-14',25,5.0,0.00,0.00,0.00,0),(126,136,'execution','test27','测试','','no','2023-01-14',26,6.0,0.00,0.00,0.00,0),(127,137,'execution','test28','测试','','yes','2023-01-14',27,7.0,0.00,0.00,0.00,0),(128,138,'execution','test29','测试','','no','2023-01-14',28,8.0,0.00,0.00,0.00,0),(129,139,'execution','test30','测试','','yes','2023-01-14',29,1.0,0.00,0.00,0.00,0),(130,140,'execution','test31','测试','','no','2023-01-14',30,2.0,0.00,0.00,0.00,0),(131,141,'execution','test32','测试','','yes','2023-01-14',31,3.0,0.00,0.00,0.00,0),(132,142,'execution','test33','测试','','no','2023-01-14',32,4.0,0.00,0.00,0.00,0),(133,143,'execution','test34','测试','','yes','2023-01-14',33,5.0,0.00,0.00,0.00,0),(134,144,'execution','test35','测试','','no','2023-01-14',34,6.0,0.00,0.00,0.00,0),(135,145,'execution','test36','测试','','yes','2023-01-14',35,7.0,0.00,0.00,0.00,0),(136,146,'execution','test37','测试','','no','2023-01-14',36,8.0,0.00,0.00,0.00,0),(137,147,'execution','test38','测试','','yes','2023-01-14',37,1.0,0.00,0.00,0.00,0),(138,148,'execution','test39','测试','','no','2023-01-14',38,2.0,0.00,0.00,0.00,0),(139,149,'execution','test40','测试','','yes','2023-01-14',39,3.0,0.00,0.00,0.00,0),(140,150,'execution','test41','测试','','no','2023-01-14',40,4.0,0.00,0.00,0.00,0),(141,151,'execution','test42','测试','','yes','2023-01-14',41,5.0,0.00,0.00,0.00,0),(142,152,'execution','test43','测试','','no','2023-01-14',42,6.0,0.00,0.00,0.00,0),(143,153,'execution','test44','测试','','yes','2023-01-14',43,7.0,0.00,0.00,0.00,0),(144,154,'execution','test45','测试','','no','2023-01-14',44,8.0,0.00,0.00,0.00,0),(145,155,'execution','test46','测试','','yes','2023-01-14',45,1.0,0.00,0.00,0.00,0),(146,156,'execution','test47','测试','','no','2023-01-14',46,2.0,0.00,0.00,0.00,0),(147,157,'execution','test48','测试','','yes','2023-01-14',47,3.0,0.00,0.00,0.00,0),(148,158,'execution','test49','测试','','no','2023-01-14',48,4.0,0.00,0.00,0.00,0),(149,159,'execution','test50','测试','','yes','2023-01-14',49,5.0,0.00,0.00,0.00,0),(150,160,'execution','test51','测试','','no','2023-01-14',50,6.0,0.00,0.00,0.00,0),(151,161,'execution','test52','测试','','yes','2023-01-14',1,7.0,0.00,0.00,0.00,0),(152,162,'execution','test53','测试','','no','2023-01-14',2,8.0,0.00,0.00,0.00,0),(153,163,'execution','test54','测试','','yes','2023-01-14',3,1.0,0.00,0.00,0.00,0),(154,164,'execution','test55','测试','','no','2023-01-14',4,2.0,0.00,0.00,0.00,0),(155,165,'execution','test56','测试','','yes','2023-01-14',5,3.0,0.00,0.00,0.00,0),(156,166,'execution','test57','测试','','no','2023-01-14',6,4.0,0.00,0.00,0.00,0),(157,167,'execution','test58','测试','','yes','2023-01-14',7,5.0,0.00,0.00,0.00,0),(158,168,'execution','test59','测试','','no','2023-01-14',8,6.0,0.00,0.00,0.00,0),(159,169,'execution','test60','测试','','yes','2023-01-14',9,7.0,0.00,0.00,0.00,0),(160,170,'execution','test61','测试','','no','2023-01-14',10,8.0,0.00,0.00,0.00,0),(161,171,'execution','test62','测试','','yes','2023-01-14',11,1.0,0.00,0.00,0.00,0),(162,172,'execution','test63','测试','','no','2023-01-14',12,2.0,0.00,0.00,0.00,0),(163,173,'execution','test64','测试','','yes','2023-01-14',13,3.0,0.00,0.00,0.00,0),(164,174,'execution','test65','测试','','no','2023-01-14',14,4.0,0.00,0.00,0.00,0),(165,175,'execution','test66','测试','','yes','2023-01-14',15,5.0,0.00,0.00,0.00,0),(166,176,'execution','test67','测试','','no','2023-01-14',16,6.0,0.00,0.00,0.00,0),(167,177,'execution','test68','测试','','yes','2023-01-14',17,7.0,0.00,0.00,0.00,0),(168,178,'execution','test69','测试','','no','2023-01-14',18,8.0,0.00,0.00,0.00,0),(169,179,'execution','test70','测试','','yes','2023-01-14',19,1.0,0.00,0.00,0.00,0),(170,180,'execution','test71','测试','','no','2023-01-14',20,2.0,0.00,0.00,0.00,0),(171,181,'execution','test72','测试','','yes','2023-01-14',21,3.0,0.00,0.00,0.00,0),(172,182,'execution','test73','测试','','no','2023-01-14',22,4.0,0.00,0.00,0.00,0),(173,183,'execution','test74','测试','','yes','2023-01-14',23,5.0,0.00,0.00,0.00,0),(174,184,'execution','test75','测试','','no','2023-01-14',24,6.0,0.00,0.00,0.00,0),(175,185,'execution','test76','测试','','yes','2023-01-14',25,7.0,0.00,0.00,0.00,0),(176,186,'execution','test77','测试','','no','2023-01-14',26,8.0,0.00,0.00,0.00,0),(177,187,'execution','test78','测试','','yes','2023-01-14',27,1.0,0.00,0.00,0.00,0),(178,188,'execution','test79','测试','','no','2023-01-14',28,2.0,0.00,0.00,0.00,0),(179,189,'execution','test80','测试','','yes','2023-01-14',29,3.0,0.00,0.00,0.00,0),(180,190,'execution','test81','测试','','no','2023-01-14',30,4.0,0.00,0.00,0.00,0),(181,191,'execution','test82','测试','','yes','2023-01-14',31,5.0,0.00,0.00,0.00,0),(182,192,'execution','test83','测试','','no','2023-01-14',32,6.0,0.00,0.00,0.00,0),(183,193,'execution','test84','测试','','yes','2023-01-14',33,7.0,0.00,0.00,0.00,0),(184,194,'execution','test85','测试','','no','2023-01-14',34,8.0,0.00,0.00,0.00,0),(185,195,'execution','test86','测试','','yes','2023-01-14',35,1.0,0.00,0.00,0.00,0),(186,196,'execution','test87','测试','','no','2023-01-14',36,2.0,0.00,0.00,0.00,0),(187,197,'execution','test88','测试','','yes','2023-01-14',37,3.0,0.00,0.00,0.00,0),(188,198,'execution','test89','测试','','no','2023-01-14',38,4.0,0.00,0.00,0.00,0),(189,199,'execution','test90','测试','','yes','2023-01-14',39,5.0,0.00,0.00,0.00,0),(190,200,'execution','test91','测试','','no','2023-01-14',40,6.0,0.00,0.00,0.00,0),(191,201,'execution','test92','测试','','yes','2023-01-14',41,7.0,0.00,0.00,0.00,0),(192,202,'execution','test93','测试','','no','2023-01-14',42,8.0,0.00,0.00,0.00,0),(193,203,'execution','test94','测试','','yes','2023-01-14',43,1.0,0.00,0.00,0.00,0),(194,204,'execution','test95','测试','','no','2023-01-14',44,2.0,0.00,0.00,0.00,0),(195,205,'execution','test96','测试','','yes','2023-01-14',45,3.0,0.00,0.00,0.00,0),(196,206,'execution','test97','测试','','no','2023-01-14',46,4.0,0.00,0.00,0.00,0),(197,207,'execution','test98','测试','','yes','2023-01-14',47,5.0,0.00,0.00,0.00,0),(198,208,'execution','test99','测试','','no','2023-01-14',48,6.0,0.00,0.00,0.00,0),(199,209,'execution','test100','测试','','yes','2023-01-14',49,7.0,0.00,0.00,0.00,0),(200,210,'execution','pm1','项目经理','','no','2023-01-14',50,8.0,0.00,0.00,0.00,0),(201,211,'execution','pm2','项目经理','','yes','2023-01-14',1,1.0,0.00,0.00,0.00,0),(202,212,'execution','pm3','项目经理','','no','2023-01-14',2,2.0,0.00,0.00,0.00,0),(203,213,'execution','pm4','项目经理','','yes','2023-01-14',3,3.0,0.00,0.00,0.00,0),(204,214,'execution','pm5','项目经理','','no','2023-01-14',4,4.0,0.00,0.00,0.00,0),(205,215,'execution','pm6','项目经理','','yes','2023-01-14',5,5.0,0.00,0.00,0.00,0),(206,216,'execution','pm7','项目经理','','no','2023-01-14',6,6.0,0.00,0.00,0.00,0),(207,217,'execution','pm8','项目经理','','yes','2023-01-14',7,7.0,0.00,0.00,0.00,0),(208,218,'execution','pm9','项目经理','','no','2023-01-14',8,8.0,0.00,0.00,0.00,0),(209,219,'execution','pm10','项目经理','','yes','2023-01-14',9,1.0,0.00,0.00,0.00,0),(210,220,'execution','pm11','项目经理','','no','2023-01-14',10,2.0,0.00,0.00,0.00,0),(211,221,'execution','pm12','项目经理','','yes','2023-01-14',11,3.0,0.00,0.00,0.00,0),(212,222,'execution','pm13','项目经理','','no','2023-01-14',12,4.0,0.00,0.00,0.00,0),(213,223,'execution','pm14','项目经理','','yes','2023-01-14',13,5.0,0.00,0.00,0.00,0),(214,224,'execution','pm15','项目经理','','no','2023-01-14',14,6.0,0.00,0.00,0.00,0),(215,225,'execution','pm16','项目经理','','yes','2023-01-14',15,7.0,0.00,0.00,0.00,0),(216,226,'execution','pm17','项目经理','','no','2023-01-14',16,8.0,0.00,0.00,0.00,0),(217,227,'execution','pm18','项目经理','','yes','2023-01-14',17,1.0,0.00,0.00,0.00,0),(218,228,'execution','pm19','项目经理','','no','2023-01-14',18,2.0,0.00,0.00,0.00,0),(219,229,'execution','pm20','项目经理','','yes','2023-01-14',19,3.0,0.00,0.00,0.00,0),(220,230,'execution','pm21','项目经理','','no','2023-01-14',20,4.0,0.00,0.00,0.00,0),(221,231,'execution','pm22','项目经理','','yes','2023-01-14',21,5.0,0.00,0.00,0.00,0),(222,232,'execution','pm23','项目经理','','no','2023-01-14',22,6.0,0.00,0.00,0.00,0),(223,233,'execution','pm24','项目经理','','yes','2023-01-14',23,7.0,0.00,0.00,0.00,0),(224,234,'execution','pm25','项目经理','','no','2023-01-14',24,8.0,0.00,0.00,0.00,0),(225,235,'execution','pm26','项目经理','','yes','2023-01-14',25,1.0,0.00,0.00,0.00,0),(226,236,'execution','pm27','项目经理','','no','2023-01-14',26,2.0,0.00,0.00,0.00,0),(227,237,'execution','pm28','项目经理','','yes','2023-01-14',27,3.0,0.00,0.00,0.00,0),(228,238,'execution','pm29','项目经理','','no','2023-01-14',28,4.0,0.00,0.00,0.00,0),(229,239,'execution','pm30','项目经理','','yes','2023-01-14',29,5.0,0.00,0.00,0.00,0),(230,240,'execution','pm31','项目经理','','no','2023-01-14',30,6.0,0.00,0.00,0.00,0),(231,241,'execution','pm32','项目经理','','yes','2023-01-14',31,7.0,0.00,0.00,0.00,0),(232,242,'execution','pm33','项目经理','','no','2023-01-14',32,8.0,0.00,0.00,0.00,0),(233,243,'execution','pm34','项目经理','','yes','2023-01-14',33,1.0,0.00,0.00,0.00,0),(234,244,'execution','pm35','项目经理','','no','2023-01-14',34,2.0,0.00,0.00,0.00,0),(235,245,'execution','pm36','项目经理','','yes','2023-01-14',35,3.0,0.00,0.00,0.00,0),(236,246,'execution','pm37','项目经理','','no','2023-01-14',36,4.0,0.00,0.00,0.00,0),(237,247,'execution','pm38','项目经理','','yes','2023-01-14',37,5.0,0.00,0.00,0.00,0),(238,248,'execution','pm39','项目经理','','no','2023-01-14',38,6.0,0.00,0.00,0.00,0),(239,249,'execution','pm40','项目经理','','yes','2023-01-14',39,7.0,0.00,0.00,0.00,0),(240,250,'execution','pm41','项目经理','','no','2023-01-14',40,8.0,0.00,0.00,0.00,0),(241,251,'execution','pm42','项目经理','','yes','2023-01-14',41,1.0,0.00,0.00,0.00,0),(242,252,'execution','pm43','项目经理','','no','2023-01-14',42,2.0,0.00,0.00,0.00,0),(243,253,'execution','pm44','项目经理','','yes','2023-01-14',43,3.0,0.00,0.00,0.00,0),(244,254,'execution','pm45','项目经理','','no','2023-01-14',44,4.0,0.00,0.00,0.00,0),(245,255,'execution','pm46','项目经理','','yes','2023-01-14',45,5.0,0.00,0.00,0.00,0),(246,256,'execution','pm47','项目经理','','no','2023-01-14',46,6.0,0.00,0.00,0.00,0),(247,257,'execution','pm48','项目经理','','yes','2023-01-14',47,7.0,0.00,0.00,0.00,0),(248,258,'execution','pm49','项目经理','','no','2023-01-14',48,8.0,0.00,0.00,0.00,0),(249,259,'execution','pm50','项目经理','','yes','2023-01-14',49,1.0,0.00,0.00,0.00,0),(250,260,'execution','pm51','项目经理','','no','2023-01-14',50,2.0,0.00,0.00,0.00,0),(251,261,'execution','pm52','项目经理','','yes','2023-01-14',1,3.0,0.00,0.00,0.00,0),(252,262,'execution','pm53','项目经理','','no','2023-01-14',2,4.0,0.00,0.00,0.00,0),(253,263,'execution','pm54','项目经理','','yes','2023-01-14',3,5.0,0.00,0.00,0.00,0),(254,264,'execution','pm55','项目经理','','no','2023-01-14',4,6.0,0.00,0.00,0.00,0),(255,265,'execution','pm56','项目经理','','yes','2023-01-14',5,7.0,0.00,0.00,0.00,0),(256,266,'execution','pm57','项目经理','','no','2023-01-14',6,8.0,0.00,0.00,0.00,0),(257,267,'execution','pm58','项目经理','','yes','2023-01-14',7,1.0,0.00,0.00,0.00,0),(258,268,'execution','pm59','项目经理','','no','2023-01-14',8,2.0,0.00,0.00,0.00,0),(259,269,'execution','pm60','项目经理','','yes','2023-01-14',9,3.0,0.00,0.00,0.00,0),(260,270,'execution','pm61','项目经理','','no','2023-01-14',10,4.0,0.00,0.00,0.00,0),(261,271,'execution','pm62','项目经理','','yes','2023-01-14',11,5.0,0.00,0.00,0.00,0),(262,272,'execution','pm63','项目经理','','no','2023-01-14',12,6.0,0.00,0.00,0.00,0),(263,273,'execution','pm64','项目经理','','yes','2023-01-14',13,7.0,0.00,0.00,0.00,0),(264,274,'execution','pm65','项目经理','','no','2023-01-14',14,8.0,0.00,0.00,0.00,0),(265,275,'execution','pm66','项目经理','','yes','2023-01-14',15,1.0,0.00,0.00,0.00,0),(266,276,'execution','pm67','项目经理','','no','2023-01-14',16,2.0,0.00,0.00,0.00,0),(267,277,'execution','pm68','项目经理','','yes','2023-01-14',17,3.0,0.00,0.00,0.00,0),(268,278,'execution','pm69','项目经理','','no','2023-01-14',18,4.0,0.00,0.00,0.00,0),(269,279,'execution','pm70','项目经理','','yes','2023-01-14',19,5.0,0.00,0.00,0.00,0),(270,280,'execution','pm71','项目经理','','no','2023-01-14',20,6.0,0.00,0.00,0.00,0),(271,281,'execution','pm72','项目经理','','yes','2023-01-14',21,7.0,0.00,0.00,0.00,0),(272,282,'execution','pm73','项目经理','','no','2023-01-14',22,8.0,0.00,0.00,0.00,0),(273,283,'execution','pm74','项目经理','','yes','2023-01-14',23,1.0,0.00,0.00,0.00,0),(274,284,'execution','pm75','项目经理','','no','2023-01-14',24,2.0,0.00,0.00,0.00,0),(275,285,'execution','pm76','项目经理','','yes','2023-01-14',25,3.0,0.00,0.00,0.00,0),(276,286,'execution','pm77','项目经理','','no','2023-01-14',26,4.0,0.00,0.00,0.00,0),(277,287,'execution','pm78','项目经理','','yes','2023-01-14',27,5.0,0.00,0.00,0.00,0),(278,288,'execution','pm79','项目经理','','no','2023-01-14',28,6.0,0.00,0.00,0.00,0),(279,289,'execution','pm80','项目经理','','yes','2023-01-14',29,7.0,0.00,0.00,0.00,0),(280,290,'execution','pm81','项目经理','','no','2023-01-14',30,8.0,0.00,0.00,0.00,0),(281,291,'execution','pm82','项目经理','','yes','2023-01-14',31,1.0,0.00,0.00,0.00,0),(282,292,'execution','pm83','项目经理','','no','2023-01-14',32,2.0,0.00,0.00,0.00,0),(283,293,'execution','pm84','项目经理','','yes','2023-01-14',33,3.0,0.00,0.00,0.00,0),(284,294,'execution','pm85','项目经理','','no','2023-01-14',34,4.0,0.00,0.00,0.00,0),(285,295,'execution','pm86','项目经理','','yes','2023-01-14',35,5.0,0.00,0.00,0.00,0),(286,296,'execution','pm87','项目经理','','no','2023-01-14',36,6.0,0.00,0.00,0.00,0),(287,297,'execution','pm88','项目经理','','yes','2023-01-14',37,7.0,0.00,0.00,0.00,0),(288,298,'execution','pm89','项目经理','','no','2023-01-14',38,8.0,0.00,0.00,0.00,0),(289,299,'execution','pm90','项目经理','','yes','2023-01-14',39,1.0,0.00,0.00,0.00,0),(290,300,'execution','pm91','项目经理','','no','2023-01-14',40,2.0,0.00,0.00,0.00,0),(291,11,'project','pm92','项目经理','','yes','2023-01-14',41,3.0,0.00,0.00,0.00,0),(292,12,'project','pm93','项目经理','','no','2023-01-14',42,4.0,0.00,0.00,0.00,0),(293,13,'project','pm94','项目经理','','yes','2023-01-14',43,5.0,0.00,0.00,0.00,0),(294,14,'project','pm95','项目经理','','no','2023-01-14',44,6.0,0.00,0.00,0.00,0),(295,15,'project','pm96','项目经理','','yes','2023-01-14',45,7.0,0.00,0.00,0.00,0),(296,16,'project','pm97','项目经理','','no','2023-01-14',46,8.0,0.00,0.00,0.00,0),(297,17,'project','pm98','项目经理','','yes','2023-01-14',47,1.0,0.00,0.00,0.00,0),(298,18,'project','pm99','项目经理','','no','2023-01-14',48,2.0,0.00,0.00,0.00,0),(299,19,'project','pm100','项目经理','','yes','2023-01-14',49,3.0,0.00,0.00,0.00,0),(300,20,'project','po1','产品经理','','no','2023-01-14',50,4.0,0.00,0.00,0.00,0),(301,21,'project','po2','产品经理','','yes','2023-01-14',1,5.0,0.00,0.00,0.00,0),(302,22,'project','po3','产品经理','','no','2023-01-14',2,6.0,0.00,0.00,0.00,0),(303,23,'project','po4','产品经理','','yes','2023-01-14',3,7.0,0.00,0.00,0.00,0),(304,24,'project','po5','产品经理','','no','2023-01-14',4,8.0,0.00,0.00,0.00,0),(305,25,'project','po6','研发','','yes','2023-01-14',5,1.0,0.00,0.00,0.00,0),(306,26,'project','po7','研发','','no','2023-01-14',6,2.0,0.00,0.00,0.00,0),(307,27,'project','po8','研发','','yes','2023-01-14',7,3.0,0.00,0.00,0.00,0),(308,28,'project','po9','研发','','no','2023-01-14',8,4.0,0.00,0.00,0.00,0),(309,29,'project','po10','研发','','yes','2023-01-14',9,5.0,0.00,0.00,0.00,0),(310,30,'project','po11','研发','','no','2023-01-14',10,6.0,0.00,0.00,0.00,0),(311,31,'project','po12','研发','','yes','2023-01-14',11,7.0,0.00,0.00,0.00,0),(312,32,'project','po13','研发','','no','2023-01-14',12,8.0,0.00,0.00,0.00,0),(313,33,'project','po14','研发','','yes','2023-01-14',13,1.0,0.00,0.00,0.00,0),(314,34,'project','po15','研发','','no','2023-01-14',14,2.0,0.00,0.00,0.00,0),(315,35,'project','po16','研发','','yes','2023-01-14',15,3.0,0.00,0.00,0.00,0),(316,36,'project','po17','研发','','no','2023-01-14',16,4.0,0.00,0.00,0.00,0),(317,37,'project','po18','研发','','yes','2023-01-14',17,5.0,0.00,0.00,0.00,0),(318,38,'project','po19','研发','','no','2023-01-14',18,6.0,0.00,0.00,0.00,0),(319,39,'project','po20','研发','','yes','2023-01-14',19,7.0,0.00,0.00,0.00,0),(320,40,'project','po21','研发','','no','2023-01-14',20,8.0,0.00,0.00,0.00,0),(321,41,'project','po22','研发','','yes','2023-01-14',21,1.0,0.00,0.00,0.00,0),(322,42,'project','po23','研发','','no','2023-01-14',22,2.0,0.00,0.00,0.00,0),(323,43,'project','po24','研发','','yes','2023-01-14',23,3.0,0.00,0.00,0.00,0),(324,44,'project','po25','研发','','no','2023-01-14',24,4.0,0.00,0.00,0.00,0),(325,45,'project','po26','研发','','yes','2023-01-14',25,5.0,0.00,0.00,0.00,0),(326,46,'project','po27','研发','','no','2023-01-14',26,6.0,0.00,0.00,0.00,0),(327,47,'project','po28','研发','','yes','2023-01-14',27,7.0,0.00,0.00,0.00,0),(328,48,'project','po29','研发','','no','2023-01-14',28,8.0,0.00,0.00,0.00,0),(329,49,'project','po30','研发','','yes','2023-01-14',29,1.0,0.00,0.00,0.00,0),(330,50,'project','po31','研发','','no','2023-01-14',30,2.0,0.00,0.00,0.00,0),(331,51,'project','po32','研发','','yes','2023-01-14',31,3.0,0.00,0.00,0.00,0),(332,52,'project','po33','研发','','no','2023-01-14',32,4.0,0.00,0.00,0.00,0),(333,53,'project','po34','研发','','yes','2023-01-14',33,5.0,0.00,0.00,0.00,0),(334,54,'project','po35','研发','','no','2023-01-14',34,6.0,0.00,0.00,0.00,0),(335,55,'project','po36','研发','','yes','2023-01-14',35,7.0,0.00,0.00,0.00,0),(336,56,'project','po37','研发','','no','2023-01-14',36,8.0,0.00,0.00,0.00,0),(337,57,'project','po38','研发','','yes','2023-01-14',37,1.0,0.00,0.00,0.00,0),(338,58,'project','po39','研发','','no','2023-01-14',38,2.0,0.00,0.00,0.00,0),(339,59,'project','po40','研发','','yes','2023-01-14',39,3.0,0.00,0.00,0.00,0),(340,60,'project','po41','研发','','no','2023-01-14',40,4.0,0.00,0.00,0.00,0),(341,61,'project','po42','研发','','yes','2023-01-14',41,5.0,0.00,0.00,0.00,0),(342,62,'project','po43','研发','','no','2023-01-14',42,6.0,0.00,0.00,0.00,0),(343,63,'project','po44','研发','','yes','2023-01-14',43,7.0,0.00,0.00,0.00,0),(344,64,'project','po45','研发','','no','2023-01-14',44,8.0,0.00,0.00,0.00,0),(345,65,'project','po46','研发','','yes','2023-01-14',45,1.0,0.00,0.00,0.00,0),(346,66,'project','po47','研发','','no','2023-01-14',46,2.0,0.00,0.00,0.00,0),(347,67,'project','po48','研发','','yes','2023-01-14',47,3.0,0.00,0.00,0.00,0),(348,68,'project','po49','研发','','no','2023-01-14',48,4.0,0.00,0.00,0.00,0),(349,69,'project','po50','研发','','yes','2023-01-14',49,5.0,0.00,0.00,0.00,0),(350,70,'project','po51','研发','','no','2023-01-14',50,6.0,0.00,0.00,0.00,0),(351,71,'project','po52','研发','','yes','2023-01-14',1,7.0,0.00,0.00,0.00,0),(352,72,'project','po53','研发','','no','2023-01-14',2,8.0,0.00,0.00,0.00,0),(353,73,'project','po54','研发','','yes','2023-01-14',3,1.0,0.00,0.00,0.00,0),(354,74,'project','po55','研发','','no','2023-01-14',4,2.0,0.00,0.00,0.00,0),(355,75,'project','po56','研发','','yes','2023-01-14',5,3.0,0.00,0.00,0.00,0),(356,76,'project','po57','研发','','no','2023-01-14',6,4.0,0.00,0.00,0.00,0),(357,77,'project','po58','研发','','yes','2023-01-14',7,5.0,0.00,0.00,0.00,0),(358,78,'project','po59','研发','','no','2023-01-14',8,6.0,0.00,0.00,0.00,0),(359,79,'project','po60','研发','','yes','2023-01-14',9,7.0,0.00,0.00,0.00,0),(360,80,'project','po61','研发','','no','2023-01-14',10,8.0,0.00,0.00,0.00,0),(361,81,'project','po62','研发','','yes','2023-01-14',11,1.0,0.00,0.00,0.00,0),(362,82,'project','po63','研发','','no','2023-01-14',12,2.0,0.00,0.00,0.00,0),(363,83,'project','po64','研发','','yes','2023-01-14',13,3.0,0.00,0.00,0.00,0),(364,84,'project','po65','研发','','no','2023-01-14',14,4.0,0.00,0.00,0.00,0),(365,85,'project','po66','研发','','yes','2023-01-14',15,5.0,0.00,0.00,0.00,0),(366,86,'project','po67','研发','','no','2023-01-14',16,6.0,0.00,0.00,0.00,0),(367,87,'project','po68','研发','','yes','2023-01-14',17,7.0,0.00,0.00,0.00,0),(368,88,'project','po69','研发','','no','2023-01-14',18,8.0,0.00,0.00,0.00,0),(369,89,'project','po70','研发','','yes','2023-01-14',19,1.0,0.00,0.00,0.00,0),(370,90,'project','po71','研发','','no','2023-01-14',20,2.0,0.00,0.00,0.00,0),(371,91,'project','po72','研发','','yes','2023-01-14',21,3.0,0.00,0.00,0.00,0),(372,92,'project','po73','研发','','no','2023-01-14',22,4.0,0.00,0.00,0.00,0),(373,93,'project','po74','研发','','yes','2023-01-14',23,5.0,0.00,0.00,0.00,0),(374,94,'project','po75','研发','','no','2023-01-14',24,6.0,0.00,0.00,0.00,0),(375,95,'project','po76','研发','','yes','2023-01-14',25,7.0,0.00,0.00,0.00,0),(376,96,'project','po77','研发','','no','2023-01-14',26,8.0,0.00,0.00,0.00,0),(377,97,'project','po78','研发','','yes','2023-01-14',27,1.0,0.00,0.00,0.00,0),(378,98,'project','po79','研发','','no','2023-01-14',28,2.0,0.00,0.00,0.00,0),(379,99,'project','po80','研发','','yes','2023-01-14',29,3.0,0.00,0.00,0.00,0),(380,100,'project','po81','研发','','no','2023-01-14',30,4.0,0.00,0.00,0.00,0),(381,101,'execution','po82','研发','','yes','2023-01-14',31,5.0,0.00,0.00,0.00,0),(382,102,'execution','po83','研发','','no','2023-01-14',32,6.0,0.00,0.00,0.00,0),(383,103,'execution','po84','研发','','yes','2023-01-14',33,7.0,0.00,0.00,0.00,0),(384,104,'execution','po85','研发','','no','2023-01-14',34,8.0,0.00,0.00,0.00,0),(385,105,'execution','po86','研发','','yes','2023-01-14',35,1.0,0.00,0.00,0.00,0),(386,106,'execution','po87','研发','','no','2023-01-14',36,2.0,0.00,0.00,0.00,0),(387,107,'execution','po88','研发','','yes','2023-01-14',37,3.0,0.00,0.00,0.00,0),(388,108,'execution','po89','研发','','no','2023-01-14',38,4.0,0.00,0.00,0.00,0),(389,109,'execution','po90','研发','','yes','2023-01-14',39,5.0,0.00,0.00,0.00,0),(390,110,'execution','po91','研发','','no','2023-01-14',40,6.0,0.00,0.00,0.00,0),(391,111,'execution','po92','研发','','yes','2023-01-14',41,7.0,0.00,0.00,0.00,0),(392,112,'execution','po93','研发','','no','2023-01-14',42,8.0,0.00,0.00,0.00,0),(393,113,'execution','po94','研发','','yes','2023-01-14',43,1.0,0.00,0.00,0.00,0),(394,114,'execution','po95','研发','','no','2023-01-14',44,2.0,0.00,0.00,0.00,0),(395,115,'execution','po96','研发','','yes','2023-01-14',45,3.0,0.00,0.00,0.00,0),(396,116,'execution','po97','研发','','no','2023-01-14',46,4.0,0.00,0.00,0.00,0),(397,117,'execution','po98','研发','','yes','2023-01-14',47,5.0,0.00,0.00,0.00,0),(398,118,'execution','po99','研发','','no','2023-01-14',48,6.0,0.00,0.00,0.00,0),(399,119,'execution','po100','研发','','yes','2023-01-14',49,7.0,0.00,0.00,0.00,0),(400,120,'execution','admin','研发','','no','2023-01-14',50,8.0,0.00,0.00,0.00,0);
+/*!40000 ALTER TABLE `zt_team` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:53:41
diff --git a/module/user/test/model/data/sql/user.sql b/module/user/test/model/data/sql/user.sql
new file mode 100644
index 0000000000..b1cc777c69
--- /dev/null
+++ b/module/user/test/model/data/sql/user.sql
@@ -0,0 +1,98 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_user`
+--
+
+DROP TABLE IF EXISTS `zt_user`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_user` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `company` mediumint(8) unsigned NOT NULL,
+ `type` char(30) NOT NULL DEFAULT 'inside',
+ `dept` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `account` char(30) NOT NULL DEFAULT '',
+ `password` char(32) NOT NULL DEFAULT '',
+ `role` char(10) NOT NULL DEFAULT '',
+ `realname` varchar(100) NOT NULL DEFAULT '',
+ `pinyin` varchar(255) NOT NULL DEFAULT '',
+ `nickname` char(60) NOT NULL DEFAULT '',
+ `commiter` varchar(100) NOT NULL,
+ `avatar` text NOT NULL,
+ `birthday` date NOT NULL DEFAULT '0000-00-00',
+ `gender` enum('f','m') NOT NULL DEFAULT 'f',
+ `email` char(90) NOT NULL DEFAULT '',
+ `skype` char(90) NOT NULL DEFAULT '',
+ `qq` char(20) NOT NULL DEFAULT '',
+ `mobile` char(11) NOT NULL DEFAULT '',
+ `phone` char(20) NOT NULL DEFAULT '',
+ `weixin` varchar(90) NOT NULL DEFAULT '',
+ `dingding` varchar(90) NOT NULL DEFAULT '',
+ `slack` varchar(90) NOT NULL DEFAULT '',
+ `whatsapp` varchar(90) NOT NULL DEFAULT '',
+ `address` char(120) NOT NULL DEFAULT '',
+ `zipcode` char(10) NOT NULL DEFAULT '',
+ `nature` text NOT NULL,
+ `analysis` text NOT NULL,
+ `strategy` text NOT NULL,
+ `join` date NOT NULL DEFAULT '0000-00-00',
+ `visits` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `visions` varchar(20) NOT NULL DEFAULT 'rnd,lite',
+ `ip` char(15) NOT NULL DEFAULT '',
+ `last` int(10) unsigned NOT NULL DEFAULT 0,
+ `fails` tinyint(5) NOT NULL DEFAULT 0,
+ `locked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `feedback` enum('0','1') NOT NULL DEFAULT '0',
+ `ranzhi` char(30) NOT NULL DEFAULT '',
+ `ldap` char(30) NOT NULL,
+ `score` int(11) NOT NULL DEFAULT 0,
+ `scoreLevel` int(11) NOT NULL DEFAULT 0,
+ `resetToken` varchar(50) NOT NULL,
+ `deleted` enum('0','1') NOT NULL DEFAULT '0',
+ `clientStatus` enum('online','away','busy','offline','meeting') NOT NULL DEFAULT 'offline',
+ `clientLang` varchar(10) NOT NULL DEFAULT 'zh-cn',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `account` (`account`),
+ KEY `dept` (`dept`),
+ KEY `email` (`email`),
+ KEY `commiter` (`commiter`),
+ KEY `deleted` (`deleted`)
+) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_user`
+--
+
+LOCK TABLES `zt_user` WRITE;
+/*!40000 ALTER TABLE `zt_user` DISABLE KEYS */;
+INSERT INTO `zt_user` VALUES (1,1,'inside',1,'admin','a0933c1218a4e745bacdcf572b10eba7','qa','admin','','','admin','/home/z/tmp/1.png','1993-01-14','f','10001000@qq.com','Skype','419853297','','16240905423','','','slack','whatsApp','','','','','','0000-00-00',4501,'rnd,lite','',1671004035,0,'0000-00-00 00:00:00','0','admin','',9879,0,'','0','offline','zh-cn'),(2,1,'inside',1,'user1','a0933c1218a4e745bacdcf572b10eba7','qa','用户1','','','user1','/home/z/user/2.png','1993-03-15','m','10021002@163.com','Skype','915222619','','1989503692','','','slack','whatsApp','','','','','','0000-00-00',1114,'rnd,lite','',1671007635,2,'0000-00-00 00:00:00','0','user1','',7739,0,'','0','offline','zh-cn'),(3,1,'inside',1,'user2','a0933c1218a4e745bacdcf572b10eba7','qa','用户2','','','user2','/home/z/tmp/3.png','1993-05-14','f','10041004@gmail.com','Skype','924207575','','13345688731','','','slack','whatsApp','','','','','','0000-00-00',9759,'rnd,lite','',1671011235,3,'0000-00-00 00:00:00','0','user2','',2959,0,'','0','offline','zh-cn'),(4,1,'inside',1,'user3','a0933c1218a4e745bacdcf572b10eba7','qa','用户3','','','user3','/home/z/user/4.png','1993-07-13','m','10061006@qq.com','Skype','323845794','','13490126294','','','slack','whatsApp','','','','','','0000-00-00',1607,'rnd,lite','',1671014835,4,'0000-00-00 00:00:00','0','user3','',616,0,'','0','offline','zh-cn'),(5,1,'inside',1,'user4','a0933c1218a4e745bacdcf572b10eba7','qa','用户4','','','user4','/home/z/tmp/5.png','1993-09-11','f','10081008@163.com','Skype','826371933','','17564815807','','','slack','whatsApp','','','','','','0000-00-00',654,'rnd,lite','',1671018435,5,'0000-00-00 00:00:00','0','user4','',8966,0,'','0','offline','zh-cn'),(6,1,'inside',1,'user5','a0933c1218a4e745bacdcf572b10eba7','qa','用户5','','','user5','/home/z/user/6.png','1993-11-10','m','10101010@gmail.com','Skype','272590473','','13360855020','','','slack','whatsApp','','','','','','0000-00-00',9296,'rnd,lite','',1671022035,6,'0000-00-00 00:00:00','0','user5','',8924,0,'','0','offline','zh-cn'),(7,1,'inside',1,'user6','a0933c1218a4e745bacdcf572b10eba7','qa','用户6','','','user6','/home/z/tmp/7.png','1994-01-09','f','10121012@qq.com','Skype','646316961','','16677041853','','','slack','whatsApp','','','','','','0000-00-00',1786,'rnd,lite','',1671025635,7,'0000-00-00 00:00:00','0','user6','',717,0,'','0','offline','zh-cn'),(8,1,'inside',1,'user7','a0933c1218a4e745bacdcf572b10eba7','qa','用户7','','','user7','/home/z/user/8.png','1994-03-10','m','10141014@163.com','Skype','170882505','','16448943540','','','slack','whatsApp','','','','','','0000-00-00',561,'rnd,lite','',1671029235,8,'0000-00-00 00:00:00','0','user7','',1353,0,'','0','offline','zh-cn'),(9,1,'inside',1,'user8','a0933c1218a4e745bacdcf572b10eba7','qa','用户8','','','user8','/home/z/tmp/9.png','1994-05-09','f','10161016@gmail.com','Skype','458693556','','13926303965','','','slack','whatsApp','','','','','','0000-00-00',1871,'rnd,lite','',1671032835,9,'0000-00-00 00:00:00','0','user8','',9391,0,'','0','offline','zh-cn'),(10,1,'inside',1,'user9','dcf859ce8dd8f998bdfe4ae6c22c329e','qa','用户9','','','user9','/home/z/user/10.png','1994-07-08','m','10181018@qq.com','Skype','913491241','','15775942596','','','slack','whatsApp','','','','','','0000-00-00',7976,'rnd,lite','',1671036435,10,'0000-00-00 00:00:00','0','user9','',7843,0,'','0','offline','zh-cn');
+/*!40000 ALTER TABLE `zt_user` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:53:41
diff --git a/module/user/test/model/data/sql/usergroup.sql b/module/user/test/model/data/sql/usergroup.sql
new file mode 100644
index 0000000000..65dc662e96
--- /dev/null
+++ b/module/user/test/model/data/sql/usergroup.sql
@@ -0,0 +1,52 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_usergroup`
+--
+
+DROP TABLE IF EXISTS `zt_usergroup`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_usergroup` (
+ `account` char(30) NOT NULL DEFAULT '',
+ `group` mediumint(8) unsigned NOT NULL DEFAULT 0,
+ `project` text NOT NULL,
+ UNIQUE KEY `account` (`account`,`group`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_usergroup`
+--
+
+LOCK TABLES `zt_usergroup` WRITE;
+/*!40000 ALTER TABLE `zt_usergroup` DISABLE KEYS */;
+INSERT INTO `zt_usergroup` VALUES ('dev1',3,''),('test10',3,''),('test100',3,''),('test11',3,''),('test12',3,''),('test13',3,''),('test14',3,''),('test15',3,''),('test16',3,''),('test17',3,''),('test18',3,''),('test19',3,''),('test2',3,''),('test20',3,''),('test21',3,''),('test22',3,''),('test23',3,''),('test24',3,''),('test25',3,''),('test26',3,''),('test27',3,''),('test28',3,''),('test29',3,''),('test3',3,''),('test30',3,''),('test31',3,''),('test32',3,''),('test33',3,''),('test34',3,''),('test35',3,''),('test36',3,''),('test37',3,''),('test38',3,''),('test39',3,''),('test4',3,''),('test40',3,''),('test41',3,''),('test42',3,''),('test43',3,''),('test44',3,''),('test45',3,''),('test46',3,''),('test47',3,''),('test48',3,''),('test49',3,''),('test5',3,''),('test50',3,''),('test51',3,''),('test52',3,''),('test53',3,''),('test54',3,''),('test55',3,''),('test56',3,''),('test57',3,''),('test58',3,''),('test59',3,''),('test6',3,''),('test60',3,''),('test61',3,''),('test62',3,''),('test63',3,''),('test64',3,''),('test65',3,''),('test66',3,''),('test67',3,''),('test68',3,''),('test69',3,''),('test7',3,''),('test70',3,''),('test71',3,''),('test72',3,''),('test73',3,''),('test74',3,''),('test75',3,''),('test76',3,''),('test77',3,''),('test78',3,''),('test79',3,''),('test8',3,''),('test80',3,''),('test81',3,''),('test82',3,''),('test83',3,''),('test84',3,''),('test85',3,''),('test86',3,''),('test87',3,''),('test88',3,''),('test89',3,''),('test9',3,''),('test90',3,''),('test91',3,''),('test92',3,''),('test93',3,''),('test94',3,''),('test95',3,''),('test96',3,''),('test97',3,''),('test98',3,''),('test99',3,'');
+/*!40000 ALTER TABLE `zt_usergroup` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-09 11:16:59
diff --git a/module/user/test/model/data/sql/usertpl.sql b/module/user/test/model/data/sql/usertpl.sql
new file mode 100644
index 0000000000..1a8866ac84
--- /dev/null
+++ b/module/user/test/model/data/sql/usertpl.sql
@@ -0,0 +1,56 @@
+-- MySQL dump 10.19 Distrib 10.3.37-MariaDB, for debian-linux-gnu (x86_64)
+--
+-- Host: 127.0.0.1 Database: zentaotmp0104
+-- ------------------------------------------------------
+-- Server version 10.3.34-MariaDB-0ubuntu0.20.04.1
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `zt_usertpl`
+--
+
+DROP TABLE IF EXISTS `zt_usertpl`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `zt_usertpl` (
+ `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
+ `account` char(30) NOT NULL,
+ `type` char(30) NOT NULL,
+ `title` varchar(150) NOT NULL,
+ `content` text NOT NULL,
+ `public` enum('0','1') NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`),
+ KEY `account` (`account`)
+) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `zt_usertpl`
+--
+
+LOCK TABLES `zt_usertpl` WRITE;
+/*!40000 ALTER TABLE `zt_usertpl` DISABLE KEYS */;
+INSERT INTO `zt_usertpl` VALUES (1,'admin','exporttask','模板名称1','模块内容1','0'),(2,'dev10','story','模板名称2','模块内容2','1'),(3,'top10','exportbug','模板名称3','模块内容3','0'),(4,'test10','exportstory','模板名称4','模块内容4','1'),(5,'po10','exporttask','模板名称5','模块内容5','0'),(6,'admin','story','模板名称6','模块内容6','1'),(7,'dev10','exportbug','模板名称7','模块内容7','0'),(8,'top10','exportstory','模板名称8','模块内容8','1'),(9,'test10','exporttask','模板名称9','模块内容9','0'),(10,'po10','story','模板名称10','模块内容10','1');
+/*!40000 ALTER TABLE `zt_usertpl` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-01-14 15:23:30
diff --git a/module/user/test/model/deletecontactlist.php b/module/user/test/model/deletecontactlist.php
new file mode 100755
index 0000000000..f3c285fcd5
--- /dev/null
+++ b/module/user/test/model/deletecontactlist.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+gen(5);
+
+/**
+
+title=测试 userModel->deleteContactList();
+cid=1
+pid=1
+
+删除ID为1的联系人列表 >> 0
+删除ID为2的联系人列表 >> 0
+删除ID为null的联系人列表 >> 0
+删除ID为1000的联系人列表 >> 0
+
+*/
+$user = new userTest();
+
+r($user->deleteContactListTest(1)) && p('listName') && e('0'); //删除ID为1的联系人列表
+r($user->deleteContactListTest(2)) && p('listName') && e('0'); //删除ID为2的联系人列表
+r($user->deleteContactListTest(null)) && p('userLsit') && e('0'); //删除ID为null的联系人列表
+r($user->deleteContactListTest(1000)) && p('userList') && e('0'); //删除ID为1000的联系人列表
diff --git a/module/user/test/model/failplus.php b/module/user/test/model/failplus.php
new file mode 100755
index 0000000000..585f38dac2
--- /dev/null
+++ b/module/user/test/model/failplus.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+gen(100);
+
+/**
+
+title=测试 userModel->failPlus();
+cid=1
+pid=1
+
+获取user2用户的登录失败次数 >> 4
+获取user90用户的登录失败次数 >> 0
+
+*/
+
+$user = new userTest();
+
+$user2 = $user->failPlusTest('user2');
+$user90 = $user->failPlusTest('user90');
+
+r($user2) && p() && e('1'); //获取user2用户的登录失败次数
+r($user90) && p() && e('0'); //获取user90用户的登录失败次数
diff --git a/module/user/test/model/getavatarpairs.php b/module/user/test/model/getavatarpairs.php
new file mode 100755
index 0000000000..296fada44b
--- /dev/null
+++ b/module/user/test/model/getavatarpairs.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+id->range('1001-1005');
+$user->account->range('1-5')->prefix("account");
+$user->realname->range('1-5')->prefix("用户名");
+$user->type->range('inside{4},ountside{1}');
+$user->avatar->range('1-5')->prefix('/home/z/user/');
+$user->deleted->range('0{4}, 1{1}');
+$user->gen(5);
+
+/**
+
+title=测试 userModel->getPairs();
+cid=1
+pid=1
+
+未删除的用户头像的数量 >> 4
+所有用户头像的数量 >> 5
+在未删除用户中查找account为"account1"的用户的头像路径 >> /home/z/user/1
+在未删除用户中查找account为"account2"的用户的头像路径 >> /home/z/user/2
+在未删除用户中查找account为"account3"的用户的头像路径 >> /home/z/user/3
+在未删除用户中查找account为"account4"的用户的头像路径 >> /home/z/user/4
+在所有用户中查找account为"account5"的用户的头像路径 >> /home/z/user/5
+
+*/
+$user = new userTest();
+
+r(count($user->getAvatarPairsTest())) && p() && e('4'); // 未删除的用户头像的数量
+r(count($user->getAvatarPairsTest('all'))) && p() && e('5'); // 所有用户头像的数量
+r($user->getAvatarPairsTest()) && p('account1') && e('/home/z/user/1'); // 在未删除用户中查找account为"account1"的用户的头像路径
+r($user->getAvatarPairsTest()) && p('account2') && e('/home/z/user/2'); // 在未删除用户中查找account为"account2"的用户的头像路径
+r($user->getAvatarPairsTest()) && p('account3') && e('/home/z/user/3'); // 在未删除用户中查找account为"account3"的用户的头像路径
+r($user->getAvatarPairsTest()) && p('account4') && e('/home/z/user/4'); // 在未删除用户中查找account为"account4"的用户的头像路径
+r($user->getAvatarPairsTest('all')) && p('account5') && e('/home/z/user/5'); // 在所有用户中查找account为"account5"的用户的头像路径
diff --git a/module/user/test/model/getbyid.php b/module/user/test/model/getbyid.php
new file mode 100755
index 0000000000..2db7be9549
--- /dev/null
+++ b/module/user/test/model/getbyid.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel::getById();
+cid=1
+pid=1
+
+通过id获取存在的用户 >> admin
+使用account字段获取存在的用户 >> admin
+通过默认字段获取存在的用户 >> admin
+
+*/
+$user = new userTest();
+
+r($user->getByIDTest(1, 'id')) && p('account') && e('admin'); // 通过id获取存在的用户
+r($user->getByIDTest('admin', 'account')) && p('account') && e('admin'); // 使用account字段获取存在的用户
+r($user->getByIDTest('admin')) && p('account') && e('admin'); // 通过默认字段获取存在的用户
+r($user->getByIDTest(1)) && p('account') && e('0'); // 通过默认字段获取不存在的用户
+r($user->getByIDTest(100000, 'id')) && p('account') && e('0'); // 通过id字段获取不存在的用户
+r($user->getByIDTest('error', 'account')) && p('account') && e('0'); // 通过默认字段获取不存在的用户
diff --git a/module/user/test/model/getbyquery.php b/module/user/test/model/getbyquery.php
new file mode 100755
index 0000000000..222d6ca8bf
--- /dev/null
+++ b/module/user/test/model/getbyquery.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+gen(1000);
+
+/**
+
+title=测试 userModel::getById();
+cid=1
+pid=1
+
+对比获取到的内部用户的数量 >> 303
+按ID倒序查询内部用户,获取最后一个用户的account >> admin
+获取第一个外部用户的真实姓名 >> 用户1
+
+*/
+$user = new userTest();
+$insideQAUsers = $user->getByQueryTest('inside', "`role` = 'qa'", 'id desc');
+$outsideUsers = $user->getByQueryTest('outside');
+
+r(count($insideQAUsers)) && p() && e('303'); //对比获取到的内部用户的数量
+r($insideQAUsers) && p('302:account') && e('admin'); //按ID倒序查询内部用户,获取最后一个用户的account
+r($outsideUsers) && p('0:realname') && e('用户1'); //获取第一个外部用户的真实姓名
diff --git a/module/user/test/model/getcancreatestoryusers.php b/module/user/test/model/getcancreatestoryusers.php
new file mode 100755
index 0000000000..26a3d0a514
--- /dev/null
+++ b/module/user/test/model/getcancreatestoryusers.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+gen(1000);
+su('admin');
+
+/**
+
+title=测试 userModel->getCanCreateStoryUsers();
+cid=1
+pid=1
+
+查找系统中有权限创建、批量创建需求的用户 >> A:admin;T:研发主管48
+
+*/
+
+$user = new userTest();
+r($user->getCanCreateStoryUsersTest()) && p('admin;td48') && e('A:admin;T:研发主管48'); //查找系统中有权限创建、批量创建需求的用户
\ No newline at end of file
diff --git a/module/user/test/model/getcommiters.php b/module/user/test/model/getcommiters.php
new file mode 100755
index 0000000000..fc4f13077c
--- /dev/null
+++ b/module/user/test/model/getcommiters.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+gen(30);
+
+/**
+
+title=测试 userModel->getCommiters();
+cid=1
+pid=1
+
+获取源代码账号为user10的用户真实姓名 >> 测试10
+获取系统中源代码账号不为空的用户数量 >> 30
+
+*/
+
+$user = new userTest();
+$commiters = $user->getCommitersTest();
+
+r($commiters) && p('user10') && e('测试10'); //获取源代码账号为user10的用户真实姓名
+r(count($commiters)) && p() && e('30'); //获取系统中源代码账号不为空的用户数量
diff --git a/module/user/test/model/getcontactlistbyid.php b/module/user/test/model/getcontactlistbyid.php
new file mode 100755
index 0000000000..1949304a18
--- /dev/null
+++ b/module/user/test/model/getcontactlistbyid.php
@@ -0,0 +1,32 @@
+#!/usr/bin/env php
+gen(3);
+
+/**
+
+title=测试 userModel->getContactListByID();
+cid=1
+pid=1
+
+获取ID为1的联系人列表名称 >> 联系人列表1
+获取ID为2的联系人列表创建者 >> dev2
+获取ID为3的联系人列表所包含的用户 >> test22,test42
+获取ID为1000的联系人列表,返回空 >> 0
+获取ID为false的联系人列表,返回空 >> 0
+获取ID为null的联系人列表,返回空 >> 0
+
+*/
+
+$user = new userTest();
+
+r($user->getContactListByIDTest(1)) && p('listName') && e('联系人列表1'); //获取ID为1的联系人列表名称
+r($user->getContactListByIDTest(2)) && p('account') && e('dev2'); //获取ID为2的联系人列表创建者
+r($user->getContactListByIDTest(3)) && p('userList') && e('test22,test42'); //获取ID为3的联系人列表所包含的用户
+r($user->getContactListByIDTest(1000)) && p() && e('0'); //获取ID为1000的联系人列表,返回空
+r($user->getContactListByIDTest(false)) && p() && e('0'); //获取ID为false的联系人列表,返回空
+r($user->getContactListByIDTest(null)) && p() && e('0'); //获取ID为null的联系人列表,返回空
diff --git a/module/user/test/model/getcontactlists.php b/module/user/test/model/getcontactlists.php
new file mode 100755
index 0000000000..27b0103968
--- /dev/null
+++ b/module/user/test/model/getcontactlists.php
@@ -0,0 +1,35 @@
+#!/usr/bin/env php
+gen(100);
+
+/**
+
+title=测试 userModel::getContactLists();
+cid=1
+pid=1
+
+获取user1的联系人列表,取出空对应的值 >> 联系人
+获取dev2的联系人列表,判断空对应的值是否为空 >> 1
+获取test3的联系人列表的总数 >> 3
+获取admin的联系人列表 >> 0
+获取空用户的联系人列表 >> 0
+
+*/
+
+$user = new userTest();
+$user1ContactList = $user->getContactListsTest('user1', 'withempty|withnote');
+$dev2ContactList = $user->getContactListsTest('dev2', 'withempty');
+$test3ContactList = $user->getContactListsTest('test3');
+$adminContactList = $user->getContactListsTest('admin');
+$emptyContactList = $user->getContactListsTest('');
+
+r($user1ContactList['']) && p() && e('联系人'); // 获取user1的联系人列表,取出空对应的值
+r($dev2ContactList[''] === '') && p() && e('1'); // 获取dev2的联系人列表,判断空对应的值是否为空
+r(count($test3ContactList)) && p() && e('3'); // 获取test3的联系人列表的总数
+r($adminContactList) && p() && e('0'); // 获取admin的联系人列表
+r($emptyContactList) && p() && e('0'); // 获取空用户的联系人列表
diff --git a/module/user/test/model/getcontactuserpairs.php b/module/user/test/model/getcontactuserpairs.php
new file mode 100755
index 0000000000..907768844a
--- /dev/null
+++ b/module/user/test/model/getcontactuserpairs.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+id->range('1-3');
+$user->account->range('1-3')->prefix('account');
+$user->realname->range('1-3')->prefix('测试人员');
+$user->gen(3);
+
+/**
+
+title=userModel->getContactUserPairs();
+cid=1
+pid=1
+
+根据传入的accountList获取account1真实姓名 >> 测试人员1
+根据传入的accountList获取account2真实姓名 >> 测试人员2
+根据传入的accountList获取account3真实姓名 >> 测试人员3
+根据传入的accountList获取asdasd真实姓名 >> N/A
+
+*/
+$user = new userTest('admin');
+$accountList = array('account1', 'account2', 'account3', 'asdasd');
+
+r($user->getContactUserPairsTest($accountList)) && p('account1') && e('测试人员1'); //根据传入的accountList获取account1真实姓名
+r($user->getContactUserPairsTest($accountList)) && p('account2') && e('测试人员2'); //根据传入的accountList获取account2真实姓名
+r($user->getContactUserPairsTest($accountList)) && p('account3') && e('测试人员3'); //根据传入的accountList获取account3真实姓名
+r($user->getContactUserPairsTest($accountList)) && p('asdasd') && e(''); //根据传入的accountList获取asdasd真实姓名
diff --git a/module/user/test/model/getdatainjson.php b/module/user/test/model/getdatainjson.php
new file mode 100755
index 0000000000..a3a8d8f468
--- /dev/null
+++ b/module/user/test/model/getdatainjson.php
@@ -0,0 +1,58 @@
+#!/usr/bin/env php
+getDataInJSON();
+cid=1
+pid=1
+
+传入用户1信息,返回公司信息 >> 易软天创网络科技有限公司
+传入用户2信息,返回用户名信息 >> account2
+传入用户3信息,返回真实姓名信息 >> 用户3
+传入用户4信息,隐藏密码信息 >> N/A
+传入用户5信息,隐藏是否删除 >> N/A
+传入null,返回空 >> N/A
+
+*/
+$userTester = new userTest();
+
+$user1 = new stdclass();
+$user1->account = 'account1';
+$user1->realname = '用户1';
+$user1->password = 'qweqwe';
+$user1->deleted = 1;
+
+$user2 = new stdclass();
+$user2->account = 'account2';
+$user2->realname = '用户2';
+$user2->password = 'qweqwe';
+$user2->deleted = 0;
+
+$user3 = new stdclass();
+$user3->account = 'account3';
+$user3->realname = '用户3';
+$user3->password = 'qweqwe';
+$user3->deleted = 0;
+
+$user4 = new stdclass();
+$user4->account = 'account4';
+$user4->realname = '用户4';
+$user4->password = 'qweqwe';
+$user4->deleted = 1;
+
+$user5 = new stdclass();
+$user5->account = 'account5';
+$user5->realname = '用户5';
+$user5->password = 'qweqwe';
+$user5->deleted = 1;
+
+r($userTester->getDataInJSONTest($user1)) && p('user:company') && e('易软天创网络科技有限公司'); //传入用户1信息,返回公司信息
+r($userTester->getDataInJSONTest($user2)) && p('user:account') && e('account2'); //传入用户2信息,返回用户名信息
+r($userTester->getDataInJSONTest($user3)) && p('user:realname') && e('用户3'); //传入用户3信息,返回真实姓名信息
+r($userTester->getDataInJSONTest($user4)) && p('user:password') && e(''); //传入用户4信息,隐藏密码信息
+r($userTester->getDataInJSONTest($user5)) && p('user:deleted') && e(''); //传入用户5信息,隐藏是否删除
+r($userTester->getDataInJSONTest(null)) && p() && e(''); //传入null,返回空
diff --git a/module/user/test/model/getgroups.php b/module/user/test/model/getgroups.php
new file mode 100755
index 0000000000..492af21e78
--- /dev/null
+++ b/module/user/test/model/getgroups.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+gen(50);
+
+$userGroup = zdTable('usergroup');
+$userGroup->gen(500);
+
+/**
+
+title=测试 userModel::getGroups();
+cid=1
+pid=1
+
+获取admin所在的分组,为空 >> 0
+通过test2所在的分组数量,1个 >> 1
+传空用户名,返回空 >> 0
+
+*/
+$user = new userTest();
+
+r($user->getGroupsTest('admin')) && p() && e('0'); // 获取admin所在的分组,为空
+r(count($user->getGroupsTest('test2'))) && p() && e('1'); // 通过test2所在的分组数量,1个
+r($user->getGroupsTest('')) && p() && e('0'); // 传空用户名,返回空
diff --git a/module/user/test/model/getgroupsbyvisions.php b/module/user/test/model/getgroupsbyvisions.php
new file mode 100755
index 0000000000..58e28b5da7
--- /dev/null
+++ b/module/user/test/model/getgroupsbyvisions.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+> 13
+获取系统中所有迅捷界面分组的数量 >> 3
+传空Visions,返回空数组 >> 0
+获取系统中所有用户分组的数量 >> 16
+
+*/
+$user = new userTest();
+
+r(count($user->getGroupsByVisionsTest(array('rnd')))) && p() && e('13'); // 获取系统中所有研发界面分组的数量
+r(count($user->getGroupsByVisionsTest(array('lite')))) && p() && e('3'); // 获取系统中所有迅捷界面分组的数量
+r($user->getGroupsByVisionsTest(array())) && p() && e('0'); // 传空Visions,返回空数组
+r(count($user->getGroupsByVisionsTest(array('rnd','lite')))) && p() && e('16'); // 获取系统中所有用户分组的数量
diff --git a/module/user/test/model/getlist.php b/module/user/test/model/getlist.php
new file mode 100755
index 0000000000..1406406c3c
--- /dev/null
+++ b/module/user/test/model/getlist.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+id->range('1001-1005');
+$user->account->range('1-5')->prefix("account");
+$user->realname->range('1-5')->prefix("用户名");
+$user->type->range('inside{3},outside{2}');
+$user->deleted->range('0-1');
+$user->gen(5);
+
+/**
+
+title=测试 userModel->getList();
+cid=1
+pid=1
+
+查找系统中第一个未删除的、内部用户真实姓名,根据account正序排 >> 用户名1
+查找系统中第二个未删除的、内部用户真实姓名,根据account正序排 >> 用户名3
+查找系统中所有未删除的、内部用户的数量 >> 2
+查找系统中第一个用户的真实姓名 >> 用户名1
+查找系统中第二个用户的真实姓名 >> 用户名2
+查找系统中第三个用户的真实姓名 >> 用户名3
+查找系统中第四个用户的真实姓名 >> 用户名4
+查找系统中第五个用户的真实姓名 >> 用户名5
+查找系统中所有用户数量 >> 5
+
+*/
+
+$user = new userTest();
+
+r($user->getListTest()) && p('0:realname') && e('用户名1'); // 查找系统中第一个未删除的、内部用户真实姓名,根据account正序排
+r($user->getListTest()) && p('1:realname') && e('用户名3'); // 查找系统中第二个未删除的、内部用户真实姓名,根据account正序排
+r($user->getListTest('nodeleted', true)) && p() && e('2'); // 查找系统中所有未删除的、内部用户的数量
+r($user->getListTest('all')) && p('0:realname') && e('用户名1'); // 查找系统中第一个用户的真实姓名
+r($user->getListTest('all')) && p('1:realname') && e('用户名2'); // 查找系统中第二个用户的真实姓名
+r($user->getListTest('all')) && p('2:realname') && e('用户名3'); // 查找系统中第三个用户的真实姓名
+r($user->getListTest('all')) && p('3:realname') && e('用户名4'); // 查找系统中第四个用户的真实姓名
+r($user->getListTest('all')) && p('4:realname') && e('用户名5'); // 查找系统中第五个用户的真实姓名
+r($user->getListTest('all', true)) && p() && e('5'); // 查找系统中所有用户数量
diff --git a/module/user/test/model/getlistbyaccount.php b/module/user/test/model/getlistbyaccount.php
new file mode 100755
index 0000000000..43f4e00f65
--- /dev/null
+++ b/module/user/test/model/getlistbyaccount.php
@@ -0,0 +1,29 @@
+#!/usr/bin/env php
+gen(100);
+
+/**
+
+title=测试 userModel::getListByAccount();
+cid=1
+pid=1
+
+获取admin的联系人列表 >> 0
+获取dev2的联系人列表 >> 3
+获取空用户的联系人列表 >> 0
+
+*/
+
+$user = new userTest();
+$adminContactList = $user->getListByAccountTest('admin');
+$test2ContactList = $user->getListByAccountTest('dev2');
+$emptyContactList = $user->getListByAccountTest('');
+
+r(count($adminContactList)) && p() && e('0'); // 获取admin的联系人列表
+r(count($test2ContactList)) && p() && e('3'); // 获取dev2的联系人列表
+r(count($emptyContactList)) && p() && e('0'); // 获取空用户的联系人列表
diff --git a/module/user/test/model/getlistbyaccounts.php b/module/user/test/model/getlistbyaccounts.php
new file mode 100755
index 0000000000..0d2d4e99f5
--- /dev/null
+++ b/module/user/test/model/getlistbyaccounts.php
@@ -0,0 +1,43 @@
+#!/usr/bin/env php
+id->range('1001-1005');
+$user->account->range('1-5')->prefix("account");
+$user->realname->range('1-5')->prefix("用户名");
+$user->role->range('po,pd,qa,qd,pm');
+$user->type->range('inside{3},outside{2}');
+$user->deleted->range('0-1');
+$user->gen(5);
+
+/**
+
+title=测试 userModel->getListByAccounts();
+cid=1
+pid=1
+
+按照给定的用户名列表查询用户信息,获取用户ID为1001的用户真实姓名和角色 >> 用户名1,po
+按照给定的用户名列表查询用户信息,获取用户ID为1002的用户真实姓名和角色 >> 用户名2,pd
+按照给定的用户名列表查询用户信息,获取用户ID为1003的用户真实姓名和角色 >> 用户名3,qa
+按照给定的用户名列表查询用户信息,获取用户ID为1004的用户真实姓名和角色 >> 用户名4,qd
+按照给定的用户名列表查询用户信息,获取查询出的用户列表数量 >> 5
+删除account4后,按照给定的用户名列表查询用户信息,获取用户account为account2的用户真实姓名和角色 >> 用户名2,pd
+删除account4后,按照给定的用户名列表查询用户信息,获取查询出的用户列表数量 >> 4
+
+*/
+$accounts = array('account1', 'account2', 'account3', 'account4', 'account5');
+$keyFiled = array('id', 'account');
+$count = array(0 => false, 1 => true);
+
+$user = new userTest();
+r($user->getListByAccountsTest($accounts, $keyFiled[0], $count[0])) && p('1001:realname,role') && e('用户名1,po'); // 按照给定的用户名列表查询用户信息,获取用户ID为1001的用户真实姓名和角色
+r($user->getListByAccountsTest($accounts, $keyFiled[0], $count[0])) && p('1002:realname,role') && e('用户名2,pd'); // 按照给定的用户名列表查询用户信息,获取用户ID为1002的用户真实姓名和角色
+r($user->getListByAccountsTest($accounts, $keyFiled[0], $count[0])) && p('1003:realname,role') && e('用户名3,qa'); // 按照给定的用户名列表查询用户信息,获取用户ID为1003的用户真实姓名和角色
+r($user->getListByAccountsTest($accounts, $keyFiled[0], $count[0])) && p('1004:realname,role') && e('用户名4,qd'); // 按照给定的用户名列表查询用户信息,获取用户ID为1004的用户真实姓名和角色
+r($user->getListByAccountsTest($accounts, $keyFiled[0], $count[1])) && p() && e('5'); // 按照给定的用户名列表查询用户信息,获取查询出的用户列表数量
+unset($accounts[3]);
+r($user->getListByAccountsTest($accounts, $keyFiled[1], $count[0])) && p('account2:realname,role') && e('用户名2,pd'); // 删除account4后,按照给定的用户名列表查询用户信息,获取用户account为account2的用户真实姓名和角色
+r($user->getListByAccountsTest($accounts, $keyFiled[1], $count[1])) && p() && e('4'); // 删除account4后,按照给定的用户名列表查询用户信息,获取查询出的用户列表数量
diff --git a/module/user/test/model/getobjects.php b/module/user/test/model/getobjects.php
new file mode 100755
index 0000000000..26113eda45
--- /dev/null
+++ b/module/user/test/model/getobjects.php
@@ -0,0 +1,48 @@
+#!/usr/bin/env php
+gen(50);
+$team = zdTable('team');
+$team->gen(200);
+$project = zdTable('project');
+$project->id->range('1-10,11-50,51-100');
+$project->type->range('program{10},project{40},sprint{20},stage{20},kanban{10}');
+$project->status->range('wait{50},done{10},closed{40}');
+$project->vision->range('[rnd,lite]{100!}');
+$project->name->range('1-100')->prefix('Object');
+$project->multiple->range('1');
+$project->deleted->range('0{90},1{10}');
+$project->gen(100);
+
+/**
+
+title=测试 userModel::getObjects();
+cid=1
+pid=1
+
+获取admin的所属项目列表,取ID为11的项目名字 >> Object11
+获取admin的所属项目列表,取ID为11的项目类型 >> project
+获取admin的所属执行列表,取ID为70的执行名字 >> 0
+获取admin的已完成的所属项目列表,返回空 >> 0
+获取test2用户的所属项目列表,返回空 >> 0
+传入一个空用户名字段,返回空 >> 0
+
+*/
+
+$user = new userTest();
+$adminProjects = $user->getObjectsTest('admin', 'project', 'all', 'id_desc');
+$adminDoneProjects = $user->getObjectsTest('admin', 'project', 'done', 'id_desc');
+$adminExecutions = $user->getObjectsTest('admin', 'execution', 'all', 'id_desc');
+$test2Projects = $user->getObjectsTest('test2', 'project', 'all', 'id_desc');
+$emptyUser = $user->getObjectsTest('', 'execution', 'all', 'id_desc');
+
+r($adminProjects) && p('11:name') && e('Object11'); //获取admin的所属项目列表,取ID为11的项目名字
+r($adminProjects) && p('11:type') && e('project'); //获取admin的所属项目列表,取ID为11的项目类型
+r($adminExecutions) && p('70:name') && e('0'); //获取admin的所属执行列表,取ID为70的执行名字,返回空
+r($adminDoneProjects) && p('') && e('0'); //获取admin的已完成的所属项目列表,返回空
+r($test2Projects) && p('') && e('0'); //获取test2用户的所属项目列表,返回空
+r($emptyUser) && p('') && e('0'); //传入一个空用户名字段,返回空
diff --git a/module/user/test/model/getpairs.php b/module/user/test/model/getpairs.php
new file mode 100755
index 0000000000..7207471ec0
--- /dev/null
+++ b/module/user/test/model/getpairs.php
@@ -0,0 +1,57 @@
+#!/usr/bin/env php
+id->range('1001-1006');
+$user->account->range('1-6')->prefix("account");
+$user->realname->range('1-6')->prefix("用户名");
+$user->type->range('inside{3},outside{3}');
+$user->role->range('po,pd,qa,qd,pm,dev');
+$user->deleted->range('0{4}, 1{2}');
+$user->visions->range('rnd');
+$user->gen(5);
+
+/**
+
+title=测试 userModel->getPairs();
+cid=1
+pid=1
+
+查找带有Closed用户的外部用户键值对 >> Closed
+查找带有首字母的外部用户键值对 >> A:用户名4
+查找不带首字母的外部用户键值对 >> 用户名4
+按照给定的用户名查找用户键值对,返回值中不带有Closed用户 >> 1
+按照给定的用户名查找用户键值对,返回值中带有Closed用户 >> 2
+使用limit参数来限制最多获取2个用户键值对 >> 2
+使用limit参数来限制最多获取50个用户键值对 >> 3
+使用pofirst参数来将系统中的产品经理用户放到返回值前列 >> A:用户名1
+使用pmfirst参数来将系统中的项目经理内部和外部用户放到返回值前列 >> A:用户名3
+
+*/
+$usersToAppended = array('account5', 'account1');
+
+$user = new userTest();
+$outsideUsersWithClosed = $user->getPairsTest('outside');
+$outsideUsersWithLetter = $user->getPairsTest('outside|noclosed');
+$outsideUsersNoLetter = $user->getPairsTest('outside|noclosed|noletter');
+$usersInAccountsNoclosed = $user->getPairsTest('noempty|noclosed', '', 0, $usersToAppended);
+$usersInAccountsWithclosed = $user->getPairsTest('noempty', '', 0, $usersToAppended);
+$limit2Users = $user->getPairsTest('noempty|noclosed', '', 2);
+$limit50Users = $user->getPairsTest('noempty|noclosed', '', 50);
+$POFirstUsers = $user->getPairsTest('noempty|noclosed|pofirst');
+$PMFirstUsers = $user->getPairsTest('noempty|noclosed|all|devfirst');
+$firstPO = array_slice($POFirstUsers, 0, 1);
+$firstPM = array_slice($PMFirstUsers, 0, 1);
+
+r($outsideUsersWithClosed) && p('closed') && e('Closed'); //查找带有Closed用户的外部用户键值对
+r($outsideUsersWithLetter) && p('account4') && e('A:用户名4'); //查找带有首字母的外部用户键值对
+r($outsideUsersNoLetter) && p('account4') && e('用户名4'); //查找不带首字母的外部用户键值对
+r(count($usersInAccountsNoclosed)) && p() && e('1'); //按照给定的用户名查找用户键值对,返回值中不带有Closed用户
+r(count($usersInAccountsWithclosed)) && p() && e('2'); //按照给定的用户名查找用户键值对,返回值中带有Closed用户
+r(count($limit2Users)) && p() && e('2'); //使用limit参数来限制最多获取2个用户键值对
+r(count($limit50Users)) && p() && e('3'); //使用limit参数来限制最多获取50个用户键值对
+r($firstPO) && p('account1') && e('A:用户名1'); //使用pofirst参数来将系统中的产品经理用户放到返回值前列
+r($firstPM) && p('account3') && e('A:用户名3'); //使用pmfirst参数来将系统中的项目经理内部和外部用户放到返回值前列
diff --git a/module/user/test/model/getparentstageauthedusers.php b/module/user/test/model/getparentstageauthedusers.php
new file mode 100755
index 0000000000..177c4f4e41
--- /dev/null
+++ b/module/user/test/model/getparentstageauthedusers.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+gen(400);
+
+/**
+
+title=测试 userModel->getParentStageAuthedUsers();
+cid=1
+pid=1
+
+传入ID为0的情况获取有权限的用户 >> 0
+传入一个阶段ID获取有权限的用户 >> dev12
+传入一个项目集ID获取有权限的用户 >> 0
+
+*/
+$user = new userTest();
+
+r($user->getParentStageAuthedUsersTest(0)) && p() && e('0'); //传入阶段ID为0获取有权限的用户
+r($user->getParentStageAuthedUsersTest(212)) && p('dev12') && e('dev12'); //传入一个阶段ID为212获取有权限的用户
+r($user->getParentStageAuthedUsersTest(1)) && p() && e('0'); //传入一个阶段ID为1获取有权限的用户
diff --git a/module/user/test/model/getpersonaldata.php b/module/user/test/model/getpersonaldata.php
new file mode 100755
index 0000000000..7472caa577
--- /dev/null
+++ b/module/user/test/model/getpersonaldata.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+gen(500);
+zdTable('story')->gen(400);
+zdTable('case')->gen(400);
+zdTable('bug')->gen(300);
+
+su('admin');
+
+/**
+
+title=测试 userModel::getPersonalData();
+cid=1
+pid=1
+
+获取admin用户的createdBugs数量 >> 30
+获取test2用户createdCases数量 >> 4
+当获取一个空用户的数据时,系统默认返回当前登录用户的数据 >> 3
+
+*/
+$user = new userTest();
+$adminData = $user->getPersonalDataTest('admin');
+$test2Data = $user->getPersonalDataTest('test2');
+$emptyData = $user->getPersonalDataTest('');
+
+r($adminData) && p('createdBugs') && e('30'); //获取admin用户的createdBugs数量
+r($test2Data) && p('createdCases') && e('4'); //获取test2用户createdCases数量
+r($emptyData) && p('createdTodos') && e('3'); //当获取一个空用户的数据时,系统默认返回当前登录用户的数据
\ No newline at end of file
diff --git a/module/user/test/model/getproductmembers.php b/module/user/test/model/getproductmembers.php
new file mode 100755
index 0000000000..2cdf9edeb6
--- /dev/null
+++ b/module/user/test/model/getproductmembers.php
@@ -0,0 +1,31 @@
+#!/usr/bin/env php
+getProductMembers();
+cid=1
+pid=1
+
+获取ID为1的产品的团队成员,判断是否包含pm92 >> pm92
+获取ID为4的产品的团队成员,判断是否包含user5 >> user5
+获取ID为2的产品的干系人,判断是否包含po3 >> po3
+获取ID为3的产品的干系人,判断是否包含user14 >> user14
+
+*/
+
+$user = new userTest();
+$products = array(1 => 1, 2 => 2, 3 => 3, 4 => 4);
+
+$members = $user->getProductMembersTest($products);
+$teamGroups = $members[0];
+$stakeholderGroups = $members[0];
+
+r($teamGroups) && p('1:pm92') && e('pm92'); //获取ID为1的产品的团队成员,判断是否包含pm92
+r($teamGroups) && p('4:user5') && e('user5'); //获取ID为4的产品的团队成员,判断是否包含user5
+r($stakeholderGroups) && p('2:po3') && e('po3'); //获取ID为2的产品的干系人,判断是否包含po3
+r($stakeholderGroups) && p('3:user14') && e('user14'); //获取ID为3的产品的干系人,判断是否包含user14
+
diff --git a/module/user/test/model/getproductviewlistusers.php b/module/user/test/model/getproductviewlistusers.php
new file mode 100755
index 0000000000..469bd78675
--- /dev/null
+++ b/module/user/test/model/getproductviewlistusers.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('user')->gen(100);
+su('admin');
+
+/**
+
+title=测试 userModel->getProductViewListUsers();
+cid=1
+pid=1
+
+获取对ID为1的产品有权限的用户 >> 11
+获取对ID为1的产品有权限的用户 >> test9
+获取对ID为1的产品有权限的用户 >> admin
+获取对ID为2的产品有权限的用户 >> astaw
+获取对ID为2的产品有权限的用户 >> test20
+
+*/
+
+$user = new userTest();
+$stakeholders['test9'] = 'test9';
+$stakeholders['test10'] = 'test10';
+
+$teams['pm7'] = 'pm7';
+$teams['pm8'] = 'pm8';
+
+$whiteList['user35'] = 'user35';
+$whiteList['user35'] = 'user35';
+$whiteList['astaw'] = 'astaw';
+
+$admins['test20'] = 'test20';
+$admins['test21'] = 'test21';
+
+r(count($user->getProductViewListUsersTest(1, $stakeholders, $teams, $whiteList, array()))) && p() && e('11'); //获取对ID为1的产品有权限的用户
+r($user->getProductViewListUsersTest(1, $stakeholders, $teams, $whiteList, array())) && p('test9') && e('test9'); //获取对ID为1的产品有权限的用户
+r($user->getProductViewListUsersTest(1, $stakeholders, $teams, $whiteList, array())) && p('admin') && e('admin'); //获取对ID为1的产品有权限的用户
+r($user->getProductViewListUsersTest(2, $stakeholders, $teams, $whiteList, array())) && p('astaw') && e('astaw'); //获取对ID为2的产品有权限的用户
+r($user->getProductViewListUsersTest(2, $stakeholders, $teams, $whiteList, $admins)) && p('test20') && e('test20'); //获取对ID为2的产品有权限的用户
\ No newline at end of file
diff --git a/module/user/test/model/getprogramauthedusers.php b/module/user/test/model/getprogramauthedusers.php
new file mode 100755
index 0000000000..1663a65ffc
--- /dev/null
+++ b/module/user/test/model/getprogramauthedusers.php
@@ -0,0 +1,37 @@
+#!/usr/bin/env php
+gen(10, 'program');
+zdTable('user')->gen(200);
+su('admin');
+
+/**
+
+title=测试 userModel->getProgramAuthedUsers();
+cid=1
+pid=1
+
+获取对ID为1的项目集有权限的用户数量 >> 7
+获取对ID为1的项目集有权限的用户 >> test9
+获取对ID为1的项目集有权限的用户 >> admin
+获取对ID为2的项目集有权限的用户 >> astaw
+
+*/
+
+$user = new userTest();
+$stakeholders['test9'] = 'test9';
+$stakeholders['test10'] = 'test10';
+
+$whiteList['user35'] = 'user35';
+$whiteList['user35'] = 'user35';
+$whiteList['astaw'] = 'astaw';
+
+$admins['test20'] = 'test20';
+$admins['test21'] = 'test21';
+
+r(count($user->getProgramAuthedUsersTest(1, $stakeholders, $whiteList, array()))) && p() && e('7'); //获取对ID为1的项目集有权限的用户数量
+r($user->getProgramAuthedUsersTest(1, $stakeholders, $whiteList, array())) && p('test9') && e('test9'); //获取对ID为1的项目集有权限的用户
+r($user->getProgramAuthedUsersTest(1, $stakeholders, $whiteList, array())) && p('admin') && e('admin'); //获取对ID为1的项目集有权限的用户
+r($user->getProgramAuthedUsersTest(2, $stakeholders, $whiteList, array())) && p('astaw') && e('astaw'); //获取对ID为2的项目集有权限的用户
+r($user->getProgramAuthedUsersTest(2, $stakeholders, $whiteList, $admins)) && p('test21') && e('test21'); //获取对ID为2的项目集有权限的用户
diff --git a/module/user/test/model/getprojectauthedusers.php b/module/user/test/model/getprojectauthedusers.php
new file mode 100755
index 0000000000..fb45feb0ef
--- /dev/null
+++ b/module/user/test/model/getprojectauthedusers.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('user')->gen(200);
+su('admin');
+
+/**
+
+title=测试 userModel->getProjectAuthedUsers();
+cid=1
+pid=1
+
+获取对ID为1的产品有权限的用户 >> test9
+获取对ID为1的产品有权限的用户 >> admin
+获取对ID为2的产品有权限的用户 >> astaw
+
+*/
+
+$user = new userTest();
+$stakeholders['test9'] = 'test9';
+$stakeholders['test10'] = 'test10';
+
+$teams['pm7'] = 'pm7';
+$teams['pm8'] = 'pm8';
+
+$whiteList['user35'] = 'user35';
+$whiteList['user35'] = 'user35';
+$whiteList['astaw'] = 'astaw';
+
+r($user->getProjectAuthedUsersTest(1, $stakeholders, $teams, $whiteList)) && p('test9') && e('test9'); //获取对ID为1的产品有权限的用户
+r($user->getProjectAuthedUsersTest(1, $stakeholders, $teams, $whiteList)) && p('admin') && e('admin'); //获取对ID为1的产品有权限的用户
+r($user->getProjectAuthedUsersTest(2, $stakeholders, $teams, $whiteList)) && p('astaw') && e('astaw'); //获取对ID为2的产品有权限的用户
diff --git a/module/user/test/model/getrealnameandemails.php b/module/user/test/model/getrealnameandemails.php
new file mode 100755
index 0000000000..1aa9e278a8
--- /dev/null
+++ b/module/user/test/model/getrealnameandemails.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+id->range('1001-1005');
+$user->account->range('1-5')->prefix("account");
+$user->realname->range('1-5')->prefix("用户名");
+$user->email->range('account1@qq.com,account2@qq.com,account3@qq.com,account4@qq.com,account5@qq.com');
+$user->deleted->range('0{5}');
+$user->gen(5);
+
+/**
+
+title=测试 userModel->getPairs();
+cid=1
+pid=1
+
+获取account1的邮箱和真实姓名 >> account1@qq.com,用户名1
+获取account2的邮箱和真实姓名 >> account2@qq.com,用户名2
+获取account3的邮箱和真实姓名 >> account3@qq.com,用户名3
+获取account4的邮箱和真实姓名 >> account4@qq.com,用户名4
+获取account5的邮箱和真实姓名 >> account5@qq.com,用户名5
+从accounts中获取到的用户邮箱数量 >> 5
+
+*/
+
+$accounts = array('account1', 'account2', 'account3', 'account4', 'account5');
+$user = new userTest();
+$emails = $user->getRealNameAndEmailsTest($accounts);
+
+r($emails['account1']) && p('email,realname') && e('account1@qq.com,用户名1'); //获取account1的邮箱和真实姓名
+r($emails['account2']) && p('email,realname') && e('account2@qq.com,用户名2'); //获取account2的邮箱和真实姓名
+r($emails['account3']) && p('email,realname') && e('account3@qq.com,用户名3'); //获取account3的邮箱和真实姓名
+r($emails['account4']) && p('email,realname') && e('account4@qq.com,用户名4'); //获取account4的邮箱和真实姓名
+r($emails['account5']) && p('email,realname') && e('account5@qq.com,用户名5'); //获取account5的邮箱和真实姓名
+r(count($emails)) && p() && e('5'); //从accounts中获取到的用户邮箱数量
diff --git a/module/user/test/model/getsprintauthedusers.php b/module/user/test/model/getsprintauthedusers.php
new file mode 100755
index 0000000000..2552dbdd54
--- /dev/null
+++ b/module/user/test/model/getsprintauthedusers.php
@@ -0,0 +1,38 @@
+#!/usr/bin/env php
+gen(300, 'execution');
+zdTable('user')->gen(200);
+su('admin');
+
+/**
+
+title=测试 userModel->getSprintAuthedUsers();
+cid=1
+pid=1
+
+获取对ID为101的执行有权限的用户 >> test9
+获取对ID为101的执行有权限的用户 >> admin
+获取对ID为201的执行有权限的用户 >> astaw
+获取对ID为201的执行有权限的用户 >> test21
+
+*/
+$user = new userTest();
+$stakeholders['test9'] = 'test9';
+$stakeholders['test10'] = 'test10';
+
+$teams['pm7'] = 'pm7';
+$teams['pm8'] = 'pm8';
+
+$whiteList['user35'] = 'user35';
+$whiteList['user35'] = 'user35';
+$whiteList['astaw'] = 'astaw';
+
+$admins['test20'] = 'test20';
+$admins['test21'] = 'test21';
+
+r($user->getSprintAuthedUsersTest(101, $stakeholders, $teams, $whiteList, array())) && p('test9') && e('test9'); //获取对ID为101的执行有权限的用户
+r($user->getSprintAuthedUsersTest(101, $stakeholders, $teams, $whiteList, array())) && p('admin') && e('admin'); //获取对ID为101的执行有权限的用户
+r($user->getSprintAuthedUsersTest(201, $stakeholders, $teams, $whiteList, array())) && p('astaw') && e('astaw'); //获取对ID为201的执行有权限的用户
+r($user->getSprintAuthedUsersTest(201, $stakeholders, $teams, $whiteList, $admins)) && p('test21') && e('test21'); //获取对ID为201的执行有权限的用户
\ No newline at end of file
diff --git a/module/user/test/model/getteammemberpairs.php b/module/user/test/model/getteammemberpairs.php
new file mode 100755
index 0000000000..0f85d0765d
--- /dev/null
+++ b/module/user/test/model/getteammemberpairs.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('team')->gen(400);
+zdTable('user')->gen(1000);
+su('admin');
+
+/**
+
+title=测试 userModel->getTeamMemberPairs();
+cid=1
+pid=1
+
+获取ID为11的项目的团队成员数量 >> 3
+获取ID为11的项目的团队成员数量,追加用户test2 >> 4
+获取ID为11的项目的团队成员数量,追加用户test2 >> project
+获取ID为110的执行的团队成员成员 >> T:测试1
+
+*/
+
+$user = new userTest();
+
+r(count($user->getTeamMemberPairsTest(11, 'project'))) && p() && e('3'); //获取ID为11的项目的团队成员数量
+r(count($user->getTeamMemberPairsTest(11, 'project', '', array('test2')))) && p() && e('4') && zdTable('project')->gen(100, 'execution' );//获取ID为11的项目的团队成员数量,追加用户test2
+zdTable('project')->gen(100, 'execution' );
+r($user->getTeamMemberPairsTest(110, 'execution')) && p('test1') && e('T:测试1'); //获取ID为110的执行的团队成员成员
diff --git a/module/user/test/model/getuserdetailsforapi.php b/module/user/test/model/getuserdetailsforapi.php
new file mode 100755
index 0000000000..9a0097d201
--- /dev/null
+++ b/module/user/test/model/getuserdetailsforapi.php
@@ -0,0 +1,25 @@
+#!/usr/bin/env php
+gen(500);
+su('admin');
+
+/**
+
+title=测试 userModel::getUserDetailsForAPI();
+cid=1
+pid=1
+
+获取admin用户的url >> getuserdetailsforapi
+获取test2用户的真实姓名 >> 测试2
+获取user10的头像信息 >> http:///home/z/tmp/10.png
+
+*/
+$user = new userTest();
+$userList = array('admin', 'test2', 'user10', '');
+$users = $user->getUserDetailsForAPITest($userList);
+
+r($users) && p('admin:url') && e('getuserdetailsforapi'); //获取admin用户的url
+r($users) && p('test2:realname') && e('测试2'); //获取test2用户的真实姓名
+r($users) && p('user10:avatar') && e('http:///home/z/tmp/10.png'); //获取user10的头像信息
\ No newline at end of file
diff --git a/module/user/test/model/getuserdisplayinfos.php b/module/user/test/model/getuserdisplayinfos.php
new file mode 100755
index 0000000000..404b8085a5
--- /dev/null
+++ b/module/user/test/model/getuserdisplayinfos.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+gen(1000);
+
+/**
+
+title=测试 userModel->getuserdisplayinfos();
+cid=1
+pid=1
+
+查找获取到的用户名为dev33的真实姓名 >> 开发33
+查找获取到的用户名为user10的头像 >> /home/z/tmp/10.png
+查找获取到的用户名为outside1的外部用户的头像信息 >> /home/z/tmp/18.png
+查找获取到的用户名为cccfff的真实姓名 >> Error: Cannot get index cccfff.
+
+*/
+
+$accounts = array('!asd12d', '中文用户名', 'user10', 'dev33', 'cccfff', 'outside1');
+$user = new userTest();
+
+r($user->getUserDisplayInfosTest($accounts)) && p('dev33:realname') && e('开发33'); //查找获取到的用户名为dev33的真实姓名
+r($user->getUserDisplayInfosTest($accounts)) && p('user10:avatar') && e('/home/z/tmp/10.png'); //查找获取到的用户名为user10的头像
+r($user->getUserDisplayInfosTest($accounts, 0, 'outside')) && p('outside1:avatar') && e('/home/z/tmp/18.png'); //查找获取到的用户名为outside1的外部用户的头像信息
+r($user->getUserDisplayInfosTest($accounts)) && p('cccfff:realname') && e('Error: Cannot get index cccfff.'); //查找获取到的用户名为cccfff的真实姓名
diff --git a/module/user/test/model/getuserroles.php b/module/user/test/model/getuserroles.php
new file mode 100755
index 0000000000..9f9f176137
--- /dev/null
+++ b/module/user/test/model/getuserroles.php
@@ -0,0 +1,28 @@
+#!/usr/bin/env php
+gen(30);
+
+/**
+
+title=测试 userModel->getPairs();
+cid=1
+pid=1
+
+获取用户名和职位Key的键值对 >> qa
+获取用户名和职位Value的键值对 >> 测试
+从指定accounts中获取到的键值对数量 => 2
+从指定accounts中获取到的键值对数量 => 2
+
+*/
+
+$accounts = array('!asd12d', '中文用户名', 'user10', 'user20', 'cccfff');
+$user = new userTest();
+
+r($user->getUserRolesTest($accounts, true)) && p('user20') && e('qa'); //获取用户名和职位Key的键值对
+r($user->getUserRolesTest($accounts, false)) && p('user20') && e('测试'); //获取用户名和职位Value的键值对
+r(count($user->getUserRolesTest($accounts, true))) && p() && e(2); //从指定accounts中获取到的Key键值对数量
+r(count($user->getUserRolesTest($accounts, false))) && p() && e(2); //从指定accounts中获取到的Value键值对数量
diff --git a/module/user/test/model/getusertemplates.php b/module/user/test/model/getusertemplates.php
new file mode 100755
index 0000000000..c6e73157ff
--- /dev/null
+++ b/module/user/test/model/getusertemplates.php
@@ -0,0 +1,27 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('user')->gen(1000);
+su('admin');
+
+/**
+
+title=测试 userModel::getUserTemplates();
+cid=1
+pid=1
+
+查询当前用户能够使用的exporttask类型的模板 >> admin
+查询当前用户能够使用的story类型的模板 >> dev10
+查询当前用户能够使用的exportbug类型的模板 >> 0
+查询当前用户能够使用的exportstory类型的模板 >> test10
+
+*/
+$typeList = array('exporttask', 'story', 'exportbug', 'exportstory');
+
+$user = new userTest();
+r($user->getUserTemplatesTest($typeList[0])) && p('0:account') && e('admin'); //查询当前用户能够使用的exporttask类型的模板
+r($user->getUserTemplatesTest($typeList[1])) && p('0:account') && e('dev10'); //查询当前用户能够使用的story类型的模板
+r($user->getUserTemplatesTest($typeList[2])) && p('0:account') && e('0'); //查询当前用户能够使用的exportbug类型的模板
+r($user->getUserTemplatesTest($typeList[3])) && p('0:account') && e('test10'); //查询当前用户能够使用的exportstory类型的模板
\ No newline at end of file
diff --git a/module/user/test/model/getvisionlist.php b/module/user/test/model/getvisionlist.php
new file mode 100755
index 0000000000..52484addbe
--- /dev/null
+++ b/module/user/test/model/getvisionlist.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+> 2
+获取test2用户的真实姓名 >> 研发综合界面
+
+*/
+$user = new userTest();
+$visions = $user->getVisionListTest();
+
+r(count($visions)) && p() && e('2'); //获取系统visions的数量
+r($visions) && p('rnd') && e('研发综合界面'); //获取test2用户的真实姓名
\ No newline at end of file
diff --git a/module/user/test/model/getweakusers.php b/module/user/test/model/getweakusers.php
new file mode 100755
index 0000000000..f9c4b273a8
--- /dev/null
+++ b/module/user/test/model/getweakusers.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+getWeakUsers();
+cid=1
+pid=1
+
+获取密码较弱的用户 >> 0
+
+*/
+$user = new userTest();
+a($user->getWeakUsersTest());die;
+
+r($user->getWeakUsersTest()) && p('') && e('0'); //获取密码较弱的用户
\ No newline at end of file
diff --git a/module/user/test/model/grantuserviewtest.php b/module/user/test/model/grantuserviewtest.php
new file mode 100755
index 0000000000..aed9eb61e7
--- /dev/null
+++ b/module/user/test/model/grantuserviewtest.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+grantUserView();
+cid=1
+pid=1
+
+获取admin账户可见的前两个项目的ID >> 12,13
+获取admin账户可见的前两个产品的ID >> 11,12
+获取test2账户可见的前两个项目的ID >> 12,11
+获取user10账户可见的前两个项目的ID >> 19,11
+
+*/
+
+$user = new userTest();
+
+$adminViews = $user->grantUserViewTest('admin');
+$test2Views = $user->grantUserViewTest('test2');
+$user10Views = $user->grantUserViewTest('user10');
+$nullViews = $user->grantUserViewTest(null);
+
+$adminProjects = substr($adminViews->projects, 0, 5);
+$adminProducts = substr($adminViews->products, 0, 5);
+$test2Projects = substr($test2Views->projects, 0, 5);
+$user10Projects = substr($user10Views->projects, 0, 5);
+
+r($adminProjects) && p() && e('12,13'); //获取admin账户可见的前两个项目的ID
+r($adminProducts) && p() && e('11,12'); //获取admin账户可见的前两个产品的ID
+r($test2Projects) && p() && e('12,11'); //获取test2账户可见的前两个项目的ID
+r($user10Projects) && p() && e('19,11'); //获取user10账户可见的前两个项目的ID
+r($nullViews) && p() && e(''); //获取null账户可见的项目、产品等
diff --git a/module/user/test/model/identify.php b/module/user/test/model/identify.php
new file mode 100755
index 0000000000..5a98d455f5
--- /dev/null
+++ b/module/user/test/model/identify.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+id->range('1-100');
+$user->account->range('1-100')->prefix('dev');
+$user->password->range('f8e41d6c31824c01e5d67c61a8ae49e9,e10adc3949ba59abbe56e057f20f883e');
+$user->realname->range('1-100')->prefix("开发");
+$user->gen(50);
+
+/**
+
+title=测试 userModel->identify();
+cid=1
+pid=1
+
+用户名密码皆正确,返回验证登录的用户真实姓名 >> 开发1
+验证一个不存在的用户,返回空 >> 0
+验证一个不传用户名和密码的用户,返回空 >> 0
+
+*/
+
+$user = new userTest();
+
+r($user->identifyTest('dev1', 'f8e41d6c31824c01e5d67c61a8ae49e9')) && p('realname') && e('开发1'); //用户名密码皆正确,返回验证登录的用户真实姓名
+r($user->identifyTest('asdjaf12', '78302615c8b79cac8df6d2607f8a83ee')) && p() && e('0'); //验证一个不存在的用户,返回空
+r($user->identifyTest('', '')) && p() && e('0'); //验证一个不传用户名和密码的用户,返回空
diff --git a/module/user/test/model/identifybycookie.php b/module/user/test/model/identifybycookie.php
new file mode 100755
index 0000000000..b4dc55a156
--- /dev/null
+++ b/module/user/test/model/identifybycookie.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+gen(300);
+
+/**
+
+title=测试 userModel->identifyByCookie();
+cid=1
+pid=1
+
+验证admin用户 >> 1
+验证游客用户 >> 0
+获取不存在的用户 >> 0
+
+*/
+
+$user = new userTest();
+
+$_COOKIE['za'] = 'admin';
+$_COOKIE['zp'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$normalUser = $user->identifyByCookieTest('admin');
+
+$_COOKIE['za'] = 'guest';
+$_COOKIE['zp'] = '';
+$guest = $user->identifyByCookieTest('guest');
+
+$_COOKIE['za'] = 'asdqwe';
+$_COOKIE['zp'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$notExistUser = $user->identifyByCookieTest('asdqwe');
+
+r($normalUser) && p() && e('1'); //验证admin用户
+r($guest) && p() && e('0'); //验证游客用户
+r($notExistsUser) && p() && e('0'); //获取不存在的用户
diff --git a/module/user/test/model/identifybyphpauth.php b/module/user/test/model/identifybyphpauth.php
new file mode 100755
index 0000000000..392bc3274d
--- /dev/null
+++ b/module/user/test/model/identifybyphpauth.php
@@ -0,0 +1,39 @@
+#!/usr/bin/env php
+gen(300);
+
+/**
+
+title=测试 userModel->identifyByPhpAuth();
+cid=1
+pid=1
+
+验证admin用户 >> 1
+验证游客用户 >> 0
+获取不存在的用户 >> 0
+
+*/
+
+$user = new userTest();
+
+$_SERVER['PHP_AUTH_USER'] = 'admin';
+$_SERVER['PHP_AUTH_PW'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$normalUser = $user->identifyByPhpAuthTest('admin');
+
+$_SERVER['PHP_AUTH_USER'] = 'guest';
+$_SERVER['PHP_AUTH_PW'] = '';
+$guest = $user->identifyByPhpAuthTest('guest');
+
+$_SERVER['PHP_AUTH_USER'] = 'asdqwe';
+$_SERVER['PHP_AUTH_PW'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$notExistUser = $user->identifyByPhpAuthTest('asdqwe');
+
+r($normalUser) && p() && e('1'); //验证admin用户
+r($guest) && p() && e('0'); //验证游客用户
+r($notExistsUser) && p() && e('0'); //获取不存在的用户
diff --git a/module/user/test/model/isclickable.php b/module/user/test/model/isclickable.php
new file mode 100755
index 0000000000..a4148c0a67
--- /dev/null
+++ b/module/user/test/model/isclickable.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel::getById();
+cid=1
+pid=1
+
+判断用户id为1,action为空时,是否可点击 >> 1
+判断用户id为1,action为unbind,是否可点击 >> 1
+判断用户id为1,action为unlock,是否可点击 >> 0
+判断用户id为1,action为undefind,是否可点击 >> 1
+判断用户id为10,action为unbind,是否可点击 >> 0
+判断用户id为10,action为unlock,是否可点击 >> 0
+
+*/
+$actionList[0] = 'unbind';
+$actionList[1] = 'unlock';
+$actionList[2] = 'undefind';
+
+$user = new userTest();
+
+r($user->isClickableTest(1)) && p() && e('1'); // 判断用户id为1,action为空时,是否可点击
+r($user->isClickableTest(1, $actionList[0])) && p() && e('1'); // 判断用户id为1,action为unbind,是否可点击
+r($user->isClickableTest(1, $actionList[1])) && p() && e('0'); // 判断用户id为1,action为unlock,是否可点击
+r($user->isClickableTest(1, $actionList[2])) && p() && e('1'); // 判断用户id为1,action为undefind,是否可点击
+r($user->isClickableTest(10,$actionList[0])) && p() && e('0'); // 判断用户id为10,action为unbind,是否可点击
+r($user->isClickableTest(10,$actionList[1])) && p() && e('0'); // 判断用户id为10,action为unlock,是否可点击
\ No newline at end of file
diff --git a/module/user/test/model/islogon.php b/module/user/test/model/islogon.php
new file mode 100755
index 0000000000..32d67e2add
--- /dev/null
+++ b/module/user/test/model/islogon.php
@@ -0,0 +1,30 @@
+#!/usr/bin/env php
+isLogon();
+cid=1
+pid=1
+
+获取admin用户的登录状态 >> 1
+获取游客的登录状态 >> 0
+
+*/
+
+$user = new userTest();
+
+$_SESSION['user'] = new stdclass();
+$_SESSION['user']->account = 'admin';
+$_SESSION['user']->password = 'a0933c1218a4e745bacdcf572b10eba7';
+$admin = $user->isLogonTest();
+
+$_SESSION['user']->account = 'guest';
+$_SESSION['user']->password = '';
+$guest = $user->isLogonTest();
+
+r($admin) && p() && e('1'); //获取admin用户的登录状态
+r($guest) && p() && e('0'); //获取游客的登录状态
diff --git a/module/user/test/model/login.php b/module/user/test/model/login.php
new file mode 100755
index 0000000000..d16b2b7008
--- /dev/null
+++ b/module/user/test/model/login.php
@@ -0,0 +1,41 @@
+#!/usr/bin/env php
+gen(50);
+
+/**
+
+title=测试 userModel->login();
+cid=1
+pid=1
+
+使用admin登录,返回此用户为超级管理员 >> 1
+使用user3登录,返回权限列表的数量 >> 6
+使用空账号登录,返回权限列表数量为0 >> 0
+
+*/
+
+$userClass = new userTest();
+
+$admin = new stdclass();
+$admin->id = 1;
+$admin->account = 'admin';
+$admin = $userClass->loginTest($admin);
+
+$normalAccount = new stdclass();
+$normalAccount->id = 4;
+$normalAccount->account = 'user3';
+$normalAccount = $userClass->loginTest($normalAccount);
+
+$emptyAccount = new stdclass();
+$emptyAccount->id = 0;
+$emptyAccount->account = '';
+$emptyAccount = $userClass->loginTest($emptyAccount);
+
+r($admin) && p('admin') && e('1'); //使用admin登录,返回此用户为超级管理员
+r(count($normalAccount->rights)) && p() && e('6'); //使用admin登录,返回权限列表的数量
+r(count($emptyAccount->group)) && p() && e('0'); //使用空账号登录,返回权限列表数量为0
diff --git a/module/user/test/model/processaccountsort.php b/module/user/test/model/processaccountsort.php
new file mode 100755
index 0000000000..0311ba624a
--- /dev/null
+++ b/module/user/test/model/processaccountsort.php
@@ -0,0 +1,24 @@
+#!/usr/bin/env php
+gen(500);
+su('admin');
+
+/**
+
+title=测试 userModel->processAccountSort();
+cid=1
+pid=1
+
+获取当前用户信息 >> admin,qa
+
+*/
+
+$user = new userTest();
+$admin = array(
+ 'account' => 'admin',
+ 'role' => 'qa',
+ 'realname' => 'admin'
+);
+r($user->processAccountSortTest(array('admin'=>$admin))) && p('admin:account,role') && e('admin,qa'); //获取当前用户信息
\ No newline at end of file
diff --git a/module/user/test/model/resetpassword.php b/module/user/test/model/resetpassword.php
new file mode 100755
index 0000000000..01baa01560
--- /dev/null
+++ b/module/user/test/model/resetpassword.php
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel->resetPassword();
+cid=1
+pid=1
+
+重设用户密码,返回重设后的加密后的密码 >> 367ef140036b0feb2f90d70d33255eea
+两次密码不相同的情况 >> 两次密码应该相同。
+密码强度小于系统设定 >> 密码必须6位及以上,且包含大小写字母、数字。
+使用常见简单密码,给出错误提示 >> 密码不能使用【123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123】这些常用弱口令。
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['account'] = 'admin';
+$normalUser['password1'] = '367ef140036b0feb2f90d70d33255eea';
+$normalUser['password2'] = '367ef140036b0feb2f90d70d33255eea';
+$normalUser['passwordStrength'] = 1;
+
+$weakPassword = $normalUser;
+$weakPassword['passwordStrength'] = 0;
+
+$differentPassword = $normalUser;
+$differentPassword['password2'] = '!@#!@#asfasf';
+
+$simplePassword = $normalUser;
+$simplePassword['password1'] = 'e10adc3949ba59abbe56e057f20f883e';
+$simplePassword['password2'] = 'e10adc3949ba59abbe56e057f20f883e';
+
+r($user->resetPasswordTest($normalUser)) && p('password') && e('367ef140036b0feb2f90d70d33255eea'); //重设用户密码,返回重设后的加密后的密码
+r($user->resetPasswordTest($differentPassword)) && p('password1:0') && e('两次密码应该相同。
'); //两次密码不相同的情况
+r($user->resetPasswordTest($weakPassword)) && p('password1:0') && e('密码必须6位及以上,且包含大小写字母、数字。
'); //密码强度小于系统设定
+r($user->resetPasswordTest($simplePassword)) && p('password1') && e('密码不能使用【123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123】这些常用弱口令。'); //使用常见简单密码,给出错误提示
diff --git a/module/user/test/model/saveusertemplate.php b/module/user/test/model/saveusertemplate.php
new file mode 100755
index 0000000000..197d139671
--- /dev/null
+++ b/module/user/test/model/saveusertemplate.php
@@ -0,0 +1,46 @@
+#!/usr/bin/env php
+gen(10);
+zdTable('user')->gen(500);
+su('admin');
+
+/**
+
+title=测试 userModel::saveUserTemplate();
+cid=1
+pid=1
+
+ >> bug
+ >> task
+ >> task
+插入一条Bug用户模板,查看数量 >> 1
+插入两条任务类型的用户模板,查看数量 >> 2
+查看插入的模板二的名字 >> Admin的模板二
+查看插入的模板二的内容 >> 这是一段模板内容
+
+*/
+$user = new userTest();
+$tpl1['title'] = 'Admin的模板一';
+$tpl1['content'] = '这是一段模板内容
';
+
+$tpl2['title'] = 'Admin的模板二';
+$tpl2['content'] = '这是二段模板内容
';
+
+$tpl3['title'] = 'Admin的模板三';
+$tpl3['content'] = '这是三段模板内容
';
+
+$_POST = $tpl1;
+$tpls1 = $user->saveUserTemplate('bug');
+
+$_POST = $tpl2;
+$tpls2 = $user->saveUserTemplate('task');
+
+$_POST = $tpl3;
+$tpls3 = $user->saveUserTemplate('task');
+
+r(count($tpls1)) && p() && e('1'); //插入一条Bug用户模板,查看数量
+r(count($tpls3)) && p() && e('2'); //插入两条任务类型的用户模板,查看数量
+r($tpls2) && p('0:title') && e('Admin的模板二'); //查看插入的模板二的名字
+r($tpls2) && p('0:content') && e('这是一段模板内容
'); //查看插入的模板二的内容
\ No newline at end of file
diff --git a/module/user/test/model/setuserlist.php b/module/user/test/model/setuserlist.php
new file mode 100755
index 0000000000..47b0561435
--- /dev/null
+++ b/module/user/test/model/setuserlist.php
@@ -0,0 +1,34 @@
+#!/usr/bin/env php
+id->range('1001-1005');
+$user->account->range('1-5')->prefix("account");
+$user->realname->range('1-5')->prefix("用户名");
+$user->deleted->range('0-1');
+$user->gen(5);
+
+/**
+
+title=测试 userModel::setUserList();
+cid=1
+pid=1
+
+测试获取account1的是否在列表中 >> 1
+测试获取account2的是否在列表中 >> 1
+测试获取account3的是否在列表中 >> 1
+测试获取account4的是否在列表中 >> 1
+测试获取account5的是否在列表中 >> 0
+
+*/
+$users = array('account1' => '用户名1', 'account2' => '用户名2', 'account3' => '用户名3', 'account4' => '用户名4');
+
+$user = new userTest();
+r($user->setUserListTest($users, 'account1')) && p() && e('1'); // 测试获取account1的是否在列表中
+r($user->setUserListTest($users, 'account2')) && p() && e('1'); // 测试获取account2的是否在列表中
+r($user->setUserListTest($users, 'account3')) && p() && e('1'); // 测试获取account3的是否在列表中
+r($user->setUserListTest($users, 'account4')) && p() && e('1'); // 测试获取account4的是否在列表中
+r($user->setUserListTest($users, 'account5')) && p() && e('0'); // 测试获取account5的是否在列表中
diff --git a/module/user/test/model/unbind.php b/module/user/test/model/unbind.php
new file mode 100755
index 0000000000..b34ff3e256
--- /dev/null
+++ b/module/user/test/model/unbind.php
@@ -0,0 +1,33 @@
+#!/usr/bin/env php
+id->range('1-10');
+$user->account->range('admin,user1,user2,user3,user4,user5,user6,user7,user8,user9');
+$user->password->range('a0933c1218a4e745bacdcf572b10eba7');
+$user->realname->range('1-10')->prefix('用户');
+$user->ranzhi->range('admin,user1,user2,user3,user4,user5,user6,user7,user8,user9');
+$user->gen(10);
+
+/**
+
+title=测试 userModel->unbind();
+cid=1
+pid=1
+
+获取user7对应的然之用户,重置为空 >> success
+获取不存在的用户的对应的然之用户,返回空 >> success
+
+*/
+
+$user = new userTest();
+$userLocked = $user->unbindTest('user7');
+$notExistUser = $user->unbindTest('test999');
+
+r($userLocked) && p('') && e('success'); //获取user7对应的然之用户,重置为空
+r($notExistUser) && p('') && e('success'); //获取不存在的用户的对应的然之用户,返回空
diff --git a/module/user/test/model/update.php b/module/user/test/model/update.php
new file mode 100755
index 0000000000..5a462e01de
--- /dev/null
+++ b/module/user/test/model/update.php
@@ -0,0 +1,45 @@
+#!/usr/bin/env php
+gen(10);
+
+su('admin');
+
+/**
+
+title=测试 userModel->updateUser();
+cid=1
+pid=1
+
+编辑用户,返回新的用户名 >> newtestuser4
+编辑用户,有重名用户的情况 >> 『用户名』已经有『admin』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。
+两次密码不相同的情况 >> 两次密码应该相同。
+用户名包含特殊字符的情况 >> 『用户名』只能是字母、数字或下划线的组合三位以上。
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['account'] = 'newtestuser4';
+$normalUser['realname'] = '新的测试用户';
+$normalUser['password1'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$normalUser['password2'] = 'a0933c1218a4e745bacdcf572b10eba7';
+$normalUser['type'] = 'inside';
+$normalUser['passwordStrength'] = 1;
+$normalUser['visions'] = 'rnd';
+
+$existUser = $normalUser;
+$existUser['account'] = 'admin';
+
+$differentPassword = $normalUser;
+$differentPassword['password2'] = 'asfjsdklj1234jkljsdklfj19';
+
+$specialUser = $normalUser;
+$specialUser['account'] = '!@#Asdsd中文';
+
+r($user->updateUserTest(3, $normalUser)) && p('account') && e('newtestuser4'); //编辑用户,返回新的用户名
+r($user->updateUserTest(3, $existUser)) && p('account:0') && e('『用户名』已经有『admin』这条记录了。如果您确定该记录已删除,请到后台-系统-数据-回收站还原。');//编辑用户,有重名用户的情况
+r($user->updateUserTest(3, $differentPassword)) && p('password1:0') && e('两次密码应该相同。
'); //两次密码不相同的情况
+r($user->updateUserTest(3, $specialUser)) && p('account:0') && e('『用户名』只能是字母、数字或下划线的组合三位以上。'); //用户名包含特殊字符的情况
diff --git a/module/user/test/model/updatecontactList.php b/module/user/test/model/updatecontactList.php
new file mode 100755
index 0000000000..f7e9090a4f
--- /dev/null
+++ b/module/user/test/model/updatecontactList.php
@@ -0,0 +1,26 @@
+#!/usr/bin/env php
+gen(3);
+
+/**
+
+title=测试 userModel->updateContactList();
+cid=1
+pid=1
+
+更新ID为1的联系人列表,获取更新的联系人列表名称 >> 新的列表名称1
+更新ID为2的联系人列表,获取更新的联系人列表 >> admin,test2,user29,assfjg
+列表名称为空时 >> 『列表名称』不能为空。
+
+*/
+$userTester = new userTest();
+$userList = array('admin,test2,user29,assfjg');
+
+r($userTester->updateContactListTest(1, '新的列表名称1', $userList)) && p('listName') && e('新的列表名称1'); //更新ID为1的联系人列表,获取更新的联系人列表名称
+r($userTester->updateContactListTest(2, '新的列表名称2', $userList)) && p('userList') && e('新的列表名称2'); //更新ID为2的联系人列表,获取更新的联系人列表名称
+r($userTester->updateContactListTest(1, '', array())) && p('message[listName]:0') && e('『列表名称』不能为空。'); //列表名称为空时 // 列表名称为空时
diff --git a/module/user/test/model/updatepassword.php b/module/user/test/model/updatepassword.php
new file mode 100755
index 0000000000..a276a7fbb3
--- /dev/null
+++ b/module/user/test/model/updatepassword.php
@@ -0,0 +1,36 @@
+#!/usr/bin/env php
+gen(10);
+
+/**
+
+title=测试 userModel->updatePassword();
+cid=1
+pid=1
+
+编辑用户密码,返回编辑后的密码 >> dcf859ce8dd8f998bdfe4ae6c22c329e
+两次密码不相同的情况 >> 两次密码应该相同。
+密码小于设定强度的情况 >> 密码必须6位及以上,且包含大小写字母、数字。
+
+*/
+
+$user = new userTest();
+$normalUser = array();
+$normalUser['originalPassword'] = 'bac0bbaaf7192f219bebd5387e88c5d7';
+$normalUser['password1'] = 'dcf859ce8dd8f998bdfe4ae6c22c329e';
+$normalUser['password2'] = 'dcf859ce8dd8f998bdfe4ae6c22c329e';
+$normalUser['passwordStrength'] = 1;
+
+$weakPassword = $normalUser;
+$weakPassword['passwordStrength'] = 0;
+
+$differentPassword = $normalUser;
+$differentPassword['password2'] = 'asdasfasf!@#!@#asfasf';
+
+r($user->updatePasswordTest(10, $normalUser)) && p('password') && e('dcf859ce8dd8f998bdfe4ae6c22c329e'); //编辑用户密码,返回编辑后的密码
+r($user->updatePasswordTest(10, $differentPassword)) && p('password1:0') && e('两次密码应该相同。
'); //两次密码不相同的情况
+r($user->updatePasswordTest(10, $weakPassword)) && p('password1:0') && e('密码必须6位及以上,且包含大小写字母、数字。
'); //密码小于设定强度的情况
diff --git a/module/user/test/model/updateprogramview.php b/module/user/test/model/updateprogramview.php
new file mode 100755
index 0000000000..ab7e914272
--- /dev/null
+++ b/module/user/test/model/updateprogramview.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+updateProgramView();
+cid=1
+pid=1
+
+
+
+*/
+
+$user = new userTest();
+
+$programIdList = array('1', '2');
+
+//r() && p() && e(''); //
diff --git a/module/user/test/model/updatesessionrandom.php b/module/user/test/model/updatesessionrandom.php
new file mode 100644
index 0000000000..8eb02cc27b
--- /dev/null
+++ b/module/user/test/model/updatesessionrandom.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+> 1
+
+*/
+$user = new userTest();
+
+$user->updateSessionRandomTest();
+r($user->updateSessionRandomTest()) && p() && e('1'); // random是否刷新
diff --git a/module/user/test/user.class.php b/module/user/test/user.class.php
new file mode 100755
index 0000000000..2d562ddf00
--- /dev/null
+++ b/module/user/test/user.class.php
@@ -0,0 +1,1144 @@
+objectModel = $tester->loadModel('user');
+ }
+
+ /**
+ * Test get user list.
+ *
+ * @param bool $count
+ * @access public
+ * @return void
+ */
+ public function getListTest($params = 'nodeleted', $count = false)
+ {
+ $objects = $this->objectModel->getList($params);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $count ? count($objects) : $objects;
+ }
+ }
+
+ /**
+ * Test get user information by accounts.
+ *
+ * @param array $accounts
+ * @param string $keyField
+ * @param bool $count
+ * @access public
+ * @return void
+ */
+ public function getListByAccountsTest($accounts = array(), $keyField = 'id', $count = false)
+ {
+ $objects = $this->objectModel->getListByAccounts($accounts, $keyField);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $count ? count($objects) : $objects;
+ }
+ }
+
+ /**
+ * Test user get pairs.
+ *
+ * @param string $params
+ * @param string $usersToAppended
+ * @param int $maxCount
+ * @param array $accounts
+ * @access public
+ * @return void
+ */
+ public function getPairsTest($params = '', $usersToAppended = '', $maxCount = 0, $accounts = array())
+ {
+ $objects = $this->objectModel->getPairs($params, $usersToAppended, $maxCount, $accounts);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get avatar pairs.
+ *
+ * @param string $params
+ * @access public
+ * @return array
+ */
+ public function getAvatarPairsTest($param = 'nodeleted')
+ {
+ $objects = $this->objectModel->getAvatarPairs($param);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user commiters.
+ *
+ * @access public
+ * @return void
+ */
+ public function getCommitersTest()
+ {
+ $objects = $this->objectModel->getCommiters();
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user realname and emails.
+ *
+ * @param array $accounts
+ * @access public
+ * @return void
+ */
+ public function getRealNameAndEmailsTest($accounts)
+ {
+ $objects = $this->objectModel->getRealNameAndEmails($accounts);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user roles.
+ *
+ * @param array $accounts
+ * @param bool $needRole
+ * @access public
+ * @return void
+ */
+ public function getUserRolesTest($accounts, $needRole = false)
+ {
+ $objects = $this->objectModel->getUserRoles($accounts, $needRole);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user display infos.
+ *
+ * @param int $accounts
+ * @param int $deptID
+ * @param string $type
+ * @access public
+ * @return void
+ */
+ public function getUserDisplayInfosTest($accounts, $deptID = 0, $type = 'inside')
+ {
+ $objects = $this->objectModel->getUserDisplayInfos($accounts, $deptID, $type);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user by id.
+ *
+ * @param int|string $userID
+ * @param string $field
+ * @access public
+ * @return void
+ */
+ public function getByIdTest($userID, $field = 'account')
+ {
+ $objects = $this->objectModel->getById($userID, $field);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test get user by query.
+ *
+ * @param string $browseType
+ * @param string $query
+ * @param string $orderBy
+ * @access public
+ * @return void
+ */
+ public function getByQueryTest($browseType = 'inside', $query = '', $orderBy = 'id')
+ {
+ $objects = $this->objectModel->getByQuery($browseType, $query, null, $orderBy);
+ if(dao::isError())
+ {
+ $error = dao::getError();
+ return $error[0];
+ }
+ else
+ {
+ return $objects;
+ }
+ }
+
+ /**
+ * Test create a user.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function createUserTest($params = array())
+ {
+ $_POST = $params;
+ $_POST['verifyPassword'] = 'bac0bbaaf7192f219bebd5387e88c5d7';
+
+ $userID = $this->objectModel->create();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $this->objectModel->getByID($userID, 'id');
+ }
+ }
+
+ /**
+ * Test batch create users.
+ *
+ * @access public
+ * @return void
+ */
+ public function batchCreateUserTest($params = array())
+ {
+ $_POST = $params;
+ $_POST['verifyPassword'] = 'bac0bbaaf7192f219bebd5387e88c5d7';
+ $_POST['userType'] = 'inside';
+
+ global $tester;
+ $tester->config->user->batchCreate = count($_POST['account']);
+
+ $userIDList = $this->objectModel->batchCreate();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $users = array();
+ foreach($userIDList as $userID) $users[] = $this->objectModel->getByID($userID, 'id');
+
+ return $users;
+ }
+ }
+
+ /**
+ * Test edit a user.
+ *
+ * @param int $userID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function updateUserTest($userID, $params = array())
+ {
+ $_POST = $params;
+ $_POST['verifyPassword'] = 'bac0bbaaf7192f219bebd5387e88c5d7';
+
+ $this->objectModel->update($userID);
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $this->objectModel->getByID($userID, 'id');
+ }
+ }
+
+ /**
+ * Test batch edit users.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function batchEditUserTest($params = array())
+ {
+ $_POST = $params;
+ $_POST['verifyPassword'] = 'bac0bbaaf7192f219bebd5387e88c5d7';
+
+ $this->objectModel->batchEdit();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $users = array();
+ $userIDList = array_keys($params['account']);
+ foreach($userIDList as $userID)
+ {
+ $user = $this->objectModel->getByID($userID, 'id');
+ $users[$user->id] = $user;
+ }
+
+ return $users;
+ }
+ }
+
+ /**
+ * Test edit a user password.
+ *
+ * @param int $userID
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function updatePasswordTest($userID, $params = array())
+ {
+ $_POST = $params;
+
+ $this->objectModel->updatePassword($userID);
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $this->objectModel->getByID($userID, 'id');
+ }
+ }
+
+ /**
+ * Reset user password.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function resetPasswordTest($params = array())
+ {
+ $_POST = $params;
+
+ $this->objectModel->resetPassword();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ $account = $params['account'];
+ return $this->objectModel->getByID($account, 'account');
+ }
+ }
+
+ /**
+ * Check user password.
+ *
+ * @param array $params
+ * @access public
+ * @return void
+ */
+ public function checkPasswordTest($params = array())
+ {
+ $_POST = $params;
+
+ $this->objectModel->checkPassword();
+ unset($_POST);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return '无报错';
+ }
+ }
+
+ /**
+ * Identify user.
+ *
+ * @param string $account
+ * @param string $password
+ * @access public
+ * @return void
+ */
+ public function identifyTest($account, $password)
+ {
+ $_POST = $params;
+
+ $user = $this->objectModel->identify($account, $password);
+ unset($_POST);
+
+ return $user;
+ }
+
+ /**
+ * Test authorize user.
+ *
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function authorizeTest($account)
+ {
+ $user = $this->objectModel->authorize($account);
+
+ return $user;
+ }
+
+ /**
+ * Test login user.
+ *
+ * @param object $user
+ * @access public
+ * @return void
+ */
+ public function loginTest($user)
+ {
+ $user = $this->objectModel->login($user);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $user;
+ }
+ }
+
+ /**
+ * Test get groups by user.
+ *
+ * @param string $account
+ * @param string $password
+ * @access public
+ * @return void
+ */
+ public function getGroupsTest($account)
+ {
+ $groups = $this->objectModel->getGroups($account);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $groups;
+ }
+ }
+
+ /**
+ * Test get groups by visions.
+ *
+ * @param string $visions
+ * @access public
+ * @return void
+ */
+ public function getGroupsByVisionsTest($visions)
+ {
+ $groups = $this->objectModel->getGroupsByVisions($visions);
+
+ if(dao::isError())
+ {
+ return dao::getError();
+ }
+ else
+ {
+ return $groups;
+ }
+ }
+
+ /**
+ * Test get my objects.
+ *
+ * @param string $account
+ * @param string $type
+ * @param string $status
+ * @param string $orderBy
+ * @access public
+ * @return void
+ */
+ public function getObjectsTest($account, $type, $status, $orderBy)
+ {
+ $myObjects = $this->objectModel->getObjects($account, $type, $status, $orderBy);
+
+ if(dao::isError()) return dao::getError();
+ return $myObjects;
+ }
+
+ /**
+ * Test clean user locked time.
+ *
+ * @param string $account
+ * @access public
+ * @return string
+ */
+ public function cleanLockedTest($account)
+ {
+ global $tester;
+
+ $this->objectModel->cleanLocked($account);
+
+ if(dao::isError()) return dao::getError();
+
+ $locked = $tester->dao->select('locked')->from(TABLE_USER)->where('account')->eq($account)->fetch('locked');
+
+ $result = $locked === '0000-00-00 00:00:00' ? 'success' : 'fail';
+
+ return $result;
+ }
+
+ /**
+ * Test unbind Ranzhi.
+ *
+ * @param string $account
+ * @access public
+ * @return string
+ */
+ public function unbindTest($account)
+ {
+ global $tester;
+
+ $this->objectModel->unbind($account);
+
+ if(dao::isError()) return dao::getError();
+
+ $ranzhi = $tester->dao->select('ranzhi')->from(TABLE_USER)->where('account')->eq($account)->fetch('ranzhi');
+
+ $result = empty($ranzhi) ? 'success' : 'fail';
+
+ return $result;
+ }
+
+ /**
+ * Test get contact list.
+ *
+ * @param string $account
+ * @param string $params
+ * @access public
+ * @return void
+ */
+ public function getContactListsTest($account = '', $params = '')
+ {
+ $contacts = $this->objectModel->getContactLists($account, $params);
+
+ if(dao::isError()) return dao::getError();
+
+ return $contacts ? $contacts : 0;
+ }
+
+ /**
+ * Test get list by account method.
+ *
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function getListByAccountTest($account)
+ {
+ return $this->objectModel->getListByAccount($account);
+ }
+
+ /**
+ * Test get parent stage authed users.
+ *
+ * @param int $stageID
+ * @access public
+ * @return void
+ */
+ public function getParentStageAuthedUsersTest($stageID)
+ {
+ return $this->objectModel->getParentStageAuthedUsers($stageID);
+ }
+
+ /**
+ * Test get contact list by id.
+ *
+ * @param int $listID
+ * @access public
+ * @return void
+ */
+ public function getContactListByIDTest($listID)
+ {
+ return $this->objectModel->getContactListByID($listID);
+ }
+
+ /**
+ * Test get contact user pairs.
+ *
+ * @param array $accountList
+ * @access public
+ * @return void
+ */
+ public function getContactUserPairsTest($accountList)
+ {
+ return $this->objectModel->getContactUserPairs($accountList);
+ }
+
+ /**
+ * Test create contact list.
+ *
+ * @param string $listName
+ * @param array $userList
+ * @access public
+ * @return void
+ */
+ public function createContactListTest($listName = '', $userList = array())
+ {
+ ob_start();
+ $listID = $this->objectModel->createContactList($listName, $userList);
+ $message = ob_get_clean();
+
+ if($message) return array('message' => array('listName' => array(1)));
+ if(dao::isError()) return array('message' => dao::getError());
+ return $this->objectModel->getContactListByID($listID);
+ }
+
+ /**
+ * Test update contact list.
+ *
+ * @param int $listID
+ * @param string $listName
+ * @param array $userList
+ * @access public
+ * @return void
+ */
+ public function updateContactListTest($listID = 0, $listName = '', $userList = array())
+ {
+ $this->objectModel->updateContactList($listID, $listName, $userList);
+
+ if(dao::isError()) return array('message' => dao::getError());
+ return $this->objectModel->getContactListByID($listID);
+ }
+
+ /**
+ * Test delete a contact list.
+ *
+ * @param int $listID
+ * @access public
+ * @return void
+ */
+ public function deleteContactListTest($listID)
+ {
+ $this->objectModel->deleteContactList($listID);
+
+ if(dao::isError()) return dao::getError();
+ return $this->objectModel->getContactListByID($listID);
+ }
+
+ /**
+ * Test get user data in json.
+ *
+ * @param object $user
+ * @access public
+ * @return void
+ */
+ public function getDataInJSONTest($user)
+ {
+ $user = $this->objectModel->getDataInJSON($user);
+
+ if(dao::isError()) return dao::getError();
+ return $user;
+ }
+
+ /**
+ * Test get weak users.
+ *
+ * @access public
+ * @return void
+ */
+ public function getWeakUsersTest()
+ {
+ $users = $this->objectModel->getWeakUsers();
+
+ if(dao::isError()) return dao::getError();
+ return $users;
+ }
+
+ /**
+ * Test compute password strength.
+ *
+ * @access public
+ * @return void
+ */
+ public function computePasswordStrengthTest($password)
+ {
+ $strength = $this->objectModel->computePasswordStrength($password);
+
+ if(dao::isError()) return dao::getError();
+ return $strength;
+ }
+
+ /**
+ * Test compute user view.
+ *
+ * @param string $account
+ * @param bool $force
+ * @access public
+ * @return void
+ */
+ public function computeUserViewTest($account, $force = false)
+ {
+ $userview = $this->objectModel->computeUserView($account, $force);
+
+ if(dao::isError()) return dao::getError();
+ return $userview;
+ }
+
+ /**
+ * Test get product members.
+ *
+ * @param string $account
+ * @param bool $force
+ * @access public
+ * @return void
+ */
+ public function getProductMembersTest($allProducts)
+ {
+ $members = $this->objectModel->getProductMembers($allProducts);
+
+ if(dao::isError()) return dao::getError();
+ return $members;
+ }
+
+ /**
+ * Test get product members.
+ *
+ * @param string $account
+ * @param bool $force
+ * @access public
+ * @return void
+ */
+ public function grantUserViewTest($account = '', $acls = array(), $projects = '')
+ {
+ $userView = $this->objectModel->grantUserView($account, $acls, $projects);
+
+ if(dao::isError()) return dao::getError();
+ return $userView;
+ }
+
+ /**
+ * Test update program view.
+ *
+ * @param array $programIdList
+ * @param array $users
+ * @access public
+ * @return void
+ */
+ public function updateProgramViewTest($programIdList = array(), $users = array())
+ {
+ $this->objectModel->updateProgramView($programIdList, $users);
+
+ if(dao::isError()) return dao::getError();
+ return $this->objectModel->grantUserView(current($users));
+ }
+
+ /**
+ * Test check program priv.
+ *
+ * @param object $program
+ * @param string $account
+ * @param array $stakeholders
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function checkProgramPrivTest($program, $account, $stakeholders, $whiteList)
+ {
+ return $this->objectModel->checkProgramPriv($program, $account, $stakeholders, $whiteList);
+ }
+
+ /**
+ * Test check project priv.
+ *
+ * @param object $project
+ * @param string $account
+ * @param array $stakeholders
+ * @param array $teams
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function checkProjectPrivTest($project, $account, $stakeholders, $teams, $whiteList)
+ {
+ return $this->objectModel->checkProjectPriv($project, $account, $stakeholders, $teams, $whiteList);
+ }
+ /**
+ * Test check sprint priv.
+ *
+ * @param object $sprint
+ * @param string $account
+ * @param array $stakeholders
+ * @param array $teams
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function checkSprintPrivTest($sprint, $account, $stakeholders, $teams, $whiteList)
+ {
+ return $this->objectModel->checkSprintPriv($sprint, $account, $stakeholders, $teams, $whiteList);
+ }
+ /**
+ * Test check product priv.
+ *
+ * @param object $program
+ * @param string $account
+ * @param array $groups
+ * @param array $teams
+ * @param array $stakeholders
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function checkProductPrivTest($product, $account, $groups = '', $teams = '', $stakeholders = '', $whiteList = '')
+ {
+ return $this->objectModel->checkProductPriv($product, $account, $groups, $teams, $stakeholders, $whiteList);
+ }
+
+ /**
+ * Test get project authed users.
+ *
+ * @param int $projectID
+ * @param array $stakeholders
+ * @param array $teams
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function getProjectAuthedUsersTest($projectID, $stakeholders, $teams, $whiteList)
+ {
+ global $tester;
+ $project = $tester->loadModel('project')->getByID($projectID);
+ return $this->objectModel->getProjectAuthedUsers($project, $stakeholders, $teams, $whiteList);
+ }
+
+ /**
+ * Test get program authed users.
+ *
+ * @param int $projectID
+ * @param array $stakeholders
+ * @param array $whiteList
+ * @param array $admins
+ * @access public
+ * @return void
+ */
+ public function getProgramAuthedUsersTest($programID, $stakeholders, $whiteList, $admins)
+ {
+ global $tester;
+ $program = $tester->loadModel('program')->getByID($programID);
+ return $this->objectModel->getProgramAuthedUsers($program, $stakeholders, $whiteList, $admins);
+ }
+
+ /**
+ * getSprintAuthedUsersTest
+ *
+ * @param int $sprintID
+ * @param array $stakeholders
+ * @param array $teams
+ * @param array $whiteList
+ * @param array $admins
+ * @access public
+ * @return void
+ */
+ public function getSprintAuthedUsersTest($sprintID, $stakeholders, $teams, $whiteList, $admins)
+ {
+ global $tester;
+ $sprint = $tester->loadModel('execution')->getByID($sprintID);
+ return $this->objectModel->getSprintAuthedUsers($sprint, $stakeholders, $teams, $whiteList, $admins);
+ }
+
+ /**
+ * Test get product view list users.
+ *
+ * @param int $productID
+ * @param array $teams
+ * @param array $stakeholders
+ * @param array $whiteList
+ * @access public
+ * @return void
+ */
+ public function getProductViewListUsersTest($productID, $teams, $stakeholders, $whiteList, $admins)
+ {
+ global $tester;
+ $product = $tester->loadModel('product')->getByID($productID);
+ return $this->objectModel->getProductViewListUsers($product, $teams, $stakeholders, $whiteList, $admins);
+ }
+
+ /**
+ * Test get product view list users.
+ *
+ * @param int $productID
+ * @param string $type
+ * @param string $params
+ * @param array $usersToAppended
+ * @access public
+ * @return void
+ */
+ public function getTeamMemberPairsTest($objectID, $type, $params = '', $usersToAppended = array())
+ {
+ return $this->objectModel->getTeamMemberPairs($objectID, $type, $params, $usersToAppended);
+ }
+
+ /**
+ * Test save user template.
+ *
+ * @param string $type
+ * @access public
+ * @return void
+ */
+ public function saveUserTemplate($type)
+ {
+ global $tester;
+ $this->objectModel->saveUserTemplate($type);
+
+ if(dao::isError()) return dao::getError();
+ return $this->objectModel->getUserTemplates($type);
+ }
+
+ /**
+ * Test get user templates.
+ *
+ * @param string $type
+ * @access public
+ * @return array
+ */
+ public function getUserTemplatesTest($type)
+ {
+ return $this->objectModel->getUserTemplates($type);
+ }
+
+ /**
+ * Test get person data.
+ *
+ * @param string $account
+ * @access public
+ * @return void
+ */
+ public function getPersonalDataTest($account)
+ {
+ return $this->objectModel->getPersonalData($account);
+ }
+
+ /**
+ * Test get user details for api.
+ *
+ * @param array $userList
+ * @access public
+ * @return void
+ */
+ public function getUserDetailsForAPITest($userList)
+ {
+ return $this->objectModel->getUserDetailsForAPI($userList);
+ }
+
+ /**
+ * Test get vision list.
+ *
+ * @access public
+ * @return void
+ */
+ public function getVisionListTest()
+ {
+ return $this->objectModel->getVisionList();
+ }
+
+ /**
+ * Get users who have authority to create stories.
+ *
+ * @access public
+ * @return array
+ */
+ public function getCanCreateStoryUsersTest()
+ {
+ return $this->objectModel->getCanCreateStoryUsers();
+ }
+
+ /**
+ * Put the current user first
+ *
+ * @param array $users
+ * @access public
+ * @return array
+ */
+ public function processAccountSortTest($users = array())
+ {
+ return $this->objectModel->processAccountSort($users);
+ }
+
+ /**
+ * Set users list.
+ *
+ * @param array $users
+ * @param string $account
+ * @access public
+ * @return string
+ */
+ public function setUserListTest($users, $account)
+ {
+ $string = $this->objectModel->setUserList($users, $account);
+ return strpos($string, "