Django单元测试在Travis CI构建上失败

Django单元测试在Travis CI构建上失败,django,python-3.x,travis-ci,Django,Python 3.x,Travis Ci,我有一个非常基本的Django应用程序(Python3.6.4),我编写了一个在本地通过的单元测试。为测试创建内存中的SQLite DB(默认情况下)。当my Travis CI build运行相同的测试时,测试通过,但测试命令失败,出现以下错误: File "/home/travis/virtualenv/python3.6.5/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 301, in execu

我有一个非常基本的Django应用程序(Python3.6.4),我编写了一个在本地通过的单元测试。为测试创建内存中的SQLite DB(默认情况下)。当my Travis CI build运行相同的测试时,测试通过,但测试命令失败,出现以下错误:

File "/home/travis/virtualenv/python3.6.5/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 301, in execute
    return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: near "SCHEMA": syntax error

The command "python manage.py test --settings=myapp.dev_settings" exited with 1.
我注意到的一件奇怪的事情是,当在Travis上运行测试时,它说它正在重用现有的DB,并且在测试运行后从不销毁它:

$ python manage.py test --settings=myapp.dev_settings
正在使用别名“default”的现有测试数据库

我真的不明白,因为它应该是内存中的数据库,当我在本地运行它时,每次都会创建一个新的数据库:

Creating test database for alias 'default'... 
. . .
Destroying test database for alias 'default'... 
我的
dev_settings.py
文件在文件系统上有一个sqlite db,但它仅用于运行本地开发服务器:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
Travis安装了所有的依赖项,它们与我的本地环境相匹配(我很确定)


任何帮助都会很好,我肯定错过了一些明显的东西

在travis构建的堆栈跟踪中,我注意到正在执行一个意外的包:

  File "/home/travis/virtualenv/python3.6.5/lib/python3.6/site-packages/django_heroku/core.py", line 41, in teardown_databases
self._wipe_tables(connection)
问题是,我正在使用一个settings.py文件执行测试,该文件包含特定于Heroku(部署)的代码:

import django_heroku
import dj_database_url

# Parse database configuration from Heroku's $DATABASE_URL (Postgres)
DATABASES = {
    'default': dj_database_url.config(conn_max_age=500, ssl_require=True)
}

# Activate Django-Heroku (DATABASE_URL and all that).
django_heroku.settings(locals())
以及my requirements.txt文件中的依赖项:

django-heroku==0.3.1
一旦我从Travis构建配置中删除了所有Heroku配置,构建就通过了

仍然不确定我是如何在本地看到此失败的。

@LaSmell是正确的(我也有同样的问题)。这是因为您试图访问构建中的Heroku依赖项

但我仍然可以向您展示如何实现解决方案

你需要做三件事来解决这个问题

1-指定一个不带django heroku的新需求文档

我个人创建了另一个名为requirements-build.txt的文件,除了django heroku==0.3.1之外,它具有所有相同的依赖项

我只是把它删掉

2-在.travis.yml中指定新的需求文件

在.travis.yml文件中,只需替换

install:
  - pip install -r requirements.txt

3-在settings.py文件中说明这些更改

要确保未安装heroku django时不会导入它,请先检查是否可以导入它。我做到了:

# Try to import django-heroku depending on Travis or Heroku
try:
    # Configure Django App for Heroku.
    import django_heroku
    django_heroku.settings(locals())
except ImportError:
    found = False
这样,只有安装了django heroku,它才会使用它。由于Heroku在默认情况下使用requirements.txt,因此此修补程序运行良好


希望这有帮助!我自己花了一段时间才得到它。

这是因为Django Heroku软件包设置了自己的测试运行程序,如果它检测到CI环境,它会对数据库执行额外的操作,这可能是为了迎合他们的Heroku CI产品:

 # Enable test runner if found in CI environment.
 if 'CI' in os.environ:
     config['TEST_RUNNER'] = 'django_heroku.HerokuDiscoverRunner'
测试运行程序执行以下不适用于SQLite的操作:

with connection.cursor() as cursor:
    cursor.execute(
        """
            DROP SCHEMA public CASCADE;
            CREATE SCHEMA public;
            GRANT ALL ON SCHEMA public TO postgres;
            GRANT ALL ON SCHEMA public TO public;
            COMMENT ON SCHEMA public IS 'standard public schema';
        """
    )
不幸的是,此检查还检测到非Heroku CI环境,如Travis或GitLab CI,并尝试使用上述配置

您可以通过在
设置.py中禁用Heroku测试运行程序来解决此问题:

# Configure Django App for Heroku.
django_heroku.settings(locals(), test_runner=False)

从完整的错误堆栈中,我可以看到测试数据库拆卸中涉及了一个依赖包“django_heroku”,也许这个特定于heroku的包不应该为测试构建安装?您可以从requirements.txt:in.travis.yml动态生成requirements-build.txt,而不是有两个需求文件,添加以下内容:在安装之前:-sed'/django heroku==/d'requirements.txt>requirements-build.txt
# Configure Django App for Heroku.
django_heroku.settings(locals(), test_runner=False)