[解決済み] PyCharm Community Editionでマウスの右クリックコンテキストメニューからDjangoアプリケーションのUnitTestsを実行/デバッグしますか?
質問
を強調しなければなりません。 PyCharm コミュニティ エディション を行うものです。 がない ジャンゴ 統合 ( v 2016.3.2 質問時)。
私は グーグル もちろん、回答がある可能性を排除するものではありませんが、私が見逃していただけなのです。
質問は簡単です。 PyCharm を実行(デバッグ)することができます。 テストケース またはそのメソッドの1つ)を、下の画像のようにマウスの右クリック(コンテキストメニューから)で簡単に実行することができます。
残念ながら、例外が発生します。
Traceback (most recent call last): File "C:\Install\PyCharm Community Edition\2016.3.2\helpers\pycharm\utrunner.py", line 254, in <module> 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 <module> from polls.models import Question File "E:\Work\Dev\Django\Tutorials\proj0\src\polls\models.py", line 9, in <module> 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.
備考 : 誰かの役に立つかもしれない答えを提供するために、質問を追加しただけです。
解決方法を教えてください。
1. 背景情報
- のみで作業しています。 Django 3ヶ月間
- について PyCharm 私は何年かそれを使って仕事をしてきましたが、IDEとしてのみ(例えば PyCharm for dummies そのため、高度な内容には触れていません。
以上のことを考えると、一部(または全部)の解決策は、一部の上級ユーザにとっては面倒/バカバカしいと思われるかもしれませんので、ご容赦ください。この解決策に付加価値を与えてくれるようなコメントがあれば、それを取り入れるつもりです。
質問に戻ります。私は、次のようなプロジェクトでテスト/調査を行いました。
Djangoチュートリアル
(
[DjangoProject]です。最初の Django アプリを書く
) + の一部と
Django Rest フレームワーク チュートリアル
(
[DRF]: クイックスタート
). 例として、次のような実行を試みます。
polls/tests.py
:
QuestionViewTests.test_index_view_with_no_questions()
メモとして 設定 django_settings_module 例外の指示通り もう1つのトリガー などなど.
2. を作成する パイソン コンフィギュレーション
これは質問に対する答えではありませんが(遠隔的に関連しているだけです)、とりあえず投稿しておきます(すでに多くの人がやっていることでしょう)。
- メニューをクリック 実行 -> 設定を編集する...
-
について
実行/デバッグ設定
ダイアログを表示します。
- タイプを持つ新しいコンフィギュレーションを追加します。 パイソン
- を設定します。 作業ディレクトリ をプロジェクトのルートパスに設定します(私の場合、" E:∕Work∕Dev∕Django∕Tutorials∕proj0src ")。デフォルトでは、このパスは Python のモジュール検索パス
- を設定します。 スクリプト を指定します。 Django プロジェクト起動スクリプト ( manage.py )
-
を設定します。
スクリプトのパラメータ
をテストパラメータに設定します (
test QuestionViewTests.test_index_view_with_no_questions
) - 設定に名前を付け(任意)、次のようにクリックします。 OK . これで、このテストを実行できるようになります。
もちろん、すべてのテストケース(とそのメソッド)に対してこれを行わなければならないのは、(本当に迷惑な話ですが)この方法はスケーラブルではありません。
3. 調整する PyCharm を実行することができます。
ただ、これは真の解決策とはいえず、むしろ(いい加減な)回避策のようなものだということは指摘しておきます ( ゲイナーリー )であり、しかも押し付けがましい。
まずは、次のようなことが起こるのかを見てみましょう。 Rクリック の上に テスト (この用語は一般的に使用するつもりで、特に指定しない限り、テストケース、メソッド、テストファイル全体を意味することがあります)。私の場合は、以下のコマンドを実行しています。
"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:\InstallPyCharm Community Edition2016.3.2版helpers "(以下、こう呼ぶことにします。 utrunner )を引数の束で指定します(1 st は、テスト仕様なので、私たちには重要です)。 ユートランナー を気にしないテスト実行フレームワークを使用しています。 Django (実際には、いくつかの Django を処理するコードですが、それは私たちの助けにはなりません)。
について一言。 PyCharm `s 実行/デバッグの設定 :
- いつ Rクリック -をクリックすると テスト , PyCharm を自動的に作成します。 実行設定 (保存できるようになります)。 実行/デバッグ設定 ダイアログを表示します。アン 重要 であるコンフィギュレーションタイプに注意する必要があります。 Pythonテスト/Unittests (これは自動的に ユートランナー )
- を作成する場合 実行設定 を一般的に使用します。 PyCharm そのコンフィギュレーションタイプの設定をコピーします。 既定値 (で見ることができます)。 実行/デバッグ設定 を新しいコンフィギュレーションに追加し、その他の部分を特定のデータで埋めます。について重要なことが一つあります。 デフォルトの設定 は、それらが プロジェクトベース に存在する。 .アイデア フォルダー ( ワークスペース.xml そのため、それらを変更しても、他のプロジェクトに影響を与えることはありません(最初に心配したとおりです)。
以上を踏まえて、進めていきましょう。
最初のこと を実行する必要があります。 実行/デバッグ設定 ダイアログ(メニュー。 実行 -> 設定を編集する... を編集してください。 デフォルト/Pythonテスト/Unittests の設定を行います。
- を設定します。 作業ディレクトリ 先ほどの方法と同じように
- での 環境変数 という名前の新しいものを追加してください。 django_test_mode_gainarie という文字列を設定し、それを任意の文字列(空/ ヌル )
2つ目 そして、より厄介なのは(侵入を伴う)、パッチを当てることです。 ユートランナー .
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()
上記は
差分
(
[man7]を参照してください。DIFF(1)
) (または
パッチ
- は連結して使用することができます。
パッチ
): の違いを示しています。
utrunner.py.orig
(元のファイル - 修正を始める前に保存しておいたものです。
utrunner.py
(変更を含む現在のバージョン)。私が使用したコマンドは
diff --binary -uN utrunner.py.orig utrunner.py
(当然ながら
ユートランナー
のフォルダ)。個人的な感想として
パッチ
を変更するのに適した形式です。
rd
パーティーのソースコードです(変更を管理下に置き、分離するため)。
のコードは何ですか? パッチ は何をするのか(おそらく、プレーンな Python のコード)。
-
の下にあるものはすべて
メイン
ブロック (
if __name__ == "__main__":
という関数に移動されました。 メイン (分離して、間違って変更しないようにするため) -
は、その
メイン
ブロックが修正され、もし env var が
django_test_mode_gainarie
が定義されている場合(そして空でない場合)、新しい実装に従います (
djangoMain
関数)、それ以外の場合は
通常
. 新しい実装です。
-
ファイルトモッド
減算
ベースパス
から
ファイルパス
に変換し、その差分を
パイソン
パッケージのスタイルです。例
fileToMod("E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py", "E:\Work\Dev\Django\Tutorials\proj0\src")
を返します。polls.tests
-
utrunnerArgToDjangoTest
: 前の関数を使用し、クラス名 (
QuestionViewTests
) と (オプションで) メソッド名 (
テストインデックス_ビュー_質問なし
に変換され、最後にテスト仕様が
ユートランナー
形式(
E:\Work\Dev\Django\Tutorials\proj0\src\polls\tests.py::QuestionViewTests::test_index_view_with_no_questions
) から manage.py フォーマット (polls.tests.QuestionViewTests.test_index_view_with_no_questions
) - フラッシュバッファ を書き込む。 eoln を生成し、それをフラッシュします。 標準出力 と 標準エラー バッファを使用する必要があります。 PyCharm と Django が交錯し、最終的にぐちゃぐちゃになる)
-
RunModAsMain
: 通常、関連するすべての
manage.py
のコードは
if __name__ == "__main__":
. この関数 "tricks"。 パイソン と思わせる manage.py は、その1として実行されました。 st 引数
-
ファイルトモッド
減算
ベースパス
から
ファイルパス
に変換し、その差分を
パイソン
パッケージのスタイルです。例
パッチング ユートランナー :
- これらの改造は自分でやりました(以下のようなバージョンを検索していません)。 Django を統合し、そこからインスパイアする)
- ユートランナー は次の製品に含まれます PyCharm . なぜ JetBrains を入れなかったのは 任意の ジャンゴ を統合しています。 コミュニティ版 を買わせるためのものです。 プロフェッショナル版 . これは、彼らのつま先を踏んでいるようなものです。を変更することが法的にどのような意味を持つのか、私は知りません。 ユートランナー が、とにかくパッチを当てれば 自分の責任とリスクでやってください。
- コーディングスタイル:最悪です(少なくともネーミング/インデントから POV しかし、ファイルの他の部分と一貫性があります(コーディングスタイルが最悪であることが許される唯一のケースです)。 [Python]: PEP 8 -- Pythonコードのためのスタイルガイド のコーディングスタイルガイドラインが含まれています。 Python
-
パッチは、元のファイル(
utrunner.py
) で、以下のようなプロパティがあります (このプロパティはまだ
v
2019.2.3
(最終確認済み。
20190930
)):
- の大きさを指定します。 5865
- sha256sumです。 db98d1043125ce2af9a9c49a1f933969678470bd863f791c2460fe090c2948a0
-
を適用する。
パッチ
:
- ユートランナー は"にあります。 ${PYCHARM_INSTALL_DIR}/helpers/pycharm "です。
-
典型的な例です。
pycharm_install_dir} を指定します。
を指しています。
- ニックス : /usr/lib/pycharm-community
- 勝利 : " C:\Program Files (x86)\JetBrains PyCharm 2016.3 "(お使いのバージョン番号に合わせます)
- を保存します。 パッチ のコンテンツ(例えば、次のようなファイル)を作成します。 utrunner.patch の下にあると仮定します。 /tmp )
-
ニックス
- は簡単で、ただ (
cd
に
utrunner
のフォルダで)実行する
patch -i /tmp/utrunner.patch
. [man7]を参照してください。PATCH(1) は、デフォルトでインストールされるユーティリティです( パッチ でのdpkg ユーブツ ). なお utrunner.py が所有する ルート この手順で必要なのは sudo -
勝つ
- と同じような手順を踏みますが、ネイティブの
パッチ
ユーティリティを使用します。ただし、回避策はあります。
- 使用する Cygwin . のように ニックス ( Lnx ) の場合です。 パッチ ユーティリティが利用可能ですが デフォルトではインストールされません。 . その パッチ pkgは必ず 明示的に からインストールされます。 Cygwinのセットアップ . これを試したところ 動作する
-
代替品がある(試していない)。
- [SourceForge.GnuWin32]を参照してください。Windows用パッチ
- 理論的には [RedBean】:svnパッチ (どんなクライアントでも) は パッチ の一部であるべきなのでしょうか、しかし、そのファイルが 作業コピー .
- を適用する。 パッチ を手動で実行します (あまり望ましくないオプションですが :) 。)
- のように ニックス の場合、ファイルのパッチは (ほとんどの場合) 管理者 . また、ファイルのパスに注意して、必ず (ダブル)クォート スペースが含まれている場合
-
を元に戻す
パッチ
:
-
バックアップは有害ではありません(ただし、ディスクの空き容量の
POV
とか、溜まってくると管理が面倒になるとか)。私たちの場合は必要ありません。変更を戻すには、変更したファイルに対してこのコマンドを実行すればよい。
patch -Ri /tmp/utrunner.patch
そうすると、元のコンテンツに切り替わります。 utrunner.py.orig ファイルを変更します。 .py と .py.orig ファイル)を作成します。
とはいえ いつもバック3 rd -パーティーのファイルを変更する前にアップする (特にツールやインストーラによって追跡されている場合)、変更中に何か問題が発生しても、元の状態に戻す方法が常にあるようにします。
-
バックアップは有害ではありません(ただし、ディスクの空き容量の
POV
とか、溜まってくると管理が面倒になるとか)。私たちの場合は必要ありません。変更を戻すには、変更したファイルに対してこのコマンドを実行すればよい。
- 今回のケースとは異なりますが、変更が別の形で行われた場合、例えばファイルに パッチ を適用した(例えば ギットハブ ) の場合、明らかにファイル全体を取得し (ファイルが多数ある場合、それらをすべて追跡するのは面倒になります)、自分のを上書きすることができます。しかし、もう一度言います。 最初にバックアップを取る !
この方法について一言 :
-
コードが(オプションの)envバーを扱うことができる。 django_test_mode_gainarie - これは必須です)。
- django_startup_name : 万が一 manage.py が別の名前を持っていたり (何らかの理由で?)、あるいは他のフォルダーにあったりした場合、そのフォルダーは 作業ディレクトリ . について 重要 ファイルパスを指定するときは、プラットフォーム固有のパスセパレータを使用することです。 スラッシュ ( / ) のために ニックス , bkslash ( \ ) のために 勝利
-
django_startup_test_args
の追加引数です。
manage.py test
を受け付ける(実行manage.py test --help
で全リストを取得します)。ここで、私が主張しなければならないのは -k / --keepdb で、テスト用データベースを保持する ( test_${REGULAR_DB_NAME} とします。 で設定されています。 設定 の下にある TEST ディクショナリ)を実行する間に 単一のテストを実行する場合 DB (そしてすべてのマイグレーションを適用する)そしてそれを破棄するのは時間がかかる(そして非常に迷惑でもある)場合がある。このフラグは DB は最後に削除されず、次のテスト実行時に再利用されます。 -
django_startup_additional_globals
: これは文字列表現が必要です。
Pythonのディクショナリ
. 何らかの理由で
manage.py
に存在する必要があります。
globals()
ディクショナリーをここに配置する必要があります。
-
を修正する場合 デフォルト設定 の場合、それを継承する以前に作成されたすべてのコンフィギュレーションは、それを継承します。 は更新されません。 そのため、手動で 削除 (そして、新しい Rクリック の テスト )
Rクリック を同じテストに使用し (以前の設定を削除した後:d)、そして さあ :
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
デバッグも動作します(ブレークポイントなど・・・)。
注意事項 (今のところ2つ確認しました)。
- これは良性で、ただの UI の問題です。 ユートランナー (ほとんどの場合)いくつかの初期化で PyCharm が行われることを期待しているのですが、今回のケースでは明らかにそうではありません。そのため、テストが正常に終了しても PyCharm 's PoV ということで 出力 のウィンドウに警告が表示されます。 テストフレームワークが予期せず終了した となります。
-
これは厄介なもので、私は(まだ)真相を知ることができませんでした。どうやら、である。
ユートランナー
任意
input
(raw_input
) の呼び出しはあまりうまく処理されません。プロンプトテキスト: " テストデータベース 'test_tut-proj0' を削除する場合は 'yes' を、キャンセルする場合は 'no' を入力してください。 "(前回のテスト実行がクラッシュした場合に表示され、その時の DB が最後に破棄されない)が表示されず、プログラムがフリーズしてしまう(これは ユートランナー ) 、ユーザーにテキストを入力させることはできません (スレッドが混在しているのかも?)。復旧するには、テスト実行を停止して DB を実行し、再度テストを実行します。ここでもまたmanage.py test -k
この問題を回避するためのフラグ
私は以下のように作業/テストしてきました。 環境 :
-
ニックス
(
Lnx
):
- Ubtu 16.04 x64
- PyCharm コミュニティ版 2016.3.3
- Python 3.4.4 ( VEnv )
- Django 1.9.5
-
勝利
:
- W10 x64
- PyCharm コミュニティ版 2016.3.2
- Python 2.7.13 ( VEnv )
- Django 1.10.6
備考 :
- 現在の問題点(少なくとも2つの nd 1)
- A クリーン の中で何らかの形で上書きすることです。 PyCharm を実行するデフォルトの設定(私がコードから行ったこと)ですが、私は設定ファイルを見つけることができませんでした(おそらく、それは PyCharm を使用します)。
- に固有のファイル/フォルダーがたくさんあることに気づきました。 Django の中にある ヘルパー ( ユートランナー の親)フォルダも使えるかもしれないので、確認が必要です。
冒頭で述べたように、どんな提案でも大歓迎です!
EDIT0 :
- Udiさんのコメントにも返信しましたが、これは、「Software」の「Software」を支払う余裕がない人(あるいは、その気がない会社)のための代替案です。 PyCharm プロフェッショナル版 ライセンス料(ざっと見た感じでは ~100$-200$ / 各インスタンスの1年分)
関連
-
Python関数の高度な応用を解説
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
任意波形を生成してtxtで保存するためのPython実装
-
Pythonショートビデオクローラーチュートリアル
-
PythonによるExcelファイルの一括操作の説明
-
PythonでECDSAを実装する方法 知っていますか?
-
[解決済み】TypeErrorの修正方法。Unicodeオブジェクトは、ハッシュ化する前にエンコードする必要がある?
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].
-
[解決済み】django インポートエラー - core.managementという名前のモジュールがない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ピローによる動的キャプチャ認識のためのPythonサンプルコード
-
PythonはWordの読み書きの変更操作を実装している
-
Python百行で韓服サークルの画像クロールを実現する
-
Pythonを使って簡単なzipファイルの解凍パスワードを手作業で解く
-
FacebookオープンソースワンストップサービスpythonのタイミングツールKats詳細
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】インポートエラー。モジュール名 urllib2 がない
-
[解決済み】SyntaxError: デフォルト以外の引数がデフォルトの引数に続く
-
[解決済み】 'numpy.float64' オブジェクトは反復可能ではない