SlideShare a Scribd company logo
WebTestでWeb APIのテスト
& Pythonメタプログラミングで
テストの自動生成
オーイシ
Shizuoka.py #6
Web APIを何故テストしたいの?
• データアーカイブを検索して再利用するためのラッパーAPI
を構築しています。
• 対象のデータベースが増える&検索対象のフィールドが増え
るとAPIが継ぎ足される感じで増えて行く。
• 仕様のアップデートで動作の影響が無いか検証する必用があ
る。
• APIが増えるとテストが大変。
WebTestとは
• WSGIアプリのテストをHTTPサーバを起動せずに行うことが
できる。※実サーバを使ったテストもできます。
• Pylons(Rails的なWebアプリケーションフレームワーク)の
パッケージの一部として開発されている。
• インストールは ”pip install WebTest” でOK
• http://docs.pylonsproject.org/projects/webtest/en/latest/
WebTestの簡単な例
from webtest import TestApp
def application(environ, start_response):
body = 'たのしー'.encode('utf-8')
headers = [('Content-Type', 'text/html; charset=utf8'),
('Content-Length', str(len(body)))]
start_response('200 OK', headers)
return [body]
app = TestApp(application)
resp = app.get('/')
assert resp.content_type == 'text/html'
assert resp.content_length > 0
assert 'たのしー' in resp
#assert 'すごーい' in resp
# このままだと実行しても何も起きないが
# assert 'すごーい' in resp をアンコメントすると
>Traceback (most recent call last):
> File "test_webtest_basic.py", line 16, in <module>
> assert 'すごーい' in resp
>AssertionError
unittestと一緒に使うことが多いのかも
• assertEqual(a, b)
• assertTrue(x)
• assertFalse(x)
• assertGreater(a, b)
• assertIn(a, b)
• assertIs(a, b)
• assertRaises
• 等々unittestのアサートメソッドを利用します
(バージョンによって利用出来るメソッドは異なる)
実サーバのテストのサンプル
os.environ['WEBTEST_TARGET_URL'] = 'http://target_api_address'
app = TestApp(index)
#またはapp = TestApp('http://target_api_address')
class ApiTest(unittest.TestCase):
def test_api_root(self):
res = app.get('/')
self.assertEqual(res.status, '200 OK')
self.assertEqual(res.content_type, 'application/json')
def test_get_ids(self):
res = app.get('/bioproject?organism_name=Papilio%20xuthus')
self.assertGreater(res.json['numFound'], 1)
def test_get_metadata(self):
res = app.get('/bioproject/PRJNA25')
keys = res.json.keys()
self.assertIn("Package", keys)
def test_post_ids(self):
res = app.post_json('/bioproject', {"ids": ["PRJNA26","PRJNA25"]})
res_len = len(list(res.json))
self.assertEqual(res_len, 2)
if __name__ == '__main__':
unittest.main()
WebTest +unittestの結果
#このままテストがエラーを発生せず完了すると
Ran 4 tests in 0.898s
OK
# エラーを発生するよう、テストを変更すると…
def test_post_ids(self):
res = app.post_json('/bioproject', {"ids": ["PRJNA26", "PRJNA25"]})
res_len = len(list(res.json))
self.assertEqual(res_len, 3)
F
==================================================================
FAIL: test_post_ids (__main__.ApiTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_api.py", line 27, in test_post_ids
self.assertEqual(res_len, 3)
AssertionError: 2 != 3
----------------------------------------------------------------------
Ran 4 tests in 0.575s
FAILED (failures=1)
テストの自動生成
ドキュメントベースでWeb APIのテストを管理・実施したい。
テストの自動生成パターンを4つ見つけました
1. 動的メソッド定義
2. メタクラス
3. nose × generator
4. nose_parameterized
動的メソッド定義
import unittest
l = [["foo", "a", "a"], ["bar", "a", "b"], ["baz", "b", "b"]]
class TestSequense(unittest.TestCase):
pass
def test_gen(a, b):
def test(self):
self.assertEqual(a, b)
return test
if __name__ == '__main__':
for t in l:
test_name = 'test_%s' % t[0]
test = test_gen(t[1], t[2])
setattr(TestSequense, test_name, test)
unittest.main()
F..
======================================================================
FAIL: test_bar (__main__.TestSequense)
~
Ran 3 tests in 0.001s
FAILED (failures=1)
動的メソッド定義
1. 高階関数のtest_genは引数(a, b)を受け取りアサートメソッドを
生成し、testメソッドを返す。
2. setattr()はTestCaseに新しい属性を追加する。その属性の値がメ
ソッド名(=test_name)と関数(=test)。
3. 1-2が設定リストの要素で繰り返される。
メタクラスによる動的テスト
import unittest
l = [["foo", "a", "b"], ["bar", "a", "b"], ["baz", "a", "a"]]
class TestSequenseMeta(type):
def __new__(mcs, cls_name, cls_base, cls_dict):
def gen_test(a, b):
def test(self):
self.assertEqual(a, b)
return test
for tname, a, b in l:
test_name = "test_{}".format(tname)
cls_dict[test_name] = gen_test(a, b)
return type.__new__(mcs, cls_name, cls_base, cls_dict)
class TestSequence(unittest.TestCase, metaclass=TestSequenseMeta):
pass
if __name__ == '__main__':
unittest.main()
F..
======================================================================
~
Ran 3 tests in 0.001s
FAILED (failures=1)
メタクラスによる動的テスト
1. クラス定義は実はtypeのインスタンス。type(クラス名、親クラス,
メソッドや属性を定義)。
2. クラス定義にmetaclassが存在すると、クラスを生成する前に
metaclassに格納された関数がtypeの代わりに呼び出される。
3. typeは__new__メソッドでクラス生成の主な処理を行う。メタク
ラスを使うとクラス定義時に処理が実行される。
4. サンプルでは、クラス生成の前にTestSequenseMeta()が呼び出さ
れ、クラス定義が返る
nose × generator
param_list = [('a', 'a'), ('a', 'b'), ('b', 'b')]
def test_generator():
for params in param_list:
yield check_em, params[0], params[1]
def check_em(a, b):
assert a == b
$ nosetests test_nose_generators.py
.F.
======================================================================
~
File "/Users/../test_nose_generators.py", line 11, in check_em
assert a == b
AssertionError
----------------------------------------------------------------------
Ran 3 tests in 0.002s
FAILED (failures=1)
nosetestsコマンドでtest_xx.pyなファイルを探し
てtest_な関数を実行してくれる。
nose_parameterized
from nose_parameterized import parameterized
import unittest
class TestSequence(unittest.TestCase):
@parameterized.expand(
[
["foo", "a", "b"],
["bar", "b", "b"],
["baz", "a", "a"],
])
def test_sequence(self, name, a, b):
self.assertEqual(a,b)
if __name__ == '__main__':
unittest.main()
FAIL: test_sequence_1_bar (__main__.TestSequence)
----------------------------------------------------------------------
~
File "test_nose_parameterized.py", line 13, in test_sequence
self.assertEqual(a,b)
AssertionError: 'a' != 'b'
- a
+ b
----------------------------------------------------------------------
Ran 3 tests in 0.001s
FAILED (failures=1)
decoratorの引数で
テストの設定を渡す感じ?
動的メソッド定義でWebTestしてみた
import unittest
from webtest import TestApp
app = TestApp('http://target_api_url')
tests = [["bioproject", "/bioproject/PRJNA25", "In", "Package"],
["organism_name", "/bioproject?organism_name=Papilio%20xuthus", "Greater", 1],
["root", "/sra", "Equal", "200 OK”]]
class TestSequense(unittest.TestCase):
pass
def test_gen(path, method, b):
def Equal(self):
res = app.get(path)
a = res.status
self.assertEqual(a, b)
def Greater(self):
res = app.get(path)
a = res.json['numFound']
self.assertGreater(a, b)
def In(self):
res = app.get(path)
a = res.json.keys()
self.assertIn(b, a)
#return eval(method)
return locals()[method]
if __name__ == '__main__':
for name, path, method, val in tests:
test_name = 'test_{}'.format(name)
test = test_gen(path, method, val)
setattr(TestSequense, test_name, test)
-------------------------------------------------------
Ran 3 tests in 0.298s
OK
でした。
- メタプログラミングなのにアドホックすぎ!
- さすがにこのままコレがしたいわけではない。
- 設定出来る項目が多すぎるのかも。
- テストのルールを整備しかつ大量なテストであれば使
えなくは無いかも。
参考サイト
How to generate dynamic (parametrized) unit tests in python?
http://stackoverflow.com/questions/32899/how-to-generate-dynamic-parametrized-unit-tests-in-python
メタプログラミングPython
https://tell-k.github.io/pyconjp2016/#1
Pythonによる黒魔術入門
http://www.slideshare.net/ssuser38b704/ll-lang-blackmagic
Pythonでメタプログラミング
http://qiita.com/fujimisakari/items/0d4786dd9ddeed4eb702

More Related Content

Viewers also liked (20)

PDF
Shizuoka.py #6 lt 確定申告をpythonで乗り切る
hiroshi sano
 
PDF
Tensor flowを使った キュウリの仕分け あれこれ
Makoto Koike
 
PDF
数学史 黎明期
yaju88
 
PDF
TensorFlowによるFizz Buzz
yaju88
 
PPTX
ClickでCLIをお手軽につくるぅぅぅ
Kazufumi Ohkawa
 
PDF
サザエさんのじゃんけん データ分析
yaju88
 
PPTX
第一回 機械学習
Akira Maegawa
 
PPTX
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
civicpg
 
PPTX
PGXでつぶやきの類似度によるグラフを生成してみた
Nao Oec
 
PPTX
For My Tay
kfudarky
 
PDF
BROOKLYN_DSM
Marleen Daniels
 
PPT
recent advancement in contraceptives
Manu Aravind
 
PDF
My balsamiqproject pdf
Daljit Kaur
 
PDF
Belgium franchise. Bebe de Paris. baby gifts
Elena Gomez del Pozuelo
 
ODP
Powerpoint ingles
Juan Manuel Castro
 
PPTX
Twitter retweet analysis
Masaki Takeda
 
PDF
בניית תכנית שנתית
sheatufim
 
PPTX
Plan educativo maternidad
Sianelys Varela
 
PDF
最近の単体テスト
Ken Morishita
 
PPTX
Didatica Docente - Educacion
Osman Villanueva
 
Shizuoka.py #6 lt 確定申告をpythonで乗り切る
hiroshi sano
 
Tensor flowを使った キュウリの仕分け あれこれ
Makoto Koike
 
数学史 黎明期
yaju88
 
TensorFlowによるFizz Buzz
yaju88
 
ClickでCLIをお手軽につくるぅぅぅ
Kazufumi Ohkawa
 
サザエさんのじゃんけん データ分析
yaju88
 
第一回 機械学習
Akira Maegawa
 
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
civicpg
 
PGXでつぶやきの類似度によるグラフを生成してみた
Nao Oec
 
For My Tay
kfudarky
 
BROOKLYN_DSM
Marleen Daniels
 
recent advancement in contraceptives
Manu Aravind
 
My balsamiqproject pdf
Daljit Kaur
 
Belgium franchise. Bebe de Paris. baby gifts
Elena Gomez del Pozuelo
 
Powerpoint ingles
Juan Manuel Castro
 
Twitter retweet analysis
Masaki Takeda
 
בניית תכנית שנתית
sheatufim
 
Plan educativo maternidad
Sianelys Varela
 
最近の単体テスト
Ken Morishita
 
Didatica Docente - Educacion
Osman Villanueva
 

Similar to Shizuoka.py #6 WebTestでWeb APIのテスト & Pythonメタプログラミングでテストの自動生成 (20)

PPTX
キーワード駆動によるシステムテストの自動化について 2015
Toru Koido
 
PDF
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
PPTX
Project lambda
Appresso Engineering Team
 
KEY
Sencha ug3 siesta_share
久司 中村
 
PPT
Apexコアデベロッパーセミナー(Apexコード)071010
stomita
 
PDF
ASP.NET シングル ページ アプリケーション (SPA) 詳説
Akira Inoue
 
PPT
Cubby 2006-08-23
Agata Toshikata
 
PDF
究極のバッチフレームワーク(予定)
fumoto kazuhiro
 
PPTX
Vertica 8.1.0 新機能
Kaito Tono
 
PDF
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
normalian
 
PDF
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
Amazon Web Services Japan
 
PDF
Akka Unit Testing
Masashi (Jangsa) Kawaguchi
 
PPTX
Vertica 7.2.3 新機能
Kaito Tono
 
PDF
【18-C-4】Google App Engine - 無限の彼方へ
Developers Summit
 
PPTX
Geeklog2.1新機能紹介 20140723
Tetsuko Komma
 
PPTX
CLRH_120414_WFTDD
Tomoyuki Obi
 
PDF
PostgreSQL 10 新機能 @オープンセミナー香川 2017
Shigeru Hanada
 
PDF
PHPUnit でテスト駆動開発を始めよう
Yuya Takeyama
 
PDF
Presto ベースのマネージドサービス Amazon Athena
Amazon Web Services Japan
 
PDF
Elasticsearchプラグインの作り方
Shinsuke Sugaya
 
キーワード駆動によるシステムテストの自動化について 2015
Toru Koido
 
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
Sencha ug3 siesta_share
久司 中村
 
Apexコアデベロッパーセミナー(Apexコード)071010
stomita
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
Akira Inoue
 
Cubby 2006-08-23
Agata Toshikata
 
究極のバッチフレームワーク(予定)
fumoto kazuhiro
 
Vertica 8.1.0 新機能
Kaito Tono
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
normalian
 
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
Amazon Web Services Japan
 
Akka Unit Testing
Masashi (Jangsa) Kawaguchi
 
Vertica 7.2.3 新機能
Kaito Tono
 
【18-C-4】Google App Engine - 無限の彼方へ
Developers Summit
 
Geeklog2.1新機能紹介 20140723
Tetsuko Komma
 
CLRH_120414_WFTDD
Tomoyuki Obi
 
PostgreSQL 10 新機能 @オープンセミナー香川 2017
Shigeru Hanada
 
PHPUnit でテスト駆動開発を始めよう
Yuya Takeyama
 
Presto ベースのマネージドサービス Amazon Athena
Amazon Web Services Japan
 
Elasticsearchプラグインの作り方
Shinsuke Sugaya
 
Ad

More from Nao Oec (10)

PPTX
Pgx user meeting_20170602
Nao Oec
 
PPTX
Lodチャレンジ2016 エリアベンチマーキング資料
Nao Oec
 
PPTX
RESASを使った静岡市の新しい産業の創成手法サンプル
Nao Oec
 
PPTX
Python neo4j cytoscapejsでデータ可視化入門
Nao Oec
 
PDF
Dockerで作るd3.jsインタラクション共有&DL環境
Nao Oec
 
PDF
Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識
Nao Oec
 
PDF
コンピュータビジョン7章資料_20140830読書会
Nao Oec
 
PDF
Open streetmapハンズオン@静岡まとめ
Nao Oec
 
PDF
Shizuokapy 3 oec_nlp
Nao Oec
 
PDF
iLeafletとは何か
Nao Oec
 
Pgx user meeting_20170602
Nao Oec
 
Lodチャレンジ2016 エリアベンチマーキング資料
Nao Oec
 
RESASを使った静岡市の新しい産業の創成手法サンプル
Nao Oec
 
Python neo4j cytoscapejsでデータ可視化入門
Nao Oec
 
Dockerで作るd3.jsインタラクション共有&DL環境
Nao Oec
 
Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識
Nao Oec
 
コンピュータビジョン7章資料_20140830読書会
Nao Oec
 
Open streetmapハンズオン@静岡まとめ
Nao Oec
 
Shizuokapy 3 oec_nlp
Nao Oec
 
iLeafletとは何か
Nao Oec
 
Ad

Recently uploaded (8)

PDF
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
PDF
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
PDF
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
PDF
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PDF
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
PDF
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
PDF
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
PDF
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 
Hyperledger Fabric最新v3.x系での機能強化、変更点にキャッチアップ!
LFDT Tokyo Meetup
 
プライバシ保護のためのインターネットアーキテクチャの進化 (2025-07-11)
Jun Kurihara
 
Hyperledger Fabric公式サンプル fabric-samples徹底解説
LFDT Tokyo Meetup
 
20250710_Devinで切り拓くDB革命_〜価値創出に集中せよ〜.pdf
Masaki Yamakawa
 
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
人気ブロックチェーン基盤「Hyperledger Fabric」最新版を動かしてみた!
LFDT Tokyo Meetup
 

Shizuoka.py #6 WebTestでWeb APIのテスト & Pythonメタプログラミングでテストの自動生成