Visual Studio CodeでPython + Djangoを書いて、py.testを実行してみた

それなりの規模のDjangoアプリを書く場合、PyCharmなどのIDEを使っています。

ただ、諸般の事情によりIDEが使えないことも考えて、Visual Studio Code(以下VS Code)のPython拡張を試してみました。
Python with Visual Studio Code - Visual Studio Code

 
なお、今回は上記の公式ドキュメント例にもある通り、DonJayamanneさんのPython support for Visual Studio Codeを使います。
DonJayamanne/pythonVSCode: Python support for Visual Studio Code

 
目次

 

環境

 

環境準備

Python support for Visual Studio Codeのインストール

コマンドプロンプトからDjango用のディレクトリを用意し、そのディレクトリでVS Codeを起動します。

# ディレクトリ作成と移動
D:\Sandbox>mkdir vscode_django
D:\Sandbox>cd vscode_django

# カレントディレクトリとして VS Codeを起動 (末尾のドットを忘れずに)
D:\Sandbox\vscode_django>code .

 
VS Codeが起動したら、

  • Ctrl + Alt + P(もしくはF1)でコマンドパレットを起動
  • ei(Extensions: Install Extension) と入力して、拡張機能:拡張機能のインストールを選択
  • Python (DonJayamanne)を選択し、インストール
  • インストール後、VS Codeを再起動

と、Pythonを設定します。

 

Djangoのインストールと確認

今回はVS Code上のターミナルで実行します。ただ、現時点のバージョンではコピー&ペーストができません(↑・↓で入力履歴の再表示は可能)。
ターミナルを統合した「Visual Studio Code」インサイダー版、6月から日毎リリースに - 窓の杜

  • 表示 > Toggle Integrated Terminal (もしくはCtrl + @) を選択
  • 画面の下にターミナルが開く
  • ターミナルに以下を入力
# virtualenv環境を作成
D:\Sandbox\vscode_django>virtualenv -p c:\python35-32\python.exe env
D:\Sandbox\vscode_django>env\Scripts\activate

# pipでインストール
(env) D:\Sandbox\vscode_django>pip install django
...
Successfully installed django-1.9.7

 
続いて、Djangoのインストール先を確認するため、以下のPythonスクリプトを作成します。
Python Tips:ライブラリ・モジュールの場所を調べたい - Life with Python

django_checker.py

import django
print(django.__file__)

 
Debug Viewに切り替えます(Ctrl + Shift + D)。

  • 実行ボタンを押す(F5)
  • 環境の選択を求められるので、Pythonを選択
  • 情報バーにPlease set up the launch configuration file for your applicationが、エディタにlaunch.jsonが表示
  • launch.jsonはデフォルトのまま、django_checker.pyファイルを選択
  • 実行環境でPythonが選択されていることを確認の上、実行ボタンを押す(F5)
  • ファイアウォールのブロック表示がでたら、必要な内容をチェックしてアクセスを許可
  • デバッグコンソールに以下が表示
Traceback (most recent call last):
  File "d:\Sandbox\vscode_django\django_checker.py", line 1, in <module>
    import django
ImportError: No module named 'django'

Djangoが認識されていないことから、virtualenvのPythonインタプリタは使われていないようです。

 
公式ドキュメントによると、対応方法としては

  • settings.jsonpython.pythonPathを指定する
  • virtualenv環境をactivateしてから、VS Codeを起動する
  • launch.jsonpythonPathを指定する
    • 今回の場合、"pythonPath": "${workspaceRoot}/env/Scripts/python.exe",
    • ただし、この場合はデバッグ時だけ有効で、エディタのインテリセンスなどが効かない

の3つが挙げられていました。
Python Path and Version · DonJayamanne/pythonVSCode Wiki

エディタのインテリセンスは効かせたいこと、グローバルな設定は避けたいことから、今回はvirtualenv環境をactivateしてから、VS Codeを起動する方法をとります。

 
そのため、いったん VS Codeを閉じてから、以下のようにVS Codeを起動します。

# virtualenvをon
D:\Sandbox\vscode_django>env\Scripts\activate

# VS Codeの起動
(env) D:\Sandbox\vscode_django>code .

 
再度、django_checker.pyファイルを選択し、デバッグ実行(F5)します。デバッグコンソールには

D:\Sandbox\vscode_django\env\lib\site-packages\django\__init__.py

と表示され、virtualenvのPythonインタプリタで実行されるようになりました。

 

Djangoアプリの作成

It worked!の確認

VS Code ターミナルを起動し(Ctrl + @)、Djangoアプリを作成します。

(env) D:\Sandbox\vscode_django>django-admin startproject myproject .
(env) D:\Sandbox\vscode_django>python manage.py startapp myapp

また、myproject/settings.pyINSTALLED_APPSに、上記作成のアプリmyappを追加します。

 
Djangoアプリができたため、

  • Debug viewに切り替える(Ctrl + Shift + D)
  • Djangoを選んでから、実行ボタンを押す(F5)
  • manage.pyの一行目のところで停止するが、そのまま続行(F5)
  • Debug Consoleに開発サーバの起動が表示
  • ブラウザでhttp://localhost:8000/へとアクセスすると、It worked!が表示されます。

を行い、動作を確認します。

 
なお、該当するlaunch.jsonの内容は

{
    "name": "Django",
    "type": "python",
    "request": "launch",
    "stopOnEntry": true,
    "program": "${workspaceRoot}/manage.py",
    "args": [
        "runserver",
        "--noreload"
    ],
    "debugOptions": [
        "WaitOnAbnormalExit",
        "WaitOnNormalExit",
        "RedirectOutput",
        "DjangoDebugging"
    ]
},

でした。

--noreloadがあることから、オートリロードされないのがデフォルトのようです。もし、オートリロードしたい場合はその部分を削除します。

 

Djangoアプリへ機能を追加

Hello worldを表示するよう、機能を追加します。

myproject/urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^myapp/', include('myapp.urls', 'my')),  # 追加
]

 
myapp/urls.py

from django.conf.urls import url
from django.views.generic.base import TemplateView

urlpatterns = [
    url(r'^$', 
        TemplateView.as_view(template_name='hello.html'),
        name='hello'),
]

 
myapp/templates/hello.html

<h1>Hello world!</h1>

 
完成したため、

  • Djangoを選択して実行ボタンを押す(F5)
  • http://localhost:8000/myapp/へアクセスすると、Hello world!が表示

にて動作を確認します。

 

py.testの設定と実行

以前、Djangoアプリをpytest-djangoでテストしたことがあったため、同じように作業します。
Djangoアプリについて、pytest-djangoを使ってテストしてみた - メモ的な思考的な

 
ターミナルにてインストールします。

(env) D:\Sandbox\vscode_django>pip install pytest pytest-django

 
pytest.iniを書きます。

pytest.ini

[pytest]
DJANGO_SETTINGS_MODULE=myproject.settings
norecursedirs=env

 
URL解決のテストを書きます。

py.testのデフォルトでは、test_*.pyというファイル名であればテストファイルとみなされます。そのため、Djangoが自動生成したmyapp/tests.pyはテストの対象とはなりません。
My tests are not being found. Why not? | FAQ — pytest-django documentation

そこで、myapp/tests/ ディレクトリを作成し、その中にテストファイルtest_urls.pyを作成することにします。

 
まずはエラーとなるよう、テストコードを書きます。

myapp/tests/test_urls.py

# myapp.urls.py
# urlpatterns = [
#    url(r'^$', TemplateView.as_view(template_name='hello.html'), name='hello'),]

# テストコード
class URL解決テスト(TestCase):
    def test_helloのパスが404とならないこと(self):
        try:
            resolve('/mysite/hello')
        except Resolver404:
            pytest.fail('raise error')

 
ターミナルから実行します。

(env) D:\Sandbox\vscode_django>py.test

...
myapp\tests\test_urls.py:11: Failed

エラーになりました。また、一部が文字化けしています。

 
テストが通るように修正します。

myapp.urls.py

urlpatterns = [
    url(r'^hello$', 
        TemplateView.as_view(template_name='hello.html'),
        name='hello'),
]

 
もう一度テストします。

(env) D:\Sandbox\vscode_django>py.test
...
========================== 1 passed =...

テストが通りました。

 
以上より、VS Codeを使ってPython + Djangoを書いて、py.testを実行することができました。

 

IDE機能

IDE機能もありました。

 

インテリセンス

f:id:thinkAmi:20160705220750p:plain

 

メソッドの引数の表示

f:id:thinkAmi:20160705220802p:plain

 

コードナビゲーション
  • Go To Definition(定義へ移動)
  • Peek Definition(定義をここに表示)
  • Find All References(すべての参照の検索)

f:id:thinkAmi:20160705220812p:plain

 

linter設定

Linting · DonJayamanne/pythonVSCode Wiki

 
他にもいろいろとありました。

なお、現時点では、タブはまだprerelease Insiders buildのため、今後に期待します。
Tabbed editor support in Visual Studio Code

2016/7/9 追記

先日リリースされた1.3.0にてタブ機能が追加されました。

2016/7/9 追記おわり

 

ソースコード

GitHubにあげておきました。
thinkAmi-sandbox/vscode_django-sample

なお、デバッグ時のみvirtualenv環境が使われるのを確認するために、pythonPathを追加した.vscode/launch.jsonも入れてあります。

 

その他参考

 
なお、公式ドキュメントではlaunch.jsonに関する説明が見当たりませんでした。そのため、以下を参考にしました。
特集:VS Code早分かりガイド:Visual Studio CodeでNode.jsアプリをデバッグする (2/4) - @IT