我必须强调的 PyCharm 社区 版_这也 没有任何 Django的 集成( _v 2016年3月2日 在质询时间)。
Google 已经解决了我的问题,并且(令人惊讶的是)我没有得到任何答案,(当然,我没有排除可能有答案的可能性,但是我只是错过了它们)。
问题很简单:在 PyCharm中 ,只需单击鼠标右键(从上下文菜单中),就可以运行(调试)单元测试( TestCase 或其方法之一),如下图所示:
不幸的是,这产生了一个例外:
Traceback (most recent call last): File "C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 254, in main() File “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 232, in main module = loadSource(a[0]) File “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 65, in loadSource module = imp.load_source(moduleName, fileName) File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py”, line 7, in from polls.models import Question File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\models.py”, line 9, in class Question(models.Model): File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\models.py”, line 10, in Question question_text = models.CharField(max_length=200) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\db\models\fields__init__.py”, line 1043, in init super(CharField, self).init(args, *kwargs) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\db\models\fields__init__.py”, line 166, in init self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\conf__init__.py”, line 53, in getattr self._setup(name) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\conf__init__.py”, line 39, in _setup % (desc, ENVIRONMENT_VARIABLE)) django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Traceback (most recent call last): File "C:\Install\PyCharm Community
Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 254, in main() File “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 232, in main module = loadSource(a[0]) File “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py”, line 65, in loadSource module = imp.load_source(moduleName, fileName) File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py”, line 7, in from polls.models import Question File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\models.py”, line 9, in class Question(models.Model): File “E:\Work\Dev\Django\Tutorials\proj0\src\polls\models.py”, line 10, in Question question_text = models.CharField(max_length=200) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\db\models\fields__init__.py”, line 1043, in init super(CharField, self).init(args, *kwargs) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\db\models\fields__init__.py”, line 166, in init self.db_tablespace = db_tablespace or settings.DEFAULT_INDEX_TABLESPACE File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\conf__init__.py”, line 53, in getattr self._setup(name) File “E:\Work\Dev\VEnvs\py2713x64-django\lib\site- packages\django\conf__init__.py”, line 39, in _setup % (desc, ENVIRONMENT_VARIABLE)) django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
注意 :我仅添加了问题,以提供可能对某人有用的答案。
考虑到上述情况,对于某些高级用户而言,解决方案的某些(或全部)部分可能看起来很繁琐/愚蠢,因此请耐心等待。我将结合任何可能增加解决方案价值的评论。
回到问题:我对一个包含 Django Tutorial ([DjangoProject]:编写您的第一个Django应用)和 Django Rest Framework Tutorial ([DRF]:Quickstart)的某些部分的项目进行了测试/研究。例如,我将尝试运行 polls / tests.py :QuestionViewTests.test_index_view_with_no_questions()
QuestionViewTests.test_index_view_with_no_questions()
请注意, 将 DJANGO_SETTINGS_MODULE 设置 为异常指示, 触发另一个触发 ,依此类推…
尽管这不是问题的答案(仅与远程相关),但无论如何我还是在发布它(我相信已经有很多人这样做了):
test QuestionViewTests.test_index_view_with_no_questions
当然,不必为每个测试用例(及其方法)执行此操作(这确实很烦人),因此该方法不可扩展。
请注意,我不认为这是一个真正的解决方案,它更像是(lame)解决方法( gainarie ),并且它也是侵入性的。
让我们开始看看当我们在 测试 上 单击RClick 时会发生什么(我通常会使用这个术语- 除非另有说明,否则可能表示测试用例或方法或整个测试文件)。对我来说,它正在运行以下命令: __
"E:\Work\Dev\VEnvs\py2713x64-django\Scripts\python.exe" “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py” E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions true
"E:\Work\Dev\VEnvs\py2713x64-django\Scripts\python.exe"
“C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py” E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions true
正如你所看到的,它的推出“ C:\安装\ PyCharm社区版\ 2016年3月2日\佣工\ pycharm \ utrunner.py ”(我要去把它称为 utrunner )与一堆参数(1日对我们来说很重要,因为这是测试规范。 utrunner 使用的测试运行框架并不关心 Django (实际上有一些 Django 处理代码,但这对我们没有帮助)。
关于 PyCharm 的 Run / Debug配置的 几句话:
考虑到以上几点,让我们继续:
__您需要做的 第一件事 是:从“ 运行/调试配置” 对话框(菜单: 运行- >编辑配置…),编辑 默认值/ Python测试/单元测试 设置:
第二件事 和棘手的 事情 (也涉及入侵):修补 utrunner 。
utrunner.patch :
--- utrunner.py.orig 2016-12-28 19:06:22.000000000 +0200 +++ utrunner.py 2017-03-23 15:20:13.643084400 +0200 @@ -113,7 +113,74 @@ except: pass -if __name__ == "__main__": + +def fileToMod(filePath, basePath): + if os.path.exists(filePath) and filePath.startswith(basePath): + modList = filePath[len(basePath):].split(os.path.sep) + mods = ".".join([os.path.splitext(item)[0] for item in modList if item]) + return mods + else: + return None + + +def utrunnerArgToDjangoTest(arg, basePath): + if arg.strip() and not arg.startswith("--"): + testData = arg.split("::") + mods = fileToMod(testData[0], basePath) + if mods: + testData[0] = mods + return ".".join(testData) + else: + return None + else: + return None + + +def flushBuffers(): + sys.stdout.write(os.linesep) + sys.stdout.flush() + sys.stderr.write(os.linesep) + sys.stderr.flush() + + +def runModAsMain(argv, codeGlobals): + with open(argv[0]) as f: + codeStr = f.read() + sys.argv = argv + code = compile(codeStr, os.path.basename(argv[0]), "exec") + codeGlobals.update({ + "__name__": "__main__", + "__file__": argv[0] + }) + exec(code, codeGlobals) + + +def djangoMain(): + djangoTests = list() + basePath = os.getcwd() + for arg in sys.argv[1: -1]: + djangoTest = utrunnerArgToDjangoTest(arg, basePath) + if djangoTest: + djangoTests.append(djangoTest) + if not djangoTests: + debug("/ [DJANGO MODE] Invalid arguments: " + sys.argv[1: -1]) + startupTestArgs = [item for item in os.getenv("DJANGO_STARTUP_TEST_ARGS", "").split(" ") if item] + startupFullName = os.path.join(basePath, os.getenv("DJANGO_STARTUP_NAME", "manage.py")) + if not os.path.isfile(startupFullName): + debug("/ [DJANGO MODE] Invalid startup file: " + startupFullName) + return + djangoStartupArgs = [startupFullName, "test"] + djangoStartupArgs.extend(startupTestArgs) + djangoStartupArgs.extend(djangoTests) + additionalGlobalsStr = os.getenv("DJANGO_STARTUP_ADDITIONAL_GLOBALS", "{}") + import ast + additionalGlobals = ast.literal_eval(additionalGlobalsStr) + flushBuffers() + runModAsMain(djangoStartupArgs, additionalGlobals) + flushBuffers() + + +def main(): arg = sys.argv[-1] if arg == "true": import unittest @@ -186,3 +253,10 @@ debug("/ Loaded " + str(all.countTestCases()) + " tests") TeamcityTestRunner().run(all, **options) + + +if __name__ == "__main__": + if os.getenv("DJANGO_TEST_MODE_GAINARIE"): + djangoMain() + else: + main()
上面是一个 diff ([man7]:DIFF(1))(或一个 补丁 -名称可以结合使用-我推荐(并将使用) patch ):它显示了 utrunner.py.orig (原始文件-我在开始修改之前保存的文件,您不需要这样做)和 utrunner.py (包含更改的当前版本)。我使用的命令是diff --binary -uN utrunner.py.orig utrunner.py(显然在 utrunner 的文件夹中)。作为个人的话, 补丁 是改变3优选形式RD方的源代码(控制住的变化,并分离)。
diff --binary -uN utrunner.py.orig utrunner.py
补丁 中的代码做什么(可能比纯 Python 代码更难遵循):
if __name__ == "__main__":
fileToMod("E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py", "E:\Work\Dev\Django\Tutorials\proj0\src")``polls.tests
E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions
polls.tests.QuestionViewTests.test_index_view_with_no_questions
修补 utrunner :
应用 补丁 :
patch -i /tmp/utrunner.patch
备份无害(除了可用磁盘空间的 PoV之外 ,或者当它们开始堆积时,管理它们变得很麻烦)。在我们的情况下,不需要它们。为了恢复更改,只需在修改后的文件:上运行命令patch -Ri /tmp/utrunner.patch,它将切换回其原始内容(它还将创建具有修改后内容的 utrunner.py.orig 文件;实际上它将切换 。 py 和 .py.orig 文件)。 不过 总是回到3 次三方修改之前文件了(特别是如果他们被一些工具/安装跟踪),这样,如果在修改他们不顺心的事,总有恢复原来状态的方法
patch -Ri /tmp/utrunner.patch
虽然这里不是这种情况,但是如果更改是以另一种形式进行的,例如应用了 补丁 的文件(例如,在GitHub上),则显然可以获取整个文件(如果有很多文件,则将其全部向下跟踪可能会成为痛苦)并覆盖您的。但是同样, 请先将其备份 !
关于这种方法的几句话 :
该代码可以处理(可选)env var( DJANGO_TEST_MODE_GAINARIE除外 -这是强制性的):
manage.py test
manage.py test --help
globals()
R单击 相同的测试(删除其先前的配置:d后),然后 voilà :
E:\Work\Dev\VEnvs\py2713x64-django\Scripts\python.exe “C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py” E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions true Testing started at 01:38 … Using existing test database for alias 'default'... . ---------------------------------------------------------------------- Ran 1 test in 0.390s OK Preserving test database for alias 'default'... Process finished with exit code 0
E:\Work\Dev\VEnvs\py2713x64-django\Scripts\python.exe
“C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py” E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions true Testing started at 01:38 …
Using existing test database for alias 'default'... . ---------------------------------------------------------------------- Ran 1 test in 0.390s OK Preserving test database for alias 'default'... Process finished with exit code 0
调试也可以(断点等)。
注意事项 (到目前为止,我确定了其中两个):
input
raw_input
manage.py test -k
我已经在以下 环境中 工作/测试过:
注意事项 :
正如我在开始时所说的,任何建议都非常受欢迎!
@ EDIT0 :