简体   繁体   English

Django用South / Selenium测试夹具

[英]Fixtures in Django testing with South / Selenium

I am trying to run Selenium tests on a Django project (1.5.4), which uses South. 我正在尝试在使用South的Django项目(1.5.4)上运行Selenium测试。 I think South is conflicting with my tests when I try to inject initial data with fixtures, but I'm not sure why; 当我尝试使用夹具注入初始数据时,我认为South与我的测试冲突,但是我不确定为什么。 I appreciate any help. 感谢您的帮助。

According to the Django documentation , fixtures are supposed to be loaded after the first syncdb and then all migrations are applied. 根据Django 文档 ,应该在第一个syncdb之后加载固定装置,然后应用所有迁移。

Question 1) Does this take into account South migrations?? 问题1)这是否考虑了南迁徙? Do I need to run those separately somehow? 我是否需要以某种方式分别运行它们?

The error I get when I run my tests makes it seem like my South migrations are still present in the test database after the first test...but I thought each test has its own database (and migrations / fixtures) created? 我在运行测试时遇到的错误使我似乎在第一次测试后仍然存在南迁移...但是我认为每个测试都有自己创建的数据库(和迁移/固定装置)吗? The first test passes / fails, but each subsequent test raises this IntegrityError: 第一个测试通过/失败,但是每个后续测试都会引发此IntegrityError:

IntegrityError: Problem installing fixture '<PROJECT_PATH>/fixtures/toy_course.json': Could not load contenttypes.ContentType(pk=8): (1062, "Duplicate entry 'south-migrationhistory' for key 'app_label'")

This South documentation and SO question seem to indicate that I need to override some type of forwards method in order to get fixtures working, but I'm not entirely sure how to apply that to a testing situation instead of production (or if that is the solution I need). 这个南方文档SO问题似乎表明我需要重写某种类型的forwards方法才能使灯具起作用,但是我不完全确定如何将其应用于测试情况而不是生产环境(或者是否适用于测试环境)。我需要的解决方案)。

Question 2) Am I supposed to override forwards in my test setup? 问题2)我应该在测试设置中覆盖转发吗? Where would I do it? 我在哪里做?

My relevant test code: 我的相关测试代码:

from django.conf import settings

from selenium import webdriver

from functional_tests.test import SeleniumTestCase

class Resources(SeleniumTestCase):
    fixtures = ['toy_course.json']

    def setUp(self):      
        self.browser = webdriver.Chrome(settings.SELENIUM_WEBDRIVER)
        self.browser.implicitly_wait(3)

    def tearDown(self):
        self.browser.quit()

    def test_main_page_renders_correctly(self):
        """
        User sees a properly formatted main page
        """
        self.open('/RDB/')

        h3_headers = self.browser.find_elements_by_tag_name('h3')
        self.assertIn(
                'Complete List of Resources',
                [header.text for header in h3_headers])

        self.assertTrue(self.check_exists_by_id('main_table'))
        self.assertTrue(self.check_exists_by_id('searchDiv'))

        self.assertTrue(self.check_exists_by_class_name('tablesorter'))

Thanks! 谢谢!


UPDATE 更新

So per Alex's suggestion below and this South doc , I added this line to my settings.py: 因此,根据以下Alex的建议以及该South doc ,我将此行添加到settings.py中:

SOUTH_TESTS_MIGRATE = False

But I am now getting 8 of 8 Errors (before I was getting 1 pass/fail on the first test, and then 7 Errors). 但是我现在得到8个错误中的8个(在我第一次测试中通过/失败之前,然后是7个错误)。 The full error for a single test is below: 单个测试的完整错误如下:

======================================================================
ERROR: test_table_sorts_on_click (functional_tests.tests.main_resources.Resources)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/test/testcases.py", line 259, in __call__
self._pre_setup()
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/test/testcases.py", line 479, in _pre_setup
self._fixture_setup()
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/test/testcases.py", line 518, in _fixture_setup
**{'verbosity': 0, 'database': db_name, 'skip_validation': True})
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/core/management/__init__.py", line 161, in call_command
return klass.execute(*args, **defaults)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/core/management/base.py", line 255, in execute
output = self.handle(*args, **options)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/core/management/commands/loaddata.py", line 193, in handle
obj.save(using=using)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/core/serializers/base.py", line 165, in save
models.Model.save_base(self.object, using=using, raw=True)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/models/base.py", line 626, in save_base
rows = manager.using(using).filter(pk=pk_val)._update(values)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/models/query.py", line 605, in _update
return query.get_compiler(self.db).execute_sql(None)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 1014, in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 122, in execute
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 120, in execute
return self.cursor.execute(query, args)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/MySQLdb/cursors.py", line 201, in execute
self.errorhandler(self, exc, value)
  File "/<PATH TO VIRTUAL ENV>/virtual_environments/relate/lib/python2.7/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
IntegrityError: Problem installing fixture '/<PATH TO PROJECT>/RDB/fixtures/toy_course.json': Could not load contenttypes.ContentType(pk=8): (1062, "Duplicate entry 'south-migrationhistory' for key 'app_label'")

The command I ran: 我运行的命令:

$ python manage.py test functional_tests

I'm not quite sure if I made the problem better, worse, or the same, but I seem to be more in-line with the documentation... 我不确定我是否使问题变得更好,更糟或相同,但是我似乎更符合文档要求……

Thanks! 谢谢!


UPDATE #2 -- with solution 更新#2-解决方案

So a couple of other pages that helped me figure it out (in addition to Alex's pointer to the South doc). 因此,还有其他几页帮助我弄清楚了(除了Alex指向South doc的指针)。 First, this person had a similar issue , and solved it using the SOUTH_TESTS_MIGRATE = False statement. 首先, 此人有一个类似的问题 ,并使用SOUTH_TESTS_MIGRATE = False语句解决了这个问题 So half my solution was to include that. 所以我一半的解决方案是将其包括在内。

The second half of my solution was to fix my fixture document. 解决方案的后半部分是修复我的装置文档。 I was dumping everything into my fixture with: 我通过以下方式将所有内容都丢弃到我的装置中:

$ python manage.py datadump > RDB/fixtures/toy-course.json

This is, apparently, a bad way to do fixtures it with South--because it also dumps the South migration tables into the fixture. 显然,这是对South进行固定的一种不好的方法-因为它还会将South迁移表转储到固定装置中。 The post above shows the blogger using app-specific fixtures (which are also talked about in this SO post ), and that was the key to getting my fixtures to work. 上面的帖子显示了博客作者使用特定于应用程序的固定装置(在本SO帖子中也有讨论),这是使固定装置工作的关键。 The Django docs on fixtures do show the optional parameters to dump just an app, but I didn't know ignoring them would cause South to conflict. 夹具上的Django文档确实显示了仅转储应用程序的可选参数,但我不知道忽略它们会导致South发生冲突。 So the second half of my solution was to create my fixture to be app-specific: 因此,解决方案的第二部分是将夹具创建为特定于应用程序的:

$ python manage.py datadump RDB > RDB/fixtures/toy-course.json

And my tests now run fine (slow, but probably a different issue)! 现在我的测试运行正常(速度慢,但可能是另一个问题)!

Your test database is created using South migrations by default. 默认情况下,您的测试数据库是使用South迁移创建的。 Set SOUTH_TESTS_MIGRATE = False in your settings.py , quote from docs : settings.py设置SOUTH_TESTS_MIGRATE = False ,引用docs

If this is False, South's test runner integration will make the test database be created using syncdb, rather than via migrations (the default). 如果为False,South的测试运行器集成将使测试数据库使用syncdb创建,而不是通过迁移(默认设置)创建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM