Creating test database for alias 'default' ('test_bookstoredb')...
上述创建方式使用了默认的文件系统,即以 MySQL 数据库的形式生成了相关的数据文件。Django为了解决数据库创建与销毁耗时的问题,也为我们提供了解决方案。我们可以通过配置使用轻量级数据库 SQLite 来解决此问题,此时 Django 将会在内存(memory)中创建数据库。if 'test' in sys.argv: DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3',}然后我们可以使用如下命令执行测试用例:
python manage.py test -v 3 index.tests.ExampleTest
最后你会发现执行的速度比之前快很对,几乎不用等待。通过命令行界面可以看到,创建的默认数据数已经更改了方式,这个数据库在内存在完成了创建,如下所示:C:\Users\Administrator\Book\BookStore>python manage.py test -v 3 index.tests.ExampleTest Creating test database for alias 'default' ('file:memorydb_default?mode=memory&cache=shared')...#内存中生成临时文件 Operations to perform: Synchronize unmigrated apps: messages, staticfiles由此可见适应 SQLite 时,同样也会在执行测试时候创建数据库,只不过这个创建与销毁的过程发生在内存中,要比使用默认的文件系统快的得多。
from index.models import Book, PubName from django.test import TestCase, tag class ExampleTest(TestCase): def setUp(self): self.pub1=PubName.objects.create(pubname="编程帮出版") @tag('tagone') #添加标记 def test_model(self): book=Book.objects.create(title='Servlet',price='35.00', retail_price='35.00',pub=self.pub1) self.assertTrue(book is not None) self.assertNotEqual(Book.objects.count(),8) self.assertEqual(Book.objects.count(),1) @tag('tagsecond')#添加标记 def test_view(self): book=Book.objects.create(title='Jsp',price='25.00', retail_price='25.00',pub=self.pub1) response=self.client.get('/index/update_book/%d/'% book.id)#视图访问获取response response['X-Token']='C语言中文网' self.assertEqual(response.status_code,200) self.assertEqual(response['X-Token'],'=?utf-8?b?Q+ivreiogOS4reaWh+e9kQ==?=','not sucessful') def tearDown(self): print('清理测试环境')使用如下命令进行测试标记的执行:
python manage.py test --tag=tagone --tag=tagsecond index.tests.ExampleTest
上面是同时执行两个标记测试,也可以只选择一个执行,大家在书写命令的时候要注意格式。我们还可以使用如下参数来排除不想执行的测试方法:--exclude-tag=tagsecond
class ExampleTest(TestCase) def test_assert1(self): """ django内置断言的方法测试 """ # 用来断言可执行对象的调用引发了异常,且在异常中发现了对应的信息 with self.assertRaisesMessage(ValueError,'invalid literal for int()'): int('a') def test_assert2(self): #判断HTML是否相等基于HTML语义,常用来检验返回模板的视图 self.assertHTMLEqual("<p>hello task.lmcjl.com</p>"," <p>hello task.lmcjl.com</p>") self.assertHTMLNotEqual("<p>hello task.lmcjl.com</p>","<p>hello task.lmcjl.com</p>") def test_assert3(self): #用来断言JSON字符串是否相等,校验JsonResponse视图返回对象 self.assertJSONEqual('{"name":"John","age":15}','{"age":15,"name":"John"}') self.assertJSONNotEqual('{"a":1,"b":2}','{"a":2,"c":1}') def test_asseret4(self): #断言查询集合是否与给定的列表内容相等,给定列表也可包含多个元素 book = Book.objects.create(title='Servlet', price='35.00', retail_price='35.00', pub=self.pub1) #repr(a)将对象a转换为字符串格式 self.assertQuerysetEqual(Book.objects.all(),[repr(book)])除了上面介绍的内置断言方法外,Django 还提供了一些其他的方法,这里就不逐一介绍了,有兴趣的可见参考官方文档《Django单元测试工具》。
pip install coverage
安装完成后之后,需要在 manage.py 所在目录执行下面的命令:coverage run --source='.' manage.py test
在 CMD 命令行工具中就可以看到测试输出了,然后再使用 coverage 工具的 coverage report --skip-covered 命令查看测试代码覆盖率,最后可以得到如下结果:C:\Users\Administrator\Book\BookStore>coverage report --skip-covered Name Stmts Miss Cover ---------------------------------------- BookStore\views.py 84 30 64% BookStore\wsgi.py 4 4 0% index\admin.py 19 1 95% index\apps.py 3 3 0% index\forms.py 59 23 61% index\models.py 36 2 94% index\test.py 41 8 80% index\views.py 245 170 31% manage.py 12 2 83% user\apps.py 3 3 0% user\backends.py 17 17 0% user\models.py 8 1 88% user\signals.py 6 1 83% user\views.py 150 106 29% ---------------------------------------- TOTAL 857 371 57% 30 files skipped due to complete coverage.结果展示中的字段含义:
coverage html
命令后,便可以在 manage.py 同级目录下生成一个名叫 htmlcov 的文件夹,使用浏览器打开其中的 index.html 文件,可以得到如下所示:
图1:HTML格式的测试代码覆盖率报告
本文链接:http://task.lmcjl.com/news/16789.html