SlideShare une entreprise Scribd logo
1  sur  19
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

Contenu connexe

En vedette

Tensor flowを使った キュウリの仕分け あれこれ
Tensor flowを使った キュウリの仕分け あれこれTensor flowを使った キュウリの仕分け あれこれ
Tensor flowを使った キュウリの仕分け あれこれ
Makoto Koike
 
For My Tay
For My TayFor My Tay
For My Tay
kfudarky
 

En vedette (20)

Shizuoka.py #6 lt 確定申告をpythonで乗り切る
Shizuoka.py #6 lt  確定申告をpythonで乗り切るShizuoka.py #6 lt  確定申告をpythonで乗り切る
Shizuoka.py #6 lt 確定申告をpythonで乗り切る
 
Tensor flowを使った キュウリの仕分け あれこれ
Tensor flowを使った キュウリの仕分け あれこれTensor flowを使った キュウリの仕分け あれこれ
Tensor flowを使った キュウリの仕分け あれこれ
 
数学史 黎明期
数学史 黎明期数学史 黎明期
数学史 黎明期
 
TensorFlowによるFizz Buzz
TensorFlowによるFizz BuzzTensorFlowによるFizz Buzz
TensorFlowによるFizz Buzz
 
ClickでCLIをお手軽につくるぅぅぅ
ClickでCLIをお手軽につくるぅぅぅClickでCLIをお手軽につくるぅぅぅ
ClickでCLIをお手軽につくるぅぅぅ
 
サザエさんのじゃんけん データ分析
サザエさんのじゃんけん データ分析サザエさんのじゃんけん データ分析
サザエさんのじゃんけん データ分析
 
第一回 機械学習
第一回 機械学習第一回 機械学習
第一回 機械学習
 
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
 
PGXでつぶやきの類似度によるグラフを生成してみた
PGXでつぶやきの類似度によるグラフを生成してみたPGXでつぶやきの類似度によるグラフを生成してみた
PGXでつぶやきの類似度によるグラフを生成してみた
 
For My Tay
For My TayFor My Tay
For My Tay
 
BROOKLYN_DSM
BROOKLYN_DSMBROOKLYN_DSM
BROOKLYN_DSM
 
recent advancement in contraceptives
recent advancement in contraceptivesrecent advancement in contraceptives
recent advancement in contraceptives
 
My balsamiqproject pdf
My balsamiqproject pdfMy balsamiqproject pdf
My balsamiqproject pdf
 
Belgium franchise. Bebe de Paris. baby gifts
Belgium franchise. Bebe de Paris. baby giftsBelgium franchise. Bebe de Paris. baby gifts
Belgium franchise. Bebe de Paris. baby gifts
 
Powerpoint ingles
Powerpoint inglesPowerpoint ingles
Powerpoint ingles
 
Twitter retweet analysis
Twitter retweet analysisTwitter retweet analysis
Twitter retweet analysis
 
בניית תכנית שנתית
בניית תכנית שנתיתבניית תכנית שנתית
בניית תכנית שנתית
 
Plan educativo maternidad
Plan educativo maternidadPlan educativo maternidad
Plan educativo maternidad
 
最近の単体テスト
最近の単体テスト最近の単体テスト
最近の単体テスト
 
Didatica Docente - Educacion
Didatica Docente - EducacionDidatica Docente - Educacion
Didatica Docente - Educacion
 

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

Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGood
Atsuhiro Kubo
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説
Akira Inoue
 
究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)
fumoto kazuhiro
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
Developers Summit
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めよう
Yuya Takeyama
 

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

キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015キーワード駆動によるシステムテストの自動化について 2015
キーワード駆動によるシステムテストの自動化について 2015
 
Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGood
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share
 
Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010Apexコアデベロッパーセミナー(Apexコード)071010
Apexコアデベロッパーセミナー(Apexコード)071010
 
ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説ASP.NET シングル ページ アプリケーション (SPA) 詳説
ASP.NET シングル ページ アプリケーション (SPA) 詳説
 
Cubby 2006-08-23
Cubby 2006-08-23Cubby 2006-08-23
Cubby 2006-08-23
 
究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)
 
Vertica 8.1.0 新機能
Vertica 8.1.0 新機能Vertica 8.1.0 新機能
Vertica 8.1.0 新機能
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
AWS Black Belt Tech シリーズ 2015 - AWS Elastic BeanstalkAWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
AWS Black Belt Tech シリーズ 2015 - AWS Elastic Beanstalk
 
Akka Unit Testing
Akka Unit TestingAkka Unit Testing
Akka Unit Testing
 
Vertica 7.2.3 新機能
Vertica 7.2.3 新機能Vertica 7.2.3 新機能
Vertica 7.2.3 新機能
 
【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ【18-C-4】Google App Engine - 無限の彼方へ
【18-C-4】Google App Engine - 無限の彼方へ
 
pi-6. 繰り返し
pi-6. 繰り返しpi-6. 繰り返し
pi-6. 繰り返し
 
Geeklog2.1新機能紹介 20140723
Geeklog2.1新機能紹介 20140723Geeklog2.1新機能紹介 20140723
Geeklog2.1新機能紹介 20140723
 
CLRH_120414_WFTDD
CLRH_120414_WFTDDCLRH_120414_WFTDD
CLRH_120414_WFTDD
 
PostgreSQL 10 新機能 @オープンセミナー香川 2017
PostgreSQL 10 新機能 @オープンセミナー香川 2017PostgreSQL 10 新機能 @オープンセミナー香川 2017
PostgreSQL 10 新機能 @オープンセミナー香川 2017
 
PHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めようPHPUnit でテスト駆動開発を始めよう
PHPUnit でテスト駆動開発を始めよう
 
Presto ベースのマネージドサービス Amazon Athena
Presto ベースのマネージドサービス Amazon AthenaPresto ベースのマネージドサービス Amazon Athena
Presto ベースのマネージドサービス Amazon Athena
 

Plus de Nao Oec

Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識
Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識
Shizuokapy4_データヴィジュアライズのための簡単なWeb API開発まめ知識
Nao Oec
 
Open streetmapハンズオン@静岡まとめ
Open streetmapハンズオン@静岡まとめOpen streetmapハンズオン@静岡まとめ
Open streetmapハンズオン@静岡まとめ
Nao Oec
 
Shizuokapy 3 oec_nlp
Shizuokapy 3 oec_nlpShizuokapy 3 oec_nlp
Shizuokapy 3 oec_nlp
Nao Oec
 
iLeafletとは何か
iLeafletとは何かiLeafletとは何か
iLeafletとは何か
Nao Oec
 

Plus de Nao Oec (10)

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

Dernier

Dernier (11)

Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 

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