テストケースに適用するFakerの動作を動的に選択する方法はありますか?
Fakerのアクション関数とテストケースの関連付けは、Illusionオブジェクトによって行われます。通常、以下の図のようにIllusionオブジェクトは複数のFakerアクション関数を包含し、テストケースはIllusionオブジェクトを包含することによってテストケース実行時のFakerアクションを適用します。
この場合、規模の大きいプロジェクトで頻繁にfake動作が増減するとIllusionとTestcaseも追従させる必要が生じ、管理が煩雑になります。このような負担を軽減するため、v21.2LTS-patch20211026
以降のリリースから Dynamic Illusion機能
を提供しています。
Dynamic Illusion
Dynamic Illusionは、従来のIllusionが保持するfakers属性にPythonスクリプトを記述する機能です。スクリプトは、引数にTestcase情報が与えられ、それらを元に動的に適用するFakerアクション関数のマップを生成して返却することができます。これによって一つのIllusionに複数のTestcaseを関連付け、Testcase毎に適用するFakerアクションを動的に関連付けることが可能となり、テストと擬似動作の対応付けを一つのIllusionに集約して管理することが出来ます。
Dynamic Illusionによる関連付けのイメージは以下の図のようになります。
サンプルプラグイン
Scenarioプラグイン
SampleScenario
- category: DynamicIllusionTest
name: SampleScenario
uri: /v1/dynamicIllusionTests
method: GET
connect_timeout: 60
request_timeout: 60
commands:
- command: script
kwargs:
code: |-
faker("SampleFakerA")
r = await callout(path="/sampleEndpointA")
if r.error:
raise Error(r.code)
faker("SampleFakerB")
r = await callout(path="/sampleEndpointB")
if r.error:
raise Error(r.code)
context.session.finish()
Fakerプラグイン
SampleFakerA
category: DynamicIllusionTest
name: SampleFakerA
fakes:
BadRequest:
script: |-
async def BadRequest(*args, **kwargs):
return FakeHttpResponse(code=400, body={"status": False})
Success:
script: |-
async def Success(*args, **kwargs):
return FakeHttpResponse(body={"status": True})
SampleFakerB
category: DynamicIllusionTest
name: SampleFakerB
fakes:
BadRequest:
script: |-
async def BadRequest(*args, **kwargs):
return FakeHttpResponse(code=400, body={"status": False})
Success:
script: |-
async def Success(*args, **kwargs):
return FakeHttpResponse(body={"status": True})
Illusionプラグイン
SampleDynamicIllusion
category: DynamicIllusionTest
name: SampleDynamicIllusion
fakers: |-
def generateFakers(testcase):
if testcase.name=="NormalTest":
return {"SampleFakerA": "Success", "SampleFakerB": "Success"}
elif testcase.name=="SubnormalATest":
return {"SampleFakerA": "BadRequest", "SampleFakerB": "Success"}
elif testcase.name=="SubnormalBTest":
return {"SampleFakerA": "Success", "SampleFakerB": "BadRequest"}
else:
return {"SampleFakerA": "BadRequest", "SampleFakerB": "BadRequest"}
Tip
本サンプルでは、テストケース名で適用するFakerマップを生成していますが、v21.2LTS-patch20211026
以降のリリースからTestcaseに任意のメタデータ辞書(metadata属性)を保持できるようになっているため、Fakerマップ生成に利用することが出来ます。またIllusionに記述するscript関数は非同期関数もサポートされているため、データベースにテストケースとFaker情報のマッピングテーブルを管理しておいて検索してくるという手法を取ることも可能です。
Testcaseプラグイン
NormalTest
category: DynamicIllusionTest
name: NormalTest
target: SampleScenario
type: testcase
illusion: SampleDynamicIllusion
input:
method: GET
path: /v1/dynamicIllusionTests
assertion:
begin: |-
async def hoge(*args, **kwargs):
pass
output: |-
async def hoge(*args, **kwargs):
assert Response.code==200, f"Invalid response code {Response.code}"
progress: []
SubnormalATest
category: DynamicIllusionTest
name: SubnormalATest
target: SampleScenario
type: testcase
illusion: SampleDynamicIllusion
input:
method: GET
path: /v1/dynamicIllusionTests
assertion:
begin: |-
async def hoge(*args, **kwargs):
pass
output: |-
async def hoge(*args, **kwargs):
assert Response.code==400, f"Invalid response code {Response.code}"
progress: []
SubnormalBTest
category: DynamicIllusionTest
name: SubnormalBTest
target: SampleScenario
type: testcase
illusion: SampleDynamicIllusion
input:
method: GET
path: /v1/dynamicIllusionTests
assertion:
begin: |-
async def hoge(*args, **kwargs):
pass
output: |-
async def hoge(*args, **kwargs):
assert Response.code==400, f"Invalid response code {Response.code}"
progress: []
SubnormalAllTest
category: DynamicIllusionTest
name: SubnormalAllTest
target: SampleScenario
type: testcase
illusion: SampleDynamicIllusion
input:
method: GET
path: /v1/dynamicIllusionTests
assertion:
begin: |-
async def hoge(*args, **kwargs):
pass
output: |-
async def hoge(*args, **kwargs):
assert Response.code==400, f"Invalid response code {Response.code}"
progress: []