diff --git a/test/class/testreport.class.php b/test/class/testreport.class.php
new file mode 100644
index 0000000000..bcf94153c6
--- /dev/null
+++ b/test/class/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/test/model/testreport/create.php b/test/model/testreport/create.php
new file mode 100755
index 0000000000..7ae5705303
--- /dev/null
+++ b/test/model/testreport/create.php
@@ -0,0 +1,35 @@
+#!/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'); //参与人员测试
+
+system("./ztest init");
\ No newline at end of file
diff --git a/test/model/testreport/getbug4report.php b/test/model/testreport/getbug4report.php
new file mode 100755
index 0000000000..c56eb5cdcb
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getbugs4test.php b/test/model/testreport/getbugs4test.php
new file mode 100755
index 0000000000..1198cf4dbe
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getbyid.php b/test/model/testreport/getbyid.php
new file mode 100755
index 0000000000..03258eeb4f
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getcaseidlist.php b/test/model/testreport/getcaseidlist.php
new file mode 100755
index 0000000000..895402992e
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getlist.php b/test/model/testreport/getlist.php
new file mode 100755
index 0000000000..90c45c465d
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getpairs.php b/test/model/testreport/getpairs.php
new file mode 100755
index 0000000000..a861506a0e
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getpercaseresult4report.php b/test/model/testreport/getpercaseresult4report.php
new file mode 100755
index 0000000000..53b7baf8c2
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getpercaserunner4report.php b/test/model/testreport/getpercaserunner4report.php
new file mode 100755
index 0000000000..c97911809e
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getresultsummary.php b/test/model/testreport/getresultsummary.php
new file mode 100755
index 0000000000..18751d0a87
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/getstories4test.php b/test/model/testreport/getstories4test.php
new file mode 100755
index 0000000000..ff8bb984fe
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/gettaskcases.php b/test/model/testreport/gettaskcases.php
new file mode 100755
index 0000000000..6e30190595
--- /dev/null
+++ b/test/model/testreport/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/test/model/testreport/update.php b/test/model/testreport/update.php
new file mode 100755
index 0000000000..ac8eafeacd
--- /dev/null
+++ b/test/model/testreport/update.php
@@ -0,0 +1,36 @@
+#!/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('『标题』不能为空。'); //标题为空测试
+
+system("./ztest init");
\ No newline at end of file