PAIZAスキルチェックでコードを提出するまでのTDDプロセスを晒す。

# TLDR
PAIZAスキルチェックで実践するゆるいTDDの話
PythonとunittestでなんとかなるからPython使おうぜ
**[コーディング]**を快適にすることで、
- スキルチェックにアタックするモチベを上げたり
- コーディング時の準備のハードルを下げたり
できたらいいな。

# つぶやき
- [前回の記事](https://qiita.com/arch_liz/items/240926302148b8c0d97d)のアップデート版。
- **プロセスが意外と面倒なことに嫌気が刺した**。
- モバイル・タブレットからの提出プロセスの自動化に向いていない。
- モバイル・タブレットからは**Pythonista内でコーディングプロセス**を完結させたい。

# スキルチェックのプロセス
1. 問題を選んで「チャレンジ」をクリックする。
3. 「問題にチャレンジする」をクリックする。
4. 問題文を読んで問題に題意を確認する。
5. 入力例・出力例を確認する。
6. 言語を選択してコーディングする。
7. **[コーディング]** 入力に対する出力を実装
8. **[コーディング]** 必要なら関数やクラスに分割
9. **[コーディング]** テストケースをチェック
10. 頑張ってなんとか形になっら提出する。
11. PAIZA側でテストケースを評価される。
12. スコアやランクが決まる。

# 方針
- 解答までの時間を可能な限り短縮できる方法を実装すること．
- スキルチェック問題で提示されている全ての入出力例をテストできること．

# 導入

```sh
skillcheck/
├── Makefile
├── solve.py
├── test_solve.py
└── testcases.txt
```

```makefile:Makefile
test:
    python3 ./test_solve.py

save:
    pbcopy < ./solve.py
```

```vimrc:vimrc
nmap [makefile] <Nop>
map <Space>mk [makefile]
nnoremap [makefile]c :make <Space>
nnoremap [makefile]t :make test<CR>
nnoremap [makefile]s :make save<CR>
```

```python:solve.py
# solve.py

''' PROBLEM ID
MEMO FOR PROBLEM SOLUTION
'''

__author__ = 'AUTHOR NAME'
__version__ = 'VERSION NUMBER'
__date__ = 'YYYY-MM-DD'


def solve(input=input):
    '''
    数字Nをa倍して表示する
    '''
    N, a = list(map(int, input().split()))
    return a * N


if __name__ == '__main__':
    print(solve())
```

```python:test_solve.py
# coding: utf-8
# test_solve.py

import re
import unittest


# depends on testcases format
SPLIT = '--'
PATTERN = u'入力例[0-9]|出力例[0-9]'
LABELS = ['equal', 'not equal']


def _format(text):
    testcases = list(map(
        lambda x: '\n'.join([
            s.strip()
            for s in x.split('\n')
            if s.strip() != ''
        ]),
        re.split(PATTERN, text)[1:]
    ))

    return list(zip(testcases[0::2], testcases[1::2]))


def format(filename):
    import codecs

    with codecs.open(filename, 'r', 'utf-8') as f:
        testcases = dict(zip(
            LABELS,
            list(map(
                _format,
                re.split(SPLIT, f.read())
            ))
        ))

    return testcases


def readlines(testcase_input):
    from collections import deque
    dq = deque(testcase_input.split('\n'))
    return lambda _=None: dq.popleft()


class TestSolve(unittest.TestCase):
    def setUp(self):
        self.__testcases = format('testcases.txt')

    def test_solve(self):
        from solve import solve

        JUDGES = [
            self.assertEqual,
            self.assertNotEqual
        ]

        for label, judge in zip(LABELS, JUDGES):
            for tci, tco in self.__testcases[label]:
                judge(str(solve(readlines(tci))), tco)


if __name__ == '__main__':
    unittest.main()
```

```text:testcases.txt
入力例1
5 2

出力例1
10
--
入力例2
0 1

出力例2
1
```

# 使い方
1. solve.pyの関数solveを書き換える。
2. 通常通り、input()で取得した一行あたりの文字列に対する処理を書く。
3. 関数solveの引数input=inputは変更してはいけない。
4. test_solve.pyのクラスTestSolveでtestcases.txtに記述したテストケースを読み込むため。
5. とりあえず、「問題にチャレンジする」をクリックしたらテストケースをtestcases.txtにコピペ。
6. test_solve.pyを実行 or [make test]する。
7. きっと失敗するはず。
8. そしたらコーディングをコツコツやってゆるくTDDする。
9. 分割した関数やクラスなんかもtest_solve.pyに放り込んでテストファースト実践してみる。

# まとめ
Pythonista3でも快適にコーディングできて良さげだと僕は思う。
※TDDってなんだっけ。。。

# 資料
[テスト駆動開発ってなんだろう](https://dev.classmethod.jp/study_meeting/read/what-tdd/)