标签: django-testing

为Django应用程序编写好的测试

我从来没有在我的生活中写过任何测试,但我想开始为我的Django项目编写测试.我已经阅读了一些关于测试的文章,并决定尝试为一个非常简单的Django应用程序或者开始编写一些测试.

该应用程序有两个视图(列表视图和详细信息视图)和一个包含四个字段的模型:

class News(models.Model):
    title = models.CharField(max_length=250)
    content = models.TextField()
    pub_date = models.DateTimeField(default=datetime.datetime.now)
    slug = models.SlugField(unique=True)
Run Code Online (Sandbox Code Playgroud)

我想向您展示我的tests.py文件并询问:

是否有意义?

我甚至在测试正确的东西吗?

是否有我不遵循的最佳实践,你可以指点我吗?

我的tests.py(它包含11个测试):

# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test.client import Client
from django.core.urlresolvers import reverse
import datetime
from someproject.myapp.models import News

class viewTest(TestCase):
    def setUp(self):
        self.test_title = u'Test title: b?rek??'
        self.test_content = u'This is a content 156'
        self.test_slug = u'test-title-bareksc'
        self.test_pub_date = datetime.datetime.today()

        self.test_item = News.objects.create(
            title=self.test_title,
            content=self.test_content,
            slug=self.test_slug,
            pub_date=self.test_pub_date,
        )

        client = Client()
        self.response_detail = client.get(self.test_item.get_absolute_url()) …
Run Code Online (Sandbox Code Playgroud)

python django unit-testing django-testing

28
推荐指数
2
解决办法
4259
查看次数

在settings.py中指定Django测试数据库名称

我正在使用python对象指定数据库:

DATABASES = {
 'default':{
   'ENGINE':'mysql',
   'NAME':'testsqldb',
   'USER':'<username>',
   'PASSWORD':'<password>',
 },
 'dynamic_data':{
   'ENGINE': 'sqlite3',
   'NAME':'',
   'USER':'',
   'PASSWORD':''
 },
}
Run Code Online (Sandbox Code Playgroud)

如何指定测试数据库的名称?我一直试图TEST_NAME = 'auto_tests'在settings.py文件中使用.但是,当我运行时,python manage.py tests <app_name>我收到以下消息:

Creating test database 'default'...
Got an error creating the test database: (1007, "Can't create database 'test_testsqldb'; database exists")
Type 'yes' if you would like to try deleting the test database 'test_testsqldb', or 'no' to cancel:
Run Code Online (Sandbox Code Playgroud)

我希望系统在运行我的测试时创建一个单独的数据库,大概叫做'auto_tests_testsqldb'; 但是,它还在问我关于test_testsqldb的问题.

任何建议表示赞赏!

testing django settings django-testing django-settings

28
推荐指数
1
解决办法
2万
查看次数

带有查询参数的APITest是否与普通网址不同?

我正在针对一个API编写一些单元测试,该API要么返回所有书籍,要么只返回查询参数中给定类型的书籍.当我在本地开发服务器中点击它时,这似乎正常.但是,如果在我的单元测试中指定了类型,它甚至不会进入else语句.

我的单元测试看起来像这样:

class TitlesAndBlurbsListTestCase(APITestCase):
     def setUp(self):
     # Creates a lot of books with genre horror
     # and books not in the horror genre

     def test_horror_genre(self):
         # Ensure that screener can see all the available books
         self.client.login(username='b', password='b')
         response = self.client.get('/api/titles-and-blurbs/?genre=horror')
         self.assertEqual(response.status_code, status.HTTP_200_OK)

         # Ensure that the screener gets all horror books at first
         horror_books = TitlesAndBlurbs.objects.filter(genre='horror')
         # I keep getting an assertion error here - it returns all the books
         self.assertEqual(len(response.data), horror_books.count()) 
Run Code Online (Sandbox Code Playgroud)

我的api视图看起来像这样

class TitlesAndBlurbsListViewSet(viewsets.mixins.ListModelMixin,
               viewsets.mixins.RetrieveModelMixin,
               viewsets.GenericViewSet):
    model = TitlesAndBlurbs …
Run Code Online (Sandbox Code Playgroud)

django unit-testing django-testing django-rest-framework

28
推荐指数
1
解决办法
1万
查看次数

我如何测试Django QuerySets是否相等?

我正在尝试测试我的Django视图.此视图将QuerySet传递给模板:

def merchant_home(request, slug):
  merchant = Merchant.objects.get(slug=slug)
  product_list = merchant.products.all()
  return render_to_response('merchant_home.html',
                            {'merchant': merchant,
                            'product_list': product_list},
                            context_instance=RequestContext(request))
Run Code Online (Sandbox Code Playgroud)

并测试:

  def test(self):
    "Merchant home view should send merchant and merchant products to the template"
    merchant = Merchant.objects.create(name='test merchant')
    product = Product.objects.create(name='test product', price=100.00)
    merchant.products.add(product)

    test_client = Client()
    response = test_client.get('/' + merchant.slug)
    # self.assertListEqual(response.context['product_list'], merchant.products.all())
    self.assertQuerysetEqual(response.context['product_list'], merchant.products.all())
Run Code Online (Sandbox Code Playgroud)

编辑 我用的是self.assertQuerysetEqual而不是self.assertListEqual.不幸的是,这仍然无效,终端显示: ['<Product: Product object>'] != [<Product: Product object>]


assertListEqual提出:'QuerySet' object has no attribute 'difference'并且 assertEqual也不起作用,虽然self.assertSetEqual(response.context['product_list'][0], …

python django django-queryset django-testing

25
推荐指数
3
解决办法
1万
查看次数

想要在Django测试中禁用信号

所以我有各种各样的信号和处理程序,它们通过应用程序发送.但是,当我执行测试/进入"测试模式"时,我希望禁用这些处理程序.

在测试模式下是否有一种特定于Django的禁用信号/处理程序的方法?我可以想到一个非常简单的方法(在if TESTING子句中包含处理程序)但我想知道Django中是否有更好的方法?...

django django-signals django-testing

25
推荐指数
4
解决办法
9940
查看次数

Django测试 - 在所有测试中修补对象

我需要MockMixin为我的测试创建一些.它应该包括调用外部源的所有内容的模拟.例如,每次我在管理面板中保存模型时,我都会调用一些远程URL.如果嘲笑并使用那样的话会很好:

class ExampleTestCase(MockedTestCase):
    # tests
Run Code Online (Sandbox Code Playgroud)

因此,每次我在管理员中保存模型时,例如在功能测试中,应用此模拟而不是调用远程URL.

这有可能吗?我能够为1个特定测试做到这一点,这不是问题.但是有一些全局模拟更有用,因为我经常使用它.

python django unit-testing django-testing python-mock

25
推荐指数
3
解决办法
1万
查看次数

Django使用测试夹具测试FileField

我正在尝试为一些具有FileField的模型构建测试.该模型如下所示:

class SolutionFile(models.Model):
    '''
    A file from a solution.
    '''
    solution = models.ForeignKey(Solution)
    file = models.FileField(upload_to=make_solution_file_path)
Run Code Online (Sandbox Code Playgroud)

我遇到了两个问题:

  1. 使用时将数据保存到夹具时./manage.py dumpdata,不保存文件内容,只将文件名保存到夹具中.虽然我发现这是预期的行为,因为文件内容没有保存到数据库中,我想以某种方式将这些信息包含在夹具中进行测试.

  2. 我有一个用于上传文件的测试用例,如下所示:

    def test_post_solution_file(self):
        import tempfile
        import os
        filename = tempfile.mkstemp()[1]
        f = open(filename, 'w')
        f.write('These are the file contents')
        f.close()
        f = open(filename, 'r')
        post_data = {'file': f}
        response = self.client.post(self.solution.get_absolute_url()+'add_solution_file/', post_data,
                                    follow=True)
        f.close()
        os.remove(filename)
        self.assertTemplateUsed(response, 'tests/solution_detail.html')
        self.assertContains(response, os.path.basename(filename))
    
    Run Code Online (Sandbox Code Playgroud)

虽然此测试工作正常,但在完成后将上传的文件保留在媒体目录中.当然,删除可以照顾tearDown(),但我想知道Django是否有另一种处理方式.

我想到的一个解决方案是使用不同的媒体文件夹进行测试,必须与测试夹具保持同步.有没有办法在settings.py运行测试时指定另一个媒体目录?我可以在dumpdata中包含某种钩子,以便同步媒体文件夹中的文件吗?

那么,是否有更多的Pythonic或Django特定方式处理涉及文件的单元测试?

python django unit-testing django-testing filefield

24
推荐指数
2
解决办法
5092
查看次数

在django测试期间加载夹具时的IntegrityError

我正在加载使用dumpdata创建的fixture,并获得以下异常:

Problem installing fixture 'db_dump.json': Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/django/core/management/commands/loaddata.py", line 174, in handle
    obj.save(using=using)
  File "/usr/lib/python2.6/site-packages/django/core/serializers/base.py", line 165, in save
    models.Model.save_base(self.object, using=using, raw=True)
  File "/usr/lib/python2.6/site-packages/django/db/models/base.py", line 526, in save_base
    rows = manager.using(using).filter(pk=pk_val)._update(values)
  File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 491, in _update
    return query.get_compiler(self.db).execute_sql(None)
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 869, in execute_sql
    cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/usr/lib/python2.6/site-packages/django/db/backends/sqlite3/base.py", line 234, in execute
    return Database.Cursor.execute(self, query, params)
IntegrityError: columns app_label, model are not unique
Run Code Online (Sandbox Code Playgroud)

这是一个sqlite3后端.

更新:使用自然键在这里没有区别. …

django django-testing django-fixtures

24
推荐指数
2
解决办法
6902
查看次数

在django单元测试中使用用户模型的问题

我有以下django测试用例,它给了我错误:

class MyTesting(unittest.TestCase):
    def setUp(self):
        self.u1 = User.objects.create(username='user1')
        self.up1 = UserProfile.objects.create(user=self.u1)

    def testA(self):
        ...

    def testB(self):
        ...
Run Code Online (Sandbox Code Playgroud)

当我运行我的测试时,testA将成功通过但在testB启动之前,我收到以下错误:

IntegrityError: column username is not unique
Run Code Online (Sandbox Code Playgroud)

很明显,它试图self.u1在每个测试用例之前创建并发现它已经存在于数据库中.如何在每个测试用例之后正确清理它以便后续情况正确运行?

python django unit-testing django-testing

21
推荐指数
2
解决办法
1万
查看次数

如何在Django unittest中使用pdb.set_trace()?

我想像调试任何其他Python代码一样调试Django TestCase:只需调用pdb.set_trace()然后进入交互式会话即可.当我这样做时,我没有看到任何东西,因为测试是在不同的过程中运行的.我正在使用django-discover-runner,但我的猜测是这适用于默认的Django测试运行器.

问题:

是否可以在每次错误/失败pdb时使用django-discover-runnera)进入会话,和/或b)只有在我调用pdb.set_trace()我的测试代码时?

有些研究:

这个答案解释了Django创建了另一个进程,并建议使用rpdb2 debugger一部分调用winpdb,但我不想使用winpdb,我宁愿使用ipdb.

这个答案django-nose通过运行如下所示的测试命令解决了问题:./manage.py test -- -s但该选项不可用django-discover-runner.

这个答案显示我可以这样做ipython:

In [9]: %pdb
Automatic pdb calling has been turned ON
Run Code Online (Sandbox Code Playgroud)

这似乎是一个潜在的选择,但ipython每次运行测试时启动它似乎有点麻烦.

最后,这个答案表明nose带有一个--pdb标志,它会pdb出现错误,这就是我想要的.我唯一的选择是切换到django-nose测试跑步者?

我在内置帮助中没有看到任何选项django-discover-runner:

$ python manage.py help test --settings=settings.test
Usage: manage.py test [options] [appname ...]

Runs …
Run Code Online (Sandbox Code Playgroud)

django debugging django-testing pdb

21
推荐指数
2
解决办法
9350
查看次数