TDD with Python (1) - Chapter 1

deutschina.hatenablog.com

数分の熟考を重ねた挙げ句、とりあえずこれを触ってみることにしました。ただ、入門Python3を一気に駆け抜けたようにまとまった時間は取れないと思いますが。

Test-Driven Development with Python

Test-Driven Development with Python

その前に前提が入っているかの確認。入門Python3などを通じて色んなパッケージを入れたけど、今使っているPython3.4.3環境にはこんなものが入っていました。

$ pip3 freeze
appnope==0.1.0
backports-abc==0.4
decorator==4.0.6
Django==1.9
gnureadline==6.3.3
ipykernel==4.2.1
ipython==4.0.1
ipython-genutils==0.1.0
ipywidgets==4.1.1
Jinja2==2.8
jsonschema==2.5.1
jupyter==1.0.0
jupyter-client==4.1.1
jupyter-console==4.0.3
jupyter-core==4.0.6
MarkupSafe==0.23
mistune==0.7.1
nbconvert==4.1.0
nbformat==4.0.1
notebook==4.0.6
path.py==8.1.2
pexpect==4.0.1
pickleshare==0.5
ptyprocess==0.5
Pygments==2.0.2
pyzmq==15.1.0
qtconsole==4.1.1
selenium==2.48.0
simplegeneric==0.8.1
terminado==0.5
tornado==4.3
traitlets==4.0.0
virtualenv==13.1.2

本の前提としてDjango1.7、seleniumと指定されているんだけど、Djangoが1.9だけど多分大丈夫だろうと言うことで、このまま突き進んでみる。

はじめの第一歩

こんなコードを作って流す。

$ python3 functional_tests.py

f:id:deutschina:20151230135203p:plain
Firefoxが立ち上がたけど、こんな感じでエラーが出たかと思ったら、これが出て終了。

$ python3 functional_test.py
Traceback (most recent call last):
  File "functional_test.py", line 6, in <module>
    assert "Django" in browser.title
AssertionError

ま、普通に考えてWebサーバーを立ち上げてないから当たり前かと。

$ django-admin.py startproject superlists

まずはDjangoのプロジェクトを立ち上げてからのrunserverという見るからにサーバー起動っぽいコマンドを実行。

$ python3 superlists/manage.py runserver
Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.

December 30, 2015 - 04:59:30
Django version 1.9, using settings 'superlists.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

なんか怒られたけど、127.0.0.1:8000でサーバーにアクセス出来るようなので、さっきのfunctional_test.pyを実行してみると。

$ python3 functional_test.py
$

f:id:deutschina:20151230140405p:plain
コマンド上は何も表示されないけど、Webページが表示されて、タイトルを見るとWelcome to Ddjangoとある。Djangoではないなと思ってソースを見たら、in演算子なのでDjangoが含まれていればいいってことだね。

assert "Django" in browser.title

ちなみに、本に載っているようなディレクトリ構成をツリー状に表示するにはtreeをインストールする必要がある(Macの場合)。

$ brew install tree
==> Downloading https://homebrew.bintray.com/bottles/tree-1.7.0.yosemite.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring tree-1.7.0.yosemite.bottle.1.tar.gz
🍺  /usr/local/Cellar/tree/1.7.0: 7 files, 128K

これで、こんな感じでやれば、本で見るのと同じようにツリー状で表示される。

$ tree superlists -a
superlists
├── .ipynb_checkpoints
│   └── Untitled-checkpoint.ipynb
├── Untitled.ipynb
├── db.sqlite3
├── manage.py
└── superlists
    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-34.pyc
    │   ├── settings.cpython-34.pyc
    │   ├── urls.cpython-34.pyc
    │   └── wsgi.cpython-34.pyc
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Gitする

これからやっていくにあたって、きちんとGitで管理しましょうねと言うことで、初期化の方法が紹介されている。

$ ls
functional_test.py	superlists		superlists2
$ mv functional_test.py superlists/
$ cd superlists
$ git init .
Initialized empty Git repository in /Users/ken/Documents/workspace/PycharmProjects/TDDPython/superlists/.git/
$

init .なので、カレントディレクトリ全体が対象になると理解。さらに続ける。

$ ls
Untitled.ipynb		db.sqlite3		functional_test.py	manage.py		superlists
Kens-Macbook-Air-2010:superlists ken$ echo "db.sqlite3" >> .gitignore
Kens-Macbook-Air-2010:superlists ken$ git add .
Kens-Macbook-Air-2010:superlists ken$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   .gitignore
	new file:   .ipynb_checkpoints/Untitled-checkpoint.ipynb
	new file:   Untitled.ipynb
	new file:   functional_test.py
	new file:   manage.py
	new file:   superlists/__init__.py
	new file:   superlists/__pycache__/__init__.cpython-34.pyc
	new file:   superlists/__pycache__/settings.cpython-34.pyc
	new file:   superlists/__pycache__/urls.cpython-34.pyc
	new file:   superlists/__pycache__/wsgi.cpython-34.pyc
	new file:   superlists/settings.py
	new file:   superlists/urls.py
	new file:   superlists/wsgi.py

db.sqliteを対象外にするために.gitignoreにパスした後に、それ以外のものをgit add .でレポジトリに追加。最後にステータスを表示させたという感じだね。

$ git rm -r --cached superlists/__pycache__
rm 'superlists/__pycache__/__init__.cpython-34.pyc'
rm 'superlists/__pycache__/settings.cpython-34.pyc'
rm 'superlists/__pycache__/urls.cpython-34.pyc'
rm 'superlists/__pycache__/wsgi.cpython-34.pyc'

__pycache__の下にある.pycファイルも管理する必要がないので外しますってことですね。

$ echo "__pycache__" >> .gitignore
$ echo "*.pyc" >> .gitignore
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   .gitignore
	new file:   .ipynb_checkpoints/Untitled-checkpoint.ipynb
	new file:   Untitled.ipynb
	new file:   functional_test.py
	new file:   manage.py
	new file:   superlists/__init__.py
	new file:   superlists/settings.py
	new file:   superlists/urls.py
	new file:   superlists/wsgi.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   .gitignore

$

今後もpycファイルたちをgitで無視するようにしますってことだね。はい、commitします。

$ git commit

vimが立ち上がるので、iキーをタイプして、INSERTモードにしてから、コメントを書いたら、ESCキーでノーマルモードに戻して、:wq!で保存する。
f:id:deutschina:20151230144801p:plain

[master (root-commit) 292cd28] First commit: First FT and basic Django config
 Committer: Ken <ken@Kens-Macbook-Air-2010.local>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:

    git config --global --edit

After doing this, you may fix the identity used for this commit with:

    git commit --amend --reset-author

 9 files changed, 257 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 .ipynb_checkpoints/Untitled-checkpoint.ipynb
 create mode 100644 Untitled.ipynb
 create mode 100644 functional_test.py
 create mode 100755 manage.py
 create mode 100644 superlists/__init__.py
 create mode 100644 superlists/settings.py
 create mode 100644 superlists/urls.py
 create mode 100644 superlists/wsgi.py

これで第1章完了。この本は、チュートリアル形式になっているので、手を動かす分には進めやすそう。

(負担にならない程度につづく)