├── .gitignore ├── README.md ├── android ├── __init__.py ├── adminx.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── templates │ └── android_testcase.html ├── tests.py └── views.py ├── h5 ├── __init__.py ├── adminx.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── templates │ └── h5_testcase.html ├── tests.py └── views.py ├── interface ├── __init__.py ├── adminx.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── templates │ ├── interface_testcase.html │ ├── model.top_toolbar.imports.html │ ├── model.top_toolbar.run.html │ └── model_list.results_top.charts.html ├── tests.py └── views.py ├── ios ├── __init__.py ├── adminx.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── tests.py └── views.py ├── manage.py ├── myweb ├── __init__.py ├── settings.py ├── urls.py ├── wsgi.py └── xsite.py ├── pc ├── __init__.py ├── adminx.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── templates │ └── pc_testcase.html ├── tests.py └── views.py └── qsc_interfacetest ├── Interface └── __init__.py ├── README.md ├── __init__.py ├── db_fixture ├── __init__.py ├── data.py └── mysql_setting.py ├── report └── log │ └── log.txt └── test_case ├── __init__.py └── models ├── __init__.py ├── buildcase.py └── myunit.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Python files 2 | *.pyc 3 | # 4 | .idea/ 5 | demo.py 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # testcase_web 2 | 知识共享许可协议
本作品采用知识共享署名 4.0 国际许可协议进行许可。 3 | *** 4 | 自动化测试用例web管理页面 5 | ## 前言 6 | 在自动化测试,一项重要的工作就是自动化测试用例的管理和维护,一套成熟的自动化测试框架包含:自动化测试脚本框架+自动化测试用例管理,只有将自动化测试用例规范的管理和维护起来,才能在需求变动时,可以很快的的去更新测试用例,让自动化测试不在因为修改测试用例繁琐成为头疼的问题 7 | ## 设计 8 | - 采用python+Django框架,搭建web应用,用于测试用例的展示 9 | - 功能: 10 | 1. 前端展示测试用例信息,只允许查看 11 | 2. 可自定义用例模板,目前用例模板包含:接口自动化测试用例、App自动化测试用例、web自动化测试用例 12 | 3. 后端管理界面可进行编辑和新增测试用例 13 | 4. 可以直接导入导出xls格式的测试用例数据 14 | 5. 支持在页面中直接运行接口测试用例 15 | 6. 支持用户权限管理 16 | ## 版本 17 | python 2.7 + Django 1.9.7 + xadmin 0.6.1 + MySql 5.7 18 | 19 | * [Django]-pythonWeb框架,用于快速搭建blog,自带管理后台(界面比较难看,功能少,不可扩展) 20 | * [xadmin]-Django后台管理页面升级版,界面展示美观,可自定义插件,功能可扩展 21 | 22 | ## 截图 23 | ![](https://cl.ly/k3wX/WX20170418-182035.png) 24 | 25 | 26 | [Django]: 27 | [xadmin]: 28 | 29 | -------------------------------------------------------------------------------- /android/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/android/__init__.py -------------------------------------------------------------------------------- /android/adminx.py: -------------------------------------------------------------------------------- 1 | import xadmin 2 | from android.models import * 3 | # Register your models here. 4 | class AndroidTestCaseAdmin(object): 5 | list_display = ('case_id', 'case_name', 'activity', 'name', 'action', 'value', 6 | 'expected','actual', 'result', 'state') 7 | search_fields = ('case_id', 'case_name', 'activity', 'name', 'action', 'value', 8 | 'expected','actual', 'result', 'state') 9 | 10 | class Android_DeviceAdmin(object): 11 | list_display = ('name', 'deviceName', 'platformVersion','resolution','appiumPort','bootstrapPort','udid') 12 | search_fields = ('name', 'deviceName', 'platformVersion','resolution','appiumPort','bootstrapPort','udid') 13 | list_editable = ['name','deviceName','platformVersion','resolution','appiumPort','bootstrapPort','udid'] 14 | 15 | xadmin.site.register(AndroidTestCase1, AndroidTestCaseAdmin) 16 | xadmin.site.register(AndroidTestCase2, AndroidTestCaseAdmin) 17 | xadmin.site.register(AndroidTestCase3, AndroidTestCaseAdmin) 18 | xadmin.site.register(AndroidTestCase4, AndroidTestCaseAdmin) 19 | xadmin.site.register(AndroidTestCase5, AndroidTestCaseAdmin) 20 | xadmin.site.register(AndroidTestCase6, AndroidTestCaseAdmin) 21 | xadmin.site.register(AndroidTestCase7, AndroidTestCaseAdmin) 22 | # xadmin.site.register(AndroidTestCase8, AndroidTestCase8Admin) 23 | xadmin.site.register(AndroidTestCase9, AndroidTestCaseAdmin) 24 | xadmin.site.register(AndroidTestCase10, AndroidTestCaseAdmin) 25 | xadmin.site.register(AndroidTestCase11, AndroidTestCaseAdmin) 26 | xadmin.site.register(AndroidTestCase12, AndroidTestCaseAdmin) 27 | # xadmin.site.register(AndroidTestCase13, AndroidTestCase13Admin) 28 | xadmin.site.register(Android_Device,Android_DeviceAdmin) 29 | xadmin.site.register(Android_MQC,AndroidTestCaseAdmin) 30 | 31 | -------------------------------------------------------------------------------- /android/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class AndroidConfig(AppConfig): 7 | name = 'android' 8 | -------------------------------------------------------------------------------- /android/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-10-14 09:21 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='AndroidTestCase1', 18 | fields=[ 19 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 20 | ('case_id', models.CharField(max_length=45)), 21 | ('case_name', models.CharField(max_length=45)), 22 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 23 | ('name', models.CharField(blank=True, max_length=45, null=True)), 24 | ('action', models.CharField(blank=True, max_length=45, null=True)), 25 | ('value', models.TextField(blank=True, null=True)), 26 | ('expected', models.TextField(blank=True, null=True)), 27 | ('actual', models.TextField(blank=True, editable=False, null=True)), 28 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 29 | ('state', models.IntegerField(default='1')), 30 | ], 31 | options={ 32 | 'ordering': ['id'], 33 | 'db_table': 'a_animal_project_released', 34 | 'verbose_name': 'Android-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 35 | 'verbose_name_plural': 'Android-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 36 | }, 37 | ), 38 | migrations.CreateModel( 39 | name='AndroidTestCase10', 40 | fields=[ 41 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 42 | ('case_id', models.CharField(max_length=45)), 43 | ('case_name', models.CharField(max_length=45)), 44 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 45 | ('name', models.CharField(blank=True, max_length=45, null=True)), 46 | ('action', models.CharField(blank=True, max_length=45, null=True)), 47 | ('value', models.TextField(blank=True, null=True)), 48 | ('expected', models.TextField(blank=True, null=True)), 49 | ('actual', models.TextField(blank=True, editable=False, null=True)), 50 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 51 | ('state', models.IntegerField(default='1')), 52 | ], 53 | options={ 54 | 'ordering': ['id'], 55 | 'db_table': 'a_check_project', 56 | 'verbose_name': 'Android-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee', 57 | 'verbose_name_plural': 'Android-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee', 58 | }, 59 | ), 60 | migrations.CreateModel( 61 | name='AndroidTestCase11', 62 | fields=[ 63 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 64 | ('case_id', models.CharField(max_length=45)), 65 | ('case_name', models.CharField(max_length=45)), 66 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 67 | ('name', models.CharField(blank=True, max_length=45, null=True)), 68 | ('action', models.CharField(blank=True, max_length=45, null=True)), 69 | ('value', models.TextField(blank=True, null=True)), 70 | ('expected', models.TextField(blank=True, null=True)), 71 | ('actual', models.TextField(blank=True, editable=False, null=True)), 72 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 73 | ('state', models.IntegerField(default='1')), 74 | ], 75 | options={ 76 | 'ordering': ['id'], 77 | 'db_table': 'a_check_build_project', 78 | 'verbose_name': 'Android-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee\u53d1\u5e03', 79 | 'verbose_name_plural': 'Android-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee\u53d1\u5e03', 80 | }, 81 | ), 82 | migrations.CreateModel( 83 | name='AndroidTestCase12', 84 | fields=[ 85 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 86 | ('case_id', models.CharField(max_length=45)), 87 | ('case_name', models.CharField(max_length=45)), 88 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 89 | ('name', models.CharField(blank=True, max_length=45, null=True)), 90 | ('action', models.CharField(blank=True, max_length=45, null=True)), 91 | ('value', models.TextField(blank=True, null=True)), 92 | ('expected', models.TextField(blank=True, null=True)), 93 | ('actual', models.TextField(blank=True, editable=False, null=True)), 94 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 95 | ('state', models.IntegerField(default='1')), 96 | ], 97 | options={ 98 | 'ordering': ['id'], 99 | 'db_table': 'a_delete_card', 100 | 'verbose_name': 'Android-\u5220\u9664\u94f6\u884c\u5361', 101 | 'verbose_name_plural': 'Android-\u5220\u9664\u94f6\u884c\u5361', 102 | }, 103 | ), 104 | migrations.CreateModel( 105 | name='AndroidTestCase13', 106 | fields=[ 107 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 108 | ('case_id', models.CharField(max_length=45)), 109 | ('case_name', models.CharField(max_length=45)), 110 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 111 | ('name', models.CharField(blank=True, max_length=45, null=True)), 112 | ('action', models.CharField(blank=True, max_length=45, null=True)), 113 | ('value', models.TextField(blank=True, null=True)), 114 | ('expected', models.TextField(blank=True, null=True)), 115 | ('actual', models.TextField(blank=True, editable=False, null=True)), 116 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 117 | ('state', models.IntegerField(default='1')), 118 | ], 119 | options={ 120 | 'ordering': ['id'], 121 | 'db_table': 'a_login', 122 | 'verbose_name': 'Android-\u767b\u5f55APP', 123 | 'verbose_name_plural': 'Android-\u767b\u5f55APP', 124 | }, 125 | ), 126 | migrations.CreateModel( 127 | name='AndroidTestCase2', 128 | fields=[ 129 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 130 | ('case_id', models.CharField(max_length=45)), 131 | ('case_name', models.CharField(max_length=45)), 132 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 133 | ('name', models.CharField(blank=True, max_length=45, null=True)), 134 | ('action', models.CharField(blank=True, max_length=45, null=True)), 135 | ('value', models.TextField(blank=True, null=True)), 136 | ('expected', models.TextField(blank=True, null=True)), 137 | ('actual', models.TextField(blank=True, editable=False, null=True)), 138 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 139 | ('state', models.IntegerField(default='1')), 140 | ], 141 | options={ 142 | 'ordering': ['id'], 143 | 'db_table': 'a_disaster_project_released', 144 | 'verbose_name': 'Android-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 145 | 'verbose_name_plural': 'Android-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 146 | }, 147 | ), 148 | migrations.CreateModel( 149 | name='AndroidTestCase3', 150 | fields=[ 151 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 152 | ('case_id', models.CharField(max_length=45)), 153 | ('case_name', models.CharField(max_length=45)), 154 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 155 | ('name', models.CharField(blank=True, max_length=45, null=True)), 156 | ('action', models.CharField(blank=True, max_length=45, null=True)), 157 | ('value', models.TextField(blank=True, null=True)), 158 | ('expected', models.TextField(blank=True, null=True)), 159 | ('actual', models.TextField(blank=True, editable=False, null=True)), 160 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 161 | ('state', models.IntegerField(default='1')), 162 | ], 163 | options={ 164 | 'ordering': ['id'], 165 | 'db_table': 'a_dream_project_released', 166 | 'verbose_name': 'Android-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 167 | 'verbose_name_plural': 'Android-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 168 | }, 169 | ), 170 | migrations.CreateModel( 171 | name='AndroidTestCase4', 172 | fields=[ 173 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 174 | ('case_id', models.CharField(max_length=45)), 175 | ('case_name', models.CharField(max_length=45)), 176 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 177 | ('name', models.CharField(blank=True, max_length=45, null=True)), 178 | ('action', models.CharField(blank=True, max_length=45, null=True)), 179 | ('value', models.TextField(blank=True, null=True)), 180 | ('expected', models.TextField(blank=True, null=True)), 181 | ('actual', models.TextField(blank=True, editable=False, null=True)), 182 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 183 | ('state', models.IntegerField(default='1')), 184 | ], 185 | options={ 186 | 'ordering': ['id'], 187 | 'db_table': 'a_illness_project_released', 188 | 'verbose_name': 'Android-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 189 | 'verbose_name_plural': 'Android-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 190 | }, 191 | ), 192 | migrations.CreateModel( 193 | name='AndroidTestCase5', 194 | fields=[ 195 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 196 | ('case_id', models.CharField(max_length=45)), 197 | ('case_name', models.CharField(max_length=45)), 198 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 199 | ('name', models.CharField(blank=True, max_length=45, null=True)), 200 | ('action', models.CharField(blank=True, max_length=45, null=True)), 201 | ('value', models.TextField(blank=True, null=True)), 202 | ('expected', models.TextField(blank=True, null=True)), 203 | ('actual', models.TextField(blank=True, editable=False, null=True)), 204 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 205 | ('state', models.IntegerField(default='1')), 206 | ], 207 | options={ 208 | 'ordering': ['id'], 209 | 'db_table': 'a_poverty_project_released', 210 | 'verbose_name': 'Android-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 211 | 'verbose_name_plural': 'Android-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 212 | }, 213 | ), 214 | migrations.CreateModel( 215 | name='AndroidTestCase6', 216 | fields=[ 217 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 218 | ('case_id', models.CharField(max_length=45)), 219 | ('case_name', models.CharField(max_length=45)), 220 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 221 | ('name', models.CharField(blank=True, max_length=45, null=True)), 222 | ('action', models.CharField(blank=True, max_length=45, null=True)), 223 | ('value', models.TextField(blank=True, null=True)), 224 | ('expected', models.TextField(blank=True, null=True)), 225 | ('actual', models.TextField(blank=True, editable=False, null=True)), 226 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 227 | ('state', models.IntegerField(default='1')), 228 | ], 229 | options={ 230 | 'ordering': ['id'], 231 | 'db_table': 'a_presale_project_released', 232 | 'verbose_name': 'Android-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 233 | 'verbose_name_plural': 'Android-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 234 | }, 235 | ), 236 | migrations.CreateModel( 237 | name='AndroidTestCase7', 238 | fields=[ 239 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 240 | ('case_id', models.CharField(max_length=45)), 241 | ('case_name', models.CharField(max_length=45)), 242 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 243 | ('name', models.CharField(blank=True, max_length=45, null=True)), 244 | ('action', models.CharField(blank=True, max_length=45, null=True)), 245 | ('value', models.TextField(blank=True, null=True)), 246 | ('expected', models.TextField(blank=True, null=True)), 247 | ('actual', models.TextField(blank=True, editable=False, null=True)), 248 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 249 | ('state', models.IntegerField(default='1')), 250 | ], 251 | options={ 252 | 'ordering': ['id'], 253 | 'db_table': 'a_other_project_released', 254 | 'verbose_name': 'Android-\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 255 | 'verbose_name_plural': 'Android-\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 256 | }, 257 | ), 258 | migrations.CreateModel( 259 | name='AndroidTestCase8', 260 | fields=[ 261 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 262 | ('case_id', models.CharField(max_length=45)), 263 | ('case_name', models.CharField(max_length=45)), 264 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 265 | ('name', models.CharField(blank=True, max_length=45, null=True)), 266 | ('action', models.CharField(blank=True, max_length=45, null=True)), 267 | ('value', models.TextField(blank=True, null=True)), 268 | ('expected', models.TextField(blank=True, null=True)), 269 | ('actual', models.TextField(blank=True, editable=False, null=True)), 270 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 271 | ('state', models.IntegerField(default='1')), 272 | ], 273 | options={ 274 | 'ordering': ['id'], 275 | 'db_table': 'a_support_project', 276 | 'verbose_name': 'Android-\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 277 | 'verbose_name_plural': 'Android-\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 278 | }, 279 | ), 280 | migrations.CreateModel( 281 | name='AndroidTestCase9', 282 | fields=[ 283 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 284 | ('case_id', models.CharField(max_length=45)), 285 | ('case_name', models.CharField(max_length=45)), 286 | ('activity', models.CharField(blank=True, max_length=60, null=True)), 287 | ('name', models.CharField(blank=True, max_length=45, null=True)), 288 | ('action', models.CharField(blank=True, max_length=45, null=True)), 289 | ('value', models.TextField(blank=True, null=True)), 290 | ('expected', models.TextField(blank=True, null=True)), 291 | ('actual', models.TextField(blank=True, editable=False, null=True)), 292 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 293 | ('state', models.IntegerField(default='1')), 294 | ], 295 | options={ 296 | 'ordering': ['id'], 297 | 'db_table': 'a_check_personal', 298 | 'verbose_name': 'Android-\u67e5\u770b\u4e2a\u4eba\u4fe1\u606f', 299 | 'verbose_name_plural': 'Android-\u67e5\u770b\u4e2a\u4eba\u4fe1\u606f', 300 | }, 301 | ), 302 | ] 303 | -------------------------------------------------------------------------------- /android/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/android/migrations/__init__.py -------------------------------------------------------------------------------- /android/models.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | # Create your models here. 6 | 7 | '''{'动物保护项目发布': 'a_animal_project_released', 8 | '灾难救助项目发布': 'a_disaster_project_released', 9 | '梦想清单项目发布': 'a_dream_project_released', 10 | '大病救助项目发布': 'a_illness_project_released', 11 | '扶贫助学项目发布': 'a_poverty_project_released', 12 | '尝鲜预售项目发布': 'a_presale_project_released', 13 | '支持已创建的项目': 'a_support_project', 14 | '其它项目发布': 'a_other_project_released', 15 | '个人中心': 'a_check_my', 16 | '微爱大病救助项目管理':'a_check_illness', 17 | '尝鲜&梦想项目管理':'a_check_saledream', 18 | '微爱剩余项目管理':'a_check_love', 19 | '登录APP':'a_login', 20 | } 21 | ''' 22 | ACTION_LIST = (('click','click'), 23 | ('sendkey','sendkey'), 24 | ('swipe','swipe'), 25 | ('tag','tag'), 26 | ('sleep','sleep'), 27 | ('back','back'), 28 | ) 29 | RESOLUTION_LIST = (('800x1280','800x1280'), 30 | ('720x1280','720x1280'), 31 | ('540x960','540x960'), 32 | ('480x854','480x854'), 33 | ('480x800','480x800'), 34 | ('600x1024','600x1024'), 35 | ('1200x1920','1200x1920'), 36 | ('1080x1920','1080x1920'), 37 | ('1080x1800','1080x1800'), 38 | ) 39 | 40 | class AndroidTestCase1(models.Model): 41 | id = models.AutoField(primary_key=True, editable=False) 42 | case_id = models.CharField(max_length=45, unique=True) 43 | case_name = models.CharField(max_length=45) 44 | activity = models.CharField(max_length=60, null=True, blank=True) 45 | name = models.CharField(max_length=45, null=True, blank=True) 46 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 47 | value = models.TextField(null=True, blank=True) 48 | expected = models.TextField(null=True, blank=True) 49 | actual = models.TextField(null=True, blank=True, editable=False) 50 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 51 | state = models.IntegerField(default='1') 52 | 53 | def __unicode__(self): 54 | return self.case_name 55 | 56 | class Meta: 57 | verbose_name = 'Android-动物保护项目发布' 58 | verbose_name_plural = 'Android-动物保护项目发布' 59 | ordering = ['case_id'] 60 | db_table = 'a_animal_project_released' 61 | 62 | class AndroidTestCase2(models.Model): 63 | id = models.AutoField(primary_key=True, editable=False) 64 | case_id = models.CharField(max_length=45, unique=True) 65 | case_name = models.CharField(max_length=45) 66 | activity = models.CharField(max_length=60, null=True, blank=True) 67 | name = models.CharField(max_length=45, null=True, blank=True) 68 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 69 | value = models.TextField(null=True, blank=True) 70 | expected = models.TextField(null=True, blank=True) 71 | actual = models.TextField(null=True, blank=True, editable=False) 72 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 73 | state = models.IntegerField(default='1') 74 | 75 | def __unicode__(self): 76 | return self.case_name 77 | 78 | class Meta: 79 | verbose_name = 'Android-灾难救助项目发布' 80 | verbose_name_plural = 'Android-灾难救助项目发布' 81 | ordering = ['case_id'] 82 | db_table = 'a_disaster_project_released' 83 | 84 | class AndroidTestCase3(models.Model): 85 | id = models.AutoField(primary_key=True, editable=False) 86 | case_id = models.CharField(max_length=45, unique=True) 87 | case_name = models.CharField(max_length=45) 88 | activity = models.CharField(max_length=60, null=True, blank=True) 89 | name = models.CharField(max_length=45, null=True, blank=True) 90 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 91 | value = models.TextField(null=True, blank=True) 92 | expected = models.TextField(null=True, blank=True) 93 | actual = models.TextField(null=True, blank=True, editable=False) 94 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 95 | state = models.IntegerField(default='1') 96 | 97 | def __unicode__(self): 98 | return self.case_name 99 | 100 | class Meta: 101 | verbose_name = 'Android-梦想清单项目发布' 102 | verbose_name_plural = 'Android-梦想清单项目发布' 103 | ordering = ['case_id'] 104 | db_table = 'a_dream_project_released' 105 | 106 | class AndroidTestCase4(models.Model): 107 | id = models.AutoField(primary_key=True, editable=False) 108 | case_id = models.CharField(max_length=45, unique=True) 109 | case_name = models.CharField(max_length=45) 110 | activity = models.CharField(max_length=60, null=True, blank=True) 111 | name = models.CharField(max_length=45, null=True, blank=True) 112 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 113 | value = models.TextField(null=True, blank=True) 114 | expected = models.TextField(null=True, blank=True) 115 | actual = models.TextField(null=True, blank=True, editable=False) 116 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 117 | state = models.IntegerField(default='1') 118 | 119 | def __unicode__(self): 120 | return self.case_name 121 | 122 | class Meta: 123 | verbose_name = 'Android-大病救助项目发布' 124 | verbose_name_plural = 'Android-大病救助项目发布' 125 | ordering = ['case_id'] 126 | db_table = 'a_illness_project_released' 127 | 128 | class AndroidTestCase5(models.Model): 129 | id = models.AutoField(primary_key=True, editable=False) 130 | case_id = models.CharField(max_length=45, unique=True) 131 | case_name = models.CharField(max_length=45) 132 | activity = models.CharField(max_length=60, null=True, blank=True) 133 | name = models.CharField(max_length=45, null=True, blank=True) 134 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 135 | value = models.TextField(null=True, blank=True) 136 | expected = models.TextField(null=True, blank=True) 137 | actual = models.TextField(null=True, blank=True, editable=False) 138 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 139 | state = models.IntegerField(default='1') 140 | 141 | def __unicode__(self): 142 | return self.case_name 143 | 144 | class Meta: 145 | verbose_name = 'Android-扶贫助学项目发布' 146 | verbose_name_plural = 'Android-扶贫助学项目发布' 147 | ordering = ['case_id'] 148 | db_table = 'a_poverty_project_released' 149 | 150 | class AndroidTestCase6(models.Model): 151 | id = models.AutoField(primary_key=True, editable=False) 152 | case_id = models.CharField(max_length=45, unique=True) 153 | case_name = models.CharField(max_length=45) 154 | activity = models.CharField(max_length=60, null=True, blank=True) 155 | name = models.CharField(max_length=45, null=True, blank=True) 156 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 157 | value = models.TextField(null=True, blank=True) 158 | expected = models.TextField(null=True, blank=True) 159 | actual = models.TextField(null=True, blank=True, editable=False) 160 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 161 | state = models.IntegerField(default='1') 162 | 163 | def __unicode__(self): 164 | return self.case_name 165 | 166 | class Meta: 167 | verbose_name = 'Android-尝鲜预售项目发布' 168 | verbose_name_plural = 'Android-尝鲜预售项目发布' 169 | ordering = ['case_id'] 170 | db_table = 'a_presale_project_released' 171 | 172 | class AndroidTestCase7(models.Model): 173 | id = models.AutoField(primary_key=True, editable=False) 174 | case_id = models.CharField(max_length=45, unique=True) 175 | case_name = models.CharField(max_length=45) 176 | activity = models.CharField(max_length=60, null=True, blank=True) 177 | name = models.CharField(max_length=45, null=True, blank=True) 178 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 179 | value = models.TextField(null=True, blank=True) 180 | expected = models.TextField(null=True, blank=True) 181 | actual = models.TextField(null=True, blank=True, editable=False) 182 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 183 | state = models.IntegerField(default='1') 184 | 185 | def __unicode__(self): 186 | return self.case_name 187 | 188 | class Meta: 189 | verbose_name = 'Android-其它项目发布' 190 | verbose_name_plural = 'Android-其它项目发布' 191 | ordering = ['case_id'] 192 | db_table = 'a_other_project_released' 193 | 194 | class AndroidTestCase8(models.Model): 195 | id = models.AutoField(primary_key=True, editable=False) 196 | case_id = models.CharField(max_length=45, unique=True) 197 | case_name = models.CharField(max_length=45) 198 | activity = models.CharField(max_length=60, null=True, blank=True) 199 | name = models.CharField(max_length=45, null=True, blank=True) 200 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 201 | value = models.TextField(null=True, blank=True) 202 | expected = models.TextField(null=True, blank=True) 203 | actual = models.TextField(null=True, blank=True, editable=False) 204 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 205 | state = models.IntegerField(default='1') 206 | 207 | def __unicode__(self): 208 | return self.case_name 209 | 210 | class Meta: 211 | verbose_name = 'Android-支持已创建的项目' 212 | verbose_name_plural = 'Android-支持已创建的项目' 213 | ordering = ['case_id'] 214 | db_table = 'a_support_project' 215 | 216 | class AndroidTestCase9(models.Model): 217 | id = models.AutoField(primary_key=True, editable=False) 218 | case_id = models.CharField(max_length=45, unique=True) 219 | case_name = models.CharField(max_length=45) 220 | activity = models.CharField(max_length=60, null=True, blank=True) 221 | name = models.CharField(max_length=45, null=True, blank=True) 222 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 223 | value = models.TextField(null=True, blank=True) 224 | expected = models.TextField(null=True, blank=True) 225 | actual = models.TextField(null=True, blank=True, editable=False) 226 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 227 | state = models.IntegerField(default='1') 228 | 229 | def __unicode__(self): 230 | return self.case_name 231 | 232 | class Meta: 233 | verbose_name = 'Android-个人中心' 234 | verbose_name_plural = 'Android-个人中心' 235 | ordering = ['case_id'] 236 | db_table = 'a_check_my' 237 | 238 | class AndroidTestCase10(models.Model): 239 | id = models.AutoField(primary_key=True, editable=False) 240 | case_id = models.CharField(max_length=45, unique=True) 241 | case_name = models.CharField(max_length=45) 242 | activity = models.CharField(max_length=60, null=True, blank=True) 243 | name = models.CharField(max_length=45, null=True, blank=True) 244 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 245 | value = models.TextField(null=True, blank=True) 246 | expected = models.TextField(null=True, blank=True) 247 | actual = models.TextField(null=True, blank=True, editable=False) 248 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 249 | state = models.IntegerField(default='1') 250 | 251 | def __unicode__(self): 252 | return self.case_name 253 | 254 | class Meta: 255 | verbose_name = 'Android-微爱大病救助项目管理' 256 | verbose_name_plural = 'Android-微爱大病救助项目管理' 257 | ordering = ['case_id'] 258 | db_table = 'a_check_illness' 259 | 260 | class AndroidTestCase11(models.Model): 261 | id = models.AutoField(primary_key=True, editable=False) 262 | case_id = models.CharField(max_length=45, unique=True) 263 | case_name = models.CharField(max_length=45) 264 | activity = models.CharField(max_length=60, null=True, blank=True) 265 | name = models.CharField(max_length=45, null=True, blank=True) 266 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 267 | value = models.TextField(null=True, blank=True) 268 | expected = models.TextField(null=True, blank=True) 269 | actual = models.TextField(null=True, blank=True, editable=False) 270 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 271 | state = models.IntegerField(default='1') 272 | 273 | def __unicode__(self): 274 | return self.case_name 275 | 276 | class Meta: 277 | verbose_name = 'Android-尝鲜&梦想项目管理' 278 | verbose_name_plural = 'Android-尝鲜&梦想项目管理' 279 | ordering = ['case_id'] 280 | db_table = 'a_check_saledream' 281 | 282 | class AndroidTestCase12(models.Model): 283 | id = models.AutoField(primary_key=True, editable=False) 284 | case_id = models.CharField(max_length=45, unique=True) 285 | case_name = models.CharField(max_length=45) 286 | activity = models.CharField(max_length=60, null=True, blank=True) 287 | name = models.CharField(max_length=45, null=True, blank=True) 288 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 289 | value = models.TextField(null=True, blank=True) 290 | expected = models.TextField(null=True, blank=True) 291 | actual = models.TextField(null=True, blank=True, editable=False) 292 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 293 | state = models.IntegerField(default='1') 294 | 295 | def __unicode__(self): 296 | return self.case_name 297 | 298 | class Meta: 299 | verbose_name = 'Android-微爱剩余项目管理' 300 | verbose_name_plural = 'Android-微爱剩余项目管理' 301 | ordering = ['case_id'] 302 | db_table = 'a_check_love' 303 | 304 | class AndroidTestCase13(models.Model): 305 | id = models.AutoField(primary_key=True, editable=False) 306 | case_id = models.CharField(max_length=45, unique=True) 307 | case_name = models.CharField(max_length=45) 308 | activity = models.CharField(max_length=60, null=True, blank=True) 309 | name = models.CharField(max_length=45, null=True, blank=True) 310 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 311 | value = models.TextField(null=True, blank=True) 312 | expected = models.TextField(null=True, blank=True) 313 | actual = models.TextField(null=True, blank=True, editable=False) 314 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 315 | state = models.IntegerField(default='1') 316 | 317 | def __unicode__(self): 318 | return self.case_name 319 | 320 | class Meta: 321 | verbose_name = 'Android-登录APP' 322 | verbose_name_plural = 'Android-登录APP' 323 | ordering = ['case_id'] 324 | db_table = 'a_login' 325 | 326 | class Android_Device(models.Model): 327 | id = models.AutoField(primary_key=True, editable=False) 328 | name = models.CharField('设备名称', max_length=20, null=True, blank=True) 329 | deviceName = models.CharField('型号', max_length=20, null=True, blank=True) 330 | platformVersion = models.CharField('ANDROID版本', max_length=5, null=True, blank=True) 331 | resolution = models.CharField('分辨率', max_length=10, null=True, blank=True, choices=RESOLUTION_LIST) 332 | appiumPort = models.CharField('APPIUM端口', max_length=5, null=True, blank=True) 333 | bootstrapPort = models.CharField('BOOTSTRAP端口', max_length=5, null=True, blank=True) 334 | udid = models.CharField('UDID', max_length=20, null=True, blank=True) 335 | 336 | def __unicode__(self): 337 | return self.name 338 | 339 | class Meta: 340 | verbose_name = 'Android-设备信息' 341 | verbose_name_plural = 'Android-设备信息' 342 | ordering = ['id'] 343 | db_table = 'a_device' 344 | 345 | 346 | class Android_MQC(models.Model): 347 | id = models.AutoField(primary_key=True, editable=False) 348 | case_id = models.CharField(max_length=45, unique=True) 349 | case_name = models.CharField(max_length=45) 350 | activity = models.CharField(max_length=60, null=True, blank=True) 351 | name = models.CharField(max_length=45, null=True, blank=True) 352 | action = models.CharField(max_length=10, null=True, blank=True, choices=ACTION_LIST) 353 | value = models.TextField(null=True, blank=True) 354 | expected = models.TextField(null=True, blank=True) 355 | actual = models.TextField(null=True, blank=True, editable=False) 356 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 357 | state = models.IntegerField(default='1') 358 | 359 | def __unicode__(self): 360 | return self.case_name 361 | 362 | class Meta: 363 | verbose_name = 'Android-MQC测试用例' 364 | verbose_name_plural = 'Android-MQC测试用例' 365 | ordering = ['case_id'] 366 | db_table = 'a_mqc' 367 | -------------------------------------------------------------------------------- /android/templates/android_testcase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {# Load the tag library #} 6 | {% load bootstrap3 %} 7 | 8 | {# Load CSS and JavaScript #} 9 | {% bootstrap_css %} 10 | {% bootstrap_javascript %} 11 | 12 | {# Display django.contrib.messages as Bootstrap alerts #} 13 | {% bootstrap_messages %} 14 | 15 | 16 | 17 | 30 |
31 |
32 |
33 |

Android测试用例

34 |
35 | 44 |
45 | Go Jenkins 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | {% for testcase in testcase_list %} 61 | {% for k in testcase %} 62 | 63 | {% endfor %} 64 | 65 | {% endfor %} 66 |
Case_idCase_nameActivityNameActionValueExpectedActualRestultStatus
{{ k }}
67 |
68 | 69 | 82 | 91 | 92 | 112 | 113 |
114 |

©Test Automation 2016 & Zhangzhiyuan

115 |
116 | 117 | -------------------------------------------------------------------------------- /android/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /android/views.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | from django.db import connection 3 | from django.http import request 4 | from android import models 5 | from django.shortcuts import render_to_response 6 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 7 | 8 | 9 | # Create your views here. 10 | def android_testcase(request): 11 | if request.GET.get('table', ''): 12 | table = request.GET.get('table', '') 13 | sql = 'select case_id,case_name,activity,name,action,value,expected,actual,result,state from ' + table 14 | else: 15 | table = 'a_login' 16 | sql = 'select case_id,case_name,activity,name,action,value,expected,actual,result,state from a_login' 17 | 18 | list = [] 19 | sql2 = "select * from index_table where index_id = 0" 20 | cursor = connection.cursor() 21 | cursor.execute(sql, None) 22 | cursor2 = connection.cursor() 23 | cursor2.execute(sql2, None) 24 | col_names = [desc[0] for desc in cursor2.description] 25 | # print col_names 26 | caselist = cursor.fetchall() 27 | # table_list = cursor2.fetchall() 28 | for row in cursor2.fetchall(): 29 | # row=cursor2.fetchall() 30 | list.append(dict(zip(col_names, row))) 31 | # print list 32 | # print table_list 33 | paginator = Paginator(caselist, 15) # Show 15 contacts per page 34 | page = request.GET.get('page') 35 | try: 36 | contacts = paginator.page(page) 37 | except PageNotAnInteger: 38 | # If page is not an integer, deliver first page. 39 | contacts = paginator.page(1) 40 | except EmptyPage: 41 | # If page is out of range (e.g. 9999), deliver last page of results. 42 | contacts = paginator.page(paginator.num_pages) 43 | 44 | return render_to_response('android_testcase.html', {'testcase_list': contacts, 'table_list': list, 'table': table}) 45 | -------------------------------------------------------------------------------- /h5/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/h5/__init__.py -------------------------------------------------------------------------------- /h5/adminx.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | import xadmin 3 | from xadmin.views import CommAdminView 4 | from xadmin.plugins.actions import BaseActionView 5 | from h5.models import * 6 | 7 | # Register your models here. 8 | class H5TestCaseAdmin(object): 9 | list_display = ('case_id', 'case_name', 'url', 'name', 'action','value', 10 | 'expected', 'actual', 'result', 'state') 11 | search_fields = ('case_id', 'case_name', 'url', 'name', 'action', 'value', 12 | 'expected', 'actual', 'result', 'state') 13 | xadmin.site.register(H5TestCase1, H5TestCaseAdmin) 14 | xadmin.site.register(H5TestCase2, H5TestCaseAdmin) 15 | xadmin.site.register(H5TestCase3, H5TestCaseAdmin) 16 | xadmin.site.register(H5TestCase4, H5TestCaseAdmin) 17 | xadmin.site.register(H5TestCase5, H5TestCaseAdmin) 18 | xadmin.site.register(H5TestCase6, H5TestCaseAdmin) 19 | xadmin.site.register(H5TestCase7, H5TestCaseAdmin) 20 | # xadmin.site.register(H5TestCase8, H5TestCase8Admin) 21 | xadmin.site.register(H5TestCase9, H5TestCaseAdmin) 22 | xadmin.site.register(H5TestCase10, H5TestCaseAdmin) 23 | xadmin.site.register(H5TestCase11, H5TestCaseAdmin) 24 | xadmin.site.register(H5TestCase12, H5TestCaseAdmin) 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /h5/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class H5Config(AppConfig): 7 | name = 'h5' 8 | -------------------------------------------------------------------------------- /h5/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-08-22 09:48 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='H5TestCase1', 18 | fields=[ 19 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 20 | ('case_id', models.CharField(max_length=45)), 21 | ('case_name', models.CharField(max_length=45)), 22 | ('url', models.URLField(null=True)), 23 | ('name', models.CharField(max_length=45, null=True)), 24 | ('action', models.CharField(max_length=45, null=True)), 25 | ('value', models.TextField(null=True)), 26 | ('expected', models.TextField(null=True)), 27 | ('actual', models.TextField(editable=False, null=True)), 28 | ('result', models.CharField(editable=False, max_length=5, null=True)), 29 | ('state', models.IntegerField(default='1')), 30 | ], 31 | options={ 32 | 'ordering': ['id'], 33 | 'db_table': 'h_animal_project_released', 34 | 'verbose_name': '\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 35 | 'verbose_name_plural': '\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 36 | }, 37 | ), 38 | migrations.CreateModel( 39 | name='H5TestCase2', 40 | fields=[ 41 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 42 | ('case_id', models.CharField(max_length=45)), 43 | ('case_name', models.CharField(max_length=45)), 44 | ('url', models.URLField(null=True)), 45 | ('name', models.CharField(max_length=45, null=True)), 46 | ('action', models.CharField(max_length=45, null=True)), 47 | ('value', models.TextField(null=True)), 48 | ('expected', models.TextField(null=True)), 49 | ('actual', models.TextField(editable=False, null=True)), 50 | ('result', models.CharField(editable=False, max_length=5, null=True)), 51 | ('state', models.IntegerField(default='1')), 52 | ], 53 | options={ 54 | 'ordering': ['id'], 55 | 'db_table': 'h_disaster_project_released', 56 | 'verbose_name': '\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 57 | 'verbose_name_plural': '\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 58 | }, 59 | ), 60 | migrations.CreateModel( 61 | name='H5TestCase3', 62 | fields=[ 63 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 64 | ('case_id', models.CharField(max_length=45)), 65 | ('case_name', models.CharField(max_length=45)), 66 | ('url', models.URLField(null=True)), 67 | ('name', models.CharField(max_length=45, null=True)), 68 | ('action', models.CharField(max_length=45, null=True)), 69 | ('value', models.TextField(null=True)), 70 | ('expected', models.TextField(null=True)), 71 | ('actual', models.TextField(editable=False, null=True)), 72 | ('result', models.CharField(editable=False, max_length=5, null=True)), 73 | ('state', models.IntegerField(default='1')), 74 | ], 75 | options={ 76 | 'ordering': ['id'], 77 | 'db_table': 'h_dream_project_released', 78 | 'verbose_name': '\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 79 | 'verbose_name_plural': '\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 80 | }, 81 | ), 82 | migrations.CreateModel( 83 | name='H5TestCase4', 84 | fields=[ 85 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 86 | ('case_id', models.CharField(max_length=45)), 87 | ('case_name', models.CharField(max_length=45)), 88 | ('url', models.URLField(null=True)), 89 | ('name', models.CharField(max_length=45, null=True)), 90 | ('action', models.CharField(max_length=45, null=True)), 91 | ('value', models.TextField(null=True)), 92 | ('expected', models.TextField(null=True)), 93 | ('actual', models.TextField(editable=False, null=True)), 94 | ('result', models.CharField(editable=False, max_length=5, null=True)), 95 | ('state', models.IntegerField(default='1')), 96 | ], 97 | options={ 98 | 'ordering': ['id'], 99 | 'db_table': 'h_illness_project_released', 100 | 'verbose_name': '\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 101 | 'verbose_name_plural': '\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 102 | }, 103 | ), 104 | migrations.CreateModel( 105 | name='H5TestCase5', 106 | fields=[ 107 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 108 | ('case_id', models.CharField(max_length=45)), 109 | ('case_name', models.CharField(max_length=45)), 110 | ('url', models.URLField(null=True)), 111 | ('name', models.CharField(max_length=45, null=True)), 112 | ('action', models.CharField(max_length=45, null=True)), 113 | ('value', models.TextField(null=True)), 114 | ('expected', models.TextField(null=True)), 115 | ('actual', models.TextField(editable=False, null=True)), 116 | ('result', models.CharField(editable=False, max_length=5, null=True)), 117 | ('state', models.IntegerField(default='1')), 118 | ], 119 | options={ 120 | 'ordering': ['id'], 121 | 'db_table': 'h_poverty_project_released', 122 | 'verbose_name': '\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 123 | 'verbose_name_plural': '\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 124 | }, 125 | ), 126 | migrations.CreateModel( 127 | name='H5TestCase6', 128 | fields=[ 129 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 130 | ('case_id', models.CharField(max_length=45)), 131 | ('case_name', models.CharField(max_length=45)), 132 | ('url', models.URLField(null=True)), 133 | ('name', models.CharField(max_length=45, null=True)), 134 | ('action', models.CharField(max_length=45, null=True)), 135 | ('value', models.TextField(null=True)), 136 | ('expected', models.TextField(null=True)), 137 | ('actual', models.TextField(editable=False, null=True)), 138 | ('result', models.CharField(editable=False, max_length=5, null=True)), 139 | ('state', models.IntegerField(default='1')), 140 | ], 141 | options={ 142 | 'ordering': ['id'], 143 | 'db_table': 'h_presale_project_released', 144 | 'verbose_name': '\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 145 | 'verbose_name_plural': '\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 146 | }, 147 | ), 148 | migrations.CreateModel( 149 | name='H5TestCase7', 150 | fields=[ 151 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 152 | ('case_id', models.CharField(max_length=45)), 153 | ('case_name', models.CharField(max_length=45)), 154 | ('url', models.URLField(null=True)), 155 | ('name', models.CharField(max_length=45, null=True)), 156 | ('action', models.CharField(max_length=45, null=True)), 157 | ('value', models.TextField(null=True)), 158 | ('expected', models.TextField(null=True)), 159 | ('actual', models.TextField(editable=False, null=True)), 160 | ('result', models.CharField(editable=False, max_length=5, null=True)), 161 | ('state', models.IntegerField(default='1')), 162 | ], 163 | options={ 164 | 'ordering': ['id'], 165 | 'db_table': 'h_other_project_released', 166 | 'verbose_name': '\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 167 | 'verbose_name_plural': '\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 168 | }, 169 | ), 170 | migrations.CreateModel( 171 | name='H5TestCase8', 172 | fields=[ 173 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 174 | ('case_id', models.CharField(max_length=45)), 175 | ('case_name', models.CharField(max_length=45)), 176 | ('url', models.URLField(null=True)), 177 | ('name', models.CharField(max_length=45, null=True)), 178 | ('action', models.CharField(max_length=45, null=True)), 179 | ('value', models.TextField(null=True)), 180 | ('expected', models.TextField(null=True)), 181 | ('actual', models.TextField(editable=False, null=True)), 182 | ('result', models.CharField(editable=False, max_length=5, null=True)), 183 | ('state', models.IntegerField(default='1')), 184 | ], 185 | options={ 186 | 'ordering': ['id'], 187 | 'db_table': 'h_support_project', 188 | 'verbose_name': '\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 189 | 'verbose_name_plural': '\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 190 | }, 191 | ), 192 | migrations.CreateModel( 193 | name='H5TestCase9', 194 | fields=[ 195 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 196 | ('case_id', models.CharField(max_length=45)), 197 | ('case_name', models.CharField(max_length=45)), 198 | ('url', models.URLField(null=True)), 199 | ('name', models.CharField(max_length=45, null=True)), 200 | ('action', models.CharField(max_length=45, null=True)), 201 | ('value', models.TextField(null=True)), 202 | ('expected', models.TextField(null=True)), 203 | ('actual', models.TextField(editable=False, null=True)), 204 | ('result', models.CharField(editable=False, max_length=5, null=True)), 205 | ('state', models.IntegerField(default='1')), 206 | ], 207 | options={ 208 | 'ordering': ['id'], 209 | 'db_table': 'h_check_project', 210 | 'verbose_name': '\u67e5\u770b\u4e2a\u4eba\u9879\u76ee', 211 | 'verbose_name_plural': '\u67e5\u770b\u4e2a\u4eba\u9879\u76ee', 212 | }, 213 | ), 214 | ] 215 | -------------------------------------------------------------------------------- /h5/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/h5/migrations/__init__.py -------------------------------------------------------------------------------- /h5/models.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | # Create your models here. 6 | 7 | '''{'动物保护项目发布': 'h_animal_project_released', 8 | '灾难救助项目发布': 'h_disaster_project_released', 9 | '梦想清单项目发布': 'h_dream_project_released', 10 | '大病救助项目发布': 'h_illness_project_released', 11 | '扶贫助学项目发布': 'h_poverty_project_released', 12 | '尝鲜预售项目发布': 'h_presale_project_released', 13 | '其它项目发布': 'h_other_project_released', 14 | '支持已创建的项目': 'h_support_project', 15 | '查看个人项目':'h_check_project', 16 | '个人中心': 'h_check_my', 17 | '微爱大病救助项目管理':'h_check_illness', 18 | '尝鲜&梦想项目管理':'h_check_saledream', 19 | '微爱剩余项目管理':'h_check_love', 20 | } 21 | ''' 22 | ACTION_LIST = (('click',u'click'), 23 | ('sendkey',u'sendkey'), 24 | ('sendkeys',u'sendkeys'), 25 | ('scroll',u'scroll'), 26 | ('swipe',u'swipe'), 27 | ('sleep',u'sleep'), 28 | ('back',u'back'), 29 | ) 30 | class H5TestCase1(models.Model): 31 | id = models.AutoField(primary_key=True, editable=False) 32 | case_id = models.CharField(unique=True, max_length=45) 33 | case_name = models.CharField(max_length=45) 34 | url = models.URLField(null=True,blank=True) 35 | name = models.CharField(max_length=45, null=True,blank=True) 36 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 37 | value = models.TextField(null=True,blank=True) 38 | expected = models.TextField(null=True,blank=True) 39 | actual = models.TextField(null=True,blank=True, editable=False) 40 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 41 | state = models.IntegerField(default='1') 42 | 43 | def __unicode__(self): 44 | return self.case_name 45 | 46 | class Meta: 47 | verbose_name = 'H5-动物保护项目发布' 48 | verbose_name_plural = 'H5-动物保护项目发布' 49 | ordering = ['case_id'] 50 | db_table = 'h_animal_project_released' 51 | 52 | class H5TestCase2(models.Model): 53 | id = models.AutoField(primary_key=True, editable=False) 54 | case_id = models.CharField(unique=True, max_length=45) 55 | case_name = models.CharField(max_length=45) 56 | url = models.URLField(null=True,blank=True) 57 | name = models.CharField(max_length=45, null=True,blank=True) 58 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 59 | value = models.TextField(null=True,blank=True) 60 | expected = models.TextField(null=True,blank=True) 61 | actual = models.TextField(null=True,blank=True, editable=False) 62 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 63 | state = models.IntegerField(default='1') 64 | 65 | def __unicode__(self): 66 | return self.case_name 67 | 68 | class Meta: 69 | verbose_name = 'H5-灾难救助项目发布' 70 | verbose_name_plural = 'H5-灾难救助项目发布' 71 | ordering = ['case_id'] 72 | db_table = 'h_disaster_project_released' 73 | 74 | class H5TestCase3(models.Model): 75 | id = models.AutoField(primary_key=True, editable=False) 76 | case_id = models.CharField(unique=True, max_length=45) 77 | case_name = models.CharField(max_length=45) 78 | url = models.URLField(null=True,blank=True) 79 | name = models.CharField(max_length=45, null=True,blank=True) 80 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 81 | value = models.TextField(null=True,blank=True) 82 | expected = models.TextField(null=True,blank=True) 83 | actual = models.TextField(null=True,blank=True, editable=False) 84 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 85 | state = models.IntegerField(default='1') 86 | 87 | def __unicode__(self): 88 | return self.case_name 89 | 90 | class Meta: 91 | verbose_name = 'H5-梦想清单项目发布' 92 | verbose_name_plural = 'H5-梦想清单项目发布' 93 | ordering = ['case_id'] 94 | db_table = 'h_dream_project_released' 95 | 96 | class H5TestCase4(models.Model): 97 | id = models.AutoField(primary_key=True, editable=False) 98 | case_id = models.CharField(unique=True, max_length=45) 99 | case_name = models.CharField(max_length=45) 100 | url = models.URLField(null=True,blank=True) 101 | name = models.CharField(max_length=45, null=True,blank=True) 102 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 103 | value = models.TextField(null=True,blank=True) 104 | expected = models.TextField(null=True,blank=True) 105 | actual = models.TextField(null=True,blank=True, editable=False) 106 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 107 | state = models.IntegerField(default='1') 108 | 109 | def __unicode__(self): 110 | return self.case_name 111 | 112 | class Meta: 113 | verbose_name = 'H5-大病救助项目发布' 114 | verbose_name_plural = 'H5-大病救助项目发布' 115 | ordering = ['case_id'] 116 | db_table = 'h_illness_project_released' 117 | 118 | class H5TestCase5(models.Model): 119 | id = models.AutoField(primary_key=True, editable=False) 120 | case_id = models.CharField(unique=True, max_length=45) 121 | case_name = models.CharField(max_length=45) 122 | url = models.URLField(null=True,blank=True) 123 | name = models.CharField(max_length=45, null=True,blank=True) 124 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 125 | value = models.TextField(null=True,blank=True) 126 | expected = models.TextField(null=True,blank=True) 127 | actual = models.TextField(null=True,blank=True, editable=False) 128 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 129 | state = models.IntegerField(default='1') 130 | 131 | def __unicode__(self): 132 | return self.case_name 133 | 134 | class Meta: 135 | verbose_name = 'H5-扶贫助学项目发布' 136 | verbose_name_plural = 'H5-扶贫助学项目发布' 137 | ordering = ['case_id'] 138 | db_table = 'h_poverty_project_released' 139 | 140 | class H5TestCase6(models.Model): 141 | id = models.AutoField(primary_key=True, editable=False) 142 | case_id = models.CharField(unique=True, max_length=45) 143 | case_name = models.CharField(max_length=45) 144 | url = models.URLField(null=True,blank=True) 145 | name = models.CharField(max_length=45, null=True,blank=True) 146 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 147 | value = models.TextField(null=True,blank=True) 148 | expected = models.TextField(null=True,blank=True) 149 | actual = models.TextField(null=True,blank=True, editable=False) 150 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 151 | state = models.IntegerField(default='1') 152 | 153 | def __unicode__(self): 154 | return self.case_name 155 | 156 | class Meta: 157 | verbose_name = 'H5-尝鲜预售项目发布' 158 | verbose_name_plural = 'H5-尝鲜预售项目发布' 159 | ordering = ['case_id'] 160 | db_table = 'h_presale_project_released' 161 | 162 | class H5TestCase7(models.Model): 163 | id = models.AutoField(primary_key=True, editable=False) 164 | case_id = models.CharField(unique=True, max_length=45) 165 | case_name = models.CharField(max_length=45) 166 | url = models.URLField(null=True,blank=True) 167 | name = models.CharField(max_length=45, null=True,blank=True) 168 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 169 | value = models.TextField(null=True,blank=True) 170 | expected = models.TextField(null=True,blank=True) 171 | actual = models.TextField(null=True,blank=True, editable=False) 172 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 173 | state = models.IntegerField(default='1') 174 | 175 | def __unicode__(self): 176 | return self.case_name 177 | class Meta: 178 | verbose_name = 'H5-其它项目发布' 179 | verbose_name_plural = 'H5-其它项目发布' 180 | ordering = ['case_id'] 181 | db_table = 'h_other_project_released' 182 | 183 | class H5TestCase8(models.Model): 184 | id = models.AutoField(primary_key=True, editable=False) 185 | case_id = models.CharField(unique=True, max_length=45) 186 | case_name = models.CharField(max_length=45) 187 | url = models.URLField(null=True,blank=True) 188 | name = models.CharField(max_length=45, null=True,blank=True) 189 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 190 | value = models.TextField(null=True,blank=True) 191 | expected = models.TextField(null=True,blank=True) 192 | actual = models.TextField(null=True,blank=True, editable=False) 193 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 194 | state = models.IntegerField(default='1') 195 | 196 | def __unicode__(self): 197 | return self.case_name 198 | 199 | class Meta: 200 | verbose_name = 'H5-支持已创建的项目' 201 | verbose_name_plural = 'H5-支持已创建的项目' 202 | ordering = ['case_id'] 203 | db_table = 'h_support_project' 204 | 205 | class H5TestCase9(models.Model): 206 | id = models.AutoField(primary_key=True, editable=False) 207 | case_id = models.CharField(unique=True, max_length=45) 208 | case_name = models.CharField(max_length=45) 209 | url = models.URLField(null=True,blank=True) 210 | name = models.CharField(max_length=45, null=True,blank=True) 211 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 212 | value = models.TextField(null=True,blank=True) 213 | expected = models.TextField(null=True,blank=True) 214 | actual = models.TextField(null=True,blank=True, editable=False) 215 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 216 | state = models.IntegerField(default='1') 217 | 218 | def __unicode__(self): 219 | return self.case_name 220 | 221 | class Meta: 222 | verbose_name = 'H5-查看个人项目' 223 | verbose_name_plural = 'H5-查看个人项目' 224 | ordering = ['case_id'] 225 | db_table = 'h_check_my' 226 | 227 | class H5TestCase10(models.Model): 228 | id = models.AutoField(primary_key=True, editable=False) 229 | case_id = models.CharField(unique=True, max_length=45) 230 | case_name = models.CharField(max_length=45) 231 | url = models.URLField(null=True,blank=True) 232 | name = models.CharField(max_length=45, null=True,blank=True) 233 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 234 | value = models.TextField(null=True,blank=True) 235 | expected = models.TextField(null=True,blank=True) 236 | actual = models.TextField(null=True,blank=True, editable=False) 237 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 238 | state = models.IntegerField(default='1') 239 | 240 | def __unicode__(self): 241 | return self.case_name 242 | 243 | class Meta: 244 | verbose_name = 'H5-微爱大病救助项目管理' 245 | verbose_name_plural = 'H5-微爱大病救助项目管理' 246 | ordering = ['case_id'] 247 | db_table = 'h_check_illness' 248 | 249 | class H5TestCase11(models.Model): 250 | id = models.AutoField(primary_key=True, editable=False) 251 | case_id = models.CharField(unique=True, max_length=45) 252 | case_name = models.CharField(max_length=45) 253 | url = models.URLField(null=True,blank=True) 254 | name = models.CharField(max_length=45, null=True,blank=True) 255 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 256 | value = models.TextField(null=True,blank=True) 257 | expected = models.TextField(null=True,blank=True) 258 | actual = models.TextField(null=True,blank=True, editable=False) 259 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 260 | state = models.IntegerField(default='1') 261 | 262 | def __unicode__(self): 263 | return self.case_name 264 | 265 | class Meta: 266 | verbose_name = 'H5-尝鲜&梦想项目管理' 267 | verbose_name_plural = 'H5-尝鲜&梦想项目管理' 268 | ordering = ['case_id'] 269 | db_table = 'h_check_saledream' 270 | 271 | class H5TestCase12(models.Model): 272 | id = models.AutoField(primary_key=True, editable=False) 273 | case_id = models.CharField(unique=True, max_length=45) 274 | case_name = models.CharField(max_length=45) 275 | url = models.URLField(null=True,blank=True) 276 | name = models.CharField(max_length=45, null=True,blank=True) 277 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 278 | value = models.TextField(null=True,blank=True) 279 | expected = models.TextField(null=True,blank=True) 280 | actual = models.TextField(null=True,blank=True, editable=False) 281 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 282 | state = models.IntegerField(default='1') 283 | 284 | def __unicode__(self): 285 | return self.case_name 286 | 287 | class Meta: 288 | verbose_name = 'H5-微爱剩余项目管理' 289 | verbose_name_plural = 'H5-微爱剩余项目管理' 290 | ordering = ['case_id'] 291 | db_table = 'h_check_love' 292 | -------------------------------------------------------------------------------- /h5/templates/h5_testcase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {# Load the tag library #} 6 | {% load bootstrap3 %} 7 | 8 | {# Load CSS and JavaScript #} 9 | {% bootstrap_css %} 10 | {% bootstrap_javascript %} 11 | 12 | {# Display django.contrib.messages as Bootstrap alerts #} 13 | {% bootstrap_messages %} 14 | 15 | 16 | 17 | 30 |
31 |
32 |
33 |

H5测试用例

34 |
35 | 44 |
45 | Go Jenkins 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {% for testcase in testcase_list %} 60 | {% for k in testcase %} 61 | 62 | {% endfor %} 63 | 64 | {% endfor %} 65 |
Case_idCase_nameUrlNameActionValueExpectedActualRestultStatus
{{ k }}
66 | 67 |
68 | 81 | 90 | 91 | 112 |
113 |

©Test Automation 2016 & Zhangzhiyuan

114 |
115 | 116 | -------------------------------------------------------------------------------- /h5/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /h5/views.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from django.shortcuts import render 3 | from django.shortcuts import render_to_response 4 | from django.db import connection 5 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 6 | # Create your views here. 7 | import pymysql 8 | def h5_testcase(request): 9 | if request.GET.get('table', ''): 10 | table = request.GET.get('table', '') 11 | sql = 'select case_id,case_name,url,name,action,value,expected,actual,result,state from ' + table 12 | else: 13 | table = 'h_animal_project_released' 14 | sql = 'select case_id,case_name,url,name,action,value,expected,actual,result,state from h_animal_project_released' 15 | 16 | list = [] 17 | sql2 = "select * from index_table where index_id = 1" 18 | cursor = connection.cursor() 19 | cursor.execute(sql, None) 20 | cursor2 = connection.cursor() 21 | cursor2.execute(sql2, None) 22 | col_names = [desc[0] for desc in cursor2.description] 23 | # print col_names 24 | caselist = cursor.fetchall() 25 | # table_list = cursor2.fetchall() 26 | for row in cursor2.fetchall(): 27 | # row=cursor2.fetchall() 28 | list.append(dict(zip(col_names, row))) 29 | # print list 30 | # print table_list 31 | paginator = Paginator(caselist, 15) # Show 15 contacts per page 32 | page = request.GET.get('page') 33 | try: 34 | contacts = paginator.page(page) 35 | except PageNotAnInteger: 36 | # If page is not an integer, deliver first page. 37 | contacts = paginator.page(1) 38 | except EmptyPage: 39 | # If page is out of range (e.g. 9999), deliver last page of results. 40 | contacts = paginator.page(paginator.num_pages) 41 | 42 | return render_to_response('h5_testcase.html', {'testcase_list': contacts, 'table_list': list, 'table': table}) -------------------------------------------------------------------------------- /interface/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/interface/__init__.py -------------------------------------------------------------------------------- /interface/adminx.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from django.contrib import admin 3 | import xadmin 4 | from interface.models import * 5 | from h5.models import * 6 | from android.models import * 7 | from pc.models import * 8 | from ios.models import * 9 | from xadmin.views import CommAdminView 10 | from django.template import loader 11 | from xadmin.sites import site 12 | from xadmin.views import BaseAdminPlugin,ListAdminView 13 | from xadmin.plugins.actions import BaseActionView 14 | from django.http import HttpResponse,HttpResponseNotFound 15 | from xadmin.util import lookup_field, label_for_field, force_unicode, json 16 | from xadmin.plugins.utils import get_context_dict 17 | from django.db import connection 18 | from qsc_interfacetest.test_case.models.buildcase import BuildCase 19 | from django.db import models 20 | import chardet 21 | import logging 22 | import datetime 23 | import decimal 24 | import calendar 25 | from django.utils.http import urlencode 26 | from xadmin.views.dashboard import ModelBaseWidget, widget_manager 27 | from django.core.serializers.json import DjangoJSONEncoder 28 | from django.utils.encoding import smart_unicode 29 | 30 | try: 31 | import xlwt 32 | has_xlwt = True 33 | except: 34 | has_xlwt = False 35 | 36 | try: 37 | import xlsxwriter 38 | has_xlsxwriter = True 39 | except: 40 | has_xlsxwriter = False 41 | 42 | class ImportMenuPlugin(BaseAdminPlugin): 43 | list_export = ['csv'] 44 | export_names = {'xlsx': 'Excel 2007', 'xls': 'Excel', 'csv': 'CSV', 45 | 'xml': 'XML', 'json': 'JSON'} 46 | 47 | def init_request(self, *args, **kwargs): 48 | self.list_export = [ 49 | f for f in self.list_export 50 | if (f != 'xlsx' or has_xlsxwriter) and (f != 'xls' or has_xlwt)] 51 | # def init_request(self, *args, **kwargs): 52 | # return self.request.GET.get('_do_') == 'import' 53 | 54 | def block_top_toolbar(self, context, nodes): 55 | if self.list_export: 56 | context.update({ 57 | # 'show_export_all': self.admin_view.paginator.count > self.admin_view.list_per_page and not ALL_VAR in self.admin_view.request.GET, 58 | 'form_params': self.admin_view.get_form_params({'_do_': 'import'}, ('import_type',)), 59 | 'import_types': [{'type': et, 'name': self.export_names[et]} for et in self.list_export], 60 | }) 61 | nodes.append(loader.render_to_string('model.top_toolbar.imports.html', 62 | context=get_context_dict(context))) 63 | 64 | class ImportPlugin(BaseAdminPlugin): 65 | #导入插件定义 66 | table_list = { 67 | 'h5testcase1':'h_animal_project_released', 68 | 'h5testcase2':'h_disaster_project_released', 69 | 'h5testcase3':'h_dream_project_released', 70 | 'h5testcase4':'h_illness_project_released', 71 | 'h5testcase5':'h_poverty_project_released', 72 | 'h5testcase6':'h_presale_project_released', 73 | 'h5testcase7':'h_other_project_released', 74 | 'h5testcase8':'h_support_project', 75 | 'h5testcase9':'h_check_my', 76 | 'h5testcase10':'h_check_illness', 77 | 'h5testcase11':'h_check_saledream', 78 | 'h5testcase12':'h_check_love', 79 | 'androidtestcase1':'a_animal_project_released', 80 | 'androidtestcase2':'a_disaster_project_released', 81 | 'androidtestcase3':'a_dream_project_released', 82 | 'androidtestcase4':'a_illness_project_released', 83 | 'androidtestcase5':'a_poverty_project_released', 84 | 'androidtestcase6':'a_presale_project_released', 85 | 'androidtestcase7':'a_other_project_released', 86 | 'androidtestcase8':'a_support_project', 87 | 'androidtestcase9':'a_check_my', 88 | 'androidtestcase10':'a_check_illness', 89 | 'androidtestcase11':'a_check_saledream', 90 | 'androidtestcase12':'a_check_love', 91 | 'androidtestcase13':'a_login', 92 | 'iostestcase1':'i_animal_project_released', 93 | 'iostestcase2':'i_disaster_project_released', 94 | 'iostestcase3':'i_dream_project_released', 95 | 'iostestcase4':'i_illness_project_released', 96 | 'iostestcase5':'i_poverty_project_released', 97 | 'iostestcase6':'i_presale_project_released', 98 | 'iostestcase7':'i_other_project_released', 99 | 'iostestcase8':'i_support_project', 100 | 'iostestcase9':'i_check_personal', 101 | 'iostestcase10':'i_check_project', 102 | 'iostestcase11':'i_check_build_project', 103 | 'iostestcase12':'i_delete_card', 104 | 'iostestcase13':'i_login', 105 | 'interfacetestcase1':'interface_test1', 106 | 'interfaceconfig':'interface_config', 107 | 'pctestcase1':'p_illness_project_released', 108 | 'pctestcase2':'p_disaster_project_released', 109 | 'pctestcase3':'p_animal_project_released', 110 | 'pctestcase4':'p_poverty_project_released', 111 | 'pctestcase5':'p_other_project_released', 112 | 'pctestcase6':'p_presale_project_released', 113 | 'pctestcase7':'p_dream_project_released', 114 | } 115 | 116 | #初始化插件 117 | def init_request(self, *args, **kwargs): 118 | # print self.request.Get.get('_do_') 119 | return True 120 | #获取post数据 121 | def post_response(self, *args, **kwargs): 122 | file = self.request.FILES.get('import_file','') 123 | if file: 124 | # table = self.request.META.get('PATH_INFO').split('/')[3] 125 | table = self.opts.db_table 126 | # print table 127 | self.message_user(self.set_db(file,table)) 128 | else: 129 | pass 130 | #导入数据库数据 131 | def set_db(self,file,table): 132 | with open('/var/lib/mysql-files/testcase.csv','wb+') as testcase_file: 133 | for f in file.chunks(): 134 | encode = chardet.detect(f)['encoding'] 135 | testcase_file.write(f.decode(encode)) 136 | with open('/var/lib/mysql-files/testcase.csv') as f_txt: 137 | column = (f_txt.readline().replace(' ','_')).replace('datetime','@datetime') 138 | sql = '''load data low_priority infile '/var/lib/mysql-files/testcase.csv' replace into table %s 139 | fields terminated by',' 140 | enclosed by '"' 141 | lines terminated by'\r\n' 142 | ignore 1 lines 143 | (%s); 144 | '''%(table,column) 145 | try: 146 | cursor = connection.cursor() 147 | cursor.execute(sql, None) 148 | return u'数据导入完成!' 149 | except BaseException,e: 150 | return e 151 | 152 | class RunAction(BaseActionView): 153 | 154 | action_name = "run_action" 155 | description = u'运行所选的 %(verbose_name_plural)s' 156 | model_perm = 'change' 157 | icon = 'fa fa-play-circle' 158 | 159 | def do_action(self, queryset): 160 | av = self.list_view 161 | table = self.opts.db_table 162 | for testcase in queryset.values(): 163 | #执行接口测试用例 164 | try: 165 | result = BuildCase().execute_case(testcase,table) 166 | logging.info(result) 167 | except Exception,e: 168 | if len(queryset.values()) == 1: 169 | av.message_user(e) 170 | else: 171 | logging.error(e) 172 | msg = '运行完成!' 173 | av.message_user(msg) 174 | 175 | @widget_manager.register 176 | class MyChartWidget(ModelBaseWidget): 177 | widget_type = 'mchart' 178 | description = ('展示测试用例执行情况') 179 | template = 'xadmin/widgets/chart.html' 180 | widget_icon = 'fa fa-bar-chart-o' 181 | 182 | def convert(self, data): 183 | self.list_params = data.pop('params', {}) 184 | self.chart = data.pop('chart', None) 185 | def setup(self): 186 | super(MyChartWidget, self).setup() 187 | 188 | self.charts = InterfaceRecordAdmin.data_mycharts 189 | 190 | def get_chart_url(self, name, v): 191 | return self.model_admin_url('mychart', name) + "?" + urlencode(self.list_params) 192 | 193 | def context(self, context): 194 | # print context 195 | context.update({ 196 | 'charts': [{"name": name, "title": v['title'], 'url': self.get_chart_url(name, v)} for name, v in self.charts.items()], 197 | }) 198 | 199 | # Media 200 | def media(self): 201 | return self.vendor('flot.js', 'xadmin.plugin.charts.js') 202 | 203 | class JSONEncoder(DjangoJSONEncoder): 204 | def default(self, o): 205 | if isinstance(o, (datetime.date, datetime.datetime)): 206 | return calendar.timegm(o.timetuple()) * 1000 207 | elif isinstance(o, decimal.Decimal): 208 | return str(o) 209 | else: 210 | try: 211 | return super(JSONEncoder, self).default(o) 212 | except Exception: 213 | return smart_unicode(o) 214 | 215 | class MyChartsPlugin(BaseAdminPlugin): 216 | 217 | data_mycharts = {} 218 | 219 | def init_request(self, *args, **kwargs): 220 | return bool(self.data_mycharts) 221 | 222 | def get_chart_url(self, name, v): 223 | return self.admin_view.model_admin_url('mychart', name) + self.admin_view.get_query_string() 224 | 225 | # Media 226 | def get_media(self, media): 227 | return media + self.vendor('flot.js', 'xadmin.plugin.charts.js') 228 | 229 | # Block Views 230 | def block_results_top(self, context, nodes): 231 | context.update({ 232 | 'charts': [{"name": name, "title": v['title'], 'url': self.get_chart_url(name, v)} for name, v in self.data_mycharts.items()], 233 | }) 234 | nodes.append(loader.render_to_string('model_list.results_top.charts.html', context_instance=context)) 235 | 236 | class MyChartsView(ListAdminView): 237 | 238 | data_mycharts = {} 239 | 240 | def get_ordering(self): 241 | if 'order' in self.chart: 242 | return self.chart['order'] 243 | else: 244 | return super(MyChartsView, self).get_ordering() 245 | 246 | def get(self, request, name): 247 | # print request,name 248 | if name not in self.data_mycharts: 249 | return HttpResponseNotFound() 250 | 251 | self.chart = self.data_mycharts[name] 252 | 253 | self.x_field = self.chart['x-field'] 254 | y_fields = self.chart['y-field'] 255 | self.y_fields = ( 256 | y_fields,) if type(y_fields) not in (list, tuple) else y_fields 257 | 258 | datas = [{"data":[], "label": force_unicode(label_for_field( 259 | i, self.model, model_admin=self))} for i in self.y_fields] 260 | self.make_result_list() 261 | result_list = self.get_list_queryset()._clone() 262 | for obj in result_list: 263 | # print obj.case_name 264 | if self.chart['title'] in obj.case_name : 265 | xf, attrs, value = lookup_field(self.x_field, obj, self) 266 | for i, yfname in enumerate(self.y_fields): 267 | yf, yattrs, yv = lookup_field(yfname, obj, self) 268 | datas[i]["data"].append((value, yv)) 269 | 270 | option = {'series': {'lines': {'show': True}, 'points': {'show': False}}, 271 | 'grid': {'hoverable': True, 'clickable': True}} 272 | try: 273 | xfield = self.opts.get_field(self.x_field) 274 | if type(xfield) in (models.DateTimeField, models.DateField, models.TimeField): 275 | option['xaxis'] = {'mode': "time", 'tickLength': 5} 276 | if type(xfield) is models.DateField: 277 | option['xaxis']['timeformat'] = "%y/%m/%d" 278 | elif type(xfield) is models.TimeField: 279 | option['xaxis']['timeformat'] = "%H:%M:%S" 280 | else: 281 | option['xaxis']['timeformat'] = "%y/%m/%d %H:%M:%S" 282 | except Exception: 283 | pass 284 | 285 | option.update(self.chart.get('option', {})) 286 | # print datas 287 | content = {'data': datas, 'option': option} 288 | result = json.dumps(content, cls=JSONEncoder, ensure_ascii=False) 289 | # print result 290 | return HttpResponse(result) 291 | 292 | site.register_plugin(ImportMenuPlugin,ListAdminView) 293 | site.register_plugin(ImportPlugin,ListAdminView) 294 | site.register_plugin(MyChartsPlugin, ListAdminView) 295 | site.register_modelview(r'^mychart/(.+)/$', MyChartsView, name='%s_%s_mychart') 296 | 297 | 298 | 299 | class InterfaceTestcaseAdmin(object): 300 | list_display = ('case_id','case_name','url','request_type','config','result','status_code','time','datetime') 301 | search_fields = ('case_id','case_name','url','request_type','result','state') 302 | list_editable = ['case_id','url','request_type','body'] 303 | show_detail_fields = ['case_name'] 304 | list_export = ['xls','json'] 305 | actions = [RunAction, ] 306 | # data_mycharts = { 307 | # "time_count": {'title': u"登录", "x-field": "datetime", "y-field": ('time','status_code'), "order": ('datetime',)}, 308 | # "state_count": {'title': u"接口数据返回状态表", "x-field": "case_id", "y-field": ('status_code',), "order": ('case_name',)} 309 | # } 310 | class InterfaceConfigAdmin(object): 311 | list_display = ('name','value','state') 312 | search_fields = ('name','value','state') 313 | list_editable = ['name','value','state'] 314 | 315 | class InterfaceRecordAdmin(object): 316 | search_fields = ('case_name') 317 | data_mycharts = { 318 | "login": {'title': u"登录", "x-field": "datetime", "y-field": ('time'), "order": ('datetime',)}, 319 | "illness_released": {'title': u"发布大病项目", "x-field": "datetime", "y-field": ('time'), "order": ('datetime',)}, 320 | "del": {'title': u"删除公益项目", "x-field": "datetime", "y-field": ('time'), "order": ('datetime',)}, 321 | } 322 | 323 | class GlobalSetting(object): 324 | #定义菜单 325 | def get_site_menu(self): 326 | return ( 327 | {'title': '接口测试用例', 'perm': self.get_model_perm(InterfaceConfig, 'view'), 328 | 'menus':( 329 | {'title':'微爱接口','url': self.get_model_url(InterfaceTestcase1, 'changelist')}, 330 | {'title':'微爱接口(新)','url': self.get_model_url(InterfaceTestcase4, 'changelist')}, 331 | {'title':'梦想接口','url': self.get_model_url(InterfaceTestcase2, 'changelist')}, 332 | {'title':'预售接口','url': self.get_model_url(InterfaceTestcase3, 'changelist')}, 333 | # {'title':'接口统计','url':self.get_model_url(InterfaceRecord, 'changelist')}, 334 | {'title':'接口参数', 'url': self.get_model_url(InterfaceConfig, 'changelist')}, 335 | )}, 336 | {'title': 'H5测试用例', 'perm': self.get_model_perm(H5TestCase1, 'change'), 'menus': ( 337 | {'title': '动物保护项目发布', 'url': self.get_model_url(H5TestCase1, 'changelist')}, 338 | {'title': '灾难救助项目发布', 'url': self.get_model_url(H5TestCase2, 'changelist')}, 339 | {'title': '梦想清单项目发布', 'url': self.get_model_url(H5TestCase3, 'changelist')}, 340 | {'title': '大病救助项目发布', 'url': self.get_model_url(H5TestCase4, 'changelist')}, 341 | {'title': '扶贫助学项目发布', 'url': self.get_model_url(H5TestCase5, 'changelist')}, 342 | {'title': '尝鲜预售项目发布', 'url': self.get_model_url(H5TestCase6, 'changelist')}, 343 | {'title': '其它项目发布', 'url': self.get_model_url(H5TestCase7, 'changelist')}, 344 | # {'title': '支持已创建的项目', 'url': self.get_model_url(H5TestCase8, 'changelist')}, 345 | {'title': '个人中心', 'url': self.get_model_url(H5TestCase9, 'changelist')}, 346 | {'title': '微爱大病救助项目管理', 'url': self.get_model_url(H5TestCase10, 'changelist')}, 347 | {'title': '尝鲜&梦想项目管理', 'url': self.get_model_url(H5TestCase11, 'changelist')}, 348 | {'title': '微爱剩余项目管理', 'url': self.get_model_url(H5TestCase12, 'changelist')}, 349 | )}, 350 | {'title': 'Android测试用例', 'perm': self.get_model_perm(AndroidTestCase1, 'change'), 'menus': ( 351 | {'title': '动物保护项目发布', 'url': self.get_model_url(AndroidTestCase1, 'changelist')}, 352 | {'title': '灾难救助项目发布', 'url': self.get_model_url(AndroidTestCase2, 'changelist')}, 353 | {'title': '梦想清单项目发布', 'url': self.get_model_url(AndroidTestCase3, 'changelist')}, 354 | {'title': '大病救助项目发布', 'url': self.get_model_url(AndroidTestCase4, 'changelist')}, 355 | {'title': '扶贫助学项目发布', 'url': self.get_model_url(AndroidTestCase5, 'changelist')}, 356 | {'title': '尝鲜预售项目发布', 'url': self.get_model_url(AndroidTestCase6, 'changelist')}, 357 | {'title': '其它项目发布', 'url': self.get_model_url(AndroidTestCase7, 'changelist')}, 358 | # {'title': '支持已创建的项目', 'url': self.get_model_url(AndroidTestCase8, 'changelist')}, 359 | {'title': '个人中心', 'url': self.get_model_url(AndroidTestCase9, 'changelist')}, 360 | {'title': '微爱大病救助项目管理', 'url': self.get_model_url(AndroidTestCase10, 'changelist')}, 361 | {'title': '尝鲜&梦想项目管理', 'url': self.get_model_url(AndroidTestCase11, 'changelist')}, 362 | {'title': '微爱剩余项目管理', 'url': self.get_model_url(AndroidTestCase12, 'changelist')}, 363 | # {'title': '登录APP', 'url': self.get_model_url(AndroidTestCase13, 'changelist')}, 364 | {'title': '设备信息', 'url': self.get_model_url(Android_Device, 'changelist')}, 365 | {'title': 'MQC测试用例', 'url': self.get_model_url(Android_MQC, 'changelist')}, 366 | )}, 367 | {'title': 'IOS测试用例', 'perm': self.get_model_perm(IOSTestCase1, 'change'), 'menus': ( 368 | {'title': '动物保护项目发布', 'url': self.get_model_url(IOSTestCase1, 'changelist')}, 369 | {'title': '灾难救助项目发布', 'url': self.get_model_url(IOSTestCase2, 'changelist')}, 370 | {'title': '梦想清单项目发布', 'url': self.get_model_url(IOSTestCase3, 'changelist')}, 371 | {'title': '大病救助项目发布', 'url': self.get_model_url(IOSTestCase4, 'changelist')}, 372 | {'title': '扶贫助学项目发布', 'url': self.get_model_url(IOSTestCase5, 'changelist')}, 373 | {'title': '尝鲜预售项目发布', 'url': self.get_model_url(IOSTestCase6, 'changelist')}, 374 | {'title': '其它项目发布', 'url': self.get_model_url(IOSTestCase7, 'changelist')}, 375 | # {'title': '支持已创建的项目', 'url': self.get_model_url(IOSTestCase8, 'changelist')}, 376 | {'title': '个人中心', 'url': self.get_model_url(IOSTestCase9, 'changelist')}, 377 | {'title': '项目管理', 'url': self.get_model_url(IOSTestCase10, 'changelist')}, 378 | {'title': '查看个人项目发布', 'url': self.get_model_url(IOSTestCase11, 'changelist')}, 379 | # {'title': '删除银行卡', 'url': self.get_model_url(IOSTestCase12, 'changelist')}, 380 | # {'title': '登录APP', 'url': self.get_model_url(IOSTestCase13, 'changelist')}, 381 | )}, 382 | {'title': 'PC测试用例', 'perm': self.get_model_perm(PCTestCase1, 'change'), 'menus': ( 383 | {'title': '大病救助项目发布', 'url': self.get_model_url(PCTestCase1, 'changelist')}, 384 | {'title': '灾难救助项目发布', 'url': self.get_model_url(PCTestCase2, 'changelist')}, 385 | {'title': '动物保护项目发布', 'url': self.get_model_url(PCTestCase3, 'changelist')}, 386 | {'title': '扶贫助学项目发布', 'url': self.get_model_url(PCTestCase4, 'changelist')}, 387 | {'title': '其他项目发布', 'url': self.get_model_url(PCTestCase5, 'changelist')}, 388 | {'title': '尝鲜预售项目发布', 'url': self.get_model_url(PCTestCase6, 'changelist')}, 389 | {'title': '梦想清单项目发布', 'url': self.get_model_url(PCTestCase7, 'changelist')}, 390 | # {'title': '支持已创建的项目', 'url': self.get_model_url(H5TestCase8, 'changelist')}, 391 | # {'title': '查看个人项目', 'url': self.get_model_url(H5TestCase9, 'changelist')}, 392 | )}, 393 | ) 394 | 395 | 396 | xadmin.site.register(CommAdminView,GlobalSetting) 397 | xadmin.site.register(InterfaceTestcase1, InterfaceTestcaseAdmin) 398 | xadmin.site.register(InterfaceTestcase2, InterfaceTestcaseAdmin) 399 | xadmin.site.register(InterfaceTestcase3, InterfaceTestcaseAdmin) 400 | xadmin.site.register(InterfaceTestcase4, InterfaceTestcaseAdmin) 401 | xadmin.site.register(InterfaceRecord,InterfaceRecordAdmin) 402 | xadmin.site.register(InterfaceConfig, InterfaceConfigAdmin) 403 | -------------------------------------------------------------------------------- /interface/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class InterfaceConfig(AppConfig): 7 | name = 'interface' 8 | -------------------------------------------------------------------------------- /interface/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-10-13 10:05 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='InterfaceConfig', 18 | fields=[ 19 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 20 | ('name', models.CharField(max_length=45)), 21 | ('value', models.CharField(max_length=200)), 22 | ('state', models.IntegerField(default='1')), 23 | ], 24 | options={ 25 | 'ordering': ['id'], 26 | 'db_table': 'interface_config', 27 | 'verbose_name': '\u53c2\u6570\u914d\u7f6e', 28 | 'verbose_name_plural': '\u53c2\u6570\u914d\u7f6e', 29 | }, 30 | ), 31 | migrations.CreateModel( 32 | name='InterfaceTestcase1', 33 | fields=[ 34 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 35 | ('case_id', models.CharField(max_length=45, unique=True)), 36 | ('case_name', models.CharField(max_length=45)), 37 | ('request_type', models.CharField(max_length=45)), 38 | ('url', models.CharField(max_length=100)), 39 | ('parameters', models.TextField(blank=True, null=True)), 40 | ('body', models.TextField(blank=True, null=True)), 41 | ('response', models.TextField(blank=True, editable=False, null=True)), 42 | ('status_code', models.CharField(blank=True, editable=False, max_length=5, null=True)), 43 | ('expected', models.TextField(blank=True, null=True)), 44 | ('not_expected', models.TextField(blank=True, null=True)), 45 | ('actual', models.TextField(blank=True, editable=False, null=True)), 46 | ('config', models.CharField(blank=True, max_length=200, null=True)), 47 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 48 | ('time', models.IntegerField(blank=True, editable=False, null=True)), 49 | ('state', models.IntegerField(default='1')), 50 | ], 51 | options={ 52 | 'ordering': ['case_id'], 53 | 'db_table': 'interface_test1', 54 | 'verbose_name': '\u6d4b\u8bd5\u7528\u4f8b', 55 | 'verbose_name_plural': '\u6d4b\u8bd5\u7528\u4f8b', 56 | }, 57 | ), 58 | ] 59 | -------------------------------------------------------------------------------- /interface/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/interface/migrations/__init__.py -------------------------------------------------------------------------------- /interface/models.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | from django.contrib import admin 6 | 7 | 8 | REQUEST_LIST = ( 9 | ('get','get'), 10 | ('post','post'), 11 | ('put','put'), 12 | ('patch','patch'), 13 | ('delete','delete'), 14 | ) 15 | # Create your models here. 16 | class InterfaceTestcase1(models.Model): 17 | id = models.AutoField(primary_key=True, editable=False) 18 | case_id = models.CharField(max_length=45,unique=True) 19 | case_name = models.CharField(max_length=45) 20 | request_type = models.CharField(max_length=10,choices=REQUEST_LIST) 21 | url = models.CharField(max_length=100) 22 | parameters = models.TextField(null=True,blank=True,editable=False) 23 | body = models.TextField(null=True,blank=True) 24 | response = models.TextField(null=True,blank=True,editable=True) 25 | status_code = models.CharField(max_length=5,null=True,blank=True,editable=False) 26 | expected = models.TextField(null=True,blank=True) 27 | not_expected = models.TextField(null=True, blank=True) 28 | actual = models.TextField(null=True,blank=True,editable=False) 29 | config = models.CharField(max_length=200,null=True,blank=True) 30 | result = models.CharField(max_length=5,null=True,blank=True,editable=False) 31 | time = models.IntegerField(null=True,blank=True,editable=False) 32 | state = models.IntegerField(default='1') 33 | datetime = models.DateTimeField(null=True,editable=False,default=None) 34 | 35 | def __unicode__(self): 36 | return self.case_name 37 | 38 | class Meta: 39 | verbose_name = '微爱接口测试用例' 40 | verbose_name_plural = '微爱接口测试用例' 41 | # app_label = '接口测试' 42 | ordering = ['case_id'] 43 | db_table = 'interface_love' 44 | 45 | class InterfaceTestcase2(models.Model): 46 | id = models.AutoField(primary_key=True, editable=False) 47 | case_id = models.CharField(max_length=45,unique=True) 48 | case_name = models.CharField(max_length=45) 49 | request_type = models.CharField(max_length=10,choices=REQUEST_LIST) 50 | url = models.CharField(max_length=100) 51 | parameters = models.TextField(null=True,blank=True,editable=False) 52 | body = models.TextField(null=True,blank=True) 53 | response = models.TextField(null=True,blank=True,editable=True) 54 | status_code = models.CharField(max_length=5,null=True,blank=True,editable=False) 55 | expected = models.TextField(null=True,blank=True) 56 | not_expected = models.TextField(null=True, blank=True) 57 | actual = models.TextField(null=True,blank=True,editable=False) 58 | config = models.CharField(max_length=200,null=True,blank=True) 59 | result = models.CharField(max_length=5,null=True,blank=True,editable=False) 60 | time = models.IntegerField(null=True,blank=True,editable=False) 61 | state = models.IntegerField(default='1') 62 | datetime = models.DateTimeField(null=True,editable=False,default=None) 63 | 64 | def __unicode__(self): 65 | return self.case_name 66 | 67 | class Meta: 68 | verbose_name = '梦想接口测试用例' 69 | verbose_name_plural = '梦想接口测试用例' 70 | # app_label = '接口测试' 71 | ordering = ['case_id'] 72 | db_table = 'interface_dream' 73 | 74 | class InterfaceTestcase3(models.Model): 75 | id = models.AutoField(primary_key=True, editable=False) 76 | case_id = models.CharField(max_length=45,unique=True) 77 | case_name = models.CharField(max_length=45) 78 | request_type = models.CharField(max_length=10,choices=REQUEST_LIST) 79 | url = models.CharField(max_length=100) 80 | parameters = models.TextField(null=True,blank=True,editable=False) 81 | body = models.TextField(null=True,blank=True) 82 | response = models.TextField(null=True,blank=True,editable=True) 83 | status_code = models.CharField(max_length=5,null=True,blank=True,editable=False) 84 | expected = models.TextField(null=True,blank=True) 85 | not_expected = models.TextField(null=True, blank=True) 86 | actual = models.TextField(null=True,blank=True,editable=False) 87 | config = models.CharField(max_length=200,null=True,blank=True) 88 | result = models.CharField(max_length=5,null=True,blank=True,editable=False) 89 | time = models.IntegerField(null=True,blank=True,editable=False) 90 | state = models.IntegerField(default='1') 91 | datetime = models.DateTimeField(null=True,editable=False,default=None) 92 | 93 | def __unicode__(self): 94 | return self.case_name 95 | 96 | class Meta: 97 | verbose_name = '预售接口测试用例' 98 | verbose_name_plural = '预售接口测试用例' 99 | # app_label = '接口测试' 100 | ordering = ['case_id'] 101 | db_table = 'interface_sale' 102 | 103 | class InterfaceTestcase4(models.Model): 104 | id = models.AutoField(primary_key=True, editable=False) 105 | case_id = models.CharField(max_length=45,unique=True) 106 | case_name = models.CharField(max_length=45) 107 | request_type = models.CharField(max_length=10,choices=REQUEST_LIST) 108 | url = models.CharField(max_length=100) 109 | parameters = models.TextField(null=True,blank=True,editable=False) 110 | body = models.TextField(null=True,blank=True) 111 | response = models.TextField(null=True,blank=True,editable=True) 112 | status_code = models.CharField(max_length=5,null=True,blank=True,editable=False) 113 | expected = models.TextField(null=True,blank=True) 114 | not_expected = models.TextField(null=True, blank=True) 115 | actual = models.TextField(null=True,blank=True,editable=False) 116 | config = models.CharField(max_length=200,null=True,blank=True) 117 | result = models.CharField(max_length=5,null=True,blank=True,editable=False) 118 | time = models.IntegerField(null=True,blank=True,editable=False) 119 | state = models.IntegerField(default='1') 120 | datetime = models.DateTimeField(null=True,editable=False,default=None) 121 | 122 | def __unicode__(self): 123 | return self.case_name 124 | 125 | class Meta: 126 | verbose_name = '微爱接口测试用例(新)' 127 | verbose_name_plural = '微爱接口测试用例(新)' 128 | # app_label = '接口测试' 129 | ordering = ['case_id'] 130 | db_table = 'interface_love_new' 131 | 132 | class InterfaceConfig(models.Model): 133 | id = models.AutoField(primary_key=True,editable=False) 134 | name = models.CharField(max_length=45) 135 | value = models.CharField(max_length=300) 136 | state = models.IntegerField(default='1') 137 | models.IntegerField() 138 | 139 | def __unicode__(self): 140 | return self.name 141 | 142 | class Meta: 143 | verbose_name = '接口参数配置' 144 | verbose_name_plural = '接口参数配置' 145 | ordering = ['id'] 146 | db_table = 'interface_config' 147 | 148 | class InterfaceRecord(models.Model): 149 | id = models.AutoField(primary_key=True,editable=False) 150 | case_name = models.CharField(max_length=45,editable=False) 151 | time = models.IntegerField(null=True,blank=True,editable=False) 152 | status_code = models.CharField(max_length=5,null=True,blank=True,editable=False) 153 | datetime = models.DateTimeField(null=True,editable=False,default=None) 154 | 155 | def __unicode__(self): 156 | return self.case_name 157 | 158 | class Meta: 159 | verbose_name = '接口请求历史记录' 160 | verbose_name_plural = '接口请求历史记录' 161 | ordering = ['id'] 162 | db_table = 'interface_record' 163 | 164 | -------------------------------------------------------------------------------- /interface/templates/interface_testcase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {# Load the tag library #} 6 | {% load bootstrap3 %} 7 | 8 | {# Load CSS and JavaScript #} 9 | {% bootstrap_css %} 10 | {% bootstrap_javascript %} 11 | 12 | {# Display django.contrib.messages as Bootstrap alerts #} 13 | {% bootstrap_messages %} 14 | 15 | 16 | 17 | 30 |
31 |
32 |
33 |

接口测试数据

34 |
35 | 44 |
45 | Go Jenkins 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {% for testcase in testcase_list %} 62 | {% for k in testcase %} 63 | 64 | {% endfor %} 65 | 66 | {% endfor %} 67 |
NameUrlRequestParametersBodyResponseCodeExpectedActualRestultTimeDatetime
{{ k }}
68 | 69 |
70 | 83 | 93 | 94 | 127 | 128 |
129 |

©Test Automation 2016 & Zhangzhiyuan

130 |
131 | 132 | -------------------------------------------------------------------------------- /interface/templates/model.top_toolbar.imports.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |
3 | 4 | {% trans "导入" %} 5 | 6 | 11 | 12 | {% for et in import_types %} 13 | 50 | {% endfor %} 51 | 52 |
-------------------------------------------------------------------------------- /interface/templates/model.top_toolbar.run.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 |
3 | 4 | {% trans "运行" %} 5 | 6 | 14 | {% for et in run_types %} 15 | 38 | {% endfor %} 39 | 40 |
-------------------------------------------------------------------------------- /interface/templates/model_list.results_top.charts.html: -------------------------------------------------------------------------------- 1 | {% extends "xadmin/includes/box.html" %} 2 | {% load i18n xadmin_tags %} 3 | {% block box_title %} 4 | {% trans "Charts" %} 5 | {% endblock box_title %} 6 | 7 | {% block box_content_class %}nopadding{% endblock box_content_class %} 8 | {% block box_content %} 9 | 14 |
15 | {% for c in charts %} 16 |
18 | {% endfor %} 19 |
20 | {% endblock box_content %} 21 | -------------------------------------------------------------------------------- /interface/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /interface/views.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from django.shortcuts import render 3 | from django.shortcuts import render_to_response 4 | from django.db import connection 5 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 6 | 7 | def interface_testcase(request): 8 | # print request.GET.get('table', '') 9 | if request.GET.get('table', ''): 10 | table = request.GET.get('table', '').split('-')[0] 11 | # state = int(request.GET.get('table', '').split('-')[1]) 12 | # print state,table 13 | sql = '''select case_name, url,request_type, parameters, body, 14 | response, status_code, expected, actual, result, time, datetime from %s 15 | order by `case_id`''' %table 16 | else: 17 | table = 'interface_love' 18 | # state = 2 19 | sql = '''select case_name, url,request_type, parameters, body, 20 | response, status_code, expected, actual, result, time,datetime from %s 21 | order by `case_id`''' %table 22 | 23 | list = [] 24 | sql2 = "select * from index_table where index_id = 2" 25 | cursor = connection.cursor() 26 | cursor.execute(sql, None) 27 | cursor2 = connection.cursor() 28 | cursor2.execute(sql2, None) 29 | col_names = [desc[0] for desc in cursor2.description] 30 | # print col_names 31 | caselist = cursor.fetchall() 32 | # print caselist 33 | # table_list = cursor2.fetchall() 34 | #返回数据库index_table表的数据 35 | for row in cursor2.fetchall(): 36 | # row=cursor2.fetchall() 37 | list.append(dict(zip(col_names, row))) 38 | # print list 39 | # print table_list 40 | # 对数据库中测试用例表进行分页查询 41 | paginator = Paginator(caselist, 15) # Show 15 contacts per page 42 | page = request.GET.get('page') 43 | try: 44 | contacts = paginator.page(page) 45 | except PageNotAnInteger: 46 | # If page is not an integer, deliver first page. 47 | contacts = paginator.page(1) 48 | except EmptyPage: 49 | # If page is out of range (e.g. 9999), deliver last page of results. 50 | contacts = paginator.page(paginator.num_pages) 51 | 52 | return render_to_response('interface_testcase.html', {'testcase_list': contacts, 'table_list': list, 'table': table,}) 53 | -------------------------------------------------------------------------------- /ios/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/ios/__init__.py -------------------------------------------------------------------------------- /ios/adminx.py: -------------------------------------------------------------------------------- 1 | import xadmin 2 | from ios.models import * 3 | # Register your models here. 4 | class IOSTestCaseAdmin(object): 5 | list_display = ('case_id', 'case_name', 'page', 'name', 'action','value', 6 | 'expected','actual', 'result', 'state') 7 | search_fields = ('case_id', 'case_name', 'page', 'name', 'action', 'value', 8 | 'expected','actual', 'result', 'state') 9 | 10 | 11 | xadmin.site.register(IOSTestCase1, IOSTestCaseAdmin) 12 | xadmin.site.register(IOSTestCase2, IOSTestCaseAdmin) 13 | xadmin.site.register(IOSTestCase3, IOSTestCaseAdmin) 14 | xadmin.site.register(IOSTestCase4, IOSTestCaseAdmin) 15 | xadmin.site.register(IOSTestCase5, IOSTestCaseAdmin) 16 | xadmin.site.register(IOSTestCase6, IOSTestCaseAdmin) 17 | xadmin.site.register(IOSTestCase7, IOSTestCaseAdmin) 18 | # xadmin.site.register(IOSTestCase8, IOSTestCase8Admin) 19 | xadmin.site.register(IOSTestCase9, IOSTestCaseAdmin) 20 | xadmin.site.register(IOSTestCase10, IOSTestCaseAdmin) 21 | xadmin.site.register(IOSTestCase11, IOSTestCaseAdmin) 22 | # xadmin.site.register(IOSTestCase12, IOSTestCase12Admin) 23 | # xadmin.site.register(IOSTestCase13, IOSTestCase13Admin) 24 | 25 | 26 | -------------------------------------------------------------------------------- /ios/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class IosConfig(AppConfig): 7 | name = 'ios' 8 | -------------------------------------------------------------------------------- /ios/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-11-01 15:36 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='IOSTestCase1', 18 | fields=[ 19 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 20 | ('case_id', models.CharField(max_length=45)), 21 | ('case_name', models.CharField(max_length=45)), 22 | ('page', models.CharField(blank=True, max_length=60, null=True)), 23 | ('name', models.CharField(blank=True, max_length=45, null=True)), 24 | ('action', models.CharField(blank=True, max_length=45, null=True)), 25 | ('value', models.TextField(blank=True, null=True)), 26 | ('expected', models.TextField(blank=True, null=True)), 27 | ('actual', models.TextField(blank=True, editable=False, null=True)), 28 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 29 | ('state', models.IntegerField(default='1')), 30 | ], 31 | options={ 32 | 'ordering': ['id'], 33 | 'db_table': 'i_animal_project_released', 34 | 'verbose_name': 'IOS-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 35 | 'verbose_name_plural': 'IOS-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 36 | }, 37 | ), 38 | migrations.CreateModel( 39 | name='IOSTestCase10', 40 | fields=[ 41 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 42 | ('case_id', models.CharField(max_length=45)), 43 | ('case_name', models.CharField(max_length=45)), 44 | ('page', models.CharField(blank=True, max_length=60, null=True)), 45 | ('name', models.CharField(blank=True, max_length=45, null=True)), 46 | ('action', models.CharField(blank=True, max_length=45, null=True)), 47 | ('value', models.TextField(blank=True, null=True)), 48 | ('expected', models.TextField(blank=True, null=True)), 49 | ('actual', models.TextField(blank=True, editable=False, null=True)), 50 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 51 | ('state', models.IntegerField(default='1')), 52 | ], 53 | options={ 54 | 'ordering': ['id'], 55 | 'db_table': 'i_check_project', 56 | 'verbose_name': 'IOS-\u9879\u76ee\u7ba1\u7406', 57 | 'verbose_name_plural': 'IOS-\u9879\u76ee\u7ba1\u7406', 58 | }, 59 | ), 60 | migrations.CreateModel( 61 | name='IOSTestCase11', 62 | fields=[ 63 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 64 | ('case_id', models.CharField(max_length=45)), 65 | ('case_name', models.CharField(max_length=45)), 66 | ('page', models.CharField(blank=True, max_length=60, null=True)), 67 | ('name', models.CharField(blank=True, max_length=45, null=True)), 68 | ('action', models.CharField(blank=True, max_length=45, null=True)), 69 | ('value', models.TextField(blank=True, null=True)), 70 | ('expected', models.TextField(blank=True, null=True)), 71 | ('actual', models.TextField(blank=True, editable=False, null=True)), 72 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 73 | ('state', models.IntegerField(default='1')), 74 | ], 75 | options={ 76 | 'ordering': ['id'], 77 | 'db_table': 'i_check_build_project', 78 | 'verbose_name': 'IOS-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee\u53d1\u5e03', 79 | 'verbose_name_plural': 'IOS-\u67e5\u770b\u4e2a\u4eba\u9879\u76ee\u53d1\u5e03', 80 | }, 81 | ), 82 | migrations.CreateModel( 83 | name='IOSTestCase12', 84 | fields=[ 85 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 86 | ('case_id', models.CharField(max_length=45)), 87 | ('case_name', models.CharField(max_length=45)), 88 | ('page', models.CharField(blank=True, max_length=60, null=True)), 89 | ('name', models.CharField(blank=True, max_length=45, null=True)), 90 | ('action', models.CharField(blank=True, max_length=45, null=True)), 91 | ('value', models.TextField(blank=True, null=True)), 92 | ('expected', models.TextField(blank=True, null=True)), 93 | ('actual', models.TextField(blank=True, editable=False, null=True)), 94 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 95 | ('state', models.IntegerField(default='1')), 96 | ], 97 | options={ 98 | 'ordering': ['id'], 99 | 'db_table': 'i_delete_card', 100 | 'verbose_name': 'IOS-\u5220\u9664\u94f6\u884c\u5361', 101 | 'verbose_name_plural': 'IOS-\u5220\u9664\u94f6\u884c\u5361', 102 | }, 103 | ), 104 | migrations.CreateModel( 105 | name='IOSTestCase13', 106 | fields=[ 107 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 108 | ('case_id', models.CharField(max_length=45)), 109 | ('case_name', models.CharField(max_length=45)), 110 | ('page', models.CharField(blank=True, max_length=60, null=True)), 111 | ('name', models.CharField(blank=True, max_length=45, null=True)), 112 | ('action', models.CharField(blank=True, max_length=45, null=True)), 113 | ('value', models.TextField(blank=True, null=True)), 114 | ('expected', models.TextField(blank=True, null=True)), 115 | ('actual', models.TextField(blank=True, editable=False, null=True)), 116 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 117 | ('state', models.IntegerField(default='1')), 118 | ], 119 | options={ 120 | 'ordering': ['id'], 121 | 'db_table': 'i_login', 122 | 'verbose_name': 'IOS-\u767b\u5f55APP', 123 | 'verbose_name_plural': 'IOS-\u767b\u5f55APP', 124 | }, 125 | ), 126 | migrations.CreateModel( 127 | name='IOSTestCase2', 128 | fields=[ 129 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 130 | ('case_id', models.CharField(max_length=45)), 131 | ('case_name', models.CharField(max_length=45)), 132 | ('page', models.CharField(blank=True, max_length=60, null=True)), 133 | ('name', models.CharField(blank=True, max_length=45, null=True)), 134 | ('action', models.CharField(blank=True, max_length=45, null=True)), 135 | ('value', models.TextField(blank=True, null=True)), 136 | ('expected', models.TextField(blank=True, null=True)), 137 | ('actual', models.TextField(blank=True, editable=False, null=True)), 138 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 139 | ('state', models.IntegerField(default='1')), 140 | ], 141 | options={ 142 | 'ordering': ['id'], 143 | 'db_table': 'i_disaster_project_released', 144 | 'verbose_name': 'IOS-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 145 | 'verbose_name_plural': 'IOS-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 146 | }, 147 | ), 148 | migrations.CreateModel( 149 | name='IOSTestCase3', 150 | fields=[ 151 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 152 | ('case_id', models.CharField(max_length=45)), 153 | ('case_name', models.CharField(max_length=45)), 154 | ('page', models.CharField(blank=True, max_length=60, null=True)), 155 | ('name', models.CharField(blank=True, max_length=45, null=True)), 156 | ('action', models.CharField(blank=True, max_length=45, null=True)), 157 | ('value', models.TextField(blank=True, null=True)), 158 | ('expected', models.TextField(blank=True, null=True)), 159 | ('actual', models.TextField(blank=True, editable=False, null=True)), 160 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 161 | ('state', models.IntegerField(default='1')), 162 | ], 163 | options={ 164 | 'ordering': ['id'], 165 | 'db_table': 'i_dream_project_released', 166 | 'verbose_name': 'IOS-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 167 | 'verbose_name_plural': 'IOS-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 168 | }, 169 | ), 170 | migrations.CreateModel( 171 | name='IOSTestCase4', 172 | fields=[ 173 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 174 | ('case_id', models.CharField(max_length=45)), 175 | ('case_name', models.CharField(max_length=45)), 176 | ('page', models.CharField(blank=True, max_length=60, null=True)), 177 | ('name', models.CharField(blank=True, max_length=45, null=True)), 178 | ('action', models.CharField(blank=True, max_length=45, null=True)), 179 | ('value', models.TextField(blank=True, null=True)), 180 | ('expected', models.TextField(blank=True, null=True)), 181 | ('actual', models.TextField(blank=True, editable=False, null=True)), 182 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 183 | ('state', models.IntegerField(default='1')), 184 | ], 185 | options={ 186 | 'ordering': ['id'], 187 | 'db_table': 'i_illness_project_released', 188 | 'verbose_name': 'IOS-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 189 | 'verbose_name_plural': 'IOS-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 190 | }, 191 | ), 192 | migrations.CreateModel( 193 | name='IOSTestCase5', 194 | fields=[ 195 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 196 | ('case_id', models.CharField(max_length=45)), 197 | ('case_name', models.CharField(max_length=45)), 198 | ('page', models.CharField(blank=True, max_length=60, null=True)), 199 | ('name', models.CharField(blank=True, max_length=45, null=True)), 200 | ('action', models.CharField(blank=True, max_length=45, null=True)), 201 | ('value', models.TextField(blank=True, null=True)), 202 | ('expected', models.TextField(blank=True, null=True)), 203 | ('actual', models.TextField(blank=True, editable=False, null=True)), 204 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 205 | ('state', models.IntegerField(default='1')), 206 | ], 207 | options={ 208 | 'ordering': ['id'], 209 | 'db_table': 'i_poverty_project_released', 210 | 'verbose_name': 'IOS-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 211 | 'verbose_name_plural': 'IOS-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 212 | }, 213 | ), 214 | migrations.CreateModel( 215 | name='IOSTestCase6', 216 | fields=[ 217 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 218 | ('case_id', models.CharField(max_length=45)), 219 | ('case_name', models.CharField(max_length=45)), 220 | ('page', models.CharField(blank=True, max_length=60, null=True)), 221 | ('name', models.CharField(blank=True, max_length=45, null=True)), 222 | ('action', models.CharField(blank=True, max_length=45, null=True)), 223 | ('value', models.TextField(blank=True, null=True)), 224 | ('expected', models.TextField(blank=True, null=True)), 225 | ('actual', models.TextField(blank=True, editable=False, null=True)), 226 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 227 | ('state', models.IntegerField(default='1')), 228 | ], 229 | options={ 230 | 'ordering': ['id'], 231 | 'db_table': 'i_presale_project_released', 232 | 'verbose_name': 'IOS-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 233 | 'verbose_name_plural': 'IOS-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 234 | }, 235 | ), 236 | migrations.CreateModel( 237 | name='IOSTestCase7', 238 | fields=[ 239 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 240 | ('case_id', models.CharField(max_length=45)), 241 | ('case_name', models.CharField(max_length=45)), 242 | ('page', models.CharField(blank=True, max_length=60, null=True)), 243 | ('name', models.CharField(blank=True, max_length=45, null=True)), 244 | ('action', models.CharField(blank=True, max_length=45, null=True)), 245 | ('value', models.TextField(blank=True, null=True)), 246 | ('expected', models.TextField(blank=True, null=True)), 247 | ('actual', models.TextField(blank=True, editable=False, null=True)), 248 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 249 | ('state', models.IntegerField(default='1')), 250 | ], 251 | options={ 252 | 'ordering': ['id'], 253 | 'db_table': 'i_other_project_released', 254 | 'verbose_name': 'IOS-\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 255 | 'verbose_name_plural': 'IOS-\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 256 | }, 257 | ), 258 | migrations.CreateModel( 259 | name='IOSTestCase8', 260 | fields=[ 261 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 262 | ('case_id', models.CharField(max_length=45)), 263 | ('case_name', models.CharField(max_length=45)), 264 | ('page', models.CharField(blank=True, max_length=60, null=True)), 265 | ('name', models.CharField(blank=True, max_length=45, null=True)), 266 | ('action', models.CharField(blank=True, max_length=45, null=True)), 267 | ('value', models.TextField(blank=True, null=True)), 268 | ('expected', models.TextField(blank=True, null=True)), 269 | ('actual', models.TextField(blank=True, editable=False, null=True)), 270 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 271 | ('state', models.IntegerField(default='1')), 272 | ], 273 | options={ 274 | 'ordering': ['id'], 275 | 'db_table': 'i_support_project', 276 | 'verbose_name': 'IOS-\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 277 | 'verbose_name_plural': 'IOS-\u652f\u6301\u5df2\u521b\u5efa\u7684\u9879\u76ee', 278 | }, 279 | ), 280 | migrations.CreateModel( 281 | name='IOSTestCase9', 282 | fields=[ 283 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 284 | ('case_id', models.CharField(max_length=45)), 285 | ('case_name', models.CharField(max_length=45)), 286 | ('page', models.CharField(blank=True, max_length=60, null=True)), 287 | ('name', models.CharField(blank=True, max_length=45, null=True)), 288 | ('action', models.CharField(blank=True, max_length=45, null=True)), 289 | ('value', models.TextField(blank=True, null=True)), 290 | ('expected', models.TextField(blank=True, null=True)), 291 | ('actual', models.TextField(blank=True, editable=False, null=True)), 292 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 293 | ('state', models.IntegerField(default='1')), 294 | ], 295 | options={ 296 | 'ordering': ['id'], 297 | 'db_table': 'i_check_personal', 298 | 'verbose_name': 'IOS-\u4e2a\u4eba\u4e2d\u5fc3', 299 | 'verbose_name_plural': 'IOS-\u4e2a\u4eba\u4e2d\u5fc3', 300 | }, 301 | ), 302 | ] 303 | -------------------------------------------------------------------------------- /ios/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/ios/migrations/__init__.py -------------------------------------------------------------------------------- /ios/models.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | # Create your models here. 6 | 7 | '''{'动物保护项目发布': 'i_animal_project_released', 8 | '灾难救助项目发布': 'i_disaster_project_released', 9 | '梦想清单项目发布': 'i_dream_project_released', 10 | '大病救助项目发布': 'i_illness_project_released', 11 | '扶贫助学项目发布': 'i_poverty_project_released', 12 | '尝鲜预售项目发布': 'i_presale_project_released', 13 | '支持已创建的项目': 'i_support_project', 14 | '其它项目发布': 'i_other_project_released', 15 | '个人中心': 'i_check_personal', 16 | '项目管理':'i_check_project', 17 | '查看个人项目发布':'i_check_build_project', 18 | '删除银行卡':'i_delete_card', 19 | '登录APP':'i_login', 20 | } 21 | ''' 22 | 23 | class IOSTestCase1(models.Model): 24 | id = models.AutoField(primary_key=True, editable=False) 25 | case_id = models.CharField(unique=True, max_length=45) 26 | case_name = models.CharField(max_length=45) 27 | page = models.CharField(max_length=60, null=True, blank=True) 28 | name = models.CharField(max_length=45, null=True, blank=True) 29 | action = models.CharField(max_length=45, null=True, blank=True) 30 | value = models.TextField(null=True, blank=True) 31 | expected = models.TextField(null=True, blank=True) 32 | actual = models.TextField(null=True, blank=True, editable=False) 33 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 34 | state = models.IntegerField(default='1') 35 | 36 | def __unicode__(self): 37 | return self.case_name 38 | 39 | class Meta: 40 | verbose_name = 'IOS-动物保护项目发布' 41 | verbose_name_plural = 'IOS-动物保护项目发布' 42 | ordering = ['case_id'] 43 | db_table = 'i_animal_project_released' 44 | 45 | class IOSTestCase2(models.Model): 46 | id = models.AutoField(primary_key=True, editable=False) 47 | case_id = models.CharField(unique=True, max_length=45) 48 | case_name = models.CharField(max_length=45) 49 | page = models.CharField(max_length=60, null=True, blank=True) 50 | name = models.CharField(max_length=45, null=True, blank=True) 51 | action = models.CharField(max_length=45, null=True, blank=True) 52 | value = models.TextField(null=True, blank=True) 53 | expected = models.TextField(null=True, blank=True) 54 | actual = models.TextField(null=True, blank=True, editable=False) 55 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 56 | state = models.IntegerField(default='1') 57 | 58 | def __unicode__(self): 59 | return self.case_name 60 | 61 | class Meta: 62 | verbose_name = 'IOS-灾难救助项目发布' 63 | verbose_name_plural = 'IOS-灾难救助项目发布' 64 | ordering = ['case_id'] 65 | db_table = 'i_disaster_project_released' 66 | 67 | class IOSTestCase3(models.Model): 68 | id = models.AutoField(primary_key=True, editable=False) 69 | case_id = models.CharField(unique=True, max_length=45) 70 | case_name = models.CharField(max_length=45) 71 | page = models.CharField(max_length=60, null=True, blank=True) 72 | name = models.CharField(max_length=45, null=True, blank=True) 73 | action = models.CharField(max_length=45, null=True, blank=True) 74 | value = models.TextField(null=True, blank=True) 75 | expected = models.TextField(null=True, blank=True) 76 | actual = models.TextField(null=True, blank=True, editable=False) 77 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 78 | state = models.IntegerField(default='1') 79 | 80 | def __unicode__(self): 81 | return self.case_name 82 | 83 | class Meta: 84 | verbose_name = 'IOS-梦想清单项目发布' 85 | verbose_name_plural = 'IOS-梦想清单项目发布' 86 | ordering = ['case_id'] 87 | db_table = 'i_dream_project_released' 88 | 89 | class IOSTestCase4(models.Model): 90 | id = models.AutoField(primary_key=True, editable=False) 91 | case_id = models.CharField(unique=True, max_length=45) 92 | case_name = models.CharField(max_length=45) 93 | page = models.CharField(max_length=60, null=True, blank=True) 94 | name = models.CharField(max_length=45, null=True, blank=True) 95 | action = models.CharField(max_length=45, null=True, blank=True) 96 | value = models.TextField(null=True, blank=True) 97 | expected = models.TextField(null=True, blank=True) 98 | actual = models.TextField(null=True, blank=True, editable=False) 99 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 100 | state = models.IntegerField(default='1') 101 | 102 | def __unicode__(self): 103 | return self.case_name 104 | 105 | class Meta: 106 | verbose_name = 'IOS-大病救助项目发布' 107 | verbose_name_plural = 'IOS-大病救助项目发布' 108 | ordering = ['case_id'] 109 | db_table = 'i_illness_project_released' 110 | 111 | class IOSTestCase5(models.Model): 112 | id = models.AutoField(primary_key=True, editable=False) 113 | case_id = models.CharField(unique=True, max_length=45) 114 | case_name = models.CharField(max_length=45) 115 | page = models.CharField(max_length=60, null=True, blank=True) 116 | name = models.CharField(max_length=45, null=True, blank=True) 117 | action = models.CharField(max_length=45, null=True, blank=True) 118 | value = models.TextField(null=True, blank=True) 119 | expected = models.TextField(null=True, blank=True) 120 | actual = models.TextField(null=True, blank=True, editable=False) 121 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 122 | state = models.IntegerField(default='1') 123 | 124 | def __unicode__(self): 125 | return self.case_name 126 | 127 | class Meta: 128 | verbose_name = 'IOS-扶贫助学项目发布' 129 | verbose_name_plural = 'IOS-扶贫助学项目发布' 130 | ordering = ['case_id'] 131 | db_table = 'i_poverty_project_released' 132 | 133 | class IOSTestCase6(models.Model): 134 | id = models.AutoField(primary_key=True, editable=False) 135 | case_id = models.CharField(unique=True, max_length=45) 136 | case_name = models.CharField(max_length=45) 137 | page = models.CharField(max_length=60, null=True, blank=True) 138 | name = models.CharField(max_length=45, null=True, blank=True) 139 | action = models.CharField(max_length=45, null=True, blank=True) 140 | value = models.TextField(null=True, blank=True) 141 | expected = models.TextField(null=True, blank=True) 142 | actual = models.TextField(null=True, blank=True, editable=False) 143 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 144 | state = models.IntegerField(default='1') 145 | 146 | def __unicode__(self): 147 | return self.case_name 148 | 149 | class Meta: 150 | verbose_name = 'IOS-尝鲜预售项目发布' 151 | verbose_name_plural = 'IOS-尝鲜预售项目发布' 152 | ordering = ['case_id'] 153 | db_table = 'i_presale_project_released' 154 | 155 | class IOSTestCase7(models.Model): 156 | id = models.AutoField(primary_key=True, editable=False) 157 | case_id = models.CharField(unique=True, max_length=45) 158 | case_name = models.CharField(max_length=45) 159 | page = models.CharField(max_length=60, null=True, blank=True) 160 | name = models.CharField(max_length=45, null=True, blank=True) 161 | action = models.CharField(max_length=45, null=True, blank=True) 162 | value = models.TextField(null=True, blank=True) 163 | expected = models.TextField(null=True, blank=True) 164 | actual = models.TextField(null=True, blank=True, editable=False) 165 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 166 | state = models.IntegerField(default='1') 167 | 168 | def __unicode__(self): 169 | return self.case_name 170 | 171 | class Meta: 172 | verbose_name = 'IOS-其它项目发布' 173 | verbose_name_plural = 'IOS-其它项目发布' 174 | ordering = ['case_id'] 175 | db_table = 'i_other_project_released' 176 | 177 | class IOSTestCase8(models.Model): 178 | id = models.AutoField(primary_key=True, editable=False) 179 | case_id = models.CharField(unique=True, max_length=45) 180 | case_name = models.CharField(max_length=45) 181 | page = models.CharField(max_length=60, null=True, blank=True) 182 | name = models.CharField(max_length=45, null=True, blank=True) 183 | action = models.CharField(max_length=45, null=True, blank=True) 184 | value = models.TextField(null=True, blank=True) 185 | expected = models.TextField(null=True, blank=True) 186 | actual = models.TextField(null=True, blank=True, editable=False) 187 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 188 | state = models.IntegerField(default='1') 189 | 190 | def __unicode__(self): 191 | return self.case_name 192 | 193 | class Meta: 194 | verbose_name = 'IOS-支持已创建的项目' 195 | verbose_name_plural = 'IOS-支持已创建的项目' 196 | ordering = ['case_id'] 197 | db_table = 'i_support_project' 198 | 199 | class IOSTestCase9(models.Model): 200 | id = models.AutoField(primary_key=True, editable=False) 201 | case_id = models.CharField(unique=True, max_length=45) 202 | case_name = models.CharField(max_length=45) 203 | page = models.CharField(max_length=60, null=True, blank=True) 204 | name = models.CharField(max_length=45, null=True, blank=True) 205 | action = models.CharField(max_length=45, null=True, blank=True) 206 | value = models.TextField(null=True, blank=True) 207 | expected = models.TextField(null=True, blank=True) 208 | actual = models.TextField(null=True, blank=True, editable=False) 209 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 210 | state = models.IntegerField(default='1') 211 | 212 | def __unicode__(self): 213 | return self.case_name 214 | 215 | class Meta: 216 | verbose_name = 'IOS-个人中心' 217 | verbose_name_plural = 'IOS-个人中心' 218 | ordering = ['case_id'] 219 | db_table = 'i_check_personal' 220 | 221 | class IOSTestCase10(models.Model): 222 | id = models.AutoField(primary_key=True, editable=False) 223 | case_id = models.CharField(unique=True, max_length=45) 224 | case_name = models.CharField(max_length=45) 225 | page = models.CharField(max_length=60, null=True, blank=True) 226 | name = models.CharField(max_length=45, null=True, blank=True) 227 | action = models.CharField(max_length=45, null=True, blank=True) 228 | value = models.TextField(null=True, blank=True) 229 | expected = models.TextField(null=True, blank=True) 230 | actual = models.TextField(null=True, blank=True, editable=False) 231 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 232 | state = models.IntegerField(default='1') 233 | 234 | def __unicode__(self): 235 | return self.case_name 236 | 237 | class Meta: 238 | verbose_name = 'IOS-项目管理' 239 | verbose_name_plural = 'IOS-项目管理' 240 | ordering = ['case_id'] 241 | db_table = 'i_check_project' 242 | 243 | class IOSTestCase11(models.Model): 244 | id = models.AutoField(primary_key=True, editable=False) 245 | case_id = models.CharField(unique=True, max_length=45) 246 | case_name = models.CharField(max_length=45) 247 | page = models.CharField(max_length=60, null=True, blank=True) 248 | name = models.CharField(max_length=45, null=True, blank=True) 249 | action = models.CharField(max_length=45, null=True, blank=True) 250 | value = models.TextField(null=True, blank=True) 251 | expected = models.TextField(null=True, blank=True) 252 | actual = models.TextField(null=True, blank=True, editable=False) 253 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 254 | state = models.IntegerField(default='1') 255 | 256 | def __unicode__(self): 257 | return self.case_name 258 | 259 | class Meta: 260 | verbose_name = 'IOS-查看个人项目发布' 261 | verbose_name_plural = 'IOS-查看个人项目发布' 262 | ordering = ['case_id'] 263 | db_table = 'i_check_build_project' 264 | 265 | class IOSTestCase12(models.Model): 266 | id = models.AutoField(primary_key=True, editable=False) 267 | case_id = models.CharField(unique=True, max_length=45) 268 | case_name = models.CharField(max_length=45) 269 | page = models.CharField(max_length=60, null=True, blank=True) 270 | name = models.CharField(max_length=45, null=True, blank=True) 271 | action = models.CharField(max_length=45, null=True, blank=True) 272 | value = models.TextField(null=True, blank=True) 273 | expected = models.TextField(null=True, blank=True) 274 | actual = models.TextField(null=True, blank=True, editable=False) 275 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 276 | state = models.IntegerField(default='1') 277 | 278 | def __unicode__(self): 279 | return self.case_name 280 | 281 | class Meta: 282 | verbose_name = 'IOS-删除银行卡' 283 | verbose_name_plural = 'IOS-删除银行卡' 284 | ordering = ['case_id'] 285 | db_table = 'i_delete_card' 286 | 287 | class IOSTestCase13(models.Model): 288 | id = models.AutoField(primary_key=True, editable=False) 289 | case_id = models.CharField(unique=True, max_length=45) 290 | case_name = models.CharField(max_length=45) 291 | page = models.CharField(max_length=60, null=True, blank=True) 292 | name = models.CharField(max_length=45, null=True, blank=True) 293 | action = models.CharField(max_length=45, null=True, blank=True) 294 | value = models.TextField(null=True, blank=True) 295 | expected = models.TextField(null=True, blank=True) 296 | actual = models.TextField(null=True, blank=True, editable=False) 297 | result = models.CharField(max_length=5, null=True, blank=True, editable=False) 298 | state = models.IntegerField(default='1') 299 | 300 | def __unicode__(self): 301 | return self.case_name 302 | 303 | class Meta: 304 | verbose_name = 'IOS-登录APP' 305 | verbose_name_plural = 'IOS-登录APP' 306 | ordering = ['case_id'] 307 | db_table = 'i_login' -------------------------------------------------------------------------------- /ios/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /ios/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myweb.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /myweb/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/myweb/__init__.py -------------------------------------------------------------------------------- /myweb/settings.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Django settings for myweb project. 4 | 5 | Generated by 'django-admin startproject' using Django 1.9.7. 6 | 7 | For more information on this file, see 8 | https://docs.djangoproject.com/en/1.9/topics/settings/ 9 | 10 | For the full list of settings and their values, see 11 | https://docs.djangoproject.com/en/1.9/ref/settings/ 12 | """ 13 | 14 | import os 15 | from django.conf.locale.zh_Hans import formats as es_formats 16 | 17 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 18 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 19 | 20 | 21 | # Quick-start development settings - unsuitable for production 22 | # See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/ 23 | 24 | # SECURITY WARNING: keep the secret key used in production secret! 25 | SECRET_KEY = '4$u7d(ir%rcizuk+r5134_8=8nz)22h&^u2n_iss7^^^=qpxoe' 26 | 27 | # SECURITY WARNING: don't run with debug turned on in production! 28 | DEBUG = True 29 | 30 | ALLOWED_HOSTS = [] 31 | 32 | 33 | # Application definition 34 | 35 | INSTALLED_APPS = [ 36 | # 'django.contrib.admin', 37 | 'xadmin', 38 | 'crispy_forms', 39 | 'reversion', 40 | 'django.contrib.auth', 41 | 'django.contrib.contenttypes', 42 | 'django.contrib.sessions', 43 | 'django.contrib.messages', 44 | 'django.contrib.staticfiles', 45 | 'interface', 46 | 'h5', 47 | 'android', 48 | 'ios', 49 | 'pc', 50 | 'bootstrap3', 51 | ] 52 | 53 | MIDDLEWARE_CLASSES = [ 54 | 'django.middleware.security.SecurityMiddleware', 55 | 'django.contrib.sessions.middleware.SessionMiddleware', 56 | 'django.middleware.common.CommonMiddleware', 57 | 'django.middleware.csrf.CsrfViewMiddleware', 58 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 59 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 60 | 'django.contrib.messages.middleware.MessageMiddleware', 61 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 62 | # 'django.middleware.locale.LocaleMiddleware' 63 | ] 64 | 65 | ROOT_URLCONF = 'myweb.urls' 66 | 67 | TEMPLATES = [ 68 | { 69 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 70 | 'DIRS': [[os.path.join(BASE_DIR, "templates")]], 71 | 'APP_DIRS': True, 72 | 'OPTIONS': { 73 | 'context_processors': [ 74 | 'django.template.context_processors.debug', 75 | 'django.template.context_processors.request', 76 | 'django.contrib.auth.context_processors.auth', 77 | 'django.contrib.messages.context_processors.messages', 78 | ], 79 | }, 80 | }, 81 | ] 82 | 83 | WSGI_APPLICATION = 'myweb.wsgi.application' 84 | 85 | 86 | # Database 87 | # https://docs.djangoproject.com/en/1.9/ref/settings/#databases 88 | 89 | DATABASES = { 90 | 'default': { 91 | # 'ENGINE': 'django.db.backends.sqlite3', 92 | # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 93 | 'ENGINE': 'django.db.backends.mysql', 94 | 'HOST': '172.16.10.83', 95 | 'PORT': '3306', 96 | 'NAME': 'myweb', 97 | 'USER': 'root', 98 | 'PASSWORD': '12345678', 99 | } 100 | } 101 | 102 | 103 | # Password validation 104 | # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 105 | 106 | AUTH_PASSWORD_VALIDATORS = [ 107 | { 108 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 109 | }, 110 | { 111 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 112 | }, 113 | { 114 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 115 | }, 116 | { 117 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 118 | }, 119 | ] 120 | 121 | 122 | # Internationalization 123 | # https://docs.djangoproject.com/en/1.9/topics/i18n/ 124 | 125 | LANGUAGE_CODE = 'zh-hans' 126 | 127 | TIME_ZONE = 'Asia/Shanghai' 128 | 129 | USE_I18N = True 130 | 131 | USE_L10N = True 132 | 133 | # USE_TZ = True 134 | 135 | 136 | # Static files (CSS, JavaScript, Images) 137 | # https://docs.djangoproject.com/en/1.9/howto/static-files/ 138 | gettext_noop = lambda s: s 139 | # 语言 140 | LANGUAGE = ( 141 | ('de', gettext_noop('German')), 142 | ('en', gettext_noop('English')), 143 | ('ja', gettext_noop('Japanese')), 144 | ('lt', gettext_noop('Lithuanian')), 145 | ('nl', gettext_noop('Dutch')), 146 | ('pl', gettext_noop('Polish')), 147 | ('pt', gettext_noop('Portuguese')), 148 | ('zh_hans', gettext_noop('Simplified Chinese')), 149 | ) 150 | 151 | # xadmin配置文件 152 | XADMIN_CONF = 'myweb.xsite' 153 | DATE_FORMAT = 'Y-m-d' 154 | # DATETIME_FORMAT = 'm-d H:i:sO' 155 | es_formats.DATETIME_FORMAT = "n/j H:i:s" 156 | TIME_FORMAT = 'H:i' 157 | FILE_CHARSET = 'utf-8' 158 | DEFAULT_CHARSET = 'utf-8' 159 | STATIC_URL = '/static/' 160 | 161 | 162 | EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' 163 | 164 | EMAIL_USE_TLS = True 165 | EMAIL_HOST = 'smtp.exmail.qq.com' 166 | EMAIL_PORT = 465 167 | EMAIL_HOST_USER = '***********************' 168 | EMAIL_HOST_PASSWORD = '****************' 169 | DEFAULT_FROM_EMAIL = '**************' -------------------------------------------------------------------------------- /myweb/urls.py: -------------------------------------------------------------------------------- 1 | """myweb URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.9/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | # from django.contrib import admin 18 | from interface.views import interface_testcase 19 | from android.views import android_testcase 20 | from h5.views import h5_testcase 21 | from pc.views import pc_testcase 22 | import xadmin 23 | xadmin.autodiscover() 24 | from xadmin.plugins import xversion 25 | xversion.register_models() 26 | 27 | urlpatterns = [ 28 | url(r'^admin/', xadmin.site.urls), 29 | url(r'^h5/$', h5_testcase), 30 | url(r'^$', android_testcase), 31 | url(r'^android/$', android_testcase), 32 | url(r'^interface/$', interface_testcase), 33 | url(r'^pc/$', pc_testcase), 34 | ] 35 | -------------------------------------------------------------------------------- /myweb/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myweb project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.9/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | import sys 12 | from os.path import dirname, abspath 13 | from django.core.wsgi import get_wsgi_application 14 | 15 | PROJECT_DIR = dirname(dirname(abspath(__file__))) 16 | 17 | sys.path.insert(0, PROJECT_DIR) 18 | 19 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myweb.settings") 20 | 21 | application = get_wsgi_application() -------------------------------------------------------------------------------- /myweb/xsite.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | from xadmin import Settings 3 | from xadmin.views.list import ListAdminView 4 | from xadmin.views import CommAdminView 5 | from xadmin.plugins.actions import BaseActionView,ActionPlugin 6 | from django.http import HttpResponse, HttpResponseRedirect 7 | class Base(Settings): 8 | enable_themes = True 9 | use_bootswatch = True 10 | # menu_style = 'default' 11 | # class List(ListAdminView): 12 | # ListAdminView.list_per_page = 20 13 | 14 | class GlobalSetting(CommAdminView): 15 | CommAdminView.site_title = u'自动化测试用例管理' 16 | CommAdminView.site_footer = u'轻松筹' 17 | 18 | class Comm(Settings): 19 | menu_style = 'accordion' 20 | 21 | 22 | -------------------------------------------------------------------------------- /pc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/pc/__init__.py -------------------------------------------------------------------------------- /pc/adminx.py: -------------------------------------------------------------------------------- 1 | import xadmin 2 | from pc.models import * 3 | 4 | # Register your models here. 5 | class PCTestCaseAdmin(object): 6 | list_display = ('case_id', 'case_name', 'url', 'name', 'action','value', 7 | 'expected', 'actual', 'result', 'state') 8 | search_fields = ('case_id', 'case_name', 'url', 'name', 'action', 'value', 9 | 'expected', 'actual', 'result', 'state') 10 | 11 | xadmin.site.register(PCTestCase1, PCTestCaseAdmin) 12 | xadmin.site.register(PCTestCase2, PCTestCaseAdmin) 13 | xadmin.site.register(PCTestCase3, PCTestCaseAdmin) 14 | xadmin.site.register(PCTestCase4, PCTestCaseAdmin) 15 | xadmin.site.register(PCTestCase5, PCTestCaseAdmin) 16 | xadmin.site.register(PCTestCase6, PCTestCaseAdmin) 17 | xadmin.site.register(PCTestCase7, PCTestCaseAdmin) 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /pc/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class PcConfig(AppConfig): 7 | name = 'pc' 8 | -------------------------------------------------------------------------------- /pc/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.9.7 on 2016-10-14 09:13 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='PCTestCase1', 18 | fields=[ 19 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 20 | ('case_id', models.CharField(max_length=45)), 21 | ('case_name', models.CharField(max_length=45)), 22 | ('url', models.URLField(blank=True, null=True)), 23 | ('name', models.CharField(blank=True, max_length=45, null=True)), 24 | ('action', models.CharField(blank=True, max_length=45, null=True)), 25 | ('value', models.TextField(blank=True, null=True)), 26 | ('expected', models.TextField(blank=True, null=True)), 27 | ('actual', models.TextField(blank=True, editable=False, null=True)), 28 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 29 | ('state', models.IntegerField(default='1')), 30 | ], 31 | options={ 32 | 'ordering': ['id'], 33 | 'db_table': 'p_illness_project_released', 34 | 'verbose_name': 'PC-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 35 | 'verbose_name_plural': 'PC-\u5927\u75c5\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 36 | }, 37 | ), 38 | migrations.CreateModel( 39 | name='PCTestCase2', 40 | fields=[ 41 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 42 | ('case_id', models.CharField(max_length=45)), 43 | ('case_name', models.CharField(max_length=45)), 44 | ('url', models.URLField(blank=True, null=True)), 45 | ('name', models.CharField(blank=True, max_length=45, null=True)), 46 | ('action', models.CharField(blank=True, max_length=45, null=True)), 47 | ('value', models.TextField(blank=True, null=True)), 48 | ('expected', models.TextField(blank=True, null=True)), 49 | ('actual', models.TextField(blank=True, editable=False, null=True)), 50 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 51 | ('state', models.IntegerField(default='1')), 52 | ], 53 | options={ 54 | 'ordering': ['id'], 55 | 'db_table': 'p_disaster_project_released', 56 | 'verbose_name': 'PC-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 57 | 'verbose_name_plural': 'PC-\u707e\u96be\u6551\u52a9\u9879\u76ee\u53d1\u5e03', 58 | }, 59 | ), 60 | migrations.CreateModel( 61 | name='PCTestCase3', 62 | fields=[ 63 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 64 | ('case_id', models.CharField(max_length=45)), 65 | ('case_name', models.CharField(max_length=45)), 66 | ('url', models.URLField(blank=True, null=True)), 67 | ('name', models.CharField(blank=True, max_length=45, null=True)), 68 | ('action', models.CharField(blank=True, max_length=45, null=True)), 69 | ('value', models.TextField(blank=True, null=True)), 70 | ('expected', models.TextField(blank=True, null=True)), 71 | ('actual', models.TextField(blank=True, editable=False, null=True)), 72 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 73 | ('state', models.IntegerField(default='1')), 74 | ], 75 | options={ 76 | 'ordering': ['id'], 77 | 'db_table': 'p_animal_project_released', 78 | 'verbose_name': 'PC-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 79 | 'verbose_name_plural': 'PC-\u52a8\u7269\u4fdd\u62a4\u9879\u76ee\u53d1\u5e03', 80 | }, 81 | ), 82 | migrations.CreateModel( 83 | name='PCTestCase4', 84 | fields=[ 85 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 86 | ('case_id', models.CharField(max_length=45)), 87 | ('case_name', models.CharField(max_length=45)), 88 | ('url', models.URLField(blank=True, null=True)), 89 | ('name', models.CharField(blank=True, max_length=45, null=True)), 90 | ('action', models.CharField(blank=True, max_length=45, null=True)), 91 | ('value', models.TextField(blank=True, null=True)), 92 | ('expected', models.TextField(blank=True, null=True)), 93 | ('actual', models.TextField(blank=True, editable=False, null=True)), 94 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 95 | ('state', models.IntegerField(default='1')), 96 | ], 97 | options={ 98 | 'ordering': ['id'], 99 | 'db_table': 'p_poverty_project_released', 100 | 'verbose_name': 'PC-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 101 | 'verbose_name_plural': 'PC-\u6276\u8d2b\u52a9\u5b66\u9879\u76ee\u53d1\u5e03', 102 | }, 103 | ), 104 | migrations.CreateModel( 105 | name='PCTestCase5', 106 | fields=[ 107 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 108 | ('case_id', models.CharField(max_length=45)), 109 | ('case_name', models.CharField(max_length=45)), 110 | ('url', models.URLField(blank=True, null=True)), 111 | ('name', models.CharField(blank=True, max_length=45, null=True)), 112 | ('action', models.CharField(blank=True, max_length=45, null=True)), 113 | ('value', models.TextField(blank=True, null=True)), 114 | ('expected', models.TextField(blank=True, null=True)), 115 | ('actual', models.TextField(blank=True, editable=False, null=True)), 116 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 117 | ('state', models.IntegerField(default='1')), 118 | ], 119 | options={ 120 | 'ordering': ['id'], 121 | 'db_table': 'p_other_project_released', 122 | 'verbose_name': 'PC-\u5176\u4ed6\u9879\u76ee\u53d1\u5e03', 123 | 'verbose_name_plural': 'PC-\u5176\u5b83\u9879\u76ee\u53d1\u5e03', 124 | }, 125 | ), 126 | migrations.CreateModel( 127 | name='PCTestCase6', 128 | fields=[ 129 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 130 | ('case_id', models.CharField(max_length=45)), 131 | ('case_name', models.CharField(max_length=45)), 132 | ('url', models.URLField(blank=True, null=True)), 133 | ('name', models.CharField(blank=True, max_length=45, null=True)), 134 | ('action', models.CharField(blank=True, max_length=45, null=True)), 135 | ('value', models.TextField(blank=True, null=True)), 136 | ('expected', models.TextField(blank=True, null=True)), 137 | ('actual', models.TextField(blank=True, editable=False, null=True)), 138 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 139 | ('state', models.IntegerField(default='1')), 140 | ], 141 | options={ 142 | 'ordering': ['id'], 143 | 'db_table': 'p_presale_project_released', 144 | 'verbose_name': 'PC-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 145 | 'verbose_name_plural': 'PC-\u5c1d\u9c9c\u9884\u552e\u9879\u76ee\u53d1\u5e03', 146 | }, 147 | ), 148 | migrations.CreateModel( 149 | name='PCTestCase7', 150 | fields=[ 151 | ('id', models.AutoField(editable=False, primary_key=True, serialize=False)), 152 | ('case_id', models.CharField(max_length=45)), 153 | ('case_name', models.CharField(max_length=45)), 154 | ('url', models.URLField(blank=True, null=True)), 155 | ('name', models.CharField(blank=True, max_length=45, null=True)), 156 | ('action', models.CharField(blank=True, max_length=45, null=True)), 157 | ('value', models.TextField(blank=True, null=True)), 158 | ('expected', models.TextField(blank=True, null=True)), 159 | ('actual', models.TextField(blank=True, editable=False, null=True)), 160 | ('result', models.CharField(blank=True, editable=False, max_length=5, null=True)), 161 | ('state', models.IntegerField(default='1')), 162 | ], 163 | options={ 164 | 'ordering': ['id'], 165 | 'db_table': 'p_dream_project_released', 166 | 'verbose_name': 'PC-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 167 | 'verbose_name_plural': 'PC-\u68a6\u60f3\u6e05\u5355\u9879\u76ee\u53d1\u5e03', 168 | }, 169 | ), 170 | ] 171 | -------------------------------------------------------------------------------- /pc/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/pc/migrations/__init__.py -------------------------------------------------------------------------------- /pc/models.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models 5 | # Create your models here. 6 | 7 | '''{'动物保护项目发布': 'p_animal_project_released', 8 | '灾难救助项目发布': 'p_disaster_project_released', 9 | '梦想清单项目发布': 'p_dream_project_released', 10 | '大病救助项目发布': 'p_illness_project_released', 11 | '扶贫助学项目发布': 'p_poverty_project_released', 12 | '尝鲜预售项目发布': 'p_presale_project_released', 13 | '其它项目发布': 'p_other_project_released', 14 | } 15 | ''' 16 | ACTION_LIST = (('click',u'点击'), 17 | ('sendkey',u'输入'), 18 | ('sendkeys',u'输入(不清除)'), 19 | ('scroll',u'滚动'), 20 | ('swipe',u'滑动'), 21 | ('sleep',u'等待'), 22 | ('back',u'返回'), 23 | ) 24 | class PCTestCase1(models.Model): 25 | id = models.AutoField(primary_key=True, editable=False) 26 | case_id = models.CharField(unique=True, max_length=45) 27 | case_name = models.CharField(max_length=45) 28 | url = models.URLField(null=True,blank=True) 29 | name = models.CharField(max_length=45, null=True,blank=True) 30 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 31 | value = models.TextField(null=True,blank=True) 32 | expected = models.TextField(null=True,blank=True) 33 | actual = models.TextField(null=True,blank=True, editable=False) 34 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 35 | state = models.IntegerField(default='1') 36 | 37 | def __unicode__(self): 38 | return self.case_name 39 | 40 | class Meta: 41 | verbose_name = 'PC-大病救助项目发布' 42 | verbose_name_plural = 'PC-大病救助项目发布' 43 | ordering = ['case_id'] 44 | db_table = 'p_illness_project_released' 45 | 46 | class PCTestCase2(models.Model): 47 | id = models.AutoField(primary_key=True, editable=False) 48 | case_id = models.CharField(unique=True, max_length=45) 49 | case_name = models.CharField(max_length=45) 50 | url = models.URLField(null=True,blank=True) 51 | name = models.CharField(max_length=45, null=True,blank=True) 52 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 53 | value = models.TextField(null=True,blank=True) 54 | expected = models.TextField(null=True,blank=True) 55 | actual = models.TextField(null=True,blank=True, editable=False) 56 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 57 | state = models.IntegerField(default='1') 58 | 59 | def __unicode__(self): 60 | return self.case_name 61 | 62 | class Meta: 63 | verbose_name = 'PC-灾难救助项目发布' 64 | verbose_name_plural = 'PC-灾难救助项目发布' 65 | ordering = ['case_id'] 66 | db_table = 'p_disaster_project_released' 67 | 68 | class PCTestCase3(models.Model): 69 | id = models.AutoField(primary_key=True, editable=False) 70 | case_id = models.CharField(unique=True, max_length=45) 71 | case_name = models.CharField(max_length=45) 72 | url = models.URLField(null=True,blank=True) 73 | name = models.CharField(max_length=45, null=True,blank=True) 74 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 75 | value = models.TextField(null=True,blank=True) 76 | expected = models.TextField(null=True,blank=True) 77 | actual = models.TextField(null=True,blank=True, editable=False) 78 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 79 | state = models.IntegerField(default='1') 80 | 81 | def __unicode__(self): 82 | return self.case_name 83 | 84 | class Meta: 85 | verbose_name = 'PC-动物保护项目发布' 86 | verbose_name_plural = 'PC-动物保护项目发布' 87 | ordering = ['case_id'] 88 | db_table = 'p_animal_project_released' 89 | 90 | class PCTestCase4(models.Model): 91 | id = models.AutoField(primary_key=True, editable=False) 92 | case_id = models.CharField(unique=True, max_length=45) 93 | case_name = models.CharField(max_length=45) 94 | url = models.URLField(null=True,blank=True) 95 | name = models.CharField(max_length=45, null=True,blank=True) 96 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 97 | value = models.TextField(null=True,blank=True) 98 | expected = models.TextField(null=True,blank=True) 99 | actual = models.TextField(null=True,blank=True, editable=False) 100 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 101 | state = models.IntegerField(default='1') 102 | 103 | def __unicode__(self): 104 | return self.case_name 105 | 106 | class Meta: 107 | verbose_name = 'PC-扶贫助学项目发布' 108 | verbose_name_plural = 'PC-扶贫助学项目发布' 109 | ordering = ['case_id'] 110 | db_table = 'p_poverty_project_released' 111 | 112 | 113 | class PCTestCase5(models.Model): 114 | id = models.AutoField(primary_key=True, editable=False) 115 | case_id = models.CharField(unique=True, max_length=45) 116 | case_name = models.CharField(max_length=45) 117 | url = models.URLField(null=True,blank=True) 118 | name = models.CharField(max_length=45, null=True,blank=True) 119 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 120 | value = models.TextField(null=True,blank=True) 121 | expected = models.TextField(null=True,blank=True) 122 | actual = models.TextField(null=True,blank=True, editable=False) 123 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 124 | state = models.IntegerField(default='1') 125 | 126 | def __unicode__(self): 127 | return self.case_name 128 | 129 | class Meta: 130 | verbose_name = 'PC-其他项目发布' 131 | verbose_name_plural = 'PC-其它项目发布' 132 | ordering = ['case_id'] 133 | db_table = 'p_other_project_released' 134 | 135 | 136 | class PCTestCase6(models.Model): 137 | id = models.AutoField(primary_key=True, editable=False) 138 | case_id = models.CharField(unique=True, max_length=45) 139 | case_name = models.CharField(max_length=45) 140 | url = models.URLField(null=True,blank=True) 141 | name = models.CharField(max_length=45, null=True,blank=True) 142 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 143 | value = models.TextField(null=True,blank=True) 144 | expected = models.TextField(null=True,blank=True) 145 | actual = models.TextField(null=True,blank=True, editable=False) 146 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 147 | state = models.IntegerField(default='1') 148 | 149 | def __unicode__(self): 150 | return self.case_name 151 | 152 | class Meta: 153 | verbose_name = 'PC-尝鲜预售项目发布' 154 | verbose_name_plural = 'PC-尝鲜预售项目发布' 155 | ordering = ['case_id'] 156 | db_table = 'p_presale_project_released' 157 | 158 | class PCTestCase7(models.Model): 159 | id = models.AutoField(primary_key=True, editable=False) 160 | case_id = models.CharField(unique=True, max_length=45) 161 | case_name = models.CharField(max_length=45) 162 | url = models.URLField(null=True,blank=True) 163 | name = models.CharField(max_length=45, null=True,blank=True) 164 | action = models.CharField(max_length=10, null=True,blank=True,choices=ACTION_LIST) 165 | value = models.TextField(null=True,blank=True) 166 | expected = models.TextField(null=True,blank=True) 167 | actual = models.TextField(null=True,blank=True, editable=False) 168 | result = models.CharField(max_length=5, null=True,blank=True, editable=False) 169 | state = models.IntegerField(default='1') 170 | 171 | def __unicode__(self): 172 | return self.case_name 173 | 174 | class Meta: 175 | verbose_name = 'PC-梦想清单项目发布' 176 | verbose_name_plural = 'PC-梦想清单项目发布' 177 | ordering = ['case_id'] 178 | db_table = 'p_dream_project_released' 179 | 180 | -------------------------------------------------------------------------------- /pc/templates/pc_testcase.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {# Load the tag library #} 6 | {% load bootstrap3 %} 7 | 8 | {# Load CSS and JavaScript #} 9 | {% bootstrap_css %} 10 | {% bootstrap_javascript %} 11 | 12 | {# Display django.contrib.messages as Bootstrap alerts #} 13 | {% bootstrap_messages %} 14 | 15 | 16 | 17 | 30 |
31 |
32 |
33 |

PC测试用例

34 |
35 | 44 |
45 | Go Jenkins 46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {% for testcase in testcase_list %} 60 | {% for k in testcase %} 61 | 62 | {% endfor %} 63 | 64 | {% endfor %} 65 |
Case_idCase_nameUrlNameActionValueExpectedActualRestultStatus
{{ k }}
66 | 67 |
68 | 81 | 90 | 91 | 112 | 115 | 116 |
-------------------------------------------------------------------------------- /pc/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /pc/views.py: -------------------------------------------------------------------------------- 1 | #-*-coding:utf-8-*- 2 | from django.shortcuts import render 3 | from django.shortcuts import render_to_response 4 | from django.db import connection 5 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger 6 | 7 | def pc_testcase(request): 8 | # print request.GET.get('table', '') 9 | if request.GET.get('table', ''): 10 | table = request.GET.get('table', '').split('-')[0] 11 | # print state,table 12 | sql = 'select case_id,case_name,url,name,action,value,expected,actual,result,state from ' + table 13 | else: 14 | table = 'p_illness_project_released' 15 | sql = 'select case_id,case_name,url,name,action,value,expected,actual,result,state from p_illness_project_released' 16 | 17 | list = [] 18 | sql2 = "select * from index_table where index_id = 3" 19 | cursor = connection.cursor() 20 | cursor.execute(sql, None) 21 | cursor2 = connection.cursor() 22 | cursor2.execute(sql2, None) 23 | col_names = [desc[0] for desc in cursor2.description] 24 | # print col_names 25 | caselist = cursor.fetchall() 26 | # print caselist 27 | # table_list = cursor2.fetchall() 28 | #返回数据库index_table表的数据 29 | for row in cursor2.fetchall(): 30 | # row=cursor2.fetchall() 31 | list.append(dict(zip(col_names, row))) 32 | # print list 33 | # print table_list 34 | # 对数据库中测试用例表进行分页查询 35 | paginator = Paginator(caselist, 15) # Show 15 contacts per page 36 | page = request.GET.get('page') 37 | try: 38 | contacts = paginator.page(page) 39 | except PageNotAnInteger: 40 | # If page is not an integer, deliver first page. 41 | contacts = paginator.page(1) 42 | except EmptyPage: 43 | # If page is out of range (e.g. 9999), deliver last page of results. 44 | contacts = paginator.page(paginator.num_pages) 45 | 46 | return render_to_response('pc_testcase.html', {'testcase_list': contacts, 'table_list': list, 'table': table}) -------------------------------------------------------------------------------- /qsc_interfacetest/Interface/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/Interface/__init__.py -------------------------------------------------------------------------------- /qsc_interfacetest/README.md: -------------------------------------------------------------------------------- 1 | ```接口自动化测试框架 2 | 采用python request库进行接口的post、get、delete...请求 -------------------------------------------------------------------------------- /qsc_interfacetest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/__init__.py -------------------------------------------------------------------------------- /qsc_interfacetest/db_fixture/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/db_fixture/__init__.py -------------------------------------------------------------------------------- /qsc_interfacetest/db_fixture/data.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/db_fixture/data.py -------------------------------------------------------------------------------- /qsc_interfacetest/db_fixture/mysql_setting.py: -------------------------------------------------------------------------------- 1 | # __author__ = 'zzy' 2 | #-*-coding:utf-8-*- 3 | 4 | import pymysql 5 | 6 | # =========设置连接测试是数据库======== 7 | host = '172.16.10.83' 8 | user = 'root' 9 | password = '12345678' 10 | db = 'myweb' 11 | 12 | # =========Mysql操作=============== 13 | class MySQLOperating(object): 14 | def __init__(self): 15 | try: 16 | #Connect to the database 17 | self.connection = pymysql.connect(host = host, 18 | user = user, 19 | password = password, 20 | db = db, 21 | charset = 'utf8mb4', 22 | cursorclass = pymysql.cursors.DictCursor) 23 | except pymysql.err.OperationalError as e: 24 | print 'Mysql Error %d: %s' % (e.args[0],e.args[1]) 25 | 26 | #向数据库中插入数据 27 | def insert(self, table_name, data): 28 | for key in data: 29 | data[key] = "'" + str(data[key]) + "'" 30 | key = ','.join(data.keys()) 31 | value = ','.join(data.values()) 32 | sql = "INSERT INTO " + table_name + " (" + key + ") VALUES (" + value +")" 33 | 34 | 35 | with self.connection: 36 | cur = self.connection.cursor() 37 | try: 38 | cur.execute(sql) 39 | # print 'execute sql success' 40 | # except: 41 | # print 'execute sql fail' 42 | except pymysql.err.OperationalError as e: 43 | print 'Mysql Error %d: %s' % (e.args[0], e.args[1]) 44 | 45 | #测试用例执行结果、接口返回数据、接口返回时间数据写入数据库: 46 | def set_InterfaceTableValue(self,table,case_id,key,value): 47 | sql = '''UPDATE %s SET %s = '%s' WHERE case_id = '%s' ''' %(table,key,value,case_id) 48 | with self.connection: 49 | cur = self.connection.cursor() 50 | cur.execute('SET NAMES utf8mb4;') 51 | try: 52 | # print sql 53 | cur.execute(sql) 54 | # print 'execute sql success' 55 | except pymysql.err.InternalError as e: 56 | print 'Mysql Error %d: %s' % (e.args[0], e.args[1]) 57 | 58 | #接口返回数据作为引用参数写入数据库,如:torken,id 59 | def set_ConfigTableValue(self,key,value,state=1): 60 | if self.get_ConfigTableValue(key) == None: 61 | sql = "INSERT INTO interface_config (name,value,state) VALUES ('%s','%s','%s')" %(key, value ,state) 62 | # print '新增引用参数' 63 | else: 64 | sql = "UPDATE interface_config SET value = '%s' WHERE name = '%s'" %(value, key) 65 | # print sql 66 | # print '更新引用参数' 67 | with self.connection: 68 | cur = self.connection.cursor() 69 | try: 70 | # print sql 71 | cur.execute(sql) 72 | # print 'execute sql success' 73 | except pymysql.err.InternalError as e: 74 | print 'Mysql Error %d: %s' % (e.args[0], e.args[1]) 75 | 76 | #获取数据库对应表中的所有测试用例,返回list 77 | def get_caselist(self,table_name): 78 | sql = "SELECT case_id,case_name,request_type,url,parameters,body,expected,not_expected,actual,config,state FROM %s" % table_name 79 | with self.connection: 80 | cur = self.connection.cursor() 81 | try: 82 | cur.execute(sql) 83 | testcases_list = cur.fetchall() 84 | return testcases_list 85 | except: 86 | print 'get case error' 87 | return None 88 | #获取接口返回的引用参数 89 | def get_ConfigTableValue(self,key): 90 | sql = "SELECT value FROM interface_config WHERE name = '%s'" % key 91 | with self.connection: 92 | cur = self.connection.cursor() 93 | try: 94 | cur.execute(sql) 95 | value = cur.fetchone() 96 | # print 'execute sql success' 97 | if value == None: 98 | return None 99 | else: 100 | return value['value'] 101 | except pymysql.err.InternalError as e: 102 | print 'Mysql Error %d: %s' % (e.args[0], e.args[1]) 103 | 104 | def get_InterfaceTableValue(self, case_id, key): 105 | sql = "SELECT %s FROM interface_test1 WHERE case_id = '%s'" %(key,case_id) 106 | with self.connection: 107 | cur = self.connection.cursor() 108 | try: 109 | cur.execute(sql) 110 | value = cur.fetchone() 111 | print 'execute sql success' 112 | return value 113 | except pymysql.err.InternalError as e: 114 | print 'Mysql Error %d: %s' % (e.args[0], e.args[1]) 115 | 116 | 117 | if __name__ == '__main__': 118 | db = MySQLOperating() 119 | # db.set_InterfaceTableValue('test_1','paraeters',0) 120 | # testcaselist = db.get_caselist('interface_test') 121 | # for testcasedict in testcaselist: 122 | # # print testcasedict 123 | # for key in testcasedict: 124 | # print '%s:%s' %(key,testcasedict[key]) 125 | # print '=' * 20 126 | print db.get_InterfaceTableValue('test_1','body') 127 | # db.set_ConfigTableValue('[access_token]','1111') 128 | print db.get_ConfigTableValue('[access_token]') -------------------------------------------------------------------------------- /qsc_interfacetest/report/log/log.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /qsc_interfacetest/test_case/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/test_case/__init__.py -------------------------------------------------------------------------------- /qsc_interfacetest/test_case/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RainYang0925/testcase_web/6698190c426be56bfc54e92b6f99a3de335d5e82/qsc_interfacetest/test_case/models/__init__.py -------------------------------------------------------------------------------- /qsc_interfacetest/test_case/models/buildcase.py: -------------------------------------------------------------------------------- 1 | # __author__ = 'zhanghzhiyuan' 2 | # -*-coding:utf-8-*- 3 | 4 | 5 | from qsc_interfacetest.db_fixture.mysql_setting import MySQLOperating 6 | from myunit import MyTest 7 | import unittest 8 | import logging 9 | import re 10 | import requests 11 | import json 12 | import time 13 | import urllib 14 | import sys 15 | import random 16 | reload(sys) 17 | sys.setdefaultencoding('utf-8') 18 | import os 19 | ''' 20 | ===========说明============ 21 | 功能:测试用例执行 22 | 入口:ecxel表格测试用例 23 | ========================== 24 | ''' 25 | 26 | class BuildCase(MyTest): 27 | '''测试用例基础类''' 28 | 29 | def __init__(self): 30 | unittest.TestCase.__init__(self, '__init__') 31 | self.db = MySQLOperating() 32 | # self.base_url = 'http://api.test.qschou.com/v5' 33 | self.path = os.path.dirname(__file__) 34 | self.log_txt = self.path.split('test_case')[0] + 'report/log/log.txt' #配置日志文件位置 35 | logging.basicConfig(level=logging.INFO, 36 | format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', 37 | datefmt='%Y-%m-%d %H:%M:%S', 38 | filename=self.log_txt, 39 | filemode='w') 40 | self.response = {} #接口返回数据经处理后的字典 41 | 42 | # 获取接口返回数据,将嵌套字典处理为普通字典返回 43 | def change_response(self,dic): 44 | for key in dic: 45 | if isinstance(dic[key], dict): 46 | self.change_response(dic[key]) 47 | else: 48 | # print '%s:%s' % (key, dic[key]) 49 | self.response[key]=dic[key] 50 | return self.response 51 | 52 | # 获取返回接口返回结果中的指定的数据,response为返回的数据,key为指定值得索引 53 | def compare_response(self,response, key): 54 | #定义列表用于存放参数列表 55 | config_list = [] 56 | #判断是否存在多个config 57 | if ';' in key: 58 | for config in key.split(';'): 59 | # 定义字典用于存放参数名和值、索引 60 | config_dic = {} 61 | #判断是否自定义参数名 62 | if '=' in config: 63 | config_dic['name'] = config.split('=')[0] 64 | config = config.split('=')[1] 65 | else: 66 | config_dic['name'] = config 67 | if '-' in config: 68 | # 分离config和索引以'_'分隔 69 | config_dic['config'] = config.split('-')[0] 70 | config_dic['index'] = int(config.split('-')[1]) 71 | # 将字典加入到列表中 72 | config_list.append(config_dic) 73 | else: 74 | # 不存在索引默认为0 75 | config_dic['config'] = config 76 | config_dic['index'] = 0 77 | #将字典加入到列表中 78 | config_list.append(config_dic) 79 | # 判断congfig中是否包含索引 80 | elif '-' in key: 81 | config_dic = {} 82 | #判断是否要自定义命名提取参数 83 | if '=' in key: 84 | config_dic['name'] = key.split('=')[0] 85 | key = key.split('=')[1] 86 | else: 87 | config_dic['name'] = key 88 | config_dic['config'] = key.split('-')[0] 89 | config_dic['index'] = int(key.split('-')[1]) 90 | config_list.append(config_dic) 91 | else: 92 | #判断是否要自定义命名提取参数 93 | if '=' in key: 94 | config_dic = {} 95 | #等号左边为写入数据库中key 96 | config_dic['name'] = key.split('=')[0] 97 | #等号右边为写入数据库中value 98 | config_dic['config'] = key.split('=')[1] 99 | config_dic['index'] = 0 100 | config_list.append(config_dic) 101 | else: 102 | config_dic = {} 103 | config_dic['name'] = key 104 | config_dic['config'] = key 105 | config_dic['index'] = 0 106 | config_list.append(config_dic) 107 | 108 | # 遍历匹配查找在response中的config 109 | for config_dict in config_list: 110 | str1 = ': "?([^,\"\}\]]+)[",}?]' # 此规则针对字符串、null 111 | q = '"' + config_dict['config'] + '"' + str1 112 | value = re.compile(q) 113 | temp = value.findall(str(response)) 114 | # print 'temp:' 115 | # print temp 116 | if temp != []: 117 | # 说明有取出,返回 118 | config_dict['value'] = temp[config_dict['index']] 119 | # print '获取response中的值->' + config_dict['name'] + ':' + config_dict['value'] 120 | else: # 换成数字匹配规则 121 | num1 = ": ([\d]+)" 122 | q = '"' + config_dict['config'] + '"' + num1 123 | value = re.compile(q) 124 | temp = value.findall(str(response)) 125 | if temp != []: 126 | # 说明有取出,返回 127 | config_dict['value'] = temp[config_dict['index']] 128 | # print '获取response中的值->'+ config_dict['name'] + ':' + config_dict['value'] 129 | else: 130 | config_dict['value'] = None # 无取出 131 | # print '获取response中的值->' + config_dict['name'] + ':' + str(config_dict['value']) 132 | # 返回参数列表 如:[{'index': 0, 'config': u'access_token', 'name': u'access_token', 'value': '*********'}] 133 | return config_list 134 | 135 | # 替换参数中包含${**}之中的值,从数据库获取 136 | def replace_config(self,config): 137 | # value = re.compile(r'%%([^,]+?)[,/\'\"]') 138 | value = re.compile(r'\$\{([^\}]+?)\}') 139 | # 从数据库中获取引用参数,传给body 140 | re_result = value.findall(config) 141 | # print u'查询config表中的参数值:' 142 | # print re_result 143 | for i in re_result: 144 | i_value = self.db.get_ConfigTableValue(i) 145 | # print i+":"+i_value 146 | config = config.replace('${'+ i + '}',i_value) 147 | return config 148 | 149 | 150 | # 接口测试结束,写入相关数据,如:返回代码,时间,返回数据 151 | def set_db(self,testcase,r,table): 152 | # 获取接口返回时间 153 | time = r.elapsed.microseconds / 1000 154 | 155 | # 获取请求返回数据 156 | self.code = r.status_code 157 | text = r.text 158 | 159 | # 定义错误代码列表 160 | expect = True 161 | error_code = ['400', '401', '403', '404', '405', '406', '412', '422', '500'] 162 | 163 | # 判断接口返回的代码是否在错误代码列表中,如果在数据库写入fail,并且将返回的错误信息赋值给response 164 | if str(r.status_code) in error_code: 165 | response = json.loads(text)['error'] 166 | expect = False 167 | self.db.set_InterfaceTableValue(table,testcase['case_id'], 'result', 'error') 168 | else: 169 | response = json.dumps(json.loads(text), ensure_ascii=False, encoding='utf8mb4',indent=1) 170 | 171 | # 将请求返回数据写入数据库 172 | # value = {'status_code':code,'response':response,'time':time,'datetime':self.datetime} 173 | # self.db.set_InterfaceTableValue(testcase['case_id'], value) 174 | self.db.set_InterfaceTableValue(table,testcase['case_id'], 'status_code', self.code) 175 | self.db.set_InterfaceTableValue(table,testcase['case_id'], 'response', response) 176 | self.db.set_InterfaceTableValue(table,testcase['case_id'], 'time', time) 177 | self.db.set_InterfaceTableValue(table,testcase['case_id'],'datetime',self.datetime) 178 | # print self.datetime 179 | # 如果用例中包含返回的数据用作之后用例的请求参数,则将参数写入config表中 180 | if testcase['config']: 181 | config_value = self.compare_response(str(response), testcase['config']) 182 | # 将查找到的config参数遍历写入数据库 183 | for config in config_value: 184 | self.db.set_ConfigTableValue(config['name'], config['value']) 185 | 186 | #断言判断接口返回代码是否为错误代码 187 | msg = self.url + '\n' + u'接口返回异常:'+ ' ' +str(self.code) + ' ' + response 188 | self.assertTrue(expect,msg) 189 | 190 | # 执行测试用例,接收一条测试用例(字典:testcase),数据库表名(tablename,目前默认数据库中的interface_test1表,所以不传参数) 191 | def execute_case(self,testcase,tablename): 192 | '''执行测试用例''' 193 | 194 | # -------------------------------------接口输入参数设置--------------------------------------- 195 | # 判断该接口用例是否为登录接口,非登录接口headers中包含token 196 | if '登录' in testcase['case_name']: 197 | headers = eval(self.db.get_ConfigTableValue('headers')) 198 | else: 199 | headers = eval(self.db.get_ConfigTableValue('headers')) 200 | headers['Authorization'] = 'Bearer '+ self.db.get_ConfigTableValue('access_token') 201 | # print self.db.get_ConfigTableValue('access_token') 202 | 203 | # 判断url里面是否包含引用参数 204 | if "${" in testcase['url']: 205 | self.url = self.replace_config(testcase['url']) 206 | else: 207 | self.url = testcase['url'] 208 | # 判断是否需要传入parameter 209 | if testcase['parameters']: 210 | # 判断是否包含引用参数 211 | if "${" in testcase['parameters']: 212 | parameters = self.replace_config(testcase['parameters']) 213 | else: 214 | parameters = testcase['parameters'] 215 | path = urllib.urlencode(eval(parameters)) 216 | uri = '?' + path 217 | else: 218 | uri = '' 219 | self.url = self.url + uri 220 | 221 | # 判断body里面是否有引用参数 222 | if testcase['body']: 223 | if '${' not in testcase['body']: 224 | body = testcase['body'] 225 | # print body 226 | else: 227 | body = self.replace_config(testcase['body']) 228 | # print body 229 | #-------------------------------------执行测试用例--------------------------------------- 230 | logging.info(u'==========开始执行测试用例' + testcase['case_id'] + '===========') 231 | # 格式化时间形式 232 | ISOTIMEFORMAT = "%Y-%m-%d %H:%M:%S" 233 | if testcase['request_type'] == 'get': 234 | # 获取发起请求时间 235 | self.datetime = time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) 236 | # 发起请求 237 | r = requests.get(self.url,headers=headers) 238 | # 结果写入数据库 239 | self.set_db(testcase,r,tablename) 240 | 241 | if testcase['request_type'] == 'post': 242 | # 获取发起请求时间 243 | self.datetime = time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) 244 | # 发起请求 245 | # r = requests.post(self.url, data=json.dumps(eval(body,{'false': False, 'true': True, 'null': None})), headers=headers) 246 | r = requests.post(self.url, data=json.dumps(eval(body)),headers=headers) 247 | # 结果写入数据库 248 | self.set_db(testcase,r,tablename) 249 | 250 | if testcase['request_type'] == 'put': 251 | # 获取发起请求时间 252 | self.datetime = time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) 253 | # 发起请求 254 | r = requests.put(self.url, data=json.dumps(eval(body)), headers=headers) 255 | # 结果写入数据库 256 | self.set_db(testcase,r,tablename) 257 | 258 | if testcase['request_type'] == 'patch': 259 | # 获取发起请求时间 260 | self.datetime = time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) 261 | # 发起请求 262 | r = requests.patch(self.url, data=json.dumps(eval(body)), headers=headers) 263 | # 结果写入数据库 264 | self.set_db(testcase,r,tablename) 265 | 266 | if testcase['request_type'] == 'delete': 267 | # 获取发起请求时间 268 | self.datetime = time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) 269 | # 发起请求 270 | r = requests.delete(self.url, headers=headers) 271 | # 结果写入数据库 272 | self.set_db(testcase,r,tablename) 273 | 274 | response = json.dumps(json.loads(r.text), ensure_ascii=False, encoding='utf-8') 275 | 276 | #--------------------------------------判断接口返回数据与预期比较------------------------------------------ 277 | # print u'测试ID:%s,请求接口地址:%s,返回代码:%s,返回数据:%s' %(testcase['case_id'],self.url,r.status_code,response) 278 | # 判断预期结果 279 | if testcase['expected']: 280 | expected = eval(testcase['expected'],{'false': False, 'true': True, 'null': None}) 281 | for key,value in expected.items(): 282 | actual = self.compare_response(response,key)[0]['value'] 283 | if actual != None: 284 | self.assertTrue(actual,msg=u'接口返回数据异常') 285 | # 将字典中的null转化为'null'字符串,注:python中没有null,只有None 286 | if actual == 'null': 287 | actual = None 288 | if actual == 'true': 289 | actual = True 290 | if actual == 'false': 291 | actual = False 292 | # print u'接口返回数据',actual 293 | # print u'预期返回数据',value 294 | #判断预期结果是否有返回值 295 | if value != '$': 296 | #判断预期结果与实际结果数据是否一致 297 | if actual == value: 298 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'],'result','pass') 299 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'actual', u'一致') 300 | else: 301 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'fail') 302 | msg = u'''%s\n状态码:%s\n接口返回数据与预期返回数据不一致\n接口返回数据:%s\n预期返回数据:%s''' %(self.url,self.code,actual,value) 303 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'actual', key+':'+str(value)) 304 | self.assertEqual(actual,value,msg) 305 | else: 306 | if actual != None: 307 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'pass') 308 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'actual', u'一致') 309 | else: 310 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'fail') 311 | msg = u'''%s\n接口预期结果%s未返回数据''' %(self.url,actual) 312 | self.assertEqual(actual,value,msg) 313 | 314 | # 判断反预期结果 315 | if testcase['not_expected']: 316 | expected = eval(testcase['not_expected'], {'false': False, 'true': True, 'null': None}) 317 | for key, value in expected.items(): 318 | actual = self.compare_response(response, key)[0]['value'] 319 | if actual != None: 320 | self.assertTrue(actual, msg=u'接口返回数据异常') 321 | # 将字典中的null转化为'null'字符串,注:python中没有null,只有None 322 | if actual == 'null': 323 | actual = None 324 | if actual == 'true': 325 | actual = True 326 | if actual == 'false': 327 | actual = False 328 | # print u'接口返回数据',actual 329 | # print u'预期返回数据', 330 | 331 | # 判断预期结果与实际结果数据是否一致 332 | if actual != value: 333 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'pass') 334 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'actual', u'一致') 335 | else: 336 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'fail') 337 | msg = u'''%s\n状态码:%s\n接口返回数据与预期返回数据不一致\n接口返回数据:%s\n预期不返回数据:%s''' % ( 338 | self.url,self.code,actual, value) 339 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'actual', 340 | key + ':' + str(value)) 341 | self.assertNotEqual(actual, value, msg) 342 | 343 | # print u'预期结果与实际结果一致' 344 | self.db.set_InterfaceTableValue(tablename,testcase['case_id'], 'result', 'pass') 345 | logging.info(u'==========测试用执行完成' + testcase['case_id'] + '===========\n\r') 346 | 347 | if __name__ == '__main__': 348 | T = BuildCase() 349 | -------------------------------------------------------------------------------- /qsc_interfacetest/test_case/models/myunit.py: -------------------------------------------------------------------------------- 1 | # __author__ = 'zhangzhiyuan' 2 | #-*-coding:utf-8-*- 3 | import unittest 4 | import logging 5 | import time 6 | ''' 7 | =====================说明====================== 8 | 功能:自定义unittest框架,编写公用函数setup(),tearDown() 9 | ================================================ 10 | ''' 11 | class MyTest(unittest.TestCase): 12 | 13 | @classmethod 14 | def setUpClass(cls): 15 | # unittest.TestCase.__init__(cls, '__init__') 16 | print u'开始接口测试........' 17 | @classmethod 18 | def tearDownClass(cls): 19 | print u'.......接口测试结束' 20 | 21 | if __name__ == '__main__': 22 | unittest.main() --------------------------------------------------------------------------------